Commit in reactos on ELF_support
Makefile+1-11.262.2.2 -> 1.262.2.3
drivers/dd/null/makefile+1-11.19.10.2 -> 1.19.10.3
drivers/fs/cdfs/common.c+1-11.7.28.1 -> 1.7.28.2
drivers/fs/vfat/cleanup.c+1-11.15.6.2 -> 1.15.6.3
               /create.c+1-11.75.2.2 -> 1.75.2.3
               /dir.c+1-11.35.2.2 -> 1.35.2.3
               /direntry.c+1-11.17.8.2 -> 1.17.8.3
               /dirwr.c+1-11.42.2.2 -> 1.42.2.3
               /fat.c+1-11.46.8.2 -> 1.46.8.3
               /fcb.c+1-11.42.2.2 -> 1.42.2.3
               /finfo.c+1-11.38.2.2 -> 1.38.2.3
               /fsctl.c+1-11.36.2.2 -> 1.36.2.3
               /misc.c+1-11.14.2.2 -> 1.14.2.3
               /rw.c+1-11.71.2.2 -> 1.71.2.3
               /shutdown.c+1-11.8.34.2 -> 1.8.34.3
               /vfat.h+1-11.69.2.2 -> 1.69.2.3
               /volume.c+1-11.27.2.2 -> 1.27.2.3
drivers/lib/ip/makefile+1-11.7.2.2 -> 1.7.2.3
drivers/lib/ip/transport/tcp/tcp.c-1251.9.2.2 -> 1.9.2.3
drivers/net/afd/afd/connect.c+1-11.5.2.2 -> 1.5.2.3
                   /info.c+1-11.4.8.2 -> 1.4.8.3
                   /main.c+1-11.13.2.2 -> 1.13.2.3
                   /read.c+1-11.12.2.2 -> 1.12.2.3
                   /select.c+1-11.7.2.2 -> 1.7.2.3
                   /tdiconn.c+1-11.5.2.1 -> 1.5.2.2
                   /write.c+1-11.12.2.2 -> 1.12.2.3
drivers/net/afd/include/afd.h+1-11.25.2.2 -> 1.25.2.3
drivers/net/afd/makefile+1-11.14.2.2 -> 1.14.2.3
drivers/net/tcpip/datalink/lan.c-21.27.2.2 -> 1.27.2.3
drivers/net/tcpip/makefile+1-11.31.2.2 -> 1.31.2.3
drivers/video/displays/vga/main/enable.c+2-21.3.20.2 -> 1.3.20.3
drivers/video/displays/vga/objects/pointer.c+1-11.3.10.1 -> 1.3.10.2
hal/halx86/include/hal.h+2-21.15.2.1 -> 1.15.2.2
include/ddk/iofuncs.h+1-11.46.2.2 -> 1.46.2.3
           /iotypes.h+1-11.69.2.2 -> 1.69.2.3
include/ntdll/rtl.h+1-11.52.2.2 -> 1.52.2.3
include/ntos/haltypes.h+1-11.9.2.2 -> 1.9.2.3
            /rtl.h+1-11.38.2.2 -> 1.38.2.3
            /zw.h+1-11.35.2.3 -> 1.35.2.4
lib/advapi32/advapi32.def+1-11.25.2.1 -> 1.25.2.2
            /makefile+1-11.42.8.1 -> 1.42.8.2
lib/advapi32/misc/sysfunc.c+1-11.8.8.1 -> 1.8.8.2
lib/advapi32/reg/reg.c+1-11.63.2.2 -> 1.63.2.3
lib/advapi32/sec/misc.c+120-281.27.2.1 -> 1.27.2.2
lib/advapi32/token/token.c+1-11.14.6.1 -> 1.14.6.2
lib/cabinet/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/comctl32/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/cpl/ncpa/tcpip_properties.c+1-11.4.2.1 -> 1.4.2.2
lib/dinput/Makefile+1-11.2.16.2 -> 1.2.16.3
lib/dnsapi/Makefile+1-11.5.16.2 -> 1.5.16.3
lib/expat/Makefile+1-11.3.16.2 -> 1.3.16.3
lib/freetype/i386/setjmplongjmp.s+1-11.1.34.2 -> 1.1.34.3
lib/icmp/Makefile.ros-template+1-11.1.6.2 -> 1.1.6.3
lib/iphlpapi/Makefile.ros-template+1-11.2.16.2 -> 1.2.16.3
lib/kernel32/debug/debugger.c+1-11.4.22.1 -> 1.4.22.2
lib/kernel32/except/except.c+16-281.18.2.1 -> 1.18.2.2
lib/kernel32/file/create.c+1-11.40.2.2 -> 1.40.2.3
                 /delete.c+1-11.17.8.2 -> 1.17.8.3
                 /dir.c+1-11.50.2.1 -> 1.50.2.2
                 /file.c+1-11.60.2.2 -> 1.60.2.3
                 /iocompl.c+1-11.15.2.2 -> 1.15.2.3
                 /move.c+1-11.14.16.2 -> 1.14.16.3
lib/kernel32/include/kernel32.h+21.6.10.1 -> 1.6.10.2
lib/kernel32/makefile+1-11.89.2.2 -> 1.89.2.3
lib/kernel32/misc/atom.c+1-11.20.16.2 -> 1.20.16.3
                 /dllmain.c+1-11.37.2.2 -> 1.37.2.3
                 /lang.c+1-11.24.2.2 -> 1.24.2.3
                 /stubs.c+1-11.94.2.2 -> 1.94.2.3
                 /time.c+1-11.32.2.2 -> 1.32.2.3
lib/kernel32/process/create.c+23-101.89.2.1 -> 1.89.2.2
lib/kernel32/synch/wait.c+1-11.31.2.2 -> 1.31.2.3
lib/kernel32/thread/thread.c+34-61.56.2.2 -> 1.56.2.3
lib/kjs/makefile+1-11.1.24.2 -> 1.1.24.3
lib/libwine/makefile+1-11.3.6.2 -> 1.3.6.3
lib/midimap/Makefile.ros-template+1-11.1.2.2 -> 1.1.2.3
lib/mpr/Makefile.ros-template+1-11.3.2.2 -> 1.3.2.3
lib/msacm/Makefile.ros-template+1-11.3.8.2 -> 1.3.8.3
lib/msvcrt/Makefile+1-11.48.6.2 -> 1.48.6.3
lib/msvcrt/setjmp/i386/setjmp.s+1-11.1.34.2 -> 1.1.34.3
lib/msvideo/Makefile.ros-template+1-11.1.8.2 -> 1.1.8.3
lib/netapi32/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/ntdll/def/ntdll.def+1-11.134.2.2 -> 1.134.2.3
lib/ntdll/rtl/path.c+1-11.29.8.2 -> 1.29.8.3
lib/odbc32/Makefile.ros-template+1-11.2.16.2 -> 1.2.16.3
lib/ole32/Makefile.ros-template+1-11.2.16.2 -> 1.2.16.3
lib/oleaut32/Makefile.ros-template+1-11.5.2.2 -> 1.5.2.3
lib/oledlg/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/olepro32/Makefile.ros-template+1-11.2.16.2 -> 1.2.16.3
lib/riched20/Makefile.ros-template+1-11.1.2.2 -> 1.1.2.3
lib/richedit/Makefile.ros-template+1-11.2.16.2 -> 1.2.16.3
lib/rpcrt4/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/rtl/acl.c+1-11.4.2.2 -> 1.4.2.3
       /largeint.c+1-11.1.18.1 -> 1.1.18.2
       /mem.c+1-11.2.8.2 -> 1.2.8.3
       /nls.c+1-11.1.18.2 -> 1.1.18.3
lib/setupapi/Makefile.ros-template+1-11.4.16.2 -> 1.4.16.3
lib/shell32/Makefile.ros-template+1-11.6.2.2 -> 1.6.2.3
lib/shlwapi/Makefile.ros-template+1-11.9.2.2 -> 1.9.2.3
lib/string/strncpy.c+1-11.2.34.2 -> 1.2.34.3
lib/syssetup/syssetup.rc+1-11.8.2.2 -> 1.8.2.3
            /wizard.c+1-11.15.2.2 -> 1.15.2.3
lib/twain/Makefile+1-11.7.16.2 -> 1.7.16.3
lib/unicode/Makefile.ros-template+1-11.3.2.2 -> 1.3.2.3
lib/urlmon/Makefile.ros-template+1-11.2.8.2 -> 1.2.8.3
lib/user32/Makefile+1-11.40.8.2 -> 1.40.8.3
lib/user32/misc/display.c+1-11.13.2.1 -> 1.13.2.2
               /misc.c+1-11.9.2.2 -> 1.9.2.3
               /stubs.c+1-11.68.2.1 -> 1.68.2.2
lib/user32/windows/class.c+1-11.51.8.2 -> 1.51.8.3
                  /defwnd.c+1-11.147.2.1 -> 1.147.2.2
                  /font.c+1-11.11.8.2 -> 1.11.8.3
                  /input.c+1-11.25.8.1 -> 1.25.8.2
                  /menu.c+1-11.71.6.2 -> 1.71.6.3
                  /message.c+1-11.43.6.2 -> 1.43.6.3
                  /messagebox.c+1-11.29.2.1 -> 1.29.2.2
lib/userenv/environment.c+1-11.8.2.2 -> 1.8.2.3
lib/version/makefile+1-11.15.16.2 -> 1.15.16.3
lib/winmm/Makefile.ros-template+1-11.3.16.2 -> 1.3.16.3
lib/winmm/midimap/Makefile.ros-template+1-11.3.2.2 -> 1.3.2.3
lib/winmm/wavemap/Makefile.ros-template+1-11.2.8.2 -> 1.2.8.3
lib/ws2_32/makefile+1-11.18.2.2 -> 1.18.2.3
ntoskrnl/cm/import.c+1-11.30.8.1 -> 1.30.8.2
           /registry.c+1-11.128.2.1 -> 1.128.2.2
ntoskrnl/dbg/print.c+1-11.20.8.1 -> 1.20.8.2
ntoskrnl/ex/i386/interlck.c+1-11.9.6.1 -> 1.9.6.2
ntoskrnl/ex/sysinfo.c+1-11.59.2.3 -> 1.59.2.4
           /time.c+1-11.24.2.3 -> 1.24.2.4
ntoskrnl/include/internal/io.h+1-11.49.2.2 -> 1.49.2.3
                         /kd.h+1-11.28.2.1 -> 1.28.2.2
                         /ps.h+1-11.75.2.2 -> 1.75.2.3
ntoskrnl/io/bootlog.c+1-11.5.6.1 -> 1.5.6.2
           /driver.c+1-11.55.2.1 -> 1.55.2.2
           /parttab.c+1-11.8.8.2 -> 1.8.8.3
ntoskrnl/kd/kdebug.c+1-11.56.2.1 -> 1.56.2.2
ntoskrnl/ke/bug.c+1-11.47.2.1 -> 1.47.2.2
           /dpc.c+1-11.48.2.2 -> 1.48.2.3
           /ipi.c+1-11.3.2.2 -> 1.3.2.3
           /kthread.c+1-11.58.2.1 -> 1.58.2.2
           /main.c+1-11.206.2.2 -> 1.206.2.3
           /process.c+1-11.31.2.2 -> 1.31.2.3
           /timer.c+1-11.90.2.2 -> 1.90.2.3
ntoskrnl/ke/i386/fpu.c+1-11.17.2.2 -> 1.17.2.3
                /irq.c+1-11.55.2.2 -> 1.55.2.3
ntoskrnl/ldr/init.c+1-11.49.2.2 -> 1.49.2.3
ntoskrnl/mm/i386/page.c+1-11.77.2.2 -> 1.77.2.3
ntoskrnl/mm/npool.c+1-11.92.2.2 -> 1.92.2.3
           /pool.c+1-11.35.6.1 -> 1.35.6.2
           /ppool.c+1-11.33.2.1 -> 1.33.2.2
ntoskrnl/ntoskrnl.def+1-11.201.2.2 -> 1.201.2.3
ntoskrnl/ps/cid.c+1-11.2.2.2 -> 1.2.2.3
           /create.c+1-11.86.2.1 -> 1.86.2.2
           /kill.c+1-11.86.2.2 -> 1.86.2.3
           /process.c+1-11.157.2.2 -> 1.157.2.3
           /thread.c+1-11.138.2.2 -> 1.138.2.3
           /w32call.c+1-11.18.2.2 -> 1.18.2.3
ntoskrnl/se/acl.c+1-11.21.2.1 -> 1.21.2.2
           /token.c+1-11.42.2.1 -> 1.42.2.2
subsys/csrss/win32csr/desktopbg.c+1-11.11.2.2 -> 1.11.2.3
                     /guiconsole.c+1-11.22.2.2 -> 1.22.2.3
subsys/system/winlogon/winlogon.h+1-11.4.8.2 -> 1.4.8.3
subsys/win32k/eng/bitblt.c+1-11.58.10.1 -> 1.58.10.2
                 /clip.c+1-11.22.18.1 -> 1.22.18.2
                 /gradient.c+1-11.11.2.1 -> 1.11.2.2
                 /mouse.c+1-11.77.8.1 -> 1.77.8.2
                 /objects.h+1-11.32.12.1 -> 1.32.12.2
                 /surface.c+1-11.44.12.1 -> 1.44.12.2
                 /xlate.c+1-11.42.8.1 -> 1.42.8.2
subsys/win32k/main/dllmain.c+1-11.82.2.1 -> 1.82.2.2
subsys/win32k/makefile+1-11.105.2.2 -> 1.105.2.3
subsys/win32k/misc/object.c+1-11.12.16.1 -> 1.12.16.2
subsys/win32k/ntuser/class.c+1-11.60.2.1 -> 1.60.2.2
                    /desktop.c+1-11.24.2.2 -> 1.24.2.3
                    /focus.c+1-11.25.2.2 -> 1.25.2.3
                    /input.c+1-11.38.6.1 -> 1.38.6.2
                    /message.c+1-11.75.2.1 -> 1.75.2.2
                    /misc.c+1-11.88.2.2 -> 1.88.2.3
                    /msgqueue.c+1-11.108.2.1 -> 1.108.2.2
                    /painting.c+1-11.87.2.2 -> 1.87.2.3
                    /stubs.c+1-11.47.2.2 -> 1.47.2.3
                    /windc.c+1-11.67.8.1 -> 1.67.8.2
                    /window.c+1-11.250.2.1 -> 1.250.2.2
                    /winpos.c+1-11.124.2.1 -> 1.124.2.2
                    /winsta.c+1-11.67.2.1 -> 1.67.2.2
subsys/win32k/objects/bitmaps.c+1-11.81.2.1 -> 1.81.2.2
                     /brush.c+1-11.40.10.2 -> 1.40.10.3
                     /cliprgn.c+1-11.42.10.2 -> 1.42.10.3
                     /color.c+1-11.50.10.1 -> 1.50.10.2
                     /dc.c+1-11.147.2.2 -> 1.147.2.3
                     /dib.c+1-11.56.12.1 -> 1.56.12.2
                     /fillshap.c+1-11.52.10.1 -> 1.52.10.2
                     /gdiobj.c+13-11.73.6.1 -> 1.73.6.2
                     /line.c+1-11.37.10.1 -> 1.37.10.2
                     /palette.c+1-11.20.12.1 -> 1.20.12.2
                     /pen.c+1-11.16.10.1 -> 1.16.10.2
                     /print.c+1-11.23.8.1 -> 1.23.8.2
                     /region.c+1-11.62.10.1 -> 1.62.10.2
                     /text.c+1-11.112.4.1 -> 1.112.4.2
tools/helper.mk+1-11.95.2.2 -> 1.95.2.3
apps/utils/net/route/makefile+17added 1.1.2.1
                    /route.c+157added 1.1.2.1
                    /route.rc+7added 1.1.2.1
drivers/video/miniport/xboxvmp/.cvsignore+8added 1.1.2.1
                              /Makefile+20added 1.1.2.1
                              /xboxvmp.c+597added 1.1.2.1
                              /xboxvmp.h+130added 1.1.2.1
                              /xboxvmp.rc+7added 1.1.2.1
hal/halx86/generic/adapter.c+679added 1.1.2.1
                  /beep.c+79added 1.1.2.1
                  /bus.c+532added 1.1.2.1
                  /display.c+794added 1.3.2.1
                  /dma.c+444added 1.2.2.1
                  /drive.c+31added 1.1.2.1
                  /enum.c+24added 1.1.2.1
                  /fmutex.c+53added 1.1.2.1
                  /halinit.c+66added 1.3.2.1
                  /ipi.c+26added 1.1.2.1
                  /irql.c+479added 1.1.2.1
                  /isa.c+78added 1.1.2.1
                  /kdbg.c+548added 1.1.2.1
                  /mca.c+82added 1.1.2.1
                  /misc.c+69added 1.1.2.1
                  /pci.c+816added 1.2.2.1
                  /portio.c+342added 1.1.2.1
                  /processor.c+50added 1.1.2.1
                  /pwroff.c+121added 1.1.2.1
                  /reboot.c+72added 1.1.2.1
                  /resource.c+32added 1.1.2.1
                  /spinlock.c+101added 1.1.2.1
                  /sysbus.c+69added 1.1.2.1
                  /sysinfo.c+76added 1.1.2.1
                  /time.c+359added 1.1.2.1
                  /timer.c+366added 1.1.2.1
hal/halx86/mp/.cvsignore+7added 1.1.2.1
             /Makefile+90added 1.4.2.1
             /apic.c+853added 1.1.2.1
             /halinit_mp.c+29added 1.1.2.1
             /halmp.rc+5added 1.1.2.1
             /ipi_mp.c+29added 1.1.2.1
             /mps.S+109added 1.1.2.1
             /mpsboot.asm+106added 1.1.2.1
             /mpsirql.c+400added 1.1.2.1
             /processor_mp.c+1807added 1.1.2.1
             /resource_mp.c+38added 1.1.2.1
hal/halx86/up/.cvsignore+7added 1.1.2.1
             /Makefile+89added 1.4.2.1
             /halinit_up.c+31added 1.1.2.1
             /halup.rc+5added 1.1.2.1
hal/halx86/xbox/.cvsignore+7added 1.1.2.1
               /Makefile+89added 1.4.2.1
               /display_xbox.c+520added 1.3.2.1
               /font.c+281added 1.1.2.1
               /halinit_xbox.c+36added 1.3.2.1
               /halxbox.h+22added 1.3.2.1
               /halxbox.rc+5added 1.1.2.1
               /part_xbox.c+322added 1.1.2.1
               /pci_xbox.c+112added 1.3.2.1
include/internal/port.h+151added 1.5.6.1
lib/advapi32/crypt/.cvsignore+2added 1.1.2.1
                  /crypt.c+1926added 1.2.2.1
                  /crypt.h+86added 1.2.2.1
                  /crypt_des.c+291added 1.2.2.1
                  /crypt_lmhash.c+49added 1.2.2.1
                  /crypt_md4.c+269added 1.2.2.1
                  /crypt_md5.c+279added 1.2.2.1
                  /crypt_sha.c+189added 1.2.2.1
lib/dinput8/.cvsignore+11added 1.1.2.1
           /Makefile.in+16added 1.1.2.1
           /Makefile.ros-template+28added 1.2.2.1
           /dinput8.spec+5added 1.1.2.1
           /dinput8_main.c+83added 1.1.2.1
           /makefile+9added 1.1.2.1
           /version.rc+27added 1.1.2.1
           /winehq2ros.patch+14added 1.1.2.1
lib/msi/.cvsignore+11added 1.2.2.1
       /Makefile+9added 1.1.2.1
       /Makefile.in+50added 1.1.2.1
       /Makefile.ros-template+39added 1.3.2.1
       /action.c+4877added 1.3.2.1
       /cond.tab.c+2022added 1.1.2.1
       /cond.tab.h+40added 1.1.2.1
       /cond.y+774added 1.1.2.1
       /create.c+258added 1.1.2.1
       /distinct.c+293added 1.1.2.1
       /handle.c+215added 1.1.2.1
       /insert.c+238added 1.1.2.1
       /msi.c+1587added 1.3.2.1
       /msi.spec+236added 1.1.2.1
       /msipriv.h+325added 1.1.2.1
       /msiquery.c+485added 1.1.2.1
       /order.c+335added 1.1.2.1
       /package.c+843added 1.1.2.1
       /query.h+139added 1.1.2.1
       /record.c+573added 1.1.2.1
       /regsvr.c+624added 1.1.2.1
       /select.c+290added 1.1.2.1
       /sql.tab.c+2180added 1.1.2.1
       /sql.tab.h+165added 1.1.2.1
       /sql.y+828added 1.1.2.1
       /string.c+459added 1.1.2.1
       /suminfo.c+234added 1.2.2.1
       /table.c+1425added 1.3.2.1
       /tokenize.c+397added 1.1.2.1
       /update.c+239added 1.1.2.1
       /version.rc+26added 1.1.2.1
       /where.c+471added 1.1.2.1
       /winehq2ros.patch+99added 1.3.2.1
lib/msvcrt/tests/.cvsignore+6added 1.1.2.1
                /Makefile+34added 1.2.2.1
                /Makefile.in+21added 1.1.2.1
                /cpp.c+831added 1.2.2.1
                /environ.c+38added 1.2.2.1
                /file.c+331added 1.1.2.1
                /heap.c+42added 1.1.2.1
                /msvcrt_test.dsp+107added 1.1.2.1
                /printf.c+151added 1.1.2.1
                /scanf.c+103added 1.1.2.1
                /string.c+51added 1.1.2.1
                /testlist.c+39added 1.1.2.1
                /time.c+189added 1.1.2.1
+38894-392
121 added + 198 modified, total 319 files
In hell, child rapists are forced to resolve CVS HEAD merge conflicts... FOREVER. Please let SVN be

reactos
Makefile 1.262.2.2 -> 1.262.2.3
diff -u -r1.262.2.2 -r1.262.2.3
--- Makefile	13 Dec 2004 09:38:44 -0000	1.262.2.2
+++ Makefile	13 Dec 2004 16:17:57 -0000	1.262.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.262.2.2 2004/12/13 09:38:44 hyperion Exp $
+# $Id: Makefile,v 1.262.2.3 2004/12/13 16:17:57 hyperion Exp $
 #
 # Global makefile
 #

reactos/drivers/dd/null
makefile 1.19.10.2 -> 1.19.10.3
diff -u -r1.19.10.2 -r1.19.10.3
--- makefile	13 Dec 2004 09:38:46 -0000	1.19.10.2
+++ makefile	13 Dec 2004 16:17:58 -0000	1.19.10.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.19.10.2 2004/12/13 09:38:46 hyperion Exp $
+# $Id: makefile,v 1.19.10.3 2004/12/13 16:17:58 hyperion Exp $
 
 PATH_TO_TOP = ../../..
 

reactos/drivers/fs/cdfs
common.c 1.7.28.1 -> 1.7.28.2
diff -u -r1.7.28.1 -r1.7.28.2
--- common.c	13 Dec 2004 09:38:46 -0000	1.7.28.1
+++ common.c	13 Dec 2004 16:17:58 -0000	1.7.28.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: common.c,v 1.7.28.1 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: common.c,v 1.7.28.2 2004/12/13 16:17:58 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
cleanup.c 1.15.6.2 -> 1.15.6.3
diff -u -r1.15.6.2 -r1.15.6.3
--- cleanup.c	13 Dec 2004 09:38:46 -0000	1.15.6.2
+++ cleanup.c	13 Dec 2004 16:17:58 -0000	1.15.6.3
@@ -1,4 +1,4 @@
-/* $Id: cleanup.c,v 1.15.6.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: cleanup.c,v 1.15.6.3 2004/12/13 16:17:58 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
create.c 1.75.2.2 -> 1.75.2.3
diff -u -r1.75.2.2 -r1.75.2.3
--- create.c	13 Dec 2004 09:38:46 -0000	1.75.2.2
+++ create.c	13 Dec 2004 16:17:58 -0000	1.75.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: create.c,v 1.75.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: create.c,v 1.75.2.3 2004/12/13 16:17:58 hyperion Exp $
  *
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/fs/vfat/create.c

reactos/drivers/fs/vfat
dir.c 1.35.2.2 -> 1.35.2.3
diff -u -r1.35.2.2 -r1.35.2.3
--- dir.c	13 Dec 2004 09:38:46 -0000	1.35.2.2
+++ dir.c	13 Dec 2004 16:17:58 -0000	1.35.2.3
@@ -1,5 +1,5 @@
 /*
- * $Id: dir.c,v 1.35.2.2 2004/12/13 09:38:46 hyperion Exp $
+ * $Id: dir.c,v 1.35.2.3 2004/12/13 16:17:58 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
direntry.c 1.17.8.2 -> 1.17.8.3
diff -u -r1.17.8.2 -r1.17.8.3
--- direntry.c	13 Dec 2004 09:38:46 -0000	1.17.8.2
+++ direntry.c	13 Dec 2004 16:17:58 -0000	1.17.8.3
@@ -1,4 +1,4 @@
-/* $Id: direntry.c,v 1.17.8.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: direntry.c,v 1.17.8.3 2004/12/13 16:17:58 hyperion Exp $
  *
  *
  * FILE:             DirEntry.c

reactos/drivers/fs/vfat
dirwr.c 1.42.2.2 -> 1.42.2.3
diff -u -r1.42.2.2 -r1.42.2.3
--- dirwr.c	13 Dec 2004 09:38:46 -0000	1.42.2.2
+++ dirwr.c	13 Dec 2004 16:17:58 -0000	1.42.2.3
@@ -1,4 +1,4 @@
-/* $Id: dirwr.c,v 1.42.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: dirwr.c,v 1.42.2.3 2004/12/13 16:17:58 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
fat.c 1.46.8.2 -> 1.46.8.3
diff -u -r1.46.8.2 -r1.46.8.3
--- fat.c	13 Dec 2004 09:38:46 -0000	1.46.8.2
+++ fat.c	13 Dec 2004 16:17:58 -0000	1.46.8.3
@@ -1,5 +1,5 @@
 /*
- * $Id: fat.c,v 1.46.8.2 2004/12/13 09:38:46 hyperion Exp $
+ * $Id: fat.c,v 1.46.8.3 2004/12/13 16:17:58 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
fcb.c 1.42.2.2 -> 1.42.2.3
diff -u -r1.42.2.2 -r1.42.2.3
--- fcb.c	13 Dec 2004 09:38:46 -0000	1.42.2.2
+++ fcb.c	13 Dec 2004 16:17:58 -0000	1.42.2.3
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.42.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: fcb.c,v 1.42.2.3 2004/12/13 16:17:58 hyperion Exp $
  *
  *
  * FILE:             drivers/fs/vfat/fcb.c

reactos/drivers/fs/vfat
finfo.c 1.38.2.2 -> 1.38.2.3
diff -u -r1.38.2.2 -r1.38.2.3
--- finfo.c	13 Dec 2004 09:38:46 -0000	1.38.2.2
+++ finfo.c	13 Dec 2004 16:17:59 -0000	1.38.2.3
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.38.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: finfo.c,v 1.38.2.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
fsctl.c 1.36.2.2 -> 1.36.2.3
diff -u -r1.36.2.2 -r1.36.2.3
--- fsctl.c	13 Dec 2004 09:38:46 -0000	1.36.2.2
+++ fsctl.c	13 Dec 2004 16:17:59 -0000	1.36.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fsctl.c,v 1.36.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: fsctl.c,v 1.36.2.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
misc.c 1.14.2.2 -> 1.14.2.3
diff -u -r1.14.2.2 -r1.14.2.3
--- misc.c	13 Dec 2004 09:38:46 -0000	1.14.2.2
+++ misc.c	13 Dec 2004 16:17:59 -0000	1.14.2.3
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.14.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: misc.c,v 1.14.2.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
rw.c 1.71.2.2 -> 1.71.2.3
diff -u -r1.71.2.2 -r1.71.2.3
--- rw.c	13 Dec 2004 09:38:46 -0000	1.71.2.2
+++ rw.c	13 Dec 2004 16:17:59 -0000	1.71.2.3
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.71.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: rw.c,v 1.71.2.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
shutdown.c 1.8.34.2 -> 1.8.34.3
diff -u -r1.8.34.2 -r1.8.34.3
--- shutdown.c	13 Dec 2004 09:38:46 -0000	1.8.34.2
+++ shutdown.c	13 Dec 2004 16:17:59 -0000	1.8.34.3
@@ -1,4 +1,4 @@
-/* $Id: shutdown.c,v 1.8.34.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: shutdown.c,v 1.8.34.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/fs/vfat
vfat.h 1.69.2.2 -> 1.69.2.3
diff -u -r1.69.2.2 -r1.69.2.3
--- vfat.h	13 Dec 2004 09:38:46 -0000	1.69.2.2
+++ vfat.h	13 Dec 2004 16:17:59 -0000	1.69.2.3
@@ -1,4 +1,4 @@
-/* $Id: vfat.h,v 1.69.2.2 2004/12/13 09:38:46 hyperion Exp $ */
+/* $Id: vfat.h,v 1.69.2.3 2004/12/13 16:17:59 hyperion Exp $ */
 
 #include <ddk/ntifs.h>
 

reactos/drivers/fs/vfat
volume.c 1.27.2.2 -> 1.27.2.3
diff -u -r1.27.2.2 -r1.27.2.3
--- volume.c	13 Dec 2004 09:38:47 -0000	1.27.2.2
+++ volume.c	13 Dec 2004 16:17:59 -0000	1.27.2.3
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.27.2.2 2004/12/13 09:38:47 hyperion Exp $
+/* $Id: volume.c,v 1.27.2.3 2004/12/13 16:17:59 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/lib/ip
makefile 1.7.2.2 -> 1.7.2.3
diff -u -r1.7.2.2 -r1.7.2.3
--- makefile	13 Dec 2004 09:38:47 -0000	1.7.2.2
+++ makefile	13 Dec 2004 16:18:00 -0000	1.7.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.7.2.2 2004/12/13 09:38:47 hyperion Exp $
+# $Id: makefile,v 1.7.2.3 2004/12/13 16:18:00 hyperion Exp $
 
 PATH_TO_TOP = ../../..
 

reactos/drivers/lib/ip/transport/tcp
tcp.c 1.9.2.2 -> 1.9.2.3
diff -u -r1.9.2.2 -r1.9.2.3
--- tcp.c	13 Dec 2004 09:38:47 -0000	1.9.2.2
+++ tcp.c	13 Dec 2004 16:18:00 -0000	1.9.2.3
@@ -144,131 +144,6 @@
     }
 }
 
-static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
-				       ULONG NewState ) {
-    NTSTATUS Status = STATUS_SUCCESS;
-    PTCP_COMPLETION_ROUTINE Complete;
-    PTDI_BUCKET Bucket;
-    PLIST_ENTRY Entry;
-    BOOLEAN CompletedOne = FALSE;
-
-    /* Things that can happen when we try the initial connection */
-    if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
-
-	!(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
-	while( !IsListEmpty( &Connection->ConnectRequest ) ) {
-	    Connection->State |= NewState & (SEL_CONNECT | SEL_FIN);
-	    Entry = RemoveHeadList( &Connection->ConnectRequest );
-	    Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-	    Complete = Bucket->Request.RequestNotifyObject;
-	    TI_DbgPrint(DEBUG_TCP,
-			("Completing Connect Request %x\n", Bucket->Request));
-	    if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED;
-	    Complete( Bucket->Request.RequestContext, Status, 0 );
-	    /* Frees the bucket allocated in TCPConnect */
-	    PoolFreeBuffer( Bucket );
-	}
-    }
-
-    /* Things that happen after we're connected */
-    if( (NewState & SEL_READ) ) {
-	TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
-			       IsListEmpty(&Connection->ReceiveRequest) ?
-			       "empty" : "nonempty"));
-
-	while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
-	    PIRP Irp;
-	    OSK_UINT RecvLen = 0, Received = 0;
-	    OSK_PCHAR RecvBuffer = 0;
-	    PMDL Mdl;
-	    NTSTATUS Status;
-
-	    Entry = RemoveHeadList( &Connection->ReceiveRequest );
-	    Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-	    Complete = Bucket->Request.RequestNotifyObject;
-
-	    TI_DbgPrint(DEBUG_TCP,
-			("Readable, Completing read request %x\n", 
-			 Bucket->Request));
-
-	    Irp = Bucket->Request.RequestContext;
-	    Mdl = Irp->MdlAddress;
-
-	    TI_DbgPrint(DEBUG_TCP,
-			("Getting the user buffer from %x\n", Mdl));
-
-	    NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
-
-	    TI_DbgPrint(DEBUG_TCP,
-			("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
-
-	    TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
-	    TI_DbgPrint
-		(DEBUG_TCP, 
-		 ("Connection->SocketContext: %x\n", 
-		  Connection->SocketContext));
-	    TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
-	    
-	    Status = TCPTranslateError
-		( OskitTCPRecv( Connection->SocketContext,
-				RecvBuffer,
-				RecvLen,
-				&Received,
-				0 ) );
-
-	    TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
-	    
-	    if( Status == STATUS_SUCCESS ) {
-		TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
-				       Received, Status));
-		
-		TI_DbgPrint(DEBUG_TCP,
-			    ("Completing Receive Request: %x\n", 
-			     Bucket->Request));
-
-		Complete( Bucket->Request.RequestContext,
-			  STATUS_SUCCESS, Received );
-		CompletedOne = TRUE;
-	    } else if( Status == STATUS_PENDING ) {
-		InsertHeadList( &Connection->ReceiveRequest,
-				&Bucket->Entry );
-		break;
-	    } else {
-		TI_DbgPrint(DEBUG_TCP,
-			    ("Completing Receive request: %x %x\n",
-			     Bucket->Request, Status));
-		Complete( Bucket->Request.RequestContext, Status, 0 );
-		CompletedOne = TRUE;
-	    }
-	}
-    }
-    if( NewState & SEL_FIN ) {
-	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 );
-	}
-    }
-
-    Connection->Signalled = FALSE;
-}
-
-VOID DrainSignals() {
-    PCONNECTION_ENDPOINT Connection;
-    PLIST_ENTRY ListEntry;
-
-    while( !IsListEmpty( &SignalledConnections ) ) {
-	ListEntry = RemoveHeadList( &SignalledConnections );
-	Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT,
-					SignalList );
-	HandleSignalledConnection( Connection, Connection->SignalState );
-    }
-}
-
 PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
     PCONNECTION_ENDPOINT Connection = 
 	ExAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT));

reactos/drivers/net/afd/afd
connect.c 1.5.2.2 -> 1.5.2.3
diff -u -r1.5.2.2 -r1.5.2.3
--- connect.c	13 Dec 2004 09:38:48 -0000	1.5.2.2
+++ connect.c	13 Dec 2004 16:18:00 -0000	1.5.2.3
@@ -1,4 +1,4 @@
-/* $Id: connect.c,v 1.5.2.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: connect.c,v 1.5.2.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/connect.c

reactos/drivers/net/afd/afd
info.c 1.4.8.2 -> 1.4.8.3
diff -u -r1.4.8.2 -r1.4.8.3
--- info.c	13 Dec 2004 09:38:48 -0000	1.4.8.2
+++ info.c	13 Dec 2004 16:18:00 -0000	1.4.8.3
@@ -1,4 +1,4 @@
-/* $Id: info.c,v 1.4.8.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: info.c,v 1.4.8.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/info.c

reactos/drivers/net/afd/afd
main.c 1.13.2.2 -> 1.13.2.3
diff -u -r1.13.2.2 -r1.13.2.3
--- main.c	13 Dec 2004 09:38:48 -0000	1.13.2.2
+++ main.c	13 Dec 2004 16:18:00 -0000	1.13.2.3
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.13.2.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: main.c,v 1.13.2.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/main.c

reactos/drivers/net/afd/afd
read.c 1.12.2.2 -> 1.12.2.3
diff -u -r1.12.2.2 -r1.12.2.3
--- read.c	13 Dec 2004 09:38:49 -0000	1.12.2.2
+++ read.c	13 Dec 2004 16:18:00 -0000	1.12.2.3
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.12.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: read.c,v 1.12.2.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/read.c

reactos/drivers/net/afd/afd
select.c 1.7.2.2 -> 1.7.2.3
diff -u -r1.7.2.2 -r1.7.2.3
--- select.c	13 Dec 2004 09:38:49 -0000	1.7.2.2
+++ select.c	13 Dec 2004 16:18:00 -0000	1.7.2.3
@@ -1,4 +1,4 @@
-/* $Id: select.c,v 1.7.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: select.c,v 1.7.2.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/select.c

reactos/drivers/net/afd/afd
tdiconn.c 1.5.2.1 -> 1.5.2.2
diff -u -r1.5.2.1 -r1.5.2.2
--- tdiconn.c	13 Dec 2004 09:38:49 -0000	1.5.2.1
+++ tdiconn.c	13 Dec 2004 16:18:00 -0000	1.5.2.2
@@ -1,4 +1,4 @@
-/* $Id: tdiconn.c,v 1.5.2.1 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: tdiconn.c,v 1.5.2.2 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/tdiconn.c

reactos/drivers/net/afd/afd
write.c 1.12.2.2 -> 1.12.2.3
diff -u -r1.12.2.2 -r1.12.2.3
--- write.c	13 Dec 2004 09:38:49 -0000	1.12.2.2
+++ write.c	13 Dec 2004 16:18:00 -0000	1.12.2.3
@@ -1,4 +1,4 @@
-/* $Id: write.c,v 1.12.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: write.c,v 1.12.2.3 2004/12/13 16:18:00 hyperion Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/write.c

reactos/drivers/net/afd/include
afd.h 1.25.2.2 -> 1.25.2.3
diff -u -r1.25.2.2 -r1.25.2.3
--- afd.h	13 Dec 2004 09:38:49 -0000	1.25.2.2
+++ afd.h	13 Dec 2004 16:18:00 -0000	1.25.2.3
@@ -1,4 +1,4 @@
-/* $Id: afd.h,v 1.25.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: afd.h,v 1.25.2.3 2004/12/13 16:18:00 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/drivers/net/afd
makefile 1.14.2.2 -> 1.14.2.3
diff -u -r1.14.2.2 -r1.14.2.3
--- makefile	13 Dec 2004 09:38:49 -0000	1.14.2.2
+++ makefile	13 Dec 2004 16:18:00 -0000	1.14.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.14.2.2 2004/12/13 09:38:49 hyperion Exp $
+# $Id: makefile,v 1.14.2.3 2004/12/13 16:18:00 hyperion Exp $
 
 PATH_TO_TOP = ../../..
 

reactos/drivers/net/tcpip/datalink
lan.c 1.27.2.2 -> 1.27.2.3
diff -u -r1.27.2.2 -r1.27.2.3
--- lan.c	13 Dec 2004 09:38:49 -0000	1.27.2.2
+++ lan.c	13 Dec 2004 16:18:00 -0000	1.27.2.3
@@ -354,8 +354,6 @@
 
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
     if( Status != NDIS_STATUS_SUCCESS ) return;
     TcpipAcquireSpinLock( &LanWorkLock, &OldIrql );
     

reactos/drivers/net/tcpip
makefile 1.31.2.2 -> 1.31.2.3
diff -u -r1.31.2.2 -r1.31.2.3
--- makefile	13 Dec 2004 09:38:49 -0000	1.31.2.2
+++ makefile	13 Dec 2004 16:18:01 -0000	1.31.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.31.2.2 2004/12/13 09:38:49 hyperion Exp $
+# $Id: makefile,v 1.31.2.3 2004/12/13 16:18:01 hyperion Exp $
 
 PATH_TO_TOP = ../../..
 

reactos/drivers/video/displays/vga/main
enable.c 1.3.20.2 -> 1.3.20.3
diff -u -r1.3.20.2 -r1.3.20.3
--- enable.c	13 Dec 2004 09:38:50 -0000	1.3.20.2
+++ enable.c	13 Dec 2004 16:18:01 -0000	1.3.20.3
@@ -1,9 +1,9 @@
 /*
  * entry.c
  *
- * $Revision: 1.3.20.2 $
+ * $Revision: 1.3.20.3 $
  * $Author: hyperion $
- * $Date: 2004/12/13 09:38:50 $
+ * $Date: 2004/12/13 16:18:01 $
  *
  */
 

reactos/drivers/video/displays/vga/objects
pointer.c 1.3.10.1 -> 1.3.10.2
diff -u -r1.3.10.1 -r1.3.10.2
--- pointer.c	13 Dec 2004 09:38:50 -0000	1.3.10.1
+++ pointer.c	13 Dec 2004 16:18:01 -0000	1.3.10.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: pointer.c,v 1.3.10.1 2004/12/13 09:38:50 hyperion Exp $
+/* $Id: pointer.c,v 1.3.10.2 2004/12/13 16:18:01 hyperion Exp $
  *
  * PROJECT:         ReactOS VGA16 display driver
  * FILE:            drivers/dd/vga/display/objects/pointer.c

reactos/hal/halx86/include
hal.h 1.15.2.1 -> 1.15.2.2
diff -u -r1.15.2.1 -r1.15.2.2
--- hal.h	8 Dec 2004 21:56:56 -0000	1.15.2.1
+++ hal.h	13 Dec 2004 16:18:01 -0000	1.15.2.2
@@ -284,10 +284,10 @@
    UCHAR Reserved9[30];                 /* 0A2h-0BFh */
    
    /* DMA Controller 2 */
-   DMA1_CONTROL DmaController2;         /* 0C0h-0DFh */
+   DMA1_CONTROL DmaController2;         /* 0C0h-0CFh */
    
    /* System Reserved Ports */
-   UCHAR SystemReserved[800];           /* 0E0h-3FFh */
+   UCHAR SystemReserved[816];           /* 0D0h-3FFh */
    
    /* Extended DMA Registers, Controller 1 */
    UCHAR DmaHighByteCount1[8];          /* 400h-407h */

reactos/include/ddk
iofuncs.h 1.46.2.2 -> 1.46.2.3
diff -u -r1.46.2.2 -r1.46.2.3
--- iofuncs.h	13 Dec 2004 09:38:50 -0000	1.46.2.2
+++ iofuncs.h	13 Dec 2004 16:18:01 -0000	1.46.2.3
@@ -1,6 +1,6 @@
 #ifndef _INCLUDE_DDK_IOFUNCS_H
 #define _INCLUDE_DDK_IOFUNCS_H
-/* $Id: iofuncs.h,v 1.46.2.2 2004/12/13 09:38:50 hyperion Exp $ */
+/* $Id: iofuncs.h,v 1.46.2.3 2004/12/13 16:18:01 hyperion Exp $ */
 
 #ifdef __NTOSKRNL__
 extern POBJECT_TYPE EXPORTED IoAdapterObjectType;

reactos/include/ddk
iotypes.h 1.69.2.2 -> 1.69.2.3
diff -u -r1.69.2.2 -r1.69.2.3
--- iotypes.h	13 Dec 2004 09:38:50 -0000	1.69.2.2
+++ iotypes.h	13 Dec 2004 16:18:01 -0000	1.69.2.3
@@ -1,4 +1,4 @@
-/* $Id: iotypes.h,v 1.69.2.2 2004/12/13 09:38:50 hyperion Exp $
+/* $Id: iotypes.h,v 1.69.2.3 2004/12/13 16:18:01 hyperion Exp $
  *
  */
 

reactos/include/ntdll
rtl.h 1.52.2.2 -> 1.52.2.3
diff -u -r1.52.2.2 -r1.52.2.3
--- rtl.h	13 Dec 2004 09:38:51 -0000	1.52.2.2
+++ rtl.h	13 Dec 2004 16:18:01 -0000	1.52.2.3
@@ -1,4 +1,4 @@
-/* $Id: rtl.h,v 1.52.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: rtl.h,v 1.52.2.3 2004/12/13 16:18:01 hyperion Exp $
  *
  */
 

reactos/include/ntos
haltypes.h 1.9.2.2 -> 1.9.2.3
diff -u -r1.9.2.2 -r1.9.2.3
--- haltypes.h	13 Dec 2004 09:38:51 -0000	1.9.2.2
+++ haltypes.h	13 Dec 2004 16:18:01 -0000	1.9.2.3
@@ -1,4 +1,4 @@
-/* $Id: haltypes.h,v 1.9.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: haltypes.h,v 1.9.2.3 2004/12/13 16:18:01 hyperion Exp $
  *
  * COPYRIGHT:                See COPYING in the top level directory
  * PROJECT:                  ReactOS kernel

reactos/include/ntos
rtl.h 1.38.2.2 -> 1.38.2.3
diff -u -r1.38.2.2 -r1.38.2.3
--- rtl.h	13 Dec 2004 09:38:51 -0000	1.38.2.2
+++ rtl.h	13 Dec 2004 16:18:01 -0000	1.38.2.3
@@ -1,4 +1,4 @@
-/* $Id: rtl.h,v 1.38.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: rtl.h,v 1.38.2.3 2004/12/13 16:18:01 hyperion Exp $
  * 
  */
 #ifndef __DDK_RTL_H

reactos/include/ntos
zw.h 1.35.2.3 -> 1.35.2.4
diff -u -r1.35.2.3 -r1.35.2.4
--- zw.h	13 Dec 2004 09:38:51 -0000	1.35.2.3
+++ zw.h	13 Dec 2004 16:18:01 -0000	1.35.2.4
@@ -1,5 +1,5 @@
 
-/* $Id: zw.h,v 1.35.2.3 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: zw.h,v 1.35.2.4 2004/12/13 16:18:01 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/lib/advapi32
advapi32.def 1.25.2.1 -> 1.25.2.2
diff -u -r1.25.2.1 -r1.25.2.2
--- advapi32.def	13 Dec 2004 09:38:53 -0000	1.25.2.1
+++ advapi32.def	13 Dec 2004 16:18:02 -0000	1.25.2.2
@@ -1,4 +1,4 @@
-; $Id: advapi32.def,v 1.25.2.1 2004/12/13 09:38:53 hyperion Exp $
+; $Id: advapi32.def,v 1.25.2.2 2004/12/13 16:18:02 hyperion Exp $
 ;
 ; advapi32.def
 ;

reactos/lib/advapi32
makefile 1.42.8.1 -> 1.42.8.2
diff -u -r1.42.8.1 -r1.42.8.2
--- makefile	13 Dec 2004 09:38:53 -0000	1.42.8.1
+++ makefile	13 Dec 2004 16:18:02 -0000	1.42.8.2
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.42.8.1 2004/12/13 09:38:53 hyperion Exp $
+# $Id: makefile,v 1.42.8.2 2004/12/13 16:18:02 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/advapi32/misc
sysfunc.c 1.8.8.1 -> 1.8.8.2
diff -u -r1.8.8.1 -r1.8.8.2
--- sysfunc.c	13 Dec 2004 09:38:54 -0000	1.8.8.1
+++ sysfunc.c	13 Dec 2004 16:18:02 -0000	1.8.8.2
@@ -1,4 +1,4 @@
-/* $Id: sysfunc.c,v 1.8.8.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: sysfunc.c,v 1.8.8.2 2004/12/13 16:18:02 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/advapi32/reg
reg.c 1.63.2.2 -> 1.63.2.3
diff -u -r1.63.2.2 -r1.63.2.3
--- reg.c	13 Dec 2004 09:38:54 -0000	1.63.2.2
+++ reg.c	13 Dec 2004 16:18:02 -0000	1.63.2.3
@@ -1,4 +1,4 @@
-/* $Id: reg.c,v 1.63.2.2 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: reg.c,v 1.63.2.3 2004/12/13 16:18:02 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/advapi32/sec
misc.c 1.27.2.1 -> 1.27.2.2
diff -u -r1.27.2.1 -r1.27.2.2
--- misc.c	13 Dec 2004 09:38:54 -0000	1.27.2.1
+++ misc.c	13 Dec 2004 16:18:02 -0000	1.27.2.2
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.27.2.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: misc.c,v 1.27.2.2 2004/12/13 16:18:02 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -8,6 +8,7 @@
 
 #include "advapi32.h"
 #include <accctrl.h>
+#include <malloc.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -478,31 +479,40 @@
  *  lpSize   [I/O] Size of lpszName.
  *
  *
- * @unimplemented
+ * @implemented
  */
 BOOL WINAPI
 GetUserNameA( LPSTR lpszName, LPDWORD lpSize )
 {
-  size_t len;
-  const char* name = "Administrator";
- 
-  DPRINT1("GetUserNameA: stub\n");
+  WCHAR* lpszNameW = NULL;
+  DWORD len = 0;
+
   if ( !lpSize )
   {
     SetLastError(ERROR_INVALID_PARAMETER);
     return FALSE;
   }
-  /* We need to include the null character when determining the size of the buffer. */
-  len = strlen(name) + 1;
-  if (len > *lpSize)
+
+  len = *lpSize;
+  lpszNameW = LocalAlloc ( LMEM_FIXED, len * sizeof(WCHAR) );
+
+  if ( !GetUserNameW ( lpszNameW, &len ) )
   {
-    SetLastError(ERROR_MORE_DATA);
-    *lpSize = len;
+    LocalFree ( lpszNameW );
     return FALSE;
   }
- 
+
+  len = wcstombs ( lpszName, lpszNameW, len );
+
+  LocalFree ( lpszNameW );
+
+  if ( len > *lpSize )
+  {
+    SetLastError(ERROR_INSUFFICIENT_BUFFER);
+    return FALSE;
+  }
+
   *lpSize = len;
-  strcpy(lpszName, name);
   return TRUE;
 }
 
@@ -511,26 +521,108 @@
  *
  * See GetUserNameA.
  *
- * @unimplemented
+ * @implemented
  */
 BOOL WINAPI
-GetUserNameW( LPWSTR lpszName, LPDWORD lpSize )
+GetUserNameW ( LPWSTR lpszName, LPDWORD lpSize )
 {
-//    char name[] = { "Administrator" };
+  HANDLE hToken = INVALID_HANDLE_VALUE;
+  DWORD tu_len = 0;
+  char* tu_buf = NULL;
+  TOKEN_USER* token_user = NULL;
+  DWORD an_len = 0;
+  SID_NAME_USE snu = SidTypeUser;
+  WCHAR* domain_name = NULL;
+  DWORD dn_len = 0;
+
+  if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
+  {
+    DWORD dwLastError = GetLastError();
+    if ( dwLastError != ERROR_NO_TOKEN
+      && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
+    {
+      // don't call SetLastError(),
+      // as OpenThreadToken() ought to have set one
+      return FALSE;
+    }
+    if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
+    {
+      // don't call SetLastError(),
+      // as OpenProcessToken() ought to have set one
+      return FALSE;
+    }
+  }
+  tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
+  if ( !tu_buf )
+  {
+    SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+    return FALSE;
+  }
+  if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
+  {
+    LocalFree ( tu_buf );
+    tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
+    if ( !tu_buf )
+    {
+      SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+      return FALSE;
+    }
+    if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
+    {
+      // don't call SetLastError(),
+      // as GetTokenInformation() ought to have set one
+      LocalFree ( tu_buf );
+      CloseHandle ( hToken );
+      return FALSE;
+    }
+  }
+  token_user = (TOKEN_USER*)tu_buf;
 
-//    DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
+  an_len = *lpSize;
+  dn_len = 32;
+  domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
+  if ( !domain_name )
+  {
+    LocalFree ( tu_buf );
+    SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+    return FALSE;
+  }
+  if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
+    || dn_len > 32 )
+  {
+    if ( dn_len > 32 )
+    {
+      LocalFree ( domain_name );
+      domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
+      if ( !domain_name )
+      {
+        LocalFree ( tu_buf );
+        SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+        return FALSE;
+      }
+    }
+    if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
+    {
+      // don't call SetLastError(),
+      // as LookupAccountSid() ought to have set one
+      LocalFree ( domain_name );
+      CloseHandle ( hToken );
+      return FALSE;
+    }
+  }
+
+  LocalFree ( domain_name );
+  LocalFree ( tu_buf );
+  CloseHandle ( hToken );
 
-//    if (len > *lpSize)
-//    {
-//        SetLastError(ERROR_MORE_DATA);
-//        *lpSize = len;
-//        return FALSE;
-//    }
-
-//    *lpSize = len;
-//    MultiByteToWideChar( CP_ACP, 0, name, -1, lpszName, len );
-    DPRINT1("GetUserNameW: stub\n");
-    return TRUE;
+  if ( an_len > *lpSize )
+  {
+    *lpSize = an_len;
+    SetLastError(ERROR_INSUFFICIENT_BUFFER);
+    return FALSE;
+  }
+
+  return TRUE;
 }
 
 

reactos/lib/advapi32/token
token.c 1.14.6.1 -> 1.14.6.2
diff -u -r1.14.6.1 -r1.14.6.2
--- token.c	13 Dec 2004 09:38:54 -0000	1.14.6.1
+++ token.c	13 Dec 2004 16:18:02 -0000	1.14.6.2
@@ -1,4 +1,4 @@
-/* $Id: token.c,v 1.14.6.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: token.c,v 1.14.6.2 2004/12/13 16:18:02 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/cabinet
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:38:54 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:02 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:54 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:02 hyperion Exp $
 
 TARGET_NAME = cabinet
 

reactos/lib/comctl32
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:38:55 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:02 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:02 hyperion Exp $
 
 TARGET_NAME = comctl32
 

reactos/lib/cpl/ncpa
tcpip_properties.c 1.4.2.1 -> 1.4.2.2
diff -u -r1.4.2.1 -r1.4.2.2
--- tcpip_properties.c	13 Dec 2004 09:38:55 -0000	1.4.2.1
+++ tcpip_properties.c	13 Dec 2004 16:18:02 -0000	1.4.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: tcpip_properties.c,v 1.4.2.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: tcpip_properties.c,v 1.4.2.2 2004/12/13 16:18:02 hyperion Exp $
  *
  * PROJECT:         ReactOS Network Control Panel
  * FILE:            lib/cpl/system/tcpip_properties.c

reactos/lib/dinput
Makefile 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile	13 Dec 2004 09:38:55 -0000	1.2.16.2
+++ Makefile	13 Dec 2004 16:18:02 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.2.16.3 2004/12/13 16:18:02 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/dnsapi
Makefile 1.5.16.2 -> 1.5.16.3
diff -u -r1.5.16.2 -r1.5.16.3
--- Makefile	13 Dec 2004 09:38:55 -0000	1.5.16.2
+++ Makefile	13 Dec 2004 16:18:03 -0000	1.5.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.5.16.3 2004/12/13 16:18:03 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/expat
Makefile 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile	13 Dec 2004 09:38:55 -0000	1.3.16.2
+++ Makefile	13 Dec 2004 16:18:03 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.3.16.3 2004/12/13 16:18:03 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/freetype/i386
setjmplongjmp.s 1.1.34.2 -> 1.1.34.3
diff -u -r1.1.34.2 -r1.1.34.3
--- setjmplongjmp.s	13 Dec 2004 09:38:55 -0000	1.1.34.2
+++ setjmplongjmp.s	13 Dec 2004 16:18:03 -0000	1.1.34.3
@@ -1,4 +1,4 @@
-/* $Id: setjmplongjmp.s,v 1.1.34.2 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: setjmplongjmp.s,v 1.1.34.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           FreeType implementation for ReactOS

reactos/lib/icmp
Makefile.ros-template 1.1.6.2 -> 1.1.6.3
diff -u -r1.1.6.2 -r1.1.6.3
--- Makefile.ros-template	13 Dec 2004 09:38:55 -0000	1.1.6.2
+++ Makefile.ros-template	13 Dec 2004 16:18:03 -0000	1.1.6.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.6.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.6.3 2004/12/13 16:18:03 hyperion Exp $
 
 TARGET_NAME = icmp
 

reactos/lib/iphlpapi
Makefile.ros-template 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template	13 Dec 2004 09:38:55 -0000	1.2.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:03 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:03 hyperion Exp $
 
 TARGET_NAME = iphlpapi
 

reactos/lib/kernel32/debug
debugger.c 1.4.22.1 -> 1.4.22.2
diff -u -r1.4.22.1 -r1.4.22.2
--- debugger.c	13 Dec 2004 09:38:55 -0000	1.4.22.1
+++ debugger.c	13 Dec 2004 16:18:03 -0000	1.4.22.2
@@ -1,4 +1,4 @@
-/* $Id: debugger.c,v 1.4.22.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: debugger.c,v 1.4.22.2 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/except
except.c 1.18.2.1 -> 1.18.2.2
diff -u -r1.18.2.1 -r1.18.2.2
--- except.c	13 Dec 2004 09:38:55 -0000	1.18.2.1
+++ except.c	13 Dec 2004 16:18:03 -0000	1.18.2.2
@@ -1,4 +1,4 @@
-/* $Id: except.c,v 1.18.2.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: except.c,v 1.18.2.2 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -88,10 +88,11 @@
 LONG STDCALL
 UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
 {
+#if 0
    DWORD RetValue;
+#endif
    HANDLE DebugPort = NULL;
    NTSTATUS ErrCode;
-   static int RecursionTrap = 3;
 
 #if 0
    if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
@@ -104,36 +105,23 @@
    }
 #endif
 
-   if (RecursionTrap > 0)
+   /* Is there a debugger running ? */
+   ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,
+                                       &DebugPort, sizeof(HANDLE), NULL);
+   if (!NT_SUCCESS(ErrCode) && ErrCode != STATUS_NOT_IMPLEMENTED)
    {
-      /* Is there a debugger running ? */
-      ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,
-                                          &DebugPort, sizeof(HANDLE), NULL);
-      if (!NT_SUCCESS(ErrCode) && ErrCode != STATUS_NOT_IMPLEMENTED)
-      {
-         SetLastErrorByStatus(ErrCode);
-         return EXCEPTION_EXECUTE_HANDLER;
-      }
-
-      if (DebugPort)
-      {
-         /* Pass the exception to debugger. */
-         DPRINT("Passing exception to debugger\n");
-         return EXCEPTION_CONTINUE_SEARCH;
-      }
+      SetLastErrorByStatus(ErrCode);
+      return EXCEPTION_EXECUTE_HANDLER;
+   }
 
-      /* Run unhandled exception handler. */
-      if (GlobalTopLevelExceptionFilter != NULL)
-      {
-         RetValue = GlobalTopLevelExceptionFilter(ExceptionInfo);
-         if (RetValue == EXCEPTION_EXECUTE_HANDLER)
-            return EXCEPTION_EXECUTE_HANDLER;
-         if (RetValue == EXCEPTION_CONTINUE_EXECUTION) 
-            return EXCEPTION_CONTINUE_EXECUTION;
-      }
+   if (DebugPort)
+   {
+      /* Pass the exception to debugger. */
+      DPRINT("Passing exception to debugger\n");
+      return EXCEPTION_CONTINUE_SEARCH;
    }
 
-   if (RecursionTrap-- > 0 && (GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
+   if ((GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
    {
 #ifdef _X86_
       PULONG Frame;

reactos/lib/kernel32/file
create.c 1.40.2.2 -> 1.40.2.3
diff -u -r1.40.2.2 -r1.40.2.3
--- create.c	13 Dec 2004 09:38:55 -0000	1.40.2.2
+++ create.c	13 Dec 2004 16:18:03 -0000	1.40.2.3
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.40.2.2 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: create.c,v 1.40.2.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/file
delete.c 1.17.8.2 -> 1.17.8.3
diff -u -r1.17.8.2 -r1.17.8.3
--- delete.c	13 Dec 2004 09:38:56 -0000	1.17.8.2
+++ delete.c	13 Dec 2004 16:18:03 -0000	1.17.8.3
@@ -1,4 +1,4 @@
-/* $Id: delete.c,v 1.17.8.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: delete.c,v 1.17.8.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/file
dir.c 1.50.2.1 -> 1.50.2.2
diff -u -r1.50.2.1 -r1.50.2.2
--- dir.c	13 Dec 2004 09:38:56 -0000	1.50.2.1
+++ dir.c	13 Dec 2004 16:18:03 -0000	1.50.2.2
@@ -1,4 +1,4 @@
-/* $Id: dir.c,v 1.50.2.1 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: dir.c,v 1.50.2.2 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/file
file.c 1.60.2.2 -> 1.60.2.3
diff -u -r1.60.2.2 -r1.60.2.3
--- file.c	13 Dec 2004 09:38:56 -0000	1.60.2.2
+++ file.c	13 Dec 2004 16:18:03 -0000	1.60.2.3
@@ -1,4 +1,4 @@
-/* $Id: file.c,v 1.60.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: file.c,v 1.60.2.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/file
iocompl.c 1.15.2.2 -> 1.15.2.3
diff -u -r1.15.2.2 -r1.15.2.3
--- iocompl.c	13 Dec 2004 09:38:56 -0000	1.15.2.2
+++ iocompl.c	13 Dec 2004 16:18:03 -0000	1.15.2.3
@@ -1,4 +1,4 @@
-/* $Id: iocompl.c,v 1.15.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: iocompl.c,v 1.15.2.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/file
move.c 1.14.16.2 -> 1.14.16.3
diff -u -r1.14.16.2 -r1.14.16.3
--- move.c	13 Dec 2004 09:38:56 -0000	1.14.16.2
+++ move.c	13 Dec 2004 16:18:03 -0000	1.14.16.3
@@ -1,4 +1,4 @@
-/* $Id: move.c,v 1.14.16.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: move.c,v 1.14.16.3 2004/12/13 16:18:03 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/include
kernel32.h 1.6.10.1 -> 1.6.10.2
diff -u -r1.6.10.1 -r1.6.10.2
--- kernel32.h	13 Dec 2004 09:38:56 -0000	1.6.10.1
+++ kernel32.h	13 Dec 2004 16:18:03 -0000	1.6.10.2
@@ -43,6 +43,8 @@
 
 extern UNICODE_STRING DllDirectory;
 
+extern LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
+
 /* FUNCTION PROTOTYPES *******************************************************/
 
 BOOL STDCALL IsConsoleHandle(HANDLE Handle);

reactos/lib/kernel32
makefile 1.89.2.2 -> 1.89.2.3
diff -u -r1.89.2.2 -r1.89.2.3
--- makefile	13 Dec 2004 09:38:56 -0000	1.89.2.2
+++ makefile	13 Dec 2004 16:18:03 -0000	1.89.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.89.2.2 2004/12/13 09:38:56 hyperion Exp $
+# $Id: makefile,v 1.89.2.3 2004/12/13 16:18:03 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/kernel32/misc
atom.c 1.20.16.2 -> 1.20.16.3
diff -u -r1.20.16.2 -r1.20.16.3
--- atom.c	13 Dec 2004 09:38:56 -0000	1.20.16.2
+++ atom.c	13 Dec 2004 16:18:04 -0000	1.20.16.3
@@ -1,4 +1,4 @@
-/* $Id: atom.c,v 1.20.16.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: atom.c,v 1.20.16.3 2004/12/13 16:18:04 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/misc
dllmain.c 1.37.2.2 -> 1.37.2.3
diff -u -r1.37.2.2 -r1.37.2.3
--- dllmain.c	13 Dec 2004 09:38:56 -0000	1.37.2.2
+++ dllmain.c	13 Dec 2004 16:18:04 -0000	1.37.2.3
@@ -1,4 +1,4 @@
-/* $Id: dllmain.c,v 1.37.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: dllmain.c,v 1.37.2.3 2004/12/13 16:18:04 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/misc
lang.c 1.24.2.2 -> 1.24.2.3
diff -u -r1.24.2.2 -r1.24.2.3
--- lang.c	13 Dec 2004 09:38:56 -0000	1.24.2.2
+++ lang.c	13 Dec 2004 16:18:04 -0000	1.24.2.3
@@ -1,4 +1,4 @@
-/* $Id: lang.c,v 1.24.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: lang.c,v 1.24.2.3 2004/12/13 16:18:04 hyperion Exp $
  *
  * COPYRIGHT: See COPYING in the top level directory
  * PROJECT  : ReactOS user mode libraries

reactos/lib/kernel32/misc
stubs.c 1.94.2.2 -> 1.94.2.3
diff -u -r1.94.2.2 -r1.94.2.3
--- stubs.c	13 Dec 2004 09:38:56 -0000	1.94.2.2
+++ stubs.c	13 Dec 2004 16:18:04 -0000	1.94.2.3
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.94.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: stubs.c,v 1.94.2.3 2004/12/13 16:18:04 hyperion Exp $
  *
  * KERNEL32.DLL stubs (STUB functions)
  * Remove from this file, if you implement them.

reactos/lib/kernel32/misc
time.c 1.32.2.2 -> 1.32.2.3
diff -u -r1.32.2.2 -r1.32.2.3
--- time.c	13 Dec 2004 09:38:56 -0000	1.32.2.2
+++ time.c	13 Dec 2004 16:18:04 -0000	1.32.2.3
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.32.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: time.c,v 1.32.2.3 2004/12/13 16:18:04 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/process
create.c 1.89.2.1 -> 1.89.2.2
diff -u -r1.89.2.1 -r1.89.2.2
--- create.c	13 Dec 2004 05:55:32 -0000	1.89.2.1
+++ create.c	13 Dec 2004 16:18:04 -0000	1.89.2.2
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.89.2.1 2004/12/13 05:55:32 hyperion Exp $
+/* $Id: create.c,v 1.89.2.2 2004/12/13 16:18:04 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -12,6 +12,7 @@
 /* INCLUDES ****************************************************************/
 
 #include <k32.h>
+#include <pseh/framebased.h>
 
 #define NDEBUG
 #include "../include/debug.h"
@@ -291,20 +292,30 @@
 {
    EXCEPTION_POINTERS ExceptionInfo;
    EXCEPTION_DISPOSITION ExceptionDisposition;
+
    ExceptionInfo.ExceptionRecord = ExceptionRecord;
    ExceptionInfo.ContextRecord = ContextRecord;
-   ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
-   if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
+
+   if (GlobalTopLevelExceptionFilter != NULL)
    {
-      /* FIXME */
-#if 0
-      if (_BaseRunningInServerProcess)
-         ExitThread(ExceptionRecord->ExceptionCode);
-      else
-#endif
-         ExitProcess(ExceptionRecord->ExceptionCode);
+      _SEH_TRY
+      {
+         ExceptionDisposition = GlobalTopLevelExceptionFilter(&ExceptionInfo);
+      }
+      _SEH_HANDLE
+      {
+         ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
+      }
+      _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;
@@ -327,6 +338,8 @@
    {
       uExitCode = (lpStartAddress)((PVOID)lpParameter);
    } __except1
+
+   ExitProcess(uExitCode);
 }
 
 

reactos/lib/kernel32/synch
wait.c 1.31.2.2 -> 1.31.2.3
diff -u -r1.31.2.2 -r1.31.2.3
--- wait.c	13 Dec 2004 09:38:57 -0000	1.31.2.2
+++ wait.c	13 Dec 2004 16:18:06 -0000	1.31.2.3
@@ -1,4 +1,4 @@
-/* $Id: wait.c,v 1.31.2.2 2004/12/13 09:38:57 hyperion Exp $
+/* $Id: wait.c,v 1.31.2.3 2004/12/13 16:18:06 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/kernel32/thread
thread.c 1.56.2.2 -> 1.56.2.3
diff -u -r1.56.2.2 -r1.56.2.3
--- thread.c	13 Dec 2004 09:38:57 -0000	1.56.2.2
+++ thread.c	13 Dec 2004 16:18:06 -0000	1.56.2.3
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.56.2.2 2004/12/13 09:38:57 hyperion Exp $
+/* $Id: thread.c,v 1.56.2.3 2004/12/13 16:18:06 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -14,6 +14,7 @@
 /* INCLUDES ******************************************************************/
 
 #include <k32.h>
+#include <pseh/framebased.h>
 
 #define NDEBUG
 #include "../include/debug.h"
@@ -28,10 +29,39 @@
 		CONTEXT *ContextRecord,
 		void * DispatcherContext)
 {
-  ExitThread(0);
+   EXCEPTION_POINTERS ExceptionInfo;
+   EXCEPTION_DISPOSITION ExceptionDisposition;
 
-  /* We should not get to here */
-  return(ExceptionContinueSearch);
+   ExceptionInfo.ExceptionRecord = ExceptionRecord;
+   ExceptionInfo.ContextRecord = ContextRecord;
+
+   if (GlobalTopLevelExceptionFilter != NULL)
+   {
+      _SEH_TRY
+      {
+         ExceptionDisposition = GlobalTopLevelExceptionFilter(&ExceptionInfo);
+      }
+      _SEH_HANDLE
+      {
+         ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
+      }
+      _SEH_END;
+   }
+   else 
+   {
+      ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
+   }
+
+   if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
+      ExitThread(ExceptionRecord->ExceptionCode);
+
+   /* translate EXCEPTION_XXX defines into EXCEPTION_DISPOSITION enum values */
+   if (ExceptionDisposition == EXCEPTION_CONTINUE_EXECUTION)
+     return ExceptionContinueExecution;
+   else if (ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH)
+     return ExceptionContinueSearch;
+
+   return -1; /* unknown return from UnhandledExceptionFilter */
 }
 
 
@@ -50,8 +80,6 @@
     uExitCode = (lpStartAddress)(lpParameter);
   }
   __except1
-  {
-  }
 
   ExitThread(uExitCode);
 }

reactos/lib/kjs
makefile 1.1.24.2 -> 1.1.24.3
diff -u -r1.1.24.2 -r1.1.24.3
--- makefile	13 Dec 2004 09:38:57 -0000	1.1.24.2
+++ makefile	13 Dec 2004 16:18:06 -0000	1.1.24.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.1.24.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: makefile,v 1.1.24.3 2004/12/13 16:18:06 hyperion Exp $
 # Kernel JavaScript
 # 
 # You can use this for various things but the most obvious is as a powerful

reactos/lib/libwine
makefile 1.3.6.2 -> 1.3.6.3
diff -u -r1.3.6.2 -r1.3.6.3
--- makefile	13 Dec 2004 09:38:57 -0000	1.3.6.2
+++ makefile	13 Dec 2004 16:18:06 -0000	1.3.6.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.3.6.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: makefile,v 1.3.6.3 2004/12/13 16:18:06 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/midimap
Makefile.ros-template 1.1.2.2 -> 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- Makefile.ros-template	13 Dec 2004 09:38:57 -0000	1.1.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:06 -0000	1.1.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.2.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.2.3 2004/12/13 16:18:06 hyperion Exp $
 
 TARGET_NAME = midimap
 

reactos/lib/mpr
Makefile.ros-template 1.3.2.2 -> 1.3.2.3
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template	13 Dec 2004 09:38:57 -0000	1.3.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = mpr
 

reactos/lib/msacm
Makefile.ros-template 1.3.8.2 -> 1.3.8.3
diff -u -r1.3.8.2 -r1.3.8.3
--- Makefile.ros-template	13 Dec 2004 09:38:57 -0000	1.3.8.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.3.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.8.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.8.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = msacm32
 

reactos/lib/msvcrt
Makefile 1.48.6.2 -> 1.48.6.3
diff -u -r1.48.6.2 -r1.48.6.3
--- Makefile	13 Dec 2004 09:38:58 -0000	1.48.6.2
+++ Makefile	13 Dec 2004 16:18:07 -0000	1.48.6.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.48.6.2 2004/12/13 09:38:58 hyperion Exp $
+# $Id: Makefile,v 1.48.6.3 2004/12/13 16:18:07 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/msvcrt/setjmp/i386
setjmp.s 1.1.34.2 -> 1.1.34.3
diff -u -r1.1.34.2 -r1.1.34.3
--- setjmp.s	13 Dec 2004 09:38:59 -0000	1.1.34.2
+++ setjmp.s	13 Dec 2004 16:18:07 -0000	1.1.34.3
@@ -1,4 +1,4 @@
-/* $Id: setjmp.s,v 1.1.34.2 2004/12/13 09:38:59 hyperion Exp $
+/* $Id: setjmp.s,v 1.1.34.3 2004/12/13 16:18:07 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS system libraries

reactos/lib/msvideo
Makefile.ros-template 1.1.8.2 -> 1.1.8.3
diff -u -r1.1.8.2 -r1.1.8.3
--- Makefile.ros-template	13 Dec 2004 09:38:59 -0000	1.1.8.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.1.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.8.2 2004/12/13 09:38:59 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.8.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = msvfw32
 

reactos/lib/netapi32
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:38:59 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:59 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = netapi32
 

reactos/lib/ntdll/def
ntdll.def 1.134.2.2 -> 1.134.2.3
diff -u -r1.134.2.2 -r1.134.2.3
--- ntdll.def	13 Dec 2004 09:39:00 -0000	1.134.2.2
+++ ntdll.def	13 Dec 2004 16:18:07 -0000	1.134.2.3
@@ -1,4 +1,4 @@
-; $Id: ntdll.def,v 1.134.2.2 2004/12/13 09:39:00 hyperion Exp $
+; $Id: ntdll.def,v 1.134.2.3 2004/12/13 16:18:07 hyperion Exp $
 ;
 ; ReactOS Operating System
 ;

reactos/lib/ntdll/rtl
path.c 1.29.8.2 -> 1.29.8.3
diff -u -r1.29.8.2 -r1.29.8.3
--- path.c	13 Dec 2004 09:39:00 -0000	1.29.8.2
+++ path.c	13 Dec 2004 16:18:07 -0000	1.29.8.3
@@ -1,4 +1,4 @@
-/* $Id: path.c,v 1.29.8.2 2004/12/13 09:39:00 hyperion Exp $
+/* $Id: path.c,v 1.29.8.3 2004/12/13 16:18:07 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/odbc32
Makefile.ros-template 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:00 -0000	1.2.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = odbc32
 

reactos/lib/ole32
Makefile.ros-template 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:00 -0000	1.2.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = ole32
 

reactos/lib/oleaut32
Makefile.ros-template 1.5.2.2 -> 1.5.2.3
diff -u -r1.5.2.2 -r1.5.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:00 -0000	1.5.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.5.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.5.2.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.5.2.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = oleaut32
 

reactos/lib/oledlg
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:07 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:07 hyperion Exp $
 
 TARGET_NAME = oledlg
 

reactos/lib/olepro32
Makefile.ros-template 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.2.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = olepro32
 

reactos/lib/riched20
Makefile.ros-template 1.1.2.2 -> 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.1.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.1.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.2.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.2.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = riched20
 

reactos/lib/richedit
Makefile.ros-template 1.2.16.2 -> 1.2.16.3
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.2.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = riched32
 

reactos/lib/rpcrt4
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = rpcrt4
 

reactos/lib/rtl
acl.c 1.4.2.2 -> 1.4.2.3
diff -u -r1.4.2.2 -r1.4.2.3
--- acl.c	13 Dec 2004 09:39:01 -0000	1.4.2.2
+++ acl.c	13 Dec 2004 16:18:08 -0000	1.4.2.3
@@ -1,4 +1,4 @@
-/* $Id: acl.c,v 1.4.2.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: acl.c,v 1.4.2.3 2004/12/13 16:18:08 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/lib/rtl
largeint.c 1.1.18.1 -> 1.1.18.2
diff -u -r1.1.18.1 -r1.1.18.2
--- largeint.c	13 Dec 2004 09:39:01 -0000	1.1.18.1
+++ largeint.c	13 Dec 2004 16:18:08 -0000	1.1.18.2
@@ -1,4 +1,4 @@
-/* $Id: largeint.c,v 1.1.18.1 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: largeint.c,v 1.1.18.2 2004/12/13 16:18:08 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/lib/rtl
mem.c 1.2.8.2 -> 1.2.8.3
diff -u -r1.2.8.2 -r1.2.8.3
--- mem.c	13 Dec 2004 09:39:01 -0000	1.2.8.2
+++ mem.c	13 Dec 2004 16:18:08 -0000	1.2.8.3
@@ -1,5 +1,5 @@
 
-/* $Id: mem.c,v 1.2.8.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: mem.c,v 1.2.8.3 2004/12/13 16:18:08 hyperion Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/lib/rtl
nls.c 1.1.18.2 -> 1.1.18.3
diff -u -r1.1.18.2 -r1.1.18.3
--- nls.c	13 Dec 2004 09:39:01 -0000	1.1.18.2
+++ nls.c	13 Dec 2004 16:18:08 -0000	1.1.18.3
@@ -1,4 +1,4 @@
-/* $Id: nls.c,v 1.1.18.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: nls.c,v 1.1.18.3 2004/12/13 16:18:08 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/lib/setupapi
Makefile.ros-template 1.4.16.2 -> 1.4.16.3
diff -u -r1.4.16.2 -r1.4.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.4.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.4.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.4.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.4.16.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = setupapi
 

reactos/lib/shell32
Makefile.ros-template 1.6.2.2 -> 1.6.2.3
diff -u -r1.6.2.2 -r1.6.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:01 -0000	1.6.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.6.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.6.2.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.6.2.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = shell32
 

reactos/lib/shlwapi
Makefile.ros-template 1.9.2.2 -> 1.9.2.3
diff -u -r1.9.2.2 -r1.9.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:02 -0000	1.9.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.9.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.9.2.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.9.2.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = shlwapi
 

reactos/lib/string
strncpy.c 1.2.34.2 -> 1.2.34.3
diff -u -r1.2.34.2 -r1.2.34.3
--- strncpy.c	13 Dec 2004 09:39:02 -0000	1.2.34.2
+++ strncpy.c	13 Dec 2004 16:18:08 -0000	1.2.34.3
@@ -1,4 +1,4 @@
-/* $Id: strncpy.c,v 1.2.34.2 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: strncpy.c,v 1.2.34.3 2004/12/13 16:18:08 hyperion Exp $
  */
 #include <string.h>
 #include "tcsncpy.h"

reactos/lib/syssetup
syssetup.rc 1.8.2.2 -> 1.8.2.3
diff -u -r1.8.2.2 -r1.8.2.3
--- syssetup.rc	13 Dec 2004 09:39:02 -0000	1.8.2.2
+++ syssetup.rc	13 Dec 2004 16:18:08 -0000	1.8.2.3
@@ -1,4 +1,4 @@
-/* $Id: syssetup.rc,v 1.8.2.2 2004/12/13 09:39:02 hyperion Exp $ */
+/* $Id: syssetup.rc,v 1.8.2.3 2004/12/13 16:18:08 hyperion Exp $ */
 
 #include <windows.h>
 #include "resource.h"

reactos/lib/syssetup
wizard.c 1.15.2.2 -> 1.15.2.3
diff -u -r1.15.2.2 -r1.15.2.3
--- wizard.c	13 Dec 2004 09:39:02 -0000	1.15.2.2
+++ wizard.c	13 Dec 2004 16:18:08 -0000	1.15.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: wizard.c,v 1.15.2.2 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: wizard.c,v 1.15.2.3 2004/12/13 16:18:08 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS system libraries

reactos/lib/twain
Makefile 1.7.16.2 -> 1.7.16.3
diff -u -r1.7.16.2 -r1.7.16.3
--- Makefile	13 Dec 2004 09:39:02 -0000	1.7.16.2
+++ Makefile	13 Dec 2004 16:18:08 -0000	1.7.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7.16.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile,v 1.7.16.3 2004/12/13 16:18:08 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/unicode
Makefile.ros-template 1.3.2.2 -> 1.3.2.3
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:02 -0000	1.3.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:08 -0000	1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:08 hyperion Exp $
 
 TARGET_NAME = wine_unicode
 

reactos/lib/urlmon
Makefile.ros-template 1.2.8.2 -> 1.2.8.3
diff -u -r1.2.8.2 -r1.2.8.3
--- Makefile.ros-template	13 Dec 2004 09:39:02 -0000	1.2.8.2
+++ Makefile.ros-template	13 Dec 2004 16:18:09 -0000	1.2.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.8.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.8.3 2004/12/13 16:18:09 hyperion Exp $
 
 TARGET_NAME = urlmon
 

reactos/lib/user32
Makefile 1.40.8.2 -> 1.40.8.3
diff -u -r1.40.8.2 -r1.40.8.3
--- Makefile	13 Dec 2004 09:39:02 -0000	1.40.8.2
+++ Makefile	13 Dec 2004 16:18:09 -0000	1.40.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.40.8.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile,v 1.40.8.3 2004/12/13 16:18:09 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/user32/misc
display.c 1.13.2.1 -> 1.13.2.2
diff -u -r1.13.2.1 -r1.13.2.2
--- display.c	13 Dec 2004 09:39:02 -0000	1.13.2.1
+++ display.c	13 Dec 2004 16:18:09 -0000	1.13.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: display.c,v 1.13.2.1 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: display.c,v 1.13.2.2 2004/12/13 16:18:09 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/misc/dde.c

reactos/lib/user32/misc
misc.c 1.9.2.2 -> 1.9.2.3
diff -u -r1.9.2.2 -r1.9.2.3
--- misc.c	13 Dec 2004 09:39:05 -0000	1.9.2.2
+++ misc.c	13 Dec 2004 16:18:09 -0000	1.9.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: misc.c,v 1.9.2.2 2004/12/13 09:39:05 hyperion Exp $
+/* $Id: misc.c,v 1.9.2.3 2004/12/13 16:18:09 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/misc/misc.c

reactos/lib/user32/misc
stubs.c 1.68.2.1 -> 1.68.2.2
diff -u -r1.68.2.1 -r1.68.2.2
--- stubs.c	13 Dec 2004 09:39:05 -0000	1.68.2.1
+++ stubs.c	13 Dec 2004 16:18:09 -0000	1.68.2.2
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.68.2.1 2004/12/13 09:39:05 hyperion Exp $
+/* $Id: stubs.c,v 1.68.2.2 2004/12/13 16:18:09 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll

reactos/lib/user32/windows
class.c 1.51.8.2 -> 1.51.8.3
diff -u -r1.51.8.2 -r1.51.8.3
--- class.c	13 Dec 2004 09:39:06 -0000	1.51.8.2
+++ class.c	13 Dec 2004 16:18:09 -0000	1.51.8.3
@@ -1,4 +1,4 @@
-/* $Id: class.c,v 1.51.8.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: class.c,v 1.51.8.3 2004/12/13 16:18:09 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll

reactos/lib/user32/windows
defwnd.c 1.147.2.1 -> 1.147.2.2
diff -u -r1.147.2.1 -r1.147.2.2
--- defwnd.c	13 Dec 2004 09:39:06 -0000	1.147.2.1
+++ defwnd.c	13 Dec 2004 16:18:09 -0000	1.147.2.2
@@ -1,4 +1,4 @@
-/* $Id: defwnd.c,v 1.147.2.1 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: defwnd.c,v 1.147.2.2 2004/12/13 16:18:09 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll

reactos/lib/user32/windows
font.c 1.11.8.2 -> 1.11.8.3
diff -u -r1.11.8.2 -r1.11.8.3
--- font.c	13 Dec 2004 09:39:06 -0000	1.11.8.2
+++ font.c	13 Dec 2004 16:18:10 -0000	1.11.8.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: font.c,v 1.11.8.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: font.c,v 1.11.8.3 2004/12/13 16:18:10 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/input.c

reactos/lib/user32/windows
input.c 1.25.8.1 -> 1.25.8.2
diff -u -r1.25.8.1 -r1.25.8.2
--- input.c	13 Dec 2004 09:39:06 -0000	1.25.8.1
+++ input.c	13 Dec 2004 16:18:10 -0000	1.25.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: input.c,v 1.25.8.1 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: input.c,v 1.25.8.2 2004/12/13 16:18:10 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/input.c

reactos/lib/user32/windows
menu.c 1.71.6.2 -> 1.71.6.3
diff -u -r1.71.6.2 -r1.71.6.3
--- menu.c	13 Dec 2004 09:39:06 -0000	1.71.6.2
+++ menu.c	13 Dec 2004 16:18:10 -0000	1.71.6.3
@@ -21,7 +21,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: menu.c,v 1.71.6.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: menu.c,v 1.71.6.3 2004/12/13 16:18:10 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/menu.c

reactos/lib/user32/windows
message.c 1.43.6.2 -> 1.43.6.3
diff -u -r1.43.6.2 -r1.43.6.3
--- message.c	13 Dec 2004 09:39:06 -0000	1.43.6.2
+++ message.c	13 Dec 2004 16:18:11 -0000	1.43.6.3
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.43.6.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: message.c,v 1.43.6.3 2004/12/13 16:18:11 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll

reactos/lib/user32/windows
messagebox.c 1.29.2.1 -> 1.29.2.2
diff -u -r1.29.2.1 -r1.29.2.2
--- messagebox.c	13 Dec 2004 09:39:07 -0000	1.29.2.1
+++ messagebox.c	13 Dec 2004 16:18:11 -0000	1.29.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: messagebox.c,v 1.29.2.1 2004/12/13 09:39:07 hyperion Exp $
+/* $Id: messagebox.c,v 1.29.2.2 2004/12/13 16:18:11 hyperion Exp $
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/messagebox.c

reactos/lib/userenv
environment.c 1.8.2.2 -> 1.8.2.3
diff -u -r1.8.2.2 -r1.8.2.3
--- environment.c	13 Dec 2004 09:39:07 -0000	1.8.2.2
+++ environment.c	13 Dec 2004 16:18:11 -0000	1.8.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: environment.c,v 1.8.2.2 2004/12/13 09:39:07 hyperion Exp $
+/* $Id: environment.c,v 1.8.2.3 2004/12/13 16:18:11 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/lib/version
makefile 1.15.16.2 -> 1.15.16.3
diff -u -r1.15.16.2 -r1.15.16.3
--- makefile	13 Dec 2004 09:39:07 -0000	1.15.16.2
+++ makefile	13 Dec 2004 16:18:11 -0000	1.15.16.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.15.16.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: makefile,v 1.15.16.3 2004/12/13 16:18:11 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/winmm
Makefile.ros-template 1.3.16.2 -> 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template	13 Dec 2004 09:39:07 -0000	1.3.16.2
+++ Makefile.ros-template	13 Dec 2004 16:18:11 -0000	1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:11 hyperion Exp $
 
 TARGET_NAME = winmm
 

reactos/lib/winmm/midimap
Makefile.ros-template 1.3.2.2 -> 1.3.2.3
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template	13 Dec 2004 09:39:07 -0000	1.3.2.2
+++ Makefile.ros-template	13 Dec 2004 16:18:11 -0000	1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:11 hyperion Exp $
 
 TARGET_NAME = midimap
 

reactos/lib/winmm/wavemap
Makefile.ros-template 1.2.8.2 -> 1.2.8.3
diff -u -r1.2.8.2 -r1.2.8.3
--- Makefile.ros-template	13 Dec 2004 09:39:07 -0000	1.2.8.2
+++ Makefile.ros-template	13 Dec 2004 16:18:11 -0000	1.2.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.8.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.8.3 2004/12/13 16:18:11 hyperion Exp $
 
 TARGET_NAME = msacm
 

reactos/lib/ws2_32
makefile 1.18.2.2 -> 1.18.2.3
diff -u -r1.18.2.2 -r1.18.2.3
--- makefile	13 Dec 2004 09:39:07 -0000	1.18.2.2
+++ makefile	13 Dec 2004 16:18:11 -0000	1.18.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.18.2.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: makefile,v 1.18.2.3 2004/12/13 16:18:11 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/ntoskrnl/cm
import.c 1.30.8.1 -> 1.30.8.2
diff -u -r1.30.8.1 -r1.30.8.2
--- import.c	13 Dec 2004 09:39:08 -0000	1.30.8.1
+++ import.c	13 Dec 2004 16:18:11 -0000	1.30.8.2
@@ -1,4 +1,4 @@
-/* $Id: import.c,v 1.30.8.1 2004/12/13 09:39:08 hyperion Exp $
+/* $Id: import.c,v 1.30.8.2 2004/12/13 16:18:11 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/cm
registry.c 1.128.2.1 -> 1.128.2.2
diff -u -r1.128.2.1 -r1.128.2.2
--- registry.c	13 Dec 2004 09:39:09 -0000	1.128.2.1
+++ registry.c	13 Dec 2004 16:18:11 -0000	1.128.2.2
@@ -1,4 +1,4 @@
-/* $Id: registry.c,v 1.128.2.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: registry.c,v 1.128.2.2 2004/12/13 16:18:11 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/dbg
print.c 1.20.8.1 -> 1.20.8.2
diff -u -r1.20.8.1 -r1.20.8.2
--- print.c	13 Dec 2004 09:39:09 -0000	1.20.8.1
+++ print.c	13 Dec 2004 16:18:12 -0000	1.20.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: print.c,v 1.20.8.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: print.c,v 1.20.8.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ex/i386
interlck.c 1.9.6.1 -> 1.9.6.2
diff -u -r1.9.6.1 -r1.9.6.2
--- interlck.c	13 Dec 2004 09:39:09 -0000	1.9.6.1
+++ interlck.c	13 Dec 2004 16:18:12 -0000	1.9.6.2
@@ -1,4 +1,4 @@
-/* $Id: interlck.c,v 1.9.6.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: interlck.c,v 1.9.6.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * reactos/ntoskrnl/ex/i386/interlck.c
  *

reactos/ntoskrnl/ex
sysinfo.c 1.59.2.3 -> 1.59.2.4
diff -u -r1.59.2.3 -r1.59.2.4
--- sysinfo.c	13 Dec 2004 09:39:09 -0000	1.59.2.3
+++ sysinfo.c	13 Dec 2004 16:18:12 -0000	1.59.2.4
@@ -1,4 +1,4 @@
-/* $Id: sysinfo.c,v 1.59.2.3 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: sysinfo.c,v 1.59.2.4 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ex
time.c 1.24.2.3 -> 1.24.2.4
diff -u -r1.24.2.3 -r1.24.2.4
--- time.c	13 Dec 2004 09:39:10 -0000	1.24.2.3
+++ time.c	13 Dec 2004 16:18:12 -0000	1.24.2.4
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.24.2.3 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: time.c,v 1.24.2.4 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/include/internal
io.h 1.49.2.2 -> 1.49.2.3
diff -u -r1.49.2.2 -r1.49.2.3
--- io.h	13 Dec 2004 09:39:10 -0000	1.49.2.2
+++ io.h	13 Dec 2004 16:18:12 -0000	1.49.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: io.h,v 1.49.2.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: io.h,v 1.49.2.3 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/include/internal
kd.h 1.28.2.1 -> 1.28.2.2
diff -u -r1.28.2.1 -r1.28.2.2
--- kd.h	13 Dec 2004 09:39:10 -0000	1.28.2.1
+++ kd.h	13 Dec 2004 16:18:12 -0000	1.28.2.2
@@ -1,4 +1,4 @@
-/* $Id: kd.h,v 1.28.2.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: kd.h,v 1.28.2.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * kernel debugger prototypes
  */

reactos/ntoskrnl/include/internal
ps.h 1.75.2.2 -> 1.75.2.3
diff -u -r1.75.2.2 -r1.75.2.3
--- ps.h	13 Dec 2004 09:39:10 -0000	1.75.2.2
+++ ps.h	13 Dec 2004 16:18:12 -0000	1.75.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: ps.h,v 1.75.2.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: ps.h,v 1.75.2.3 2004/12/13 16:18:12 hyperion Exp $
  *
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Process manager definitions

reactos/ntoskrnl/io
bootlog.c 1.5.6.1 -> 1.5.6.2
diff -u -r1.5.6.1 -r1.5.6.2
--- bootlog.c	13 Dec 2004 09:39:10 -0000	1.5.6.1
+++ bootlog.c	13 Dec 2004 16:18:12 -0000	1.5.6.2
@@ -1,4 +1,4 @@
-/* $Id: bootlog.c,v 1.5.6.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: bootlog.c,v 1.5.6.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel

reactos/ntoskrnl/io
driver.c 1.55.2.1 -> 1.55.2.2
diff -u -r1.55.2.1 -r1.55.2.2
--- driver.c	13 Dec 2004 09:39:10 -0000	1.55.2.1
+++ driver.c	13 Dec 2004 16:18:12 -0000	1.55.2.2
@@ -1,4 +1,4 @@
-/* $Id: driver.c,v 1.55.2.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: driver.c,v 1.55.2.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel

reactos/ntoskrnl/io
parttab.c 1.8.8.2 -> 1.8.8.3
diff -u -r1.8.8.2 -r1.8.8.3
--- parttab.c	13 Dec 2004 09:39:10 -0000	1.8.8.2
+++ parttab.c	13 Dec 2004 16:18:12 -0000	1.8.8.3
@@ -1,4 +1,4 @@
-/* $Id: parttab.c,v 1.8.8.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: parttab.c,v 1.8.8.3 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/kd
kdebug.c 1.56.2.1 -> 1.56.2.2
diff -u -r1.56.2.1 -r1.56.2.2
--- kdebug.c	13 Dec 2004 09:39:11 -0000	1.56.2.1
+++ kdebug.c	13 Dec 2004 16:18:12 -0000	1.56.2.2
@@ -1,4 +1,4 @@
-/* $Id: kdebug.c,v 1.56.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: kdebug.c,v 1.56.2.2 2004/12/13 16:18:12 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ke
bug.c 1.47.2.1 -> 1.47.2.2
diff -u -r1.47.2.1 -r1.47.2.2
--- bug.c	13 Dec 2004 09:39:11 -0000	1.47.2.1
+++ bug.c	13 Dec 2004 16:18:13 -0000	1.47.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bug.c,v 1.47.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: bug.c,v 1.47.2.2 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/bug.c

reactos/ntoskrnl/ke
dpc.c 1.48.2.2 -> 1.48.2.3
diff -u -r1.48.2.2 -r1.48.2.3
--- dpc.c	13 Dec 2004 09:39:11 -0000	1.48.2.2
+++ dpc.c	13 Dec 2004 16:18:13 -0000	1.48.2.3
@@ -19,7 +19,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dpc.c,v 1.48.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: dpc.c,v 1.48.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ke
ipi.c 1.3.2.2 -> 1.3.2.3
diff -u -r1.3.2.2 -r1.3.2.3
--- ipi.c	13 Dec 2004 09:39:11 -0000	1.3.2.2
+++ ipi.c	13 Dec 2004 16:18:13 -0000	1.3.2.3
@@ -1,4 +1,4 @@
-/* $Id: ipi.c,v 1.3.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: ipi.c,v 1.3.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ke
kthread.c 1.58.2.1 -> 1.58.2.2
diff -u -r1.58.2.1 -r1.58.2.2
--- kthread.c	13 Dec 2004 09:39:11 -0000	1.58.2.1
+++ kthread.c	13 Dec 2004 16:18:13 -0000	1.58.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: kthread.c,v 1.58.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: kthread.c,v 1.58.2.2 2004/12/13 16:18:13 hyperion Exp $
  *
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Microkernel thread support

reactos/ntoskrnl/ke
main.c 1.206.2.2 -> 1.206.2.3
diff -u -r1.206.2.2 -r1.206.2.3
--- main.c	13 Dec 2004 09:39:11 -0000	1.206.2.2
+++ main.c	13 Dec 2004 16:18:13 -0000	1.206.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: main.c,v 1.206.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: main.c,v 1.206.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c

reactos/ntoskrnl/ke
process.c 1.31.2.2 -> 1.31.2.3
diff -u -r1.31.2.2 -r1.31.2.3
--- process.c	13 Dec 2004 09:39:11 -0000	1.31.2.2
+++ process.c	13 Dec 2004 16:18:13 -0000	1.31.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: process.c,v 1.31.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: process.c,v 1.31.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/process.c

reactos/ntoskrnl/ke
timer.c 1.90.2.2 -> 1.90.2.3
diff -u -r1.90.2.2 -r1.90.2.3
--- timer.c	13 Dec 2004 09:39:11 -0000	1.90.2.2
+++ timer.c	13 Dec 2004 16:18:13 -0000	1.90.2.3
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.90.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: timer.c,v 1.90.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel

reactos/ntoskrnl/ke/i386
fpu.c 1.17.2.2 -> 1.17.2.3
diff -u -r1.17.2.2 -r1.17.2.3
--- fpu.c	13 Dec 2004 09:39:11 -0000	1.17.2.2
+++ fpu.c	13 Dec 2004 16:18:13 -0000	1.17.2.3
@@ -1,4 +1,4 @@
-/* $Id: fpu.c,v 1.17.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: fpu.c,v 1.17.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  *  ReactOS kernel
  *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team

reactos/ntoskrnl/ke/i386
irq.c 1.55.2.2 -> 1.55.2.3
diff -u -r1.55.2.2 -r1.55.2.3
--- irq.c	13 Dec 2004 09:39:12 -0000	1.55.2.2
+++ irq.c	13 Dec 2004 16:18:13 -0000	1.55.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: irq.c,v 1.55.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: irq.c,v 1.55.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/irq.c

reactos/ntoskrnl/ldr
init.c 1.49.2.2 -> 1.49.2.3
diff -u -r1.49.2.2 -r1.49.2.3
--- init.c	13 Dec 2004 09:39:12 -0000	1.49.2.2
+++ init.c	13 Dec 2004 16:18:13 -0000	1.49.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: init.c,v 1.49.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: init.c,v 1.49.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ldr/init.c

reactos/ntoskrnl/mm/i386
page.c 1.77.2.2 -> 1.77.2.3
diff -u -r1.77.2.2 -r1.77.2.3
--- page.c	13 Dec 2004 09:39:12 -0000	1.77.2.2
+++ page.c	13 Dec 2004 16:18:13 -0000	1.77.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: page.c,v 1.77.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: page.c,v 1.77.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * PROJECT:     ReactOS kernel
  * FILE:        ntoskrnl/mm/i386/page.c

reactos/ntoskrnl/mm
npool.c 1.92.2.2 -> 1.92.2.3
diff -u -r1.92.2.2 -r1.92.2.3
--- npool.c	13 Dec 2004 09:39:12 -0000	1.92.2.2
+++ npool.c	13 Dec 2004 16:18:13 -0000	1.92.2.3
@@ -1,4 +1,4 @@
-/* $Id: npool.c,v 1.92.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: npool.c,v 1.92.2.3 2004/12/13 16:18:13 hyperion Exp $
  *
  * COPYRIGHT:    See COPYING in the top level directory
  * PROJECT:      ReactOS kernel

reactos/ntoskrnl/mm
pool.c 1.35.6.1 -> 1.35.6.2
diff -u -r1.35.6.1 -r1.35.6.2
--- pool.c	13 Dec 2004 09:39:14 -0000	1.35.6.1
+++ pool.c	13 Dec 2004 16:18:14 -0000	1.35.6.2
@@ -1,4 +1,4 @@
-/* $Id: pool.c,v 1.35.6.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: pool.c,v 1.35.6.2 2004/12/13 16:18:14 hyperion Exp $
  * 
  * COPYRIGHT:    See COPYING in the top level directory
  * PROJECT:      ReactOS kernel

reactos/ntoskrnl/mm
ppool.c 1.33.2.1 -> 1.33.2.2
diff -u -r1.33.2.1 -r1.33.2.2
--- ppool.c	13 Dec 2004 09:39:14 -0000	1.33.2.1
+++ ppool.c	13 Dec 2004 16:18:14 -0000	1.33.2.2
@@ -1,4 +1,4 @@
-/* $Id: ppool.c,v 1.33.2.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: ppool.c,v 1.33.2.2 2004/12/13 16:18:14 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl
ntoskrnl.def 1.201.2.2 -> 1.201.2.3
diff -u -r1.201.2.2 -r1.201.2.3
--- ntoskrnl.def	13 Dec 2004 09:39:08 -0000	1.201.2.2
+++ ntoskrnl.def	13 Dec 2004 16:18:14 -0000	1.201.2.3
@@ -1,4 +1,4 @@
-; $Id: ntoskrnl.def,v 1.201.2.2 2004/12/13 09:39:08 hyperion Exp $
+; $Id: ntoskrnl.def,v 1.201.2.3 2004/12/13 16:18:14 hyperion Exp $
 ;
 ; reactos/ntoskrnl/ntoskrnl.def
 ;

reactos/ntoskrnl/ps
cid.c 1.2.2.2 -> 1.2.2.3
diff -u -r1.2.2.2 -r1.2.2.3
--- cid.c	13 Dec 2004 09:39:14 -0000	1.2.2.2
+++ cid.c	13 Dec 2004 16:18:14 -0000	1.2.2.3
@@ -1,4 +1,4 @@
-/* $Id: cid.c,v 1.2.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: cid.c,v 1.2.2.3 2004/12/13 16:18:14 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/ntoskrnl/ps
create.c 1.86.2.1 -> 1.86.2.2
diff -u -r1.86.2.1 -r1.86.2.2
--- create.c	13 Dec 2004 09:39:14 -0000	1.86.2.1
+++ create.c	13 Dec 2004 16:18:14 -0000	1.86.2.2
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.86.2.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: create.c,v 1.86.2.2 2004/12/13 16:18:14 hyperion Exp $
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel

reactos/ntoskrnl/ps
kill.c 1.86.2.2 -> 1.86.2.3
diff -u -r1.86.2.2 -r1.86.2.3
--- kill.c	13 Dec 2004 09:39:14 -0000	1.86.2.2
+++ kill.c	13 Dec 2004 16:18:15 -0000	1.86.2.3
@@ -1,4 +1,4 @@
-/* $Id: kill.c,v 1.86.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: kill.c,v 1.86.2.3 2004/12/13 16:18:15 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel

reactos/ntoskrnl/ps
process.c 1.157.2.2 -> 1.157.2.3
diff -u -r1.157.2.2 -r1.157.2.3
--- process.c	13 Dec 2004 09:39:14 -0000	1.157.2.2
+++ process.c	13 Dec 2004 16:18:16 -0000	1.157.2.3
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.157.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: process.c,v 1.157.2.3 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/ntoskrnl/ps
thread.c 1.138.2.2 -> 1.138.2.3
diff -u -r1.138.2.2 -r1.138.2.3
--- thread.c	13 Dec 2004 09:39:15 -0000	1.138.2.2
+++ thread.c	13 Dec 2004 16:18:16 -0000	1.138.2.3
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.138.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: thread.c,v 1.138.2.3 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel

reactos/ntoskrnl/ps
w32call.c 1.18.2.2 -> 1.18.2.3
diff -u -r1.18.2.2 -r1.18.2.3
--- w32call.c	13 Dec 2004 09:39:15 -0000	1.18.2.2
+++ w32call.c	13 Dec 2004 16:18:16 -0000	1.18.2.3
@@ -1,4 +1,4 @@
-/* $Id: w32call.c,v 1.18.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: w32call.c,v 1.18.2.3 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel

reactos/ntoskrnl/se
acl.c 1.21.2.1 -> 1.21.2.2
diff -u -r1.21.2.1 -r1.21.2.2
--- acl.c	13 Dec 2004 09:39:15 -0000	1.21.2.1
+++ acl.c	13 Dec 2004 16:18:16 -0000	1.21.2.2
@@ -1,4 +1,4 @@
-/* $Id: acl.c,v 1.21.2.1 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: acl.c,v 1.21.2.2 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/ntoskrnl/se
token.c 1.42.2.1 -> 1.42.2.2
diff -u -r1.42.2.1 -r1.42.2.2
--- token.c	13 Dec 2004 09:39:15 -0000	1.42.2.1
+++ token.c	13 Dec 2004 16:18:16 -0000	1.42.2.2
@@ -1,4 +1,4 @@
-/* $Id: token.c,v 1.42.2.1 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: token.c,v 1.42.2.2 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/subsys/csrss/win32csr
desktopbg.c 1.11.2.2 -> 1.11.2.3
diff -u -r1.11.2.2 -r1.11.2.3
--- desktopbg.c	13 Dec 2004 09:39:15 -0000	1.11.2.2
+++ desktopbg.c	13 Dec 2004 16:18:16 -0000	1.11.2.3
@@ -1,4 +1,4 @@
-/* $Id: desktopbg.c,v 1.11.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: desktopbg.c,v 1.11.2.3 2004/12/13 16:18:16 hyperion Exp $
  *
  * reactos/subsys/csrss/win32csr/desktopbg.c
  *

reactos/subsys/csrss/win32csr
guiconsole.c 1.22.2.2 -> 1.22.2.3
diff -u -r1.22.2.2 -r1.22.2.3
--- guiconsole.c	13 Dec 2004 09:39:15 -0000	1.22.2.2
+++ guiconsole.c	13 Dec 2004 16:18:16 -0000	1.22.2.3
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.c,v 1.22.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: guiconsole.c,v 1.22.2.3 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries

reactos/subsys/system/winlogon
winlogon.h 1.4.8.2 -> 1.4.8.3
diff -u -r1.4.8.2 -r1.4.8.3
--- winlogon.h	13 Dec 2004 09:39:16 -0000	1.4.8.2
+++ winlogon.h	13 Dec 2004 16:18:16 -0000	1.4.8.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: winlogon.h,v 1.4.8.2 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: winlogon.h,v 1.4.8.3 2004/12/13 16:18:16 hyperion Exp $
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS winlogon
  * FILE:            subsys/system/winlogon/winlogon.h

reactos/subsys/win32k/eng
bitblt.c 1.58.10.1 -> 1.58.10.2
diff -u -r1.58.10.1 -r1.58.10.2
--- bitblt.c	13 Dec 2004 09:39:16 -0000	1.58.10.1
+++ bitblt.c	13 Dec 2004 16:18:16 -0000	1.58.10.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bitblt.c,v 1.58.10.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: bitblt.c,v 1.58.10.2 2004/12/13 16:18:16 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/eng
clip.c 1.22.18.1 -> 1.22.18.2
diff -u -r1.22.18.1 -r1.22.18.2
--- clip.c	13 Dec 2004 09:39:16 -0000	1.22.18.1
+++ clip.c	13 Dec 2004 16:18:16 -0000	1.22.18.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: clip.c,v 1.22.18.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: clip.c,v 1.22.18.2 2004/12/13 16:18:16 hyperion Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/subsys/win32k/eng
gradient.c 1.11.2.1 -> 1.11.2.2
diff -u -r1.11.2.1 -r1.11.2.2
--- gradient.c	13 Dec 2004 09:39:16 -0000	1.11.2.1
+++ gradient.c	13 Dec 2004 16:18:16 -0000	1.11.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: gradient.c,v 1.11.2.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: gradient.c,v 1.11.2.2 2004/12/13 16:18:16 hyperion Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/subsys/win32k/eng
mouse.c 1.77.8.1 -> 1.77.8.2
diff -u -r1.77.8.1 -r1.77.8.2
--- mouse.c	13 Dec 2004 09:39:16 -0000	1.77.8.1
+++ mouse.c	13 Dec 2004 16:18:16 -0000	1.77.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: mouse.c,v 1.77.8.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: mouse.c,v 1.77.8.2 2004/12/13 16:18:16 hyperion Exp $
  *
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Mouse

reactos/subsys/win32k/eng
objects.h 1.32.12.1 -> 1.32.12.2
diff -u -r1.32.12.1 -r1.32.12.2
--- objects.h	13 Dec 2004 09:39:16 -0000	1.32.12.1
+++ objects.h	13 Dec 2004 16:18:16 -0000	1.32.12.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: objects.h,v 1.32.12.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: objects.h,v 1.32.12.2 2004/12/13 16:18:16 hyperion Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/subsys/win32k/eng
surface.c 1.44.12.1 -> 1.44.12.2
diff -u -r1.44.12.1 -r1.44.12.2
--- surface.c	13 Dec 2004 09:39:16 -0000	1.44.12.1
+++ surface.c	13 Dec 2004 16:18:16 -0000	1.44.12.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: surface.c,v 1.44.12.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: surface.c,v 1.44.12.2 2004/12/13 16:18:16 hyperion Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel

reactos/subsys/win32k/eng
xlate.c 1.42.8.1 -> 1.42.8.2
diff -u -r1.42.8.1 -r1.42.8.2
--- xlate.c	13 Dec 2004 09:39:16 -0000	1.42.8.1
+++ xlate.c	13 Dec 2004 16:18:16 -0000	1.42.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: xlate.c,v 1.42.8.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: xlate.c,v 1.42.8.2 2004/12/13 16:18:16 hyperion Exp $
  * 
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/main
dllmain.c 1.82.2.1 -> 1.82.2.2
diff -u -r1.82.2.1 -r1.82.2.2
--- dllmain.c	13 Dec 2004 09:39:17 -0000	1.82.2.1
+++ dllmain.c	13 Dec 2004 16:18:17 -0000	1.82.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dllmain.c,v 1.82.2.1 2004/12/13 09:39:17 hyperion Exp $
+/* $Id: dllmain.c,v 1.82.2.2 2004/12/13 16:18:17 hyperion Exp $
  *
  *  Entry Point for win32k.sys
  */

reactos/subsys/win32k
makefile 1.105.2.2 -> 1.105.2.3
diff -u -r1.105.2.2 -r1.105.2.3
--- makefile	13 Dec 2004 09:39:18 -0000	1.105.2.2
+++ makefile	13 Dec 2004 16:18:17 -0000	1.105.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.105.2.2 2004/12/13 09:39:18 hyperion Exp $
+# $Id: makefile,v 1.105.2.3 2004/12/13 16:18:17 hyperion Exp $
 
 PATH_TO_TOP = ../..
 

reactos/subsys/win32k/misc
object.c 1.12.16.1 -> 1.12.16.2
diff -u -r1.12.16.1 -r1.12.16.2
--- object.c	13 Dec 2004 09:39:19 -0000	1.12.16.1
+++ object.c	13 Dec 2004 16:18:17 -0000	1.12.16.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: object.c,v 1.12.16.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: object.c,v 1.12.16.2 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel

reactos/subsys/win32k/ntuser
class.c 1.60.2.1 -> 1.60.2.2
diff -u -r1.60.2.1 -r1.60.2.2
--- class.c	13 Dec 2004 09:39:19 -0000	1.60.2.1
+++ class.c	13 Dec 2004 16:18:17 -0000	1.60.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: class.c,v 1.60.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: class.c,v 1.60.2.2 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
desktop.c 1.24.2.2 -> 1.24.2.3
diff -u -r1.24.2.2 -r1.24.2.3
--- desktop.c	13 Dec 2004 09:39:19 -0000	1.24.2.2
+++ desktop.c	13 Dec 2004 16:18:17 -0000	1.24.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  $Id: desktop.c,v 1.24.2.2 2004/12/13 09:39:19 hyperion Exp $
+ *  $Id: desktop.c,v 1.24.2.3 2004/12/13 16:18:17 hyperion Exp $
  *
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
focus.c 1.25.2.2 -> 1.25.2.3
diff -u -r1.25.2.2 -r1.25.2.3
--- focus.c	13 Dec 2004 09:39:19 -0000	1.25.2.2
+++ focus.c	13 Dec 2004 16:18:17 -0000	1.25.2.3
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: focus.c,v 1.25.2.2 2004/12/13 09:39:19 hyperion Exp $
+ * $Id: focus.c,v 1.25.2.3 2004/12/13 16:18:17 hyperion Exp $
  */
 
 #include <w32k.h>

reactos/subsys/win32k/ntuser
input.c 1.38.6.1 -> 1.38.6.2
diff -u -r1.38.6.1 -r1.38.6.2
--- input.c	13 Dec 2004 09:39:19 -0000	1.38.6.1
+++ input.c	13 Dec 2004 16:18:17 -0000	1.38.6.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: input.c,v 1.38.6.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: input.c,v 1.38.6.2 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
message.c 1.75.2.1 -> 1.75.2.2
diff -u -r1.75.2.1 -r1.75.2.2
--- message.c	13 Dec 2004 09:39:19 -0000	1.75.2.1
+++ message.c	13 Dec 2004 16:18:17 -0000	1.75.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: message.c,v 1.75.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: message.c,v 1.75.2.2 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
misc.c 1.88.2.2 -> 1.88.2.3
diff -u -r1.88.2.2 -r1.88.2.3
--- misc.c	13 Dec 2004 09:39:19 -0000	1.88.2.2
+++ misc.c	13 Dec 2004 16:18:17 -0000	1.88.2.3
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.88.2.2 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: misc.c,v 1.88.2.3 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
msgqueue.c 1.108.2.1 -> 1.108.2.2
diff -u -r1.108.2.1 -r1.108.2.2
--- msgqueue.c	13 Dec 2004 09:39:19 -0000	1.108.2.1
+++ msgqueue.c	13 Dec 2004 16:18:17 -0000	1.108.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: msgqueue.c,v 1.108.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: msgqueue.c,v 1.108.2.2 2004/12/13 16:18:17 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
painting.c 1.87.2.2 -> 1.87.2.3
diff -u -r1.87.2.2 -r1.87.2.3
--- painting.c	13 Dec 2004 09:39:19 -0000	1.87.2.2
+++ painting.c	13 Dec 2004 16:18:17 -0000	1.87.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  $Id: painting.c,v 1.87.2.2 2004/12/13 09:39:19 hyperion Exp $
+ *  $Id: painting.c,v 1.87.2.3 2004/12/13 16:18:17 hyperion Exp $
  *
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
stubs.c 1.47.2.2 -> 1.47.2.3
diff -u -r1.47.2.2 -r1.47.2.3
--- stubs.c	13 Dec 2004 09:39:20 -0000	1.47.2.2
+++ stubs.c	13 Dec 2004 16:18:18 -0000	1.47.2.3
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.47.2.2 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: stubs.c,v 1.47.2.3 2004/12/13 16:18:18 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
windc.c 1.67.8.1 -> 1.67.8.2
diff -u -r1.67.8.1 -r1.67.8.2
--- windc.c	13 Dec 2004 09:39:20 -0000	1.67.8.1
+++ windc.c	13 Dec 2004 16:18:18 -0000	1.67.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: windc.c,v 1.67.8.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: windc.c,v 1.67.8.2 2004/12/13 16:18:18 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
window.c 1.250.2.1 -> 1.250.2.2
diff -u -r1.250.2.1 -r1.250.2.2
--- window.c	13 Dec 2004 09:39:20 -0000	1.250.2.1
+++ window.c	13 Dec 2004 16:18:18 -0000	1.250.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: window.c,v 1.250.2.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: window.c,v 1.250.2.2 2004/12/13 16:18:18 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
winpos.c 1.124.2.1 -> 1.124.2.2
diff -u -r1.124.2.1 -r1.124.2.2
--- winpos.c	13 Dec 2004 09:39:20 -0000	1.124.2.1
+++ winpos.c	13 Dec 2004 16:18:18 -0000	1.124.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: winpos.c,v 1.124.2.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: winpos.c,v 1.124.2.2 2004/12/13 16:18:18 hyperion Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel

reactos/subsys/win32k/ntuser
winsta.c 1.67.2.1 -> 1.67.2.2
diff -u -r1.67.2.1 -r1.67.2.2
--- winsta.c	13 Dec 2004 09:39:20 -0000	1.67.2.1
+++ winsta.c	13 Dec 2004 16:18:18 -0000	1.67.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  $Id: winsta.c,v 1.67.2.1 2004/12/13 09:39:20 hyperion Exp $
+ *  $Id: winsta.c,v 1.67.2.2 2004/12/13 16:18:18 hyperion Exp $
  *
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel

reactos/subsys/win32k/objects
bitmaps.c 1.81.2.1 -> 1.81.2.2
diff -u -r1.81.2.1 -r1.81.2.2
--- bitmaps.c	13 Dec 2004 09:39:21 -0000	1.81.2.1
+++ bitmaps.c	13 Dec 2004 16:18:18 -0000	1.81.2.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bitmaps.c,v 1.81.2.1 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: bitmaps.c,v 1.81.2.2 2004/12/13 16:18:18 hyperion Exp $ */
 #include <w32k.h>
 
 #define IN_RECT(r,x,y) \

reactos/subsys/win32k/objects
brush.c 1.40.10.2 -> 1.40.10.3
diff -u -r1.40.10.2 -r1.40.10.3
--- brush.c	13 Dec 2004 09:39:21 -0000	1.40.10.2
+++ brush.c	13 Dec 2004 16:18:18 -0000	1.40.10.3
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: brush.c,v 1.40.10.2 2004/12/13 09:39:21 hyperion Exp $
+ * $Id: brush.c,v 1.40.10.3 2004/12/13 16:18:18 hyperion Exp $
  */
 #include <w32k.h>
 

reactos/subsys/win32k/objects
cliprgn.c 1.42.10.2 -> 1.42.10.3
diff -u -r1.42.10.2 -r1.42.10.3
--- cliprgn.c	13 Dec 2004 09:39:21 -0000	1.42.10.2
+++ cliprgn.c	13 Dec 2004 16:18:18 -0000	1.42.10.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: cliprgn.c,v 1.42.10.2 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: cliprgn.c,v 1.42.10.3 2004/12/13 16:18:18 hyperion Exp $ */
 #include <w32k.h>
 
 int FASTCALL

reactos/subsys/win32k/objects
color.c 1.50.10.1 -> 1.50.10.2
diff -u -r1.50.10.1 -r1.50.10.2
--- color.c	13 Dec 2004 09:39:21 -0000	1.50.10.1
+++ color.c	13 Dec 2004 16:18:18 -0000	1.50.10.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: color.c,v 1.50.10.1 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: color.c,v 1.50.10.2 2004/12/13 16:18:18 hyperion Exp $ */
 #include <w32k.h>
 
 // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping

reactos/subsys/win32k/objects
dc.c 1.147.2.2 -> 1.147.2.3
diff -u -r1.147.2.2 -r1.147.2.3
--- dc.c	13 Dec 2004 09:39:21 -0000	1.147.2.2
+++ dc.c	13 Dec 2004 16:18:18 -0000	1.147.2.3
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dc.c,v 1.147.2.2 2004/12/13 09:39:21 hyperion Exp $
+/* $Id: dc.c,v 1.147.2.3 2004/12/13 16:18:18 hyperion Exp $
  *
  * DC.C - Device context functions
  *

reactos/subsys/win32k/objects
dib.c 1.56.12.1 -> 1.56.12.2
diff -u -r1.56.12.1 -r1.56.12.2
--- dib.c	13 Dec 2004 09:39:22 -0000	1.56.12.1
+++ dib.c	13 Dec 2004 16:18:19 -0000	1.56.12.2
@@ -1,5 +1,5 @@
 /*
- * $Id: dib.c,v 1.56.12.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: dib.c,v 1.56.12.2 2004/12/13 16:18:19 hyperion Exp $
  *
  * ReactOS W32 Subsystem
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team

reactos/subsys/win32k/objects
fillshap.c 1.52.10.1 -> 1.52.10.2
diff -u -r1.52.10.1 -r1.52.10.2
--- fillshap.c	13 Dec 2004 09:39:22 -0000	1.52.10.1
+++ fillshap.c	13 Dec 2004 16:18:19 -0000	1.52.10.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fillshap.c,v 1.52.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: fillshap.c,v 1.52.10.2 2004/12/13 16:18:19 hyperion Exp $ */
 #include <w32k.h>
 
 /*

reactos/subsys/win32k/objects
gdiobj.c 1.73.6.1 -> 1.73.6.2
diff -u -r1.73.6.1 -r1.73.6.2
--- gdiobj.c	13 Dec 2004 09:39:22 -0000	1.73.6.1
+++ gdiobj.c	13 Dec 2004 16:18:19 -0000	1.73.6.2
@@ -19,7 +19,7 @@
 /*
  * GDIOBJ.C - GDI object manipulation routines
  *
- * $Id: gdiobj.c,v 1.73.6.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: gdiobj.c,v 1.73.6.2 2004/12/13 16:18:19 hyperion Exp $
  */
 #include <w32k.h>
 
@@ -364,6 +364,7 @@
       if(GdiHdr->LockingThread == NULL)
       {
         BOOL Ret;
+        PW32PROCESS W32Process = PsGetWin32Process();
         ULONG Type = Entry->Type << 16;
 
         /* Clear the type field so when unlocking the handle it gets finally deleted */
@@ -372,6 +373,11 @@
         
         /* unlock the handle slot */
         InterlockedExchange(&Entry->ProcessId, 0);
+        
+        if(W32Process != NULL)
+        {
+          InterlockedDecrement(&W32Process->GDIObjects);
+        }
 
         /* call the cleanup routine. */
         Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type);
@@ -817,6 +823,7 @@
         if(Entry->Type == 0 && GdiHdr->Locks == 0)
         {
           PPAGED_LOOKASIDE_LIST LookasideList;
+          PW32PROCESS W32Process = PsGetWin32Process();
           DWORD Type = GDI_HANDLE_GET_TYPE(hObj);
           
           ASSERT(ProcessId != 0); /* must not delete a global handle!!!! */
@@ -825,6 +832,11 @@
           Entry->KernelData = NULL;
           InterlockedExchange(&Entry->ProcessId, 0);
           
+          if(W32Process != NULL)
+          {
+            InterlockedDecrement(&W32Process->GDIObjects);
+          }
+          
           /* call the cleanup routine. */
           Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type);
 

reactos/subsys/win32k/objects
line.c 1.37.10.1 -> 1.37.10.2
diff -u -r1.37.10.1 -r1.37.10.2
--- line.c	13 Dec 2004 09:39:22 -0000	1.37.10.1
+++ line.c	13 Dec 2004 16:18:19 -0000	1.37.10.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: line.c,v 1.37.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: line.c,v 1.37.10.2 2004/12/13 16:18:19 hyperion Exp $ */
 #include <w32k.h>
 
 // Some code from the WINE project source (www.winehq.com)

reactos/subsys/win32k/objects
palette.c 1.20.12.1 -> 1.20.12.2
diff -u -r1.20.12.1 -r1.20.12.2
--- palette.c	13 Dec 2004 09:39:22 -0000	1.20.12.1
+++ palette.c	13 Dec 2004 16:18:19 -0000	1.20.12.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: palette.c,v 1.20.12.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: palette.c,v 1.20.12.2 2004/12/13 16:18:19 hyperion Exp $ */
 #include <w32k.h>
 
 #ifndef NO_MAPPING

reactos/subsys/win32k/objects
pen.c 1.16.10.1 -> 1.16.10.2
diff -u -r1.16.10.1 -r1.16.10.2
--- pen.c	13 Dec 2004 09:39:22 -0000	1.16.10.1
+++ pen.c	13 Dec 2004 16:18:19 -0000	1.16.10.2
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: pen.c,v 1.16.10.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: pen.c,v 1.16.10.2 2004/12/13 16:18:19 hyperion Exp $
  */
 #include <w32k.h>
 

reactos/subsys/win32k/objects
print.c 1.23.8.1 -> 1.23.8.2
diff -u -r1.23.8.1 -r1.23.8.2
--- print.c	13 Dec 2004 09:39:22 -0000	1.23.8.1
+++ print.c	13 Dec 2004 16:18:19 -0000	1.23.8.2
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: print.c,v 1.23.8.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: print.c,v 1.23.8.2 2004/12/13 16:18:19 hyperion Exp $ */
 #include <w32k.h>
 
 INT

reactos/subsys/win32k/objects
region.c 1.62.10.1 -> 1.62.10.2
diff -u -r1.62.10.1 -r1.62.10.2
--- region.c	13 Dec 2004 09:39:22 -0000	1.62.10.1
+++ region.c	13 Dec 2004 16:18:19 -0000	1.62.10.2
@@ -113,7 +113,7 @@
  * the y-x-banding that's so nice to have...
  */
 
-/* $Id: region.c,v 1.62.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: region.c,v 1.62.10.2 2004/12/13 16:18:19 hyperion Exp $ */
 #include <w32k.h>
 #include <win32k/float.h>
 

reactos/subsys/win32k/objects
text.c 1.112.4.1 -> 1.112.4.2
diff -u -r1.112.4.1 -r1.112.4.2
--- text.c	13 Dec 2004 09:39:22 -0000	1.112.4.1
+++ text.c	13 Dec 2004 16:18:22 -0000	1.112.4.2
@@ -22,7 +22,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: text.c,v 1.112.4.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: text.c,v 1.112.4.2 2004/12/13 16:18:22 hyperion Exp $ */
 #include <w32k.h>
 
 #include <ft2build.h>

reactos/tools
helper.mk 1.95.2.2 -> 1.95.2.3
diff -u -r1.95.2.2 -r1.95.2.3
--- helper.mk	13 Dec 2004 09:39:25 -0000	1.95.2.2
+++ helper.mk	13 Dec 2004 16:18:22 -0000	1.95.2.3
@@ -1,4 +1,4 @@
-# $Id: helper.mk,v 1.95.2.2 2004/12/13 09:39:25 hyperion Exp $
+# $Id: helper.mk,v 1.95.2.3 2004/12/13 16:18:22 hyperion Exp $
 #
 # Helper makefile for ReactOS modules
 # Variables this makefile accepts:

reactos/apps/utils/net/route
makefile added at 1.1.2.1
diff -N makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ makefile	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,17 @@
+PATH_TO_TOP = ../../../..
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = console
+
+TARGET_NAME = route
+
+TARGET_SDKLIBS = ws2_32.a iphlpapi.a ntdll.a
+
+TARGET_OBJECTS = $(TARGET_NAME).o
+
+TARGET_GCCLIBS = 
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk

reactos/apps/utils/net/route
route.c added at 1.1.2.1
diff -N route.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ route.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,157 @@
+/* Poor man's route
+ *
+ * Supported commands:
+ *
+ * "print"
+ * "add" target ["mask" mask] gw ["metric" metric]
+ * "delete" target gw
+ *
+ * Goals:
+ *
+ * Flexible, simple
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <iphlpapi.h>
+#include <winsock2.h>
+
+#define IPBUF 17
+#define IN_ADDR_OF(x) *((struct in_addr *)&(x))
+
+int usage() {
+    fprintf( stderr, 
+	     "route usage:\n"
+	     "route print\n"
+	     "  prints the route table\n"
+	     "route add <target> [mask <mask>] <gw> [metric <m>]\n"
+	     "  adds a route\n"
+	     "route delete <target> <gw>\n"
+	     "  deletes a route\n" );
+    return 1;
+}
+
+int print_routes() {
+    PMIB_IPFORWARDTABLE IpForwardTable;
+    DWORD Error;
+    ULONG Size = 0;
+    char Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF], 
+	Index[IPBUF], Metric[IPBUF];
+    int i;
+
+    if( (Error = GetIpForwardTable( NULL, &Size, TRUE )) ==
+    	ERROR_INSUFFICIENT_BUFFER ) {
+	IpForwardTable = malloc( Size );
+	Error = GetIpForwardTable( IpForwardTable, &Size, TRUE );
+    }
+
+    if( Error == ERROR_SUCCESS ) {
+	printf( "%-16s%-16s%-16s%-10s%-10s\n", 
+		"Destination",
+		"Netmask",
+		"Gateway",
+		"Index",
+		"Metric" );
+	for( i = 0; i < IpForwardTable->dwNumEntries; i++ ) {
+	    strcpy( Destination,
+		    inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+		    		dwForwardDest) ) );
+	    strcpy( Netmask,
+		    inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+		    		dwForwardMask) ) );
+	    strcpy( Gateway,
+		    inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+		    		dwForwardNextHop) ) );
+
+	    printf( "%-16s%-16s%-16s%-10d%-10d\n", 
+		    Destination,
+		    Netmask,
+		    Gateway,
+		    IpForwardTable->table[i].dwForwardIfIndex,
+		    IpForwardTable->table[i].dwForwardMetric1 );
+	}
+
+	free( IpForwardTable );
+
+	return ERROR_SUCCESS;
+    } else {
+	fprintf( stderr, "Route enumerate failed\n" );
+	return Error;
+    }
+}
+
+int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd, 
+			  int argc, char **argv ) {
+    int i;
+
+    if( argc > 1 ) RowToAdd->dwForwardDest = inet_addr( argv[0] );
+    else return FALSE;
+    for( i = 1; i < argc; i++ ) {
+	if( !strcasecmp( argv[i], "mask" ) ) {
+	    i++; if( i >= argc ) return FALSE;
+	    RowToAdd->dwForwardMask = inet_addr( argv[i] );
+	} else if( !strcasecmp( argv[i], "metric" ) ) {
+	    i++; if( i >= argc ) return FALSE;
+	    RowToAdd->dwForwardMetric1 = atoi( argv[i] );
+	} else {
+	    RowToAdd->dwForwardNextHop = inet_addr( argv[i] );
+	}
+    }
+
+    return TRUE;
+}
+
+int add_route( int argc, char **argv ) {
+    MIB_IPFORWARDROW RowToAdd = { 0 };
+    DWORD Error;
+
+    if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) ) {
+	fprintf( stderr, 
+		 "route add usage:\n"
+		 "route add <target> [mask <mask>] <gw> [metric <m>]\n"
+		 "  Adds a route to the IP route table.\n"
+		 "  <target> is the network or host to add a route to.\n"
+		 "  <mask>   is the netmask to use (autodetected if unspecified)\n"
+		 "  <gw>     is the gateway to use to access the network\n"
+		 "  <m>      is the metric to use (lower is preferred)\n" );
+	return 1;
+    }
+    
+    if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS ) 
+	return 0;
+    
+    fprintf( stderr, "Route addition failed\n" );
+    return Error;
+}
+
+int del_route( int argc, char **argv ) {
+    MIB_IPFORWARDROW RowToDel = { 0 };
+    DWORD Error;
+
+    if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) ) {
+	fprintf( stderr, 
+		 "route delete usage:\n"
+		 "route delete <target> <gw>\n"
+		 "  Removes a route from the IP route table.\n"
+		 "  <target> is the network or host to add a route to.\n"
+		 "  <gw>     is the gateway to remove the route from.\n" );
+	return 1;
+    }
+    
+    if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS ) 
+	return 0;
+    
+    fprintf( stderr, "Route addition failed\n" );
+    return Error;
+}
+
+int main( int argc, char **argv ) {
+    if( argc < 2 ) return usage();
+    else if( !strcasecmp( argv[1], "print" ) ) 
+	return print_routes();
+    else if( !strcasecmp( argv[1], "add" ) ) 
+	return add_route( argc-2, argv+2 );
+    else if( !strcasecmp( argv[1], "delete" ) ) 
+	return del_route( argc-2, argv+2 );
+    else return usage();
+}

reactos/apps/utils/net/route
route.rc added at 1.1.2.1
diff -N route.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ route.rc	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,7 @@
+/* $Id: route.rc,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $ */
+
+#define REACTOS_STR_FILE_DESCRIPTION	"ReactOS TCP/IPv4 Win32 Route\0"
+#define REACTOS_STR_INTERNAL_NAME	"route\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"route.exe\0"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT	"Art Yerkes (arty@users.sourceforge.net)\0"
+#include <reactos/version.rc>

reactos/drivers/video/miniport/xboxvmp
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,8 @@
+junk.tmp
+base.tmp
+temp.exp
+xboxvmp.coff
+*.o
+*.sym
+*.sys
+*.map

reactos/drivers/video/miniport/xboxvmp
Makefile added at 1.1.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,20 @@
+PATH_TO_TOP = ../../../..
+
+TARGET_TYPE = driver
+
+TARGET_NAME = xboxvmp
+
+TARGET_DDKLIBS = videoprt.a ntoskrnl.a
+
+TARGET_CFLAGS = -Werror -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -D__USE_W32API
+
+TARGET_OBJECTS = \
+  xboxvmp.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# Automatic dependency tracking
+DEP_OBJECTS := $(TARGET_OBJECTS)
+include $(PATH_TO_TOP)/tools/depend.mk

reactos/drivers/video/miniport/xboxvmp
xboxvmp.c added at 1.1.2.1
diff -N xboxvmp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ xboxvmp.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,597 @@
+/*
+ * ReactOS Xbox miniport video driver
+ *
+ * Based on VBE miniport video driver
+ * Copyright (C) 2004 Filip Navara
+ *
+ * Power Management and VBE 1.2 support
+ * Copyright (C) 2004 Magnus Olsen
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * TODO:
+ * - Check input parameters everywhere.
+ * - Call VideoPortVerifyAccessRanges to reserve the memory we're about
+ *   to map.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "xboxvmp.h"
+
+#define I2C_IO_BASE 0xc000
+
+#define CONTROL_FRAMEBUFFER_ADDRESS_OFFSET 0x600800
+
+/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
+
+VP_STATUS STDCALL
+DriverEntry(IN PVOID Context1, IN PVOID Context2)
+{
+  VIDEO_HW_INITIALIZATION_DATA InitData;
+
+  VideoPortZeroMemory(&InitData, sizeof(InitData));
+  InitData.AdapterInterfaceType = PCIBus;
+  InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
+  InitData.HwFindAdapter = XboxVmpFindAdapter;
+  InitData.HwInitialize = XboxVmpInitialize;
+  InitData.HwStartIO = XboxVmpStartIO;
+  InitData.HwResetHw = XboxVmpResetHw;
+  InitData.HwGetPowerState = XboxVmpGetPowerState;
+  InitData.HwSetPowerState = XboxVmpSetPowerState;
+  InitData.HwDeviceExtensionSize = sizeof(XBOXVMP_DEVICE_EXTENSION);
+  
+  return VideoPortInitialize(Context1, Context2, &InitData, NULL);
+}
+
+/*
+ * XboxVmpFindAdapter
+ *
+ * Detects the Xbox Nvidia display adapter.
+ */
+
+VP_STATUS STDCALL
+XboxVmpFindAdapter(
+   IN PVOID HwDeviceExtension,
+   IN PVOID HwContext,
+   IN PWSTR ArgumentString,
+   IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+   OUT PUCHAR Again)
+{
+  PXBOXVMP_DEVICE_EXTENSION XboxVmpDeviceExtension;
+  VIDEO_ACCESS_RANGE AccessRanges[3];
+  VP_STATUS Status;
+
+  DPRINT("XboxVmpFindAdapter\n");
+
+  XboxVmpDeviceExtension = (PXBOXVMP_DEVICE_EXTENSION) HwDeviceExtension;
+  Status = VideoPortGetAccessRanges(HwDeviceExtension, 0, NULL, 3, AccessRanges,
+                                    NULL, NULL, NULL);
+
+  if (NO_ERROR == Status)
+    {
+      XboxVmpDeviceExtension->PhysControlStart = AccessRanges[0].RangeStart;
+      XboxVmpDeviceExtension->ControlLength = AccessRanges[0].RangeLength;
+      XboxVmpDeviceExtension->PhysFrameBufferStart = AccessRanges[1].RangeStart;
+    }
+ 
+  return Status;
+}
+
+/*
+ * XboxVmpInitialize
+ *
+ * Performs the first initialization of the adapter, after the HAL has given
+ * up control of the video hardware to the video port driver.
+ */
+
+BOOLEAN STDCALL
+XboxVmpInitialize(PVOID HwDeviceExtension)
+{
+  PXBOXVMP_DEVICE_EXTENSION XboxVmpDeviceExtension;
+  ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
+  ULONG Length;
+
+  DPRINT("XboxVmpInitialize\n");
+
+  XboxVmpDeviceExtension = (PXBOXVMP_DEVICE_EXTENSION) HwDeviceExtension;
+
+  Length = XboxVmpDeviceExtension->ControlLength;
+  XboxVmpDeviceExtension->VirtControlStart = NULL;
+  if (NO_ERROR != VideoPortMapMemory(HwDeviceExtension,
+                                     XboxVmpDeviceExtension->PhysControlStart,
+                                     &Length, &inIoSpace,
+                                     &XboxVmpDeviceExtension->VirtControlStart))
+    {
+      DPRINT1("Failed to map control memory\n");
+      return FALSE;
+    }
+  DPRINT("Mapped 0x%x bytes of control mem at 0x%x to virt addr 0x%x\n",
+         XboxVmpDeviceExtension->ControlLength,
+         XboxVmpDeviceExtension->PhysControlStart.u.LowPart,
+         XboxVmpDeviceExtension->VirtControlStart);
+
+  return TRUE;
+}
+
+/*
+ * XboxVmpStartIO
+ *
+ * Processes the specified Video Request Packet.
+ */
+
+BOOLEAN STDCALL
+XboxVmpStartIO(
+   PVOID HwDeviceExtension,
+   PVIDEO_REQUEST_PACKET RequestPacket)
+{
+  BOOL Result;
+
+  RequestPacket->StatusBlock->Status = STATUS_UNSUCCESSFUL;
+
+  switch (RequestPacket->IoControlCode)
+    {
+      case IOCTL_VIDEO_SET_CURRENT_MODE:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_SET_CURRENT_MODE\n");
+        if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpSetCurrentMode(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_MODE)RequestPacket->InputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_RESET_DEVICE:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_RESET_DEVICE\n");
+        Result = XboxVmpResetDevice(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_MAP_VIDEO_MEMORY\n");
+        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
+            RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpMapVideoMemory(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_MEMORY)RequestPacket->InputBuffer,
+            (PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_UNMAP_VIDEO_MEMORY\n");
+        if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpUnmapVideoMemory(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_MEMORY)RequestPacket->InputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES\n");
+        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpQueryNumAvailModes(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_NUM_MODES)RequestPacket->OutputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_QUERY_AVAIL_MODES:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_AVAIL_MODES\n");
+        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpQueryAvailModes(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+
+      case IOCTL_VIDEO_QUERY_CURRENT_MODE:
+        DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_CURRENT_MODE\n");
+        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) 
+          {
+            RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+            return TRUE;
+          }
+        Result = XboxVmpQueryCurrentMode(
+            (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+            (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
+            RequestPacket->StatusBlock);
+        break;
+         
+      default:
+        DPRINT("XboxVmpStartIO 0x%x not implemented\n");
+        RequestPacket->StatusBlock->Status = STATUS_NOT_IMPLEMENTED;
+        return FALSE;
+    }
+  
+  if (Result)
+    {
+      RequestPacket->StatusBlock->Status = STATUS_SUCCESS;
+    }
+
+  return TRUE;
+}
+
+/*
+ * XboxVmpResetHw
+ *
+ * This function is called to reset the hardware to a known state.
+ */
+
+BOOLEAN STDCALL
+XboxVmpResetHw(
+   PVOID DeviceExtension,
+   ULONG Columns,
+   ULONG Rows)
+{
+  DPRINT("XboxVmpResetHw\n");
+
+  if (! XboxVmpResetDevice((PXBOXVMP_DEVICE_EXTENSION) DeviceExtension, NULL))
+    {
+      return FALSE;
+    }
+   
+   return TRUE;
+}
+
+/*
+ * XboxVmpGetPowerState
+ *
+ * Queries whether the device can support the requested power state.
+ */
+
+VP_STATUS STDCALL
+XboxVmpGetPowerState(
+   PVOID HwDeviceExtension,
+   ULONG HwId,
+   PVIDEO_POWER_MANAGEMENT VideoPowerControl)
+{
+  DPRINT1("XboxVmpGetPowerState is not supported\n");
+
+  return ERROR_NOT_SUPPORTED;   
+}
+
+/*
+ * XboxVmpSetPowerState
+ *
+ * Sets the power state of the specified device
+ */
+
+VP_STATUS STDCALL
+XboxVmpSetPowerState(
+   PVOID HwDeviceExtension,
+   ULONG HwId,
+   PVIDEO_POWER_MANAGEMENT VideoPowerControl)
+{
+  DPRINT1("XboxVmpSetPowerState not supported\n");
+
+  return ERROR_NOT_SUPPORTED;   
+}
+
+/*
+ * VBESetCurrentMode
+ *
+ * Sets the adapter to the specified operating mode.
+ */
+
+BOOL FASTCALL
+XboxVmpSetCurrentMode(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE RequestedMode,
+   PSTATUS_BLOCK StatusBlock)
+{
+  if (0 != RequestedMode->RequestedMode)
+    {
+      return FALSE;
+    }
+
+  /* Nothing to do, really. We only support a single mode and we're already
+     in that mode */
+  return TRUE;
+}
+
+/*
+ * XboxVmpResetDevice
+ *
+ * Resets the video hardware to the default mode, to which it was initialized
+ * at system boot. 
+ */
+
+BOOL FASTCALL
+XboxVmpResetDevice(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PSTATUS_BLOCK StatusBlock)
+{
+  /* There is nothing to be done here */
+
+  return TRUE;
+}
+
+/*
+ * XboxVmpMapVideoMemory
+ *
+ * Maps the video hardware frame buffer and video RAM into the virtual address
+ * space of the requestor. 
+ */
+
+BOOL FASTCALL
+XboxVmpMapVideoMemory(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MEMORY RequestedAddress,
+   PVIDEO_MEMORY_INFORMATION MapInformation,
+   PSTATUS_BLOCK StatusBlock)
+{
+  PHYSICAL_ADDRESS FrameBuffer;
+  ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
+  SYSTEM_BASIC_INFORMATION BasicInfo;
+  ULONG Length;
+
+  StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
+
+  FrameBuffer.u.HighPart = 0;
+  if (NT_SUCCESS(ZwQuerySystemInformation(SystemBasicInformation,
+                                          (PVOID) &BasicInfo,
+                                          sizeof(SYSTEM_BASIC_INFORMATION),
+                                          &Length)))
+    {
+      FrameBuffer.u.LowPart = BasicInfo.HighestPhysicalPage * PAGE_SIZE;
+    }
+  else
+    {
+      DPRINT1("ZwQueryBasicInformation failed, assuming 64MB total memory\n");
+      FrameBuffer.u.LowPart = 60 * 1024 * 1024;
+    }
+  
+  FrameBuffer.QuadPart += DeviceExtension->PhysFrameBufferStart.QuadPart;
+  MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
+  MapInformation->VideoRamLength = 4 * 1024 * 1024;
+  VideoPortMapMemory(DeviceExtension, FrameBuffer,
+      &MapInformation->VideoRamLength, &inIoSpace,
+      &MapInformation->VideoRamBase);
+
+  MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
+  MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
+
+  /* Tell the nVidia controller about the framebuffer */
+  *((PULONG)((char *) DeviceExtension->VirtControlStart + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = FrameBuffer.u.LowPart;
+
+  DPRINT("Mapped 0x%x bytes of phys mem at 0x%x to virt addr 0x%x\n",
+          MapInformation->VideoRamLength, FrameBuffer.u.LowPart, MapInformation->VideoRamBase);
+
+  return TRUE;
+}
+
+/*
+ * VBEUnmapVideoMemory
+ *
+ * Releases a mapping between the virtual address space and the adapter's
+ * frame buffer and video RAM.
+ */
+
+BOOL FASTCALL
+XboxVmpUnmapVideoMemory(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MEMORY VideoMemory,
+   PSTATUS_BLOCK StatusBlock)
+{
+  VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
+                       NULL);
+
+  return TRUE;
+}
+
+/*
+ * XboxVmpQueryNumAvailModes
+ *
+ * Returns the number of video modes supported by the adapter and the size
+ * in bytes of the video mode information, which can be used to allocate a
+ * buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
+ */
+
+BOOL FASTCALL
+XboxVmpQueryNumAvailModes(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_NUM_MODES Modes,
+   PSTATUS_BLOCK StatusBlock)
+{
+  Modes->NumModes = 1;
+  Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
+  StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
+  return TRUE;
+}
+
+static BOOL
+ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus)
+{
+  int nRetriesToLive=50;
+
+  while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800))
+    {
+      ;  /* Franz's spin while bus busy with any master traffic */
+    }
+
+  while (0 != nRetriesToLive--)
+    {
+      UCHAR b;
+      int temp;
+
+      WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
+      WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister);
+
+      temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0));
+      WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp);  /* clear down all preexisting errors */
+
+      switch (Size)
+        {
+          case 4:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d);      /* DWORD modus ? */
+            break;
+          case 2:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b);      /* WORD modus */
+            break;
+          default:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a);      // BYTE
+            break;
+        }
+
+      b = 0;
+
+      while (0 == (b & 0x36))
+        {
+          b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0));
+        }
+
+      if (0 != (b & 0x24))
+        {
+          /* printf("I2CTransmitByteGetReturn error %x\n", b); */
+        }
+
+      if(0 == (b & 0x10))
+        {
+          /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
+        }
+      else
+        {
+          switch (Size)
+            {
+              case 4:
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                break;
+              case 2:
+                *Data_to_smbus = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6));
+                break;
+              default:
+                *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+                break;
+            }
+
+
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+
+static BOOL
+I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return)
+{
+  return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
+}
+
+/*
+ * XboxVmpQueryAvailModes
+ *
+ * Returns information about each video mode supported by the adapter.
+ */
+
+BOOL FASTCALL
+XboxVmpQueryAvailModes(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE_INFORMATION VideoMode,
+   PSTATUS_BLOCK StatusBlock)
+{
+  return XboxVmpQueryCurrentMode(DeviceExtension, VideoMode, StatusBlock);
+}
+
+/*
+ * VBEQueryCurrentMode
+ *
+ * Returns information about current video mode.
+ */
+
+BOOL FASTCALL  
+XboxVmpQueryCurrentMode(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE_INFORMATION VideoMode,
+   PSTATUS_BLOCK StatusBlock)
+{
+  ULONG AvMode;
+
+  VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
+  VideoMode->ModeIndex = 0;
+  if (I2CTransmitByteGetReturn(0x10, 0x04, &AvMode))
+    {
+      if (1 == AvMode) /* HDTV */
+        {
+          VideoMode->VisScreenWidth = 720;
+        }
+      else
+        {
+          /* FIXME Other possible values of AvMode:
+           * 0 - AV_SCART_RGB
+           * 2 - AV_VGA_SOG
+           * 4 - AV_SVIDEO
+           * 6 - AV_COMPOSITE
+           * 7 - AV_VGA
+           * other AV_COMPOSITE
+           */
+          VideoMode->VisScreenWidth = 640;
+        }
+    }
+  else
+    {
+      VideoMode->VisScreenWidth = 640;
+    }
+   VideoMode->VisScreenHeight = 480;
+   VideoMode->ScreenStride = VideoMode->VisScreenWidth * 4;
+   VideoMode->NumberOfPlanes = 1;
+   VideoMode->BitsPerPlane = 32;
+   VideoMode->Frequency = 1;
+   VideoMode->XMillimeter = 0; /* FIXME */
+   VideoMode->YMillimeter = 0; /* FIXME */
+   VideoMode->NumberRedBits = 8;
+   VideoMode->NumberGreenBits = 8;
+   VideoMode->NumberBlueBits = 8;
+   VideoMode->RedMask = 0xff0000;
+   VideoMode->GreenMask = 0x00ff00;
+   VideoMode->BlueMask = 0x0000ff;
+   VideoMode->VideoMemoryBitmapWidth = VideoMode->VisScreenWidth;
+   VideoMode->VideoMemoryBitmapHeight = VideoMode->VisScreenHeight;
+   VideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
+      VIDEO_MODE_NO_OFF_SCREEN;
+   VideoMode->DriverSpecificAttributeFlags = 0;
+
+   StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
+
+   return TRUE;
+}
+
+/* EOF */

reactos/drivers/video/miniport/xboxvmp
xboxvmp.h added at 1.1.2.1
diff -N xboxvmp.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ xboxvmp.h	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,130 @@
+/*
+ * ReactOS Xbox miniport video driver
+ *
+ * Based on VBE miniport video driver
+ * Copyright (C) 2004 Filip Navara
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef XBOXVMP_H
+#define XBOXVMP_H
+
+/* INCLUDES *******************************************************************/
+
+#include "stddef.h"
+#include "windef.h"
+#include "wingdi.h"
+#include <ddk/miniport.h>
+#include <ddk/video.h>
+#include <ddk/ntddvdeo.h>
+#include <ddk/ntapi.h>
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct
+{
+  PHYSICAL_ADDRESS PhysControlStart;
+  ULONG ControlLength;
+  PVOID VirtControlStart;
+  PHYSICAL_ADDRESS PhysFrameBufferStart;
+} XBOXVMP_DEVICE_EXTENSION, *PXBOXVMP_DEVICE_EXTENSION;
+
+VP_STATUS STDCALL
+XboxVmpFindAdapter(
+   IN PVOID HwDeviceExtension,
+   IN PVOID HwContext,
+   IN PWSTR ArgumentString,
+   IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+   OUT PUCHAR Again);
+
+BOOLEAN STDCALL
+XboxVmpInitialize(PVOID HwDeviceExtension);
+
+BOOLEAN STDCALL
+XboxVmpStartIO(
+   PVOID HwDeviceExtension,
+   PVIDEO_REQUEST_PACKET RequestPacket);
+
+BOOLEAN STDCALL
+XboxVmpResetHw(
+   PVOID DeviceExtension,
+   ULONG Columns,
+   ULONG Rows);
+
+VP_STATUS STDCALL
+XboxVmpGetPowerState(
+   PVOID HwDeviceExtension,
+   ULONG HwId,
+   PVIDEO_POWER_MANAGEMENT VideoPowerControl);
+
+VP_STATUS STDCALL
+XboxVmpSetPowerState(
+   PVOID HwDeviceExtension,
+   ULONG HwId,
+   PVIDEO_POWER_MANAGEMENT VideoPowerControl);
+
+BOOL FASTCALL
+XboxVmpSetCurrentMode(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE RequestedMode,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpResetDevice(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpMapVideoMemory(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MEMORY RequestedAddress,
+   PVIDEO_MEMORY_INFORMATION MapInformation,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpUnmapVideoMemory(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MEMORY VideoMemory,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpQueryNumAvailModes(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_NUM_MODES Modes,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpQueryAvailModes(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE_INFORMATION ReturnedModes,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL  
+XboxVmpQueryCurrentMode(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_MODE_INFORMATION VideoModeInfo,
+   PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpSetColorRegisters(
+   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+   PVIDEO_CLUT ColorLookUpTable,
+   PSTATUS_BLOCK StatusBlock);
+
+#endif /* XBOXVMP_H */
+
+/* EOF */

reactos/drivers/video/miniport/xboxvmp
xboxvmp.rc added at 1.1.2.1
diff -N xboxvmp.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ xboxvmp.rc	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,7 @@
+/* $Id: xboxvmp.rc,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $ */
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"Xbox Miniport Device Driver\0"
+#define REACTOS_STR_INTERNAL_NAME	"xboxvmp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"xboxvmp.sys\0"
+#include <reactos/version.rc>

reactos/hal/halx86/generic
adapter.c added at 1.1.2.1
diff -N adapter.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ adapter.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,679 @@
+/* $Id: adapter.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
+ * PURPOSE:         DMA handling
+ * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ *                  Vizzini (vizzini@plasmic.com)
+ * UPDATE HISTORY:
+ *                  Created 22/05/98
+ *                  18-Oct-2003 Vizzini DMA support modifications
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <ddk/iotypes.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* FUNCTIONS *****************************************************************/
+
+/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
+
+
+NTSTATUS STDCALL
+HalAllocateAdapterChannel(
+  PADAPTER_OBJECT AdapterObject,
+  PWAIT_CONTEXT_BLOCK WaitContextBlock,
+  ULONG NumberOfMapRegisters,
+  PDRIVER_CONTROL ExecutionRoutine)
+/*
+ * FUNCTION: Sets up an ADAPTER_OBJECT with map registers
+ * ARGUMENTS:
+ *     - AdapterObject: pointer to an ADAPTER_OBJECT to set up 
+ *     - WaitContextBlock: Context block to be used with ExecutionRoutine
+ *     - NumberOfMapRegisters: number of map registers requested 
+ *     - ExecutionRoutine: callback to call when map registers are allocated
+ * RETURNS:
+ *     STATUS_INSUFFICIENT_RESOURCES if map registers cannot be allocated
+ *     STATUS_SUCCESS in all other cases, including if the callbacak had
+ *                    to be queued for later delivery
+ * NOTES:
+ *     - the ADAPTER_OBJECT struct is undocumented; please make copious
+ *       notes in hal.h if anything is changed or improved since there is
+ *       no other documentation for this data structure
+ * BUGS:
+ *     - it's possible that some of this code is in the wrong place
+ *     - there are many unhandled cases
+ */
+{
+  LARGE_INTEGER MinAddress;
+  LARGE_INTEGER MaxAddress;
+  LARGE_INTEGER BoundryAddressMultiple;
+  IO_ALLOCATION_ACTION Retval;
+  
+  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+  
+  /*
+  FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters 
+  requested is larger than the value returned by IoGetDmaAdapter. 
+  */
+
+  /* set up the wait context block in case we can't run right away */
+  WaitContextBlock->DeviceRoutine = ExecutionRoutine;
+  WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
+
+  /* returns true if queued, else returns false and sets the queue to busy */
+  if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
+    return STATUS_SUCCESS;
+
+  /* 24-bit max address due to 16-bit dma controllers */
+  MinAddress.QuadPart = 0x0000000;
+  MaxAddress.QuadPart = 0x1000000;
+  BoundryAddressMultiple.QuadPart = 0;
+
+  /* why 64K alignment? */
+  /*
+   * X86 lacks map registers, so for now, we allocate a contiguous
+   * block of physical memory <16MB and copy all DMA buffers into
+   * that.  This can be optimized.
+   *
+   * FIXME: We propably shouldn't allocate the memory here for common
+   * buffer transfers. See a comment in IoMapTransfer about common buffer
+   * support.
+   */
+  AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory( 
+      NumberOfMapRegisters * PAGE_SIZE,
+      MinAddress,
+      MaxAddress,
+      BoundryAddressMultiple,
+      MmCached,
+      0x10000 );
+
+  if(!AdapterObject->MapRegisterBase)
+    return STATUS_INSUFFICIENT_RESOURCES;
+
+  AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
+
+  /* call the client's AdapterControl callback with its map registers and context */
+  Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp, 
+      AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+  /* 
+   * KeepObject: don't free any resources; the ADAPTER_OBJECT is still in use
+   *             and the caller will call IoFreeAdapterChannel later
+   *
+   * DeallocateObject: Deallocate the map registers and release the ADAPTER_OBJECT
+   *             so someone else can use it
+   *
+   * DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang on to
+   *             the map registers.  The client will later call IoFreeMapRegisters.
+   *
+   * NOTE - IoFreeAdapterChannel runs the queue, so it must be called
+   *        unless the adapter object is not to be freed.
+   */
+  if( Retval == DeallocateObject )
+      IoFreeAdapterChannel(AdapterObject);
+  else if(Retval == DeallocateObjectKeepRegisters)
+    {
+      /* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
+      AdapterObject->CommittedMapRegisters = 0;
+      IoFreeAdapterChannel(AdapterObject);
+    }
+
+  /*
+   * if we don't call IoFreeAdapterChannel, the next device won't get de-queued,
+   * which is what we want.
+   */
+
+  return STATUS_SUCCESS;
+}
+
+
+BOOLEAN
+HalpGrowMapBuffers(
+  IN PADAPTER_OBJECT	AdapterObject,
+  IN ULONG		SizeOfMapBuffers)
+/*
+ * FUNCTION: Allocate initial, or additional, map buffers for IO adapters.
+ * ARGUMENTS:
+ *     AdapterObject: DMA adapter to allocate buffers for.
+ *     SizeOfMapBuffers: Size of the map buffers to allocate
+ * NOTES:
+ *     - Needs to be tested...
+ */
+{
+	//ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
+	
+	/* TODO: Allocation */
+
+	return TRUE;
+}
+
+PADAPTER_OBJECT STDCALL
+HalpAllocateAdapterEx(
+  ULONG NumberOfMapRegisters,
+  BOOLEAN IsMaster,
+  BOOLEAN Dma32BitAddresses)
+/*
+ * FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master Adapter.
+ * ARGUMENTS:
+ *     - NumberOfMapRegisters: Number of map registers to allocate
+ *     - IsMaster: Wether this is a Master Device or not
+ *     - Dma32BitAddresses: Wether 32-bit Addresses are supported
+ * RETURNS:
+ *     - Pointer to Adapter Object, or NULL if failure.
+ * BUGS:
+ *     - Some stuff is unhandled/incomplete
+ */
+{
+	OBJECT_ATTRIBUTES ObjectAttributes;
+	ULONG ObjectSize;
+	ULONG BitmapSize;
+	NTSTATUS Status;
+	ULONG AllowedMapRegisters = 64;
+	PADAPTER_OBJECT AdapterObject;
+	HANDLE Handle;
+	
+	/* Allocate the Master Adapter if we haven't already 
+	   but make sure we're not asked to do it now, and also check if we need it */
+	if ((MasterAdapter == NULL) && (!IsMaster) && (NumberOfMapRegisters)) {
+		
+		/* Allocate and Save */
+		DPRINT("Allocating the Master Adapter Object\n");
+		MasterAdapter = HalpAllocateAdapterEx(NumberOfMapRegisters,
+						     TRUE,
+						     Dma32BitAddresses);
+		
+		/* Cancel on Failure */
+		DPRINT("Checking if Master Adapter was allocated properly\n");
+		if (!MasterAdapter) return NULL;
+	}
+	
+	/* Initialize the Object Attributes for the Adapter Object */
+	InitializeObjectAttributes(&ObjectAttributes,
+				   NULL,
+				   OBJ_PERMANENT,
+				   NULL,
+				   NULL);
+	
+	/* Check if this is the Master Adapter, in which case we need to allocate the bitmap */
+	if (IsMaster) {
+		/* Size due to the Bitmap + Bytes in the Bitmap Buffer (8 bytes, 64 bits)*/
+		BitmapSize = sizeof(RTL_BITMAP) + AllowedMapRegisters / 8;
+		
+		/* We will put the Bitmap Buffer after the Adapter Object for simplicity */
+		ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
+	} else {
+		ObjectSize = sizeof(ADAPTER_OBJECT);
+	}
+	
+	/* Create and Allocate the Object */
+	DPRINT("Creating the Object\n");
+	Status = ObCreateObject(KernelMode,
+				IoAdapterObjectType,
+				&ObjectAttributes,
+				KernelMode,
+				NULL,
+				ObjectSize,
+				0,
+				0,
+				(PVOID)&AdapterObject);
+	
+	if (!NT_SUCCESS(Status)) return NULL;
+	
+	/* Add a Reference */
+	DPRINT("Referencing the Object\n");
+	Status = ObReferenceObjectByPointer(AdapterObject,
+					    FILE_READ_DATA | FILE_WRITE_DATA,
+					    IoAdapterObjectType,
+					    KernelMode);
+	
+	if (!NT_SUCCESS(Status)) return NULL;
+	
+	/* It's a Valid Object, so now we can play with the memory */
+	RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
+	
+	/* Insert it into the Object Table */
+	DPRINT("Inserting the Object\n");
+	Status = ObInsertObject(AdapterObject,
+				NULL,
+				FILE_READ_DATA | FILE_WRITE_DATA,
+				0,
+				NULL,
+				&Handle);
+	
+	if (!NT_SUCCESS(Status)) return NULL;
+	
+	/* We don't want the handle */
+	NtClose(Handle);	
+	
+	/* Set up the Adapter Object fields */
+	AdapterObject->MapRegistersPerChannel = 1;
+	
+	/* Set the Master if needed (master only needed if we use Map Registers) */
+	if (NumberOfMapRegisters) AdapterObject->MasterAdapter = MasterAdapter;
+	
+	/* Initalize the Channel Wait queue, which every adapter has */
+	DPRINT("Initializing the Device Queue of the Object\n");
+	KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
+	
+	/* Initialize the SpinLock, Queue and Bitmap, which are kept in the Master Adapter only */
+	if (IsMaster) {
+		
+		DPRINT("Initializing the Master Adapter Stuff\n");
+		KeInitializeSpinLock(&AdapterObject->SpinLock);
+		InitializeListHead(&AdapterObject->AdapterQueue);
+		
+		/* As said previously, we put them here for simplicity */
+		AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1);
+		
+		/* Set up Bitmap */
+		RtlInitializeBitMap(AdapterObject->MapRegisters,
+				    (PULONG)(AdapterObject->MapRegisters + 1),
+				    AllowedMapRegisters);
+				    
+		/* Reset the Bitmap */	
+		RtlSetAllBits(AdapterObject->MapRegisters);
+		AdapterObject->NumberOfMapRegisters = 0;
+		AdapterObject->CommittedMapRegisters = 0;
+		
+		/* Allocate Memory for the Map Registers */
+		AdapterObject->MapRegisterBase = ExAllocatePool(NonPagedPool,
+								AllowedMapRegisters * sizeof(DWORD));
+		
+		/* Clear them */
+		RtlZeroMemory(AdapterObject->MapRegisterBase, AllowedMapRegisters * sizeof(DWORD));
+		
+		/* Allocate the contigous memory */
+		DPRINT("Allocating Buffers\n");
+		HalpGrowMapBuffers(AdapterObject, 0x1000000);
+	}
+	
+	DPRINT("Adapter Object allocated\n");
+	return AdapterObject;	
+}
+
+
+BOOLEAN STDCALL
+IoFlushAdapterBuffers (
+  PADAPTER_OBJECT	AdapterObject,
+  PMDL		Mdl,
+  PVOID		MapRegisterBase,
+  PVOID		CurrentVa,
+  ULONG		Length,
+  BOOLEAN		WriteToDevice)
+/*
+ * FUNCTION: flush any data remaining in the dma controller's memory into the host memory
+ * ARGUMENTS:
+ *     AdapterObject: the adapter object to flush
+ *     Mdl: original MDL to flush data into
+ *     MapRegisterBase: map register base that was just used by IoMapTransfer, etc
+ *     CurrentVa: offset into Mdl to be flushed into, same as was passed to IoMapTransfer
+ *     Length: length of the buffer to be flushed into
+ *     WriteToDevice: True if it's a write, False if it's a read
+ * RETURNS:
+ *     TRUE in all cases
+ * NOTES:
+ *     - This copies data from the map register-backed buffer to the user's target buffer.
+ *       Data is not in the user buffer until this is called.
+ *     - This is only meaningful on a read operation.  Return immediately for a write.
+ */
+{
+  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+  
+  /* this can happen if the card supports scatter/gather */
+  if(!MapRegisterBase)
+    return TRUE;
+
+  /* mask out (disable) the dma channel */
+  if (AdapterObject->AdapterNumber == 1) {
+  
+  		/* Set this for Ease */
+  		PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+	
+		/* Set Channel */
+		WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
+  } else {
+  		/* Set this for Ease */
+  		PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+	
+		/* Set Channel */
+		WRITE_PORT_UCHAR(&DmaControl2->SingleMask, (AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
+  }
+  
+  if(WriteToDevice)
+    return TRUE;
+    
+  memcpy( 
+        (PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) + (DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )), 
+      MapRegisterBase, Length );
+
+  return TRUE;
+}
+
+
+VOID STDCALL
+IoFreeAdapterChannel (PADAPTER_OBJECT	AdapterObject)
+/*
+ * FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
+ * ARGUMENTS:
+ *     AdapterObject: Adapter object with resources to free
+ * NOTES:
+ *     - This function releases the DMA adapter and optionally the map registers
+ *     - After releasing the adapter, it checks the adapter's queue and runs
+ *       each queued device object in series until the queue is empty
+ *     - This is the only way the device queue is emptied.
+ */
+{
+  LARGE_INTEGER MaxAddress;
+  LARGE_INTEGER MinAddress;
+  LARGE_INTEGER BoundryAddressMultiple;
+  PWAIT_CONTEXT_BLOCK WaitContextBlock;
+  IO_ALLOCATION_ACTION Retval;
+
+  while(1)
+    {
+      /* To keep map registers, call here with the following set to 0 */
+      if(AdapterObject->CommittedMapRegisters)
+        IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
+
+      if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
+        break;
+
+      /*
+       * the following should really be done elsewhere since this
+       * function really can't return an error code.  FIXME.
+       */
+
+      /* 24-bit max address due to 16-bit dma controllers */
+      MinAddress.QuadPart = 0x0000000;
+      MaxAddress.QuadPart = 0x1000000;
+      BoundryAddressMultiple.QuadPart = 0;
+
+      AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory( 
+          WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
+          MinAddress,
+          MaxAddress,
+          BoundryAddressMultiple,
+          MmCached,
+          0x10000 );
+
+      if(!AdapterObject->MapRegisterBase)
+        return;
+
+      /* call the adapter control routine */
+      Retval = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+          AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+      if(Retval == KeepObject)
+        {
+          /* we're done until the caller manually calls IoFreeAdapterChannel */
+          break;
+        }
+      else if(Retval == DeallocateObjectKeepRegisters)
+        {
+          /* hide the map registers so they aren't deallocated next time around */
+          AdapterObject->CommittedMapRegisters = 0;
+        }
+    }
+}
+
+
+VOID STDCALL
+IoFreeMapRegisters (
+  IN PADAPTER_OBJECT	AdapterObject,
+  IN PVOID		MapRegisterBase,
+  IN ULONG		NumberOfMapRegisters)
+/*
+ * FUNCTION: free map registers reserved by the system for a DMA
+ * ARGUMENTS:
+ *     AdapterObject: dma adapter to free map registers on
+ *     MapRegisterBase: hadle to map registers to free
+ *     NumberOfRegisters: number of map registers to be freed
+ * NOTES:
+ *     - XXX real windows has a funky interdependence between IoFreeMapRegisters 
+ *       and IoFreeAdapterChannel 
+ * BUGS:
+ *     - needs to be improved to use a real map register implementation
+ */
+{
+  if( AdapterObject->CommittedMapRegisters )
+    {
+      MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
+      AdapterObject->MapRegisterBase = 0;
+    }
+}
+
+
+PHYSICAL_ADDRESS  STDCALL
+IoMapTransfer (
+  IN PADAPTER_OBJECT	AdapterObject,
+  IN PMDL		Mdl,
+  IN PVOID		MapRegisterBase,
+  IN PVOID		CurrentVa,
+  IN OUT PULONG		Length,
+  IN BOOLEAN		WriteToDevice)
+/*
+ * FUNCTION: map a dma for transfer and do the dma if it's a slave
+ * ARGUMENTS:
+ *     AdapterObject: adapter object to do the dma on. busmaster may pass NULL.
+ *     Mdl: locked-down user buffer to DMA in to or out of
+ *     MapRegisterBase: handle to map registers to use for this dma. allways NULL
+ *      when doing s/g.
+ *     CurrentVa: index into Mdl to transfer into/out of
+ *     Length: length of transfer in/out. Only modified on out when doing s/g.
+ *     WriteToDevice: TRUE if it's an output dma, FALSE otherwise
+ * RETURNS: 
+ *     If a busmaster: A logical address that can be used to program a dma controller
+ *     Otherwise: nothing meaningful
+ * NOTES:
+ *     - This function does a copyover to contiguous memory <16MB
+ *     - If it's a slave transfer, this function actually performs it.
+ * BUGS:
+ *     - If the controller supports scatter/gather, the copyover should not happen
+ */
+{
+  PHYSICAL_ADDRESS Address;
+  KIRQL OldIrql;
+  UCHAR Mode;
+
+#if defined(__GNUC__)
+  Address.QuadPart = 0ULL;
+#else
+  Address.QuadPart = 0;
+#endif
+
+  /* Isa System (slave) DMA? */
+  if (MapRegisterBase && !AdapterObject->MasterDevice)
+  {
+
+    KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
+
+    /*
+     * FIXME: Handle case when doing common-buffer System DMA. In this case,
+     * the buffer described by MDL is already phys. contiguous and below
+     * 16 mega. Driver makes a one-shot call to IoMapTransfer during init.
+     * to program controller with the common-buffer.
+     *
+     * UPDATE: Common buffer support is in place, but it's not done in a
+     * clean way. We use the buffer passed by the MDL in case that the
+     * adapter object is marked as auto initialize. I'm not sure if this
+     * is correct and if not, how to do it properly. Note that it's also
+     * possible to allocate the common buffer with different adapter object
+     * and IoMapTransfer must still work in this case. Eventually this should
+     * be cleaned up somehow or at least this comment modified to reflect
+     * the reality.
+     * -- Filip Navara, 19/07/2004     
+     */
+
+     /* Get the mode for easier coding */
+     Mode = AdapterObject->AdapterMode;
+     
+    /* if it is a write to the device, copy the caller buffer to the low buffer */
+    if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
+    {
+      memcpy(MapRegisterBase,
+             (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+	           *Length );
+    }
+
+    /* Writer Adapter Mode, transfer type */
+    ((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
+
+    // program up the dma controller, and return
+    if (!((PDMA_MODE)&Mode)->AutoInitialize) {
+      Address = MmGetPhysicalAddress( MapRegisterBase );
+    } else {
+      Address = MmGetPhysicalAddress( CurrentVa );
+    }
+    
+    /* 16-bit DMA has a shifted length */
+    if (AdapterObject->Width16Bits) *Length = (*Length >> 1);
+     
+    /* Make the Transfer */
+    if (AdapterObject->AdapterNumber == 1) {
+    
+    	PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+    	
+	/* Reset Register */
+	WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+	
+	/* Set the Mode */
+	WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode));
+	
+	/* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+	WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+	WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+	
+	/* Set the Length */
+ 	WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+			(UCHAR)((*Length) - 1));
+	WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+			(UCHAR)((*Length) - 1) >> 8);
+			
+	/* Unmask the Channel */
+	WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+    } else {
+        PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+    	
+	/* Reset Register */
+	WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+	
+	/* Set the Mode */
+	WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode));
+	
+	/* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+	WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+	WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+	
+	/* Set the Length */
+ 	WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+			(UCHAR)((*Length) - 1));
+	WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+			(UCHAR)((*Length) - 1) >> 8);
+			
+	/* Unmask the Channel */
+	WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+    }
+	
+    /* Release Spinlock */
+    KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
+
+    /* 
+    NOTE: Return value should be ignored when doing System DMA.
+    Maybe return some more obvious invalid address here (thou returning 
+    MapRegisterBase is also wrong;-)to catch invalid use?
+    */
+    Address.QuadPart = (ULONG)MapRegisterBase;
+    return Address;
+  }
+  
+
+  /* 
+  Busmaster with s/g support?   
+  NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase 
+  being NULL is used to detect a s/g busmaster.
+  */
+  if ((!AdapterObject && !MapRegisterBase) ||
+      (AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
+  {
+    /* 
+    Just return the passed VA's corresponding phys. address. 
+    Update length to the number of phys. contiguous bytes found.
+    */
+  
+    PULONG MdlPages;
+    ULONG MdlPageIndex, PhysContiguousLen;
+    ULONG PhysAddress;
+    
+    MdlPages = (PULONG)(Mdl + 1);
+    
+    /* Get VA's corresponding mdl phys. page index */
+    MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) / PAGE_SIZE;
+   
+    /* Get phys. page containing the VA */
+    PhysAddress = MdlPages[MdlPageIndex];
+    
+    PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
+    
+    /* VA to map may span several contiguous phys. pages (unlikely) */
+    while (PhysContiguousLen < *Length &&
+           MdlPages[MdlPageIndex++] + PAGE_SIZE == MdlPages[MdlPageIndex])
+    {
+      /* 
+      Note that allways adding PAGE_SIZE may make PhysContiguousLen greater
+      than Length if buffer doesn't end on page boundary. Take this
+      into consideration below. 
+      */
+      PhysContiguousLen += PAGE_SIZE; 
+    }
+    
+    if (PhysContiguousLen < *Length)
+    {
+      *Length = PhysContiguousLen;
+    }
+    
+    //add offset to phys. page address
+    Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
+    return Address;
+  }
+  
+  
+  /* 
+  Busmaster without s/g support? 
+  NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase 
+  not being NULL is used to detect a non s/g busmaster.
+  */
+  if ((!AdapterObject && MapRegisterBase) ||
+      (AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
+  {
+    /*
+    NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
+    know if it's illegal... Maybe figure out what to do in this case...
+    */
+
+    if( WriteToDevice )
+    {
+      memcpy(MapRegisterBase,
+             (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+             *Length );
+    }
+
+    return MmGetPhysicalAddress(MapRegisterBase);
+  }
+
+  DPRINT("IoMapTransfer: Unsupported operation\n");
+  KEBUGCHECK(0);
+  return Address;
+}
+
+
+/* EOF */
+
+
+
+

reactos/hal/halx86/generic
beep.c added at 1.1.2.1
diff -N beep.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ beep.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/beep.c
+ * PURPOSE:         Speaker function (it's only one)
+ * PROGRAMMER:      Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ *                  Created 31/01/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* CONSTANTS *****************************************************************/
+
+#define TIMER2     0x42
+#define TIMER3     0x43
+#define PORT_B     0x61
+#define CLOCKFREQ  1193167
+
+
+/* FUNCTIONS *****************************************************************/
+/*
+ * FUNCTION: Beeps the speaker.
+ * ARGUMENTS:
+ *       Frequency = If 0, the speaker will be switched off, otherwise
+ *                   the speaker beeps with the specified frequency.
+ */
+
+BOOLEAN
+STDCALL
+HalMakeBeep (
+	ULONG	Frequency
+	)
+{
+    UCHAR b;
+    ULONG flags;
+   
+    /* save flags and disable interrupts */
+    Ki386SaveFlags(flags);
+    Ki386DisableInterrupts();
+
+    /* speaker off */
+    b = READ_PORT_UCHAR((PUCHAR)PORT_B);
+    WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(b & 0xFC));
+
+    if (Frequency)
+    {
+        DWORD Divider = CLOCKFREQ / Frequency;
+
+        if (Divider > 0x10000)
+        {
+            /* restore flags */
+            Ki386RestoreFlags(flags);
+
+            return FALSE;
+        }
+
+        /* set timer divider */
+        WRITE_PORT_UCHAR((PUCHAR)TIMER3, 0xB6);
+        WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)(Divider & 0xFF));
+        WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)((Divider>>8) & 0xFF));
+
+        /* speaker on */
+        WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(READ_PORT_UCHAR((PUCHAR)PORT_B) | 0x03));
+    }
+
+    /* restore flags */
+    Ki386RestoreFlags(flags);
+
+    return TRUE;
+}
+

reactos/hal/halx86/generic
bus.c added at 1.1.2.1
diff -N bus.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bus.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,532 @@
+/* $Id: bus.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/bus.c
+ * PURPOSE:         Bus functions
+ * PROGRAMMER:      David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ *                  Created 22/05/98
+ *
+ *
+ * TODO:
+ *   - Add bus handler functions for all busses
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define TAG_BUS  TAG('B', 'U', 'S', 'H')
+
+KSPIN_LOCK HalpBusHandlerSpinLock = {0,};
+LIST_ENTRY HalpBusHandlerList;
+
+
+/* FUNCTIONS *****************************************************************/
+
+static NTSTATUS STDCALL
+HalpNoAdjustResourceList(PBUS_HANDLER BusHandler,
+			 ULONG BusNumber,
+			 PCM_RESOURCE_LIST Resources)
+{
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS STDCALL
+HalpNoAssignSlotResources(PBUS_HANDLER BusHandler,
+			  ULONG BusNumber,
+			  PUNICODE_STRING RegistryPath,
+			  PUNICODE_STRING DriverClassName,
+			  PDRIVER_OBJECT DriverObject,
+			  PDEVICE_OBJECT DeviceObject,
+			  ULONG SlotNumber,
+			  PCM_RESOURCE_LIST *AllocatedResources)
+{
+   return STATUS_NOT_SUPPORTED;
+}
+
+
+static ULONG STDCALL
+HalpNoBusData(PBUS_HANDLER BusHandler,
+	      ULONG BusNumber,
+	      ULONG SlotNumber,
+	      PVOID Buffer,
+	      ULONG Offset,
+	      ULONG Length)
+{
+   return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoGetInterruptVector(PBUS_HANDLER BusHandler,
+			 ULONG BusNumber,
+			 ULONG BusInterruptLevel,
+			 ULONG BusInterruptVector,
+			 PKIRQL Irql,
+			 PKAFFINITY Affinity)
+{
+   return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler,
+			  ULONG BusNumber,
+			  PHYSICAL_ADDRESS BusAddress,
+			  PULONG AddressSpace,
+			  PPHYSICAL_ADDRESS TranslatedAddress)
+{
+   return 0;
+}
+
+
+PBUS_HANDLER
+HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
+		       BUS_DATA_TYPE BusDataType,
+		       ULONG BusNumber)
+{
+   PBUS_HANDLER BusHandler = NULL;
+
+   DPRINT("HalpAllocateBusHandler()\n");
+
+   BusHandler = ExAllocatePoolWithTag(NonPagedPool,
+				      sizeof(BUS_HANDLER),
+				      TAG_BUS);
+   if (BusHandler == NULL)
+     return NULL;
+
+   RtlZeroMemory(BusHandler,
+		 sizeof(BUS_HANDLER));
+
+   InsertTailList(&HalpBusHandlerList,
+		  &BusHandler->Entry);
+
+   BusHandler->InterfaceType = InterfaceType;
+   BusHandler->BusDataType = BusDataType;
+   BusHandler->BusNumber = BusNumber;
+
+   /* initialize default bus handler functions */
+   BusHandler->GetBusData = HalpNoBusData;
+   BusHandler->SetBusData = HalpNoBusData;
+   BusHandler->AdjustResourceList = HalpNoAdjustResourceList;
+   BusHandler->AssignSlotResources = HalpNoAssignSlotResources;
+   BusHandler->GetInterruptVector = HalpNoGetInterruptVector;
+   BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress;
+
+   /* any more ?? */
+
+   DPRINT("HalpAllocateBusHandler() done\n");
+
+   return BusHandler;
+}
+
+
+VOID
+HalpInitBusHandlers(VOID)
+{
+  PBUS_HANDLER BusHandler;
+
+  /* General preparations */
+  KeInitializeSpinLock(&HalpBusHandlerSpinLock);
+  InitializeListHead(&HalpBusHandlerList);
+
+  /* Initialize hal dispatch tables */
+  HalQuerySystemInformation = HalpQuerySystemInformation;
+
+#if 0
+  HalSetSystemInformation = HalpSetSystemInformation;
+
+  HalQueryBusSlots = HalpQueryBusSlots;
+#endif
+
+  /* Add system bus handler */
+  BusHandler = HalpAllocateBusHandler(Internal,
+				      ConfigurationSpaceUndefined,
+				      0);
+  if (BusHandler == NULL)
+    return;
+  BusHandler->GetInterruptVector =
+    (pGetInterruptVector)HalpGetSystemInterruptVector;
+  BusHandler->TranslateBusAddress =
+    (pTranslateBusAddress)HalpTranslateSystemBusAddress;
+
+  /* Add cmos bus handler */
+  BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined,
+				      Cmos,
+				      0);
+  if (BusHandler == NULL)
+    return;
+  BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
+  BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
+
+  /* Add isa bus handler */
+  BusHandler = HalpAllocateBusHandler(Isa,
+				      ConfigurationSpaceUndefined,
+				      0);
+  if (BusHandler == NULL)
+    return;
+
+  BusHandler->GetInterruptVector =
+    (pGetInterruptVector)HalpGetIsaInterruptVector;
+  BusHandler->TranslateBusAddress =
+    (pTranslateBusAddress)HalpTranslateIsaBusAddress;
+
+  /* Add MicroChannel bus handler */
+  BusHandler = HalpAllocateBusHandler(MicroChannel,
+				      Pos,
+				      0);
+  if (BusHandler == NULL)
+    return;
+
+  BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
+		  ULONG BusNumber)
+{
+   PBUS_HANDLER BusHandler;
+   PLIST_ENTRY CurrentEntry;
+   KIRQL OldIrql;
+
+   KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+		     &OldIrql);
+
+   CurrentEntry = HalpBusHandlerList.Flink;
+   while (CurrentEntry != &HalpBusHandlerList)
+     {
+	BusHandler = (PBUS_HANDLER)CurrentEntry;
+	if (BusHandler->InterfaceType == InterfaceType &&
+	    BusHandler->BusNumber == BusNumber)
+	  {
+	     KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+			       OldIrql);
+	     return BusHandler;
+	  }
+	CurrentEntry = CurrentEntry->Flink;
+     }
+   KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+		     OldIrql);
+
+   return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+			  ULONG BusNumber)
+{
+   PBUS_HANDLER BusHandler;
+   PLIST_ENTRY CurrentEntry;
+   KIRQL OldIrql;
+
+   KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+		     &OldIrql);
+
+   CurrentEntry = HalpBusHandlerList.Flink;
+   while (CurrentEntry != &HalpBusHandlerList)
+     {
+	BusHandler = (PBUS_HANDLER)CurrentEntry;
+	if (BusHandler->BusDataType == BusDataType &&
+	    BusHandler->BusNumber == BusNumber)
+	  {
+	     KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+			       OldIrql);
+	     return BusHandler;
+	  }
+	CurrentEntry = CurrentEntry->Flink;
+     }
+   KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+		     OldIrql);
+
+   return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
+			   ULONG BusNumber)
+{
+   PBUS_HANDLER BusHandler;
+   PLIST_ENTRY CurrentEntry;
+   KIRQL OldIrql;
+
+   KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+		     &OldIrql);
+
+   CurrentEntry = HalpBusHandlerList.Flink;
+   while (CurrentEntry != &HalpBusHandlerList)
+     {
+	BusHandler = (PBUS_HANDLER)CurrentEntry;
+	if (BusHandler->InterfaceType == InterfaceType &&
+	    BusHandler->BusNumber == BusNumber)
+	  {
+	     BusHandler->RefCount++;
+	     KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+			       OldIrql);
+	     return BusHandler;
+	  }
+	CurrentEntry = CurrentEntry->Flink;
+     }
+   KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+		     OldIrql);
+
+   return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+				   ULONG BusNumber)
+{
+   PBUS_HANDLER BusHandler;
+   PLIST_ENTRY CurrentEntry;
+   KIRQL OldIrql;
+
+   KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+		     &OldIrql);
+
+   CurrentEntry = HalpBusHandlerList.Flink;
+   while (CurrentEntry != &HalpBusHandlerList)
+     {
+	BusHandler = (PBUS_HANDLER)CurrentEntry;
+	if (BusHandler->BusDataType == BusDataType &&
+	    BusHandler->BusNumber == BusNumber)
+	  {
+	     BusHandler->RefCount++;
+	     KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+			       OldIrql);
+	     return BusHandler;
+	  }
+	CurrentEntry = CurrentEntry->Flink;
+     }
+   KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+		     OldIrql);
+
+   return NULL;
+}
+
+
+VOID FASTCALL
+HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
+{
+   KIRQL OldIrql;
+
+   KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+		     &OldIrql);
+   BusHandler->RefCount--;
+   KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+		     OldIrql);
+}
+
+
+NTSTATUS STDCALL
+HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
+{
+   PBUS_HANDLER BusHandler;
+   NTSTATUS Status;
+
+   BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
+					   Resources->List[0].BusNumber);
+   if (BusHandler == NULL)
+     return STATUS_SUCCESS;
+
+   Status = BusHandler->AdjustResourceList(BusHandler,
+					   Resources->List[0].BusNumber,
+					   Resources);
+   HaliDereferenceBusHandler (BusHandler);
+
+   return Status;
+}
+
+
+NTSTATUS STDCALL
+HalAssignSlotResources(PUNICODE_STRING RegistryPath,
+		       PUNICODE_STRING DriverClassName,
+		       PDRIVER_OBJECT DriverObject,
+		       PDEVICE_OBJECT DeviceObject,
+		       INTERFACE_TYPE BusType,
+		       ULONG BusNumber,
+		       ULONG SlotNumber,
+		       PCM_RESOURCE_LIST *AllocatedResources)
+{
+   PBUS_HANDLER BusHandler;
+   NTSTATUS Status;
+
+   BusHandler = HaliReferenceHandlerForBus(BusType,
+					   BusNumber);
+   if (BusHandler == NULL)
+     return STATUS_NOT_FOUND;
+
+   Status = BusHandler->AssignSlotResources(BusHandler,
+					    BusNumber,
+					    RegistryPath,
+					    DriverClassName,
+					    DriverObject,
+					    DeviceObject,
+					    SlotNumber,
+					    AllocatedResources);
+
+   HaliDereferenceBusHandler(BusHandler);
+
+   return Status;
+}
+
+
+ULONG STDCALL
+HalGetBusData(BUS_DATA_TYPE BusDataType,
+	      ULONG BusNumber,
+	      ULONG SlotNumber,
+	      PVOID Buffer,
+	      ULONG Length)
+{
+   return (HalGetBusDataByOffset(BusDataType,
+				 BusNumber,
+				 SlotNumber,
+				 Buffer,
+				 0,
+				 Length));
+}
+
+
+ULONG STDCALL
+HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+		      ULONG BusNumber,
+		      ULONG SlotNumber,
+		      PVOID Buffer,
+		      ULONG Offset,
+		      ULONG Length)
+{
+   PBUS_HANDLER BusHandler;
+   ULONG Result;
+
+   BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+						   BusNumber);
+   if (BusHandler == NULL)
+     return 0;
+
+   Result = BusHandler->GetBusData(BusHandler,
+				   BusNumber,
+				   SlotNumber,
+				   Buffer,
+				   Offset,
+				   Length);
+
+   HaliDereferenceBusHandler (BusHandler);
+
+   return Result;
+}
+
+
+ULONG STDCALL
+HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
+		      ULONG BusNumber,
+		      ULONG BusInterruptLevel,
+		      ULONG BusInterruptVector,
+		      PKIRQL Irql,
+		      PKAFFINITY Affinity)
+{
+   PBUS_HANDLER BusHandler;
+   ULONG Result;
+
+   BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+					   BusNumber);
+   if (BusHandler == NULL)
+     return 0;
+
+   Result = BusHandler->GetInterruptVector(BusHandler,
+					   BusNumber,
+					   BusInterruptLevel,
+					   BusInterruptVector,
+					   Irql,
+					   Affinity);
+
+   HaliDereferenceBusHandler(BusHandler);
+
+   return Result;
+}
+
+
+ULONG STDCALL
+HalSetBusData(BUS_DATA_TYPE BusDataType,
+	      ULONG BusNumber,
+	      ULONG SlotNumber,
+	      PVOID Buffer,
+	      ULONG Length)
+{
+   return (HalSetBusDataByOffset(BusDataType,
+				 BusNumber,
+				 SlotNumber,
+				 Buffer,
+				 0,
+				 Length));
+}
+
+
+ULONG STDCALL
+HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+		      ULONG BusNumber,
+		      ULONG SlotNumber,
+		      PVOID Buffer,
+		      ULONG Offset,
+		      ULONG Length)
+{
+   PBUS_HANDLER BusHandler;
+   ULONG Result;
+
+   BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+						   BusNumber);
+   if (BusHandler == NULL)
+     return 0;
+
+   Result = BusHandler->SetBusData(BusHandler,
+				   BusNumber,
+				   SlotNumber,
+				   Buffer,
+				   Offset,
+				   Length);
+
+   HaliDereferenceBusHandler(BusHandler);
+
+   return Result;
+}
+
+
+BOOLEAN STDCALL
+HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
+		       ULONG BusNumber,
+		       PHYSICAL_ADDRESS BusAddress,
+		       PULONG AddressSpace,
+		       PPHYSICAL_ADDRESS TranslatedAddress)
+{
+   PBUS_HANDLER BusHandler;
+   BOOLEAN Result;
+
+   BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+					   BusNumber);
+   if (BusHandler == NULL)
+     return FALSE;
+
+   Result = (BOOLEAN)BusHandler->TranslateBusAddress(BusHandler,
+					    BusNumber,
+					    BusAddress,
+					    AddressSpace,
+					    TranslatedAddress);
+
+   HaliDereferenceBusHandler(BusHandler);
+
+   return Result;
+}
+
+/* EOF */

reactos/hal/halx86/generic
display.c added at 1.3.2.1
diff -N display.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ display.c	13 Dec 2004 16:18:23 -0000	1.3.2.1
@@ -0,0 +1,794 @@
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002 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: display.c,v 1.3.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/display.c
+ * PURPOSE:         Blue screen display
+ * PROGRAMMER:      Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  Created 08/10/99
+ */
+
+/*
+ * Portions of this code are from the XFree86 Project and available from the
+ * following license:
+ *
+ * Copyright (C) 1994-2003 The XFree86 Project, Inc.  All Rights Reserved.
+ *
+ * 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 the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+*/  
+
+/* DISPLAY OWNERSHIP
+ *
+ * So, who owns the physical display and is allowed to write to it?
+ *
+ * In MS NT, upon boot HAL owns the display. Somewhere in the boot
+ * sequence (haven't figured out exactly where or by who), some
+ * component calls HalAcquireDisplayOwnership. From that moment on,
+ * the display is owned by that component and is switched to graphics
+ * mode. The display is not supposed to return to text mode, except
+ * in case of a bug check. The bug check will call HalDisplayString
+ * to output a string to the text screen. HAL will notice that it
+ * currently doesn't own the display and will re-take ownership, by
+ * calling the callback function passed to HalAcquireDisplayOwnership.
+ * After the bugcheck, execution is halted. So, under NT, the only
+ * possible sequence of display modes is text mode -> graphics mode ->
+ * text mode (the latter hopefully happening very infrequently).
+ *
+ * Things are a little bit different in the current state of ReactOS.
+ * We want to have a functional interactive text mode. We should be
+ * able to switch from text mode to graphics mode when a GUI app is
+ * started and switch back to text mode when it's finished. Then, when
+ * another GUI app is started, another switch to and from graphics mode
+ * is possible. Also, when the system bugchecks in graphics mode we want
+ * to switch back to text mode to show the registers and stack trace.
+ * Last but not least, HalDisplayString is used a lot more in ReactOS,
+ * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
+ * is present.
+ * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
+ * As in NT, on boot HAL owns the display. When entering the text mode
+ * command interpreter, BLUE.SYS kicks in. It will write directly to the
+ * screen, more or less behind HALs back.
+ * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
+ * This open call will end up in VIDEOPRT.SYS. That component will then
+ * take ownership of the display by calling HalAcquireDisplayOwnership.
+ * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
+ * we want to give ownership of the display back to HAL. Using the
+ * standard exported HAL functions, that's a bit of a problem, because
+ * there is no function defined to do that. In NT, this is handled by
+ * HalDisplayString, but that solution isn't satisfactory in ReactOS,
+ * because HalDisplayString is (in some cases) also used to output debug
+ * messages. If we do it the NT way, the first debug message output while
+ * in graphics mode would switch the display back to text mode.
+ * So, instead, if HalDisplayString detects that HAL doesn't have ownership
+ * of the display, it doesn't do anything.
+ * To return ownership to HAL, a new function is exported,
+ * HalReleaseDisplayOwnership. This function is called by the DISPLAY
+ * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
+ * of a bug check, so HalDisplayString is activated again.
+ * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
+ * should also refrain from writing to the screen buffer. The text mode
+ * screen buffer might overlap the graphics mode screen buffer, so changing
+ * something in the text mode buffer might mess up the graphics screen. To
+ * allow BLUE.SYS to detect if HAL owns the display, another new function is
+ * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
+ * check if it's allowed to touch the text mode buffer.
+ *
+ * In an ideal world, when HAL takes ownership of the display, it should set
+ * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
+ * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
+ * table etc. So, we chickened out of that by having the loader set up the
+ * display before switching to protected mode. If HAL is given back ownership
+ * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
+ * since there is already support for them via the VideoPortInt10 routine.
+ */
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define SCREEN_SYNCHRONIZATION
+
+#define VGA_GRAPH_MEM 0xa0000
+#define VGA_CHAR_MEM  0xb8000
+#define VGA_END_MEM   0xbffff
+
+#define VGA_AC_INDEX            0x3c0
+#define VGA_AC_READ             0x3c1
+#define VGA_AC_WRITE            0x3c0
+
+#define VGA_MISC_WRITE          0x3c2
+
+#define VGA_SEQ_INDEX           0x3c4
+#define VGA_SEQ_DATA            0x3c5
+
+#define VGA_DAC_MASK            0x3c6
+#define VGA_DAC_READ_INDEX      0x3c7
+#define VGA_DAC_WRITE_INDEX     0x3c8
+#define VGA_DAC_DATA            0x3c9
+#define VGA_FEATURE_READ        0x3ca
+#define VGA_MISC_READ           0x3cc
+
+#define VGA_GC_INDEX            0x3ce
+#define VGA_GC_DATA             0x3cf
+
+#define VGA_CRTC_INDEX          0x3d4
+#define VGA_CRTC_DATA           0x3d5
+
+#define VGA_INSTAT_READ         0x3da
+
+#define VGA_SEQ_NUM_REGISTERS   5
+#define VGA_CRTC_NUM_REGISTERS  25
+#define VGA_GC_NUM_REGISTERS    9
+#define VGA_AC_NUM_REGISTERS    21
+
+#define CRTC_COLUMNS       0x01
+#define CRTC_OVERFLOW      0x07
+#define CRTC_ROWS          0x12
+#define CRTC_SCANLINES     0x09
+
+#define CRTC_CURHI         0x0e
+#define CRTC_CURLO         0x0f
+
+
+#define CHAR_ATTRIBUTE_BLACK  0x00  /* black on black */
+#define CHAR_ATTRIBUTE        0x17  /* grey on blue */
+
+#define FONT_AMOUNT        (8*8192)
+
+/* VARIABLES ****************************************************************/
+
+static ULONG CursorX = 0;      /* Cursor Position */
+static ULONG CursorY = 0;
+static ULONG SizeX = 80;       /* Display size */
+static ULONG SizeY = 25;
+
+static BOOLEAN DisplayInitialized = FALSE;
+static BOOLEAN HalOwnsDisplay = TRUE;
+
+static PUSHORT VideoBuffer = NULL;
+static PUCHAR GraphVideoBuffer = NULL;
+
+static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
+
+static UCHAR SavedTextPalette[768];
+static UCHAR SavedTextMiscOutReg;
+static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
+static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
+static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
+static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
+static UCHAR SavedTextFont[2][FONT_AMOUNT];
+static BOOLEAN TextPaletteEnabled = FALSE;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID FASTCALL
+HalClearDisplay (UCHAR CharAttribute)
+{
+   WORD *ptr = (WORD*)VideoBuffer;
+   ULONG i;
+
+  for (i = 0; i < SizeX * SizeY; i++, ptr++)
+    *ptr = ((CharAttribute << 8) + ' ');
+
+  CursorX = 0;
+  CursorY = 0;
+}
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+VOID STATIC
+HalScrollDisplay (VOID)
+{
+  PUSHORT ptr;
+  int i;
+
+  ptr = VideoBuffer + SizeX;
+  RtlMoveMemory(VideoBuffer,
+		ptr,
+		SizeX * (SizeY - 1) * 2);
+
+  ptr = VideoBuffer  + (SizeX * (SizeY - 1));
+  for (i = 0; i < (int)SizeX; i++, ptr++)
+    {
+      *ptr = (CHAR_ATTRIBUTE << 8) + ' ';
+    }
+}
+
+VOID STATIC FASTCALL
+HalPutCharacter (CHAR Character)
+{
+  PUSHORT ptr;
+
+  ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
+  *ptr = (CHAR_ATTRIBUTE << 8) + Character;
+}
+
+VOID STATIC
+HalDisablePalette(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
+  TextPaletteEnabled = FALSE;
+}
+
+VOID STATIC
+HalEnablePalette(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
+  TextPaletteEnabled = TRUE;
+}
+
+UCHAR STATIC FASTCALL
+HalReadGc(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteGc(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadSeq(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteSeq(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
+}
+
+VOID STATIC FASTCALL
+HalWriteAc(ULONG Index, UCHAR Value)
+{
+  if (TextPaletteEnabled)
+    {
+      Index &= ~0x20;
+    }
+  else
+    {
+      Index |= 0x20;
+    }
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadAc(ULONG Index)
+{
+  if (TextPaletteEnabled)
+    {
+      Index &= ~0x20;
+    }
+  else
+    {
+      Index |= 0x20;
+    }
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
+}
+
+VOID STATIC FASTCALL
+HalWriteCrtc(ULONG Index, UCHAR Value)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadCrtc(ULONG Index)
+{
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+  return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalResetSeq(BOOLEAN Start)
+{
+  if (Start)
+    {
+      HalWriteSeq(0x00, 0x01);
+    }
+  else
+    {
+      HalWriteSeq(0x00, 0x03);
+    }
+}
+
+VOID STATIC FASTCALL
+HalBlankScreen(BOOLEAN On)
+{
+  UCHAR Scrn;
+
+  Scrn = HalReadSeq(0x01);
+
+  if (On)
+    {
+      Scrn &= ~0x20;
+    }
+  else
+    {
+      Scrn |= 0x20;
+    }
+
+  HalResetSeq(TRUE);
+  HalWriteSeq(0x01, Scrn);
+  HalResetSeq(FALSE);
+}
+
+VOID STATIC
+HalSaveFont(VOID)
+{
+  UCHAR Attr10;
+  UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
+  ULONG i;
+
+  /* Check if we are already in graphics mode. */
+  Attr10 = HalReadAc(0x10);
+  if (Attr10 & 0x01)
+    {
+      return;
+    }
+
+  /* Save registers. */
+  MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+  Gc4 = HalReadGc(0x04);
+  Gc5 = HalReadGc(0x05);
+  Gc6 = HalReadGc(0x06);
+  Seq2 = HalReadSeq(0x02);
+  Seq4 = HalReadSeq(0x04);
+
+  /* Force colour mode. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01));
+
+  HalBlankScreen(FALSE);
+
+  for (i = 0; i < 2; i++)
+    {
+      /* Save font 1 */
+      HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+      HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+      HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+      HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
+      HalWriteGc(0x06, 0x05); /* Set graphics. */
+      memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
+    }
+
+  /* Restore registers. */
+  HalWriteAc(0x10, Attr10);
+  HalWriteSeq(0x02, Seq2);
+  HalWriteSeq(0x04, Seq4);
+  HalWriteGc(0x04, Gc4);
+  HalWriteGc(0x05, Gc5);
+  HalWriteGc(0x06, Gc6);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+
+  HalBlankScreen(TRUE);
+}
+
+VOID STATIC
+HalSaveMode(VOID)
+{
+  ULONG i;
+
+  SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+
+  for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+    {
+      SavedTextCrtcReg[i] = HalReadCrtc(i);
+    }
+
+  HalEnablePalette();
+  for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+    {
+      SavedTextAcReg[i] = HalReadAc(i);
+    }
+  HalDisablePalette();
+
+  for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+    {
+      SavedTextGcReg[i] = HalReadGc(i);
+    }
+
+  for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
+    {
+      SavedTextSeqReg[i] = HalReadSeq(i);
+    }
+}
+
+VOID STATIC
+HalDacDelay(VOID)
+{
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+  (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+}
+
+VOID STATIC
+HalSavePalette(VOID)
+{
+  ULONG i;
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
+  for (i = 0; i < 768; i++)
+    {
+      SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
+      HalDacDelay();
+    }
+}
+
+VOID STATIC
+HalRestoreFont(VOID)
+{
+  UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
+  UCHAR Seq2, Seq4;
+  ULONG i;
+
+  /* Save registers. */
+  MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+  Attr10 = HalReadAc(0x10);
+  Gc1 = HalReadGc(0x01);
+  Gc3 = HalReadGc(0x03);
+  Gc4 = HalReadGc(0x04);
+  Gc5 = HalReadGc(0x05);
+  Gc6 = HalReadGc(0x06);
+  Gc8 = HalReadGc(0x08);
+  Seq2 = HalReadSeq(0x02);
+  Seq4 = HalReadSeq(0x04);
+
+  /* Force into colour mode. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
+
+  HalBlankScreen(FALSE);
+
+  HalWriteGc(0x03, 0x00);  /* Don't rotate; write unmodified. */
+  HalWriteGc(0x08, 0xFF);  /* Write all bits. */
+  HalWriteGc(0x01, 0x00);  /* All planes from CPU. */
+
+  for (i = 0; i < 2; i++)
+    {
+      HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+      HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+      HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+      HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
+      HalWriteGc(0x06, 0x05); /* Set graphics. */
+      memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
+    }
+
+  HalBlankScreen(TRUE);
+
+  /* Restore registers. */
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+  HalWriteAc(0x10, Attr10);
+  HalWriteGc(0x01, Gc1);
+  HalWriteGc(0x03, Gc3);
+  HalWriteGc(0x04, Gc4);
+  HalWriteGc(0x05, Gc5);
+  HalWriteGc(0x06, Gc6);
+  HalWriteGc(0x08, Gc8);
+  HalWriteSeq(0x02, Seq2);
+  HalWriteSeq(0x04, Seq4);
+}
+
+VOID STATIC
+HalRestoreMode(VOID)
+{
+  ULONG i;
+
+  WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
+
+  for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
+    {
+      HalWriteSeq(i, SavedTextSeqReg[i]);
+    }
+
+  /* Unlock CRTC registers 0-7 */
+  HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
+
+  for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+    {
+      HalWriteCrtc(i, SavedTextCrtcReg[i]);
+    }
+
+  for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+    {
+      HalWriteGc(i, SavedTextGcReg[i]);
+    }
+
+  HalEnablePalette();
+  for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+    {
+      HalWriteAc(i, SavedTextAcReg[i]);
+    }
+  HalDisablePalette();
+}
+
+VOID STATIC
+HalRestorePalette(VOID)
+{
+  ULONG i;
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
+  for (i = 0; i < 768; i++)
+    {
+      WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
+      HalDacDelay();
+    }
+  HalDisablePalette();
+}
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+VOID FASTCALL
+HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
+/*
+ * FUNCTION: Initalize the display
+ * ARGUMENTS:
+ *         InitParameters = Parameters setup by the boot loader
+ */
+{
+  PHYSICAL_ADDRESS PhysBuffer;
+
+  if (! DisplayInitialized)
+    {
+      ULONG ScanLines;
+      ULONG Data;
+
+      PhysBuffer.u.HighPart = 0;
+      PhysBuffer.u.LowPart = VGA_GRAPH_MEM;
+      GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached);
+      if (NULL == GraphVideoBuffer)
+        {
+          return;
+        }
+      VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM));
+
+      /* Set cursor position */
+//      CursorX = LoaderBlock->cursorx;
+//      CursorY = LoaderBlock->cursory;
+      CursorX = 0;
+      CursorY = 0;
+
+      /* read screen size from the crtc */
+      /* FIXME: screen size should be read from the boot parameters */
+      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
+      SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
+      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
+      SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
+      Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+      SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
+      SizeY++;
+      WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
+      ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
+      SizeY = SizeY / ScanLines;
+
+#ifdef BOCHS_30ROWS
+      SizeY=30;
+#endif
+      HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
+
+      DisplayInitialized = TRUE;
+
+      /* 
+	 Save the VGA state at this point so we can restore it on a bugcheck.
+      */
+      HalSavePalette();
+      HalSaveMode();
+      HalSaveFont();
+    }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+VOID STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+  if (HalResetDisplayParameters == NULL)
+    return;
+
+  if (HalOwnsDisplay == TRUE)
+    return;
+
+  if (!HalResetDisplayParameters(SizeX, SizeY))
+    {
+      HalRestoreMode();
+      HalRestoreFont();
+      HalRestorePalette();
+    }
+  HalOwnsDisplay = TRUE;
+  HalClearDisplay(CHAR_ATTRIBUTE);
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION: 
+ * ARGUMENTS:
+ *         ResetDisplayParameters = Pointer to a driver specific
+ *         reset routine.
+ */
+{
+  HalOwnsDisplay = FALSE;
+  HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+HalDisplayString(IN PCH String)
+/*
+ * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
+ * already and displays a string
+ * ARGUMENT:
+ *        string = ASCII string to display
+ * NOTE: Use with care because there is no support for returning from BSOD
+ * mode
+ */
+{
+  PCH pch;
+#ifdef SCREEN_SYNCHRONIZATION
+  int offset;
+#endif
+  static KSPIN_LOCK Lock;
+  KIRQL OldIrql;
+  ULONG Flags;
+
+  /* See comment at top of file */
+  if (! HalOwnsDisplay || ! DisplayInitialized)
+    {
+      return;
+    }
+
+  pch = String;
+
+  OldIrql = KfRaiseIrql(HIGH_LEVEL);
+  KiAcquireSpinLock(&Lock);
+
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+  
+#ifdef SCREEN_SYNCHRONIZATION
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+  offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+  offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+  
+  CursorY = offset / SizeX;
+  CursorX = offset % SizeX;
+#endif
+  
+  while (*pch != 0)
+    {
+      if (*pch == '\n')
+	{
+	  CursorY++;
+	  CursorX = 0;
+	}
+      else if (*pch == '\b')
+	{
+	  if (CursorX > 0)
+	    {
+	      CursorX--;
+	    }
+	}
+      else if (*pch != '\r')
+	{
+	  HalPutCharacter (*pch);
+	  CursorX++;
+	  
+	  if (CursorX >= SizeX)
+	    {
+	      CursorY++;
+	      CursorX = 0;
+	    }
+	}
+  
+      if (CursorY >= SizeY)
+	{
+	  HalScrollDisplay ();
+	  CursorY = SizeY - 1;
+	}
+  
+      pch++;
+    }
+  
+#ifdef SCREEN_SYNCHRONIZATION
+  offset = (CursorY * SizeX) + CursorX;
+  
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+  WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
+#endif
+  Ki386RestoreFlags(Flags);
+
+  KiReleaseSpinLock(&Lock);
+  KfLowerIrql(OldIrql);
+}
+
+VOID STDCALL
+HalQueryDisplayParameters(OUT PULONG DispSizeX,
+			  OUT PULONG DispSizeY,
+			  OUT PULONG CursorPosX,
+			  OUT PULONG CursorPosY)
+{
+  if (DispSizeX)
+    *DispSizeX = SizeX;
+  if (DispSizeY)
+    *DispSizeY = SizeY;
+  if (CursorPosX)
+    *CursorPosX = CursorX;
+  if (CursorPosY)
+    *CursorPosY = CursorY;
+}
+
+
+VOID STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+			IN ULONG CursorPosY)
+{
+  CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+  CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+  return !HalOwnsDisplay;
+}
+
+/* EOF */

reactos/hal/halx86/generic
dma.c added at 1.2.2.1
diff -N dma.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dma.c	13 Dec 2004 16:18:23 -0000	1.2.2.1
@@ -0,0 +1,444 @@
+/* $Id: dma.c,v 1.2.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/dma.c
+ * PURPOSE:         DMA functions
+ * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ *                  Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* Adapters for each channel */
+PADAPTER_OBJECT HalpEisaAdapter[8];
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+HalpInitDma (VOID)
+{
+  /* TODO: Initialize the first Map Buffer */
+}
+
+PVOID STDCALL
+HalAllocateCommonBuffer (PADAPTER_OBJECT    AdapterObject,
+			 ULONG              Length,
+			 PPHYSICAL_ADDRESS  LogicalAddress,
+			 BOOLEAN            CacheEnabled)
+/*
+ * FUNCTION: Allocates memory that is visible to both the processor(s) and
+ * a dma device
+ * ARGUMENTS: 
+ *         AdapterObject = Adapter object representing the bus master or
+ *                         system dma controller
+ *         Length = Number of bytes to allocate
+ *         LogicalAddress = Logical address the driver can use to access the
+ *                          buffer 
+ *         CacheEnabled = Specifies if the memory can be cached
+ * RETURNS: The base virtual address of the memory allocated
+ *          NULL on failure
+ * NOTES:
+ *      CacheEnabled is ignored - it's all cache-disabled (like in NT)
+ *      UPDATE: It's not ignored now. If that's wrong just modify the
+ *      CacheEnabled comparsion below. 
+ */
+{
+  PHYSICAL_ADDRESS LowestAddress, HighestAddress, BoundryAddressMultiple;
+  PVOID BaseAddress;
+
+  LowestAddress.QuadPart = 0;
+  BoundryAddressMultiple.QuadPart = 0;
+  HighestAddress.u.HighPart = 0;
+  if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
+      HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
+  } else {
+      HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
+  }
+
+  BaseAddress = MmAllocateContiguousAlignedMemory(
+      Length,
+      LowestAddress,
+      HighestAddress,
+      BoundryAddressMultiple,
+      CacheEnabled ? MmCached : MmNonCached,
+      0x10000 );
+  if (!BaseAddress)
+    return 0;
+
+  *LogicalAddress = MmGetPhysicalAddress(BaseAddress);
+
+  return BaseAddress;
+}
+
+BOOLEAN STDCALL
+HalFlushCommonBuffer (ULONG	Unknown1,
+		      ULONG	Unknown2,
+		      ULONG	Unknown3,
+		      ULONG	Unknown4,
+		      ULONG	Unknown5,
+		      ULONG	Unknown6,
+		      ULONG	Unknown7,
+		      ULONG	Unknown8)
+{
+   return TRUE;
+}
+
+VOID STDCALL
+HalFreeCommonBuffer (PADAPTER_OBJECT		AdapterObject,
+		     ULONG			Length,
+		     PHYSICAL_ADDRESS	LogicalAddress,
+		     PVOID			VirtualAddress,
+		     BOOLEAN			CacheEnabled)
+{
+   MmFreeContiguousMemory(VirtualAddress);
+}
+
+PADAPTER_OBJECT STDCALL
+HalGetAdapter (PDEVICE_DESCRIPTION	DeviceDescription,
+	       PULONG			NumberOfMapRegisters)
+/*
+ * FUNCTION: Returns a pointer to an adapter object for the DMA device 
+ * defined in the device description structure
+ * ARGUMENTS:
+ *        DeviceDescription = Structure describing the attributes of the device
+ *        NumberOfMapRegisters (OUT) = Returns the maximum number of map
+ *                                     registers the device driver can
+ *                                     allocate for DMA transfer operations
+ * RETURNS: The allocated adapter object on success
+ *          NULL on failure
+ * TODO:
+ *        Testing
+ */
+{
+	PADAPTER_OBJECT AdapterObject;
+	DWORD ChannelSelect;
+	DWORD Controller;
+	ULONG MaximumLength;
+	BOOLEAN ChannelSetup;
+
+	DPRINT("Entered Function\n");
+  
+	/* Validate parameters in device description, and return a pointer to
+	the adapter object for the requested dma channel */
+	if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
+		DPRINT("Invalid Adapter version!\n");
+		return NULL;
+	}
+
+	DPRINT("Checking Interface Type: %x \n", DeviceDescription->InterfaceType);
+	if (DeviceDescription->InterfaceType == PCIBus) {
+		if (DeviceDescription->Master == FALSE) {
+			DPRINT("Invalid request!\n");
+			return NULL;
+		}
+		ChannelSetup = FALSE;
+	}
+	
+	/* There are only 8 DMA channels on ISA, so any request above this
+	should not get any channel setup */
+	if (DeviceDescription->DmaChannel >= 8) {
+		ChannelSetup = FALSE;
+	}
+	
+	/* Channel 4 is Reserved for Chaining, so you cant use it */
+	if (DeviceDescription->DmaChannel == 4 && ChannelSetup) {
+		DPRINT("Invalid request!\n");
+		return NULL;
+	}
+	
+	/* Devices that support Scatter/Gather do not need Map Registers */
+	if (DeviceDescription->ScatterGather ||
+	    DeviceDescription->InterfaceType == PCIBus) {
+		*NumberOfMapRegisters = 0;
+	}
+	
+	/* Check if Extended DMA is available (we're just going to do a random read/write
+	I picked Channel 2 because it's the first Channel in the Register */
+	WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2), 0x2A);
+	if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2)) == 0x2A) {
+		HalpEisaDma = TRUE;
+	}
+	 
+	/* Find out how many Map Registers we need */
+	DPRINT("Setting up Adapter Settings!\n");
+	MaximumLength = DeviceDescription->MaximumLength & 0x7FFFFFFF;
+        *NumberOfMapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
+	
+	/* Set the Channel Selection */
+	ChannelSelect = DeviceDescription->DmaChannel & 0x03;
+	
+	/* Get the Controller Setup */
+	Controller = (DeviceDescription->DmaChannel & 0x04) ? 2 : 1;
+	
+	/* Get the Adapter Object */
+	if (HalpEisaAdapter[DeviceDescription->DmaChannel] != NULL) {
+	
+		/* Already allocated, return it */
+		DPRINT("Getting an Adapter Object from the Cache\n");
+		AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
+		
+		/* Do we need more Map Registers this time? */
+		if ((AdapterObject->NeedsMapRegisters) && 
+		    (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)) {
+			AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+		}
+		
+		} else {
+	
+		/* We have to allocate a new object! How exciting! */
+		DPRINT("Allocating a new Adapter Object\n");
+		AdapterObject = HalpAllocateAdapterEx(*NumberOfMapRegisters,
+						      FALSE,
+						      DeviceDescription->Dma32BitAddresses);
+
+		if (AdapterObject == NULL) return NULL;
+		
+		HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
+		
+		if (!*NumberOfMapRegisters) {
+			/* Easy case, no Map Registers needed */
+			AdapterObject->NeedsMapRegisters = FALSE;
+		
+			/* If you're the master, you get all you want */
+			if (DeviceDescription->Master) {
+				AdapterObject->MapRegistersPerChannel= *NumberOfMapRegisters;
+			} else {
+				AdapterObject->MapRegistersPerChannel = 1;
+			}
+		} else {
+			/* We Desire Registers */
+			AdapterObject->NeedsMapRegisters = TRUE;
+		
+			/* The registers you want */
+			AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+		
+			/* Increase commitment */
+			MasterAdapter->CommittedMapRegisters += *NumberOfMapRegisters;
+		}
+	}
+	
+	/* Set up DMA Structure */
+	if (Controller == 1) {
+		AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
+	} else {
+		AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
+	}
+	        
+	/* Set up Some Adapter Data */
+	DPRINT("Setting up an Adapter Object\n");
+	AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
+	AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+	AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
+	AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
+        AdapterObject->MasterDevice = DeviceDescription->Master;
+	if (DeviceDescription->InterfaceType != PCIBus) AdapterObject->LegacyAdapter = TRUE;
+	
+	/* Everything below is not required if we don't need a channel */
+	if (!ChannelSetup) {
+		DPRINT("Retuning Adapter Object without Channel Setup\n");
+		return AdapterObject;
+	}
+	
+	AdapterObject->ChannelNumber = ChannelSelect;
+	
+	
+	/* Set up the Page Port */
+	if (Controller == 1) {
+		switch (ChannelSelect) {
+		
+		case 0:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0));
+			break;
+		case 1:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1));
+			break;
+		case 2:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2));
+			break;
+		case 3:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3));
+			break;
+		}
+	
+		/* Set Controller Number */
+		AdapterObject->AdapterNumber = 1; 
+	} else {
+		switch (ChannelSelect) {
+		
+		case 1:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5));
+			break;
+		case 2:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6));
+			break;
+		case 3:
+			AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7));
+			break;
+		}
+		
+		/* Set Controller Number */
+		AdapterObject->AdapterNumber = 2; 
+	}
+	
+	/* Set up the Extended Register */
+	if (HalpEisaDma) {
+		DMA_EXTENDED_MODE ExtendedMode;
+		
+		ExtendedMode.ChannelNumber = ChannelSelect;
+	
+		switch (DeviceDescription->DmaSpeed) {
+		
+		case Compatible:
+			ExtendedMode.TimingMode = COMPATIBLE_TIMING;
+			break;
+		
+		case TypeA:
+			ExtendedMode.TimingMode = TYPE_A_TIMING;
+			break;
+			
+		case TypeB:
+			ExtendedMode.TimingMode = TYPE_B_TIMING;
+			break;
+			
+		case TypeC:
+			ExtendedMode.TimingMode = BURST_TIMING;
+			break;
+		
+		default:
+			return NULL;
+		}
+	
+		switch (DeviceDescription->DmaWidth) {
+		
+		case Width8Bits:
+			ExtendedMode.TransferSize = B_8BITS;
+			break;
+		
+		case Width16Bits:
+			ExtendedMode.TransferSize = B_16BITS;
+			break;
+			
+		case Width32Bits:
+			ExtendedMode.TransferSize = B_32BITS;
+			break;
+			
+		default:
+			return NULL;
+				}
+		
+		if (Controller == 1) {
+			WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
+				    	*((PUCHAR)&ExtendedMode));
+		} else {
+	       		WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
+				    	*((PUCHAR)&ExtendedMode));
+		}
+	}
+			/* Do 8/16-bit validation */
+	DPRINT("Validating an Adapter Object\n");
+	if (!DeviceDescription->Master) {
+		if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) {
+			return NULL; /* 8-bit is only avalable on Controller 1 */
+		} else if (DeviceDescription->DmaWidth == Width16Bits) {
+			if (Controller != 2) {
+				return NULL; /* 16-bit is only avalable on Controller 2 */
+			} else {
+				AdapterObject->Width16Bits = TRUE;
+			}
+		}
+	}
+		UCHAR DmaMode;	
+			DPRINT("Final DMA Request Mode Setting of the Adapter Object\n");
+	/* Set the DMA Request Modes */
+	if (DeviceDescription->Master) {
+		/* This is a cascade request */
+		((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE;
+		
+		/* Send the request */
+		if (AdapterObject->AdapterNumber == 1) {
+			/* Set the Request Data */
+			WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+				  	AdapterObject->AdapterMode);
+					  
+			/* Unmask DMA Channel */
+			WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+				  	AdapterObject->ChannelNumber | DMA_CLEARMASK);
+		} else {
+			/* Set the Request Data */
+			WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+				  	AdapterObject->AdapterMode);
+				  
+			/* Unmask DMA Channel */
+			WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+				  	AdapterObject->ChannelNumber | DMA_CLEARMASK);
+		}
+	} else if (DeviceDescription->DemandMode) {
+		/* This is a Demand request */
+		((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE;
+	} else {
+		/* Normal Request */
+		((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE;
+	}
+	
+	/* Auto Initialize Enabled or Not*/
+	((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize;
+	AdapterObject->AdapterMode = DmaMode;
+	return AdapterObject;
+}
+
+ULONG STDCALL
+HalReadDmaCounter (PADAPTER_OBJECT	AdapterObject)
+{
+  KIRQL OldIrql;
+  ULONG Count;
+
+ 	KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
+  
+  	/* Send the Request to the specific controller */
+	if (AdapterObject->AdapterNumber == 1) {
+  	
+		/* Set this for Ease */
+  		PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+	
+		/* Send Reset */
+		WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+	
+		/* Read Count */
+		Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+					[AdapterObject->ChannelNumber].DmaBaseCount);
+		Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+					[AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+      
+	} else {
+
+		/* Set this for Ease */
+  		PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+	
+		/* Send Reset */
+		WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+	
+		/* Read Count */
+		Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+					[AdapterObject->ChannelNumber].DmaBaseCount);
+		Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+					[AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+	}
+	
+	/* Play around with the count (add bias and multiply by 2 if 16-bit DMA) */
+	Count ++;
+	if (AdapterObject->Width16Bits) Count *=2 ;
+	
+	KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
+	
+	/* Return it */
+	return Count;
+}
+
+/* EOF */

reactos/hal/halx86/generic
drive.c added at 1.1.2.1
diff -N drive.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ drive.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,31 @@
+/* $Id: drive.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            hal/x86/drive.c
+ * PURPOSE:         Drive letter assignment
+ * PROGRAMMER:      
+ * UPDATE HISTORY:
+ *	2000-03-25
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+		     IN PSTRING NtDeviceName,
+		     OUT PUCHAR NtSystemPath,
+		     OUT PSTRING NtSystemPathString)
+{
+  HalIoAssignDriveLetters(LoaderBlock,
+			  NtDeviceName,
+			  NtSystemPath,
+			  NtSystemPathString);
+}
+
+/* EOF */

reactos/hal/halx86/generic
enum.c added at 1.1.2.1
diff -N enum.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ enum.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,24 @@
+/* $Id: enum.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/enum.c
+ * PURPOSE:         Motherboard device enumerator
+ * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ *                  Created 01/05/2001
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+VOID
+HalpStartEnumerator (VOID)
+{
+}
+
+/* EOF */

reactos/hal/halx86/generic
fmutex.c added at 1.1.2.1
diff -N fmutex.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ fmutex.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,53 @@
+/* $Id: fmutex.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/fmutex.c
+ * PURPOSE:         Implements fast mutexes
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
+ *                  Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  Created 09/06/2000
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID FASTCALL
+ExAcquireFastMutex (PFAST_MUTEX	FastMutex)
+{
+   KeEnterCriticalRegion();
+   ExAcquireFastMutexUnsafe(FastMutex);
+}
+
+
+VOID FASTCALL
+ExReleaseFastMutex (PFAST_MUTEX	FastMutex)
+{
+  ExReleaseFastMutexUnsafe(FastMutex);
+  KeLeaveCriticalRegion();
+}
+
+
+BOOLEAN FASTCALL
+ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
+{
+  KeEnterCriticalRegion();
+  if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+    {
+      FastMutex->Owner = KeGetCurrentThread();
+      return(TRUE);
+    }
+  else
+    {
+      KeLeaveCriticalRegion();
+      return(FALSE);
+    }
+}
+
+/* EOF */

reactos/hal/halx86/generic
halinit.c added at 1.3.2.1
diff -N halinit.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halinit.c	13 Dec 2004 16:18:23 -0000	1.3.2.1
@@ -0,0 +1,66 @@
+/* $Id: halinit.c,v 1.3.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          ntoskrnl/hal/x86/halinit.c
+ * PURPOSE:       Initalize the x86 hal
+ * PROGRAMMER:    David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ *              11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *****************************************************************/
+
+PVOID HalpZeroPageMapping = NULL;
+HALP_HOOKS HalpHooks;
+
+/* FUNCTIONS ***************************************************************/
+
+NTSTATUS
+STDCALL
+DriverEntry(
+    PDRIVER_OBJECT DriverObject,
+    PUNICODE_STRING RegistryPath)
+{
+	return STATUS_SUCCESS;
+}
+
+BOOLEAN STDCALL
+HalInitSystem (ULONG BootPhase,
+               PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+  if (BootPhase == 0)
+    {
+      RtlZeroMemory(&HalpHooks, sizeof(HALP_HOOKS));
+      HalpInitPhase0();      
+    }
+  else if (BootPhase == 1)
+    {
+      /* Initialize display and make the screen black */
+      HalInitializeDisplay (LoaderBlock);
+      HalpInitBusHandlers();
+      HalpInitDma();
+
+      /* Enumerate the devices on the motherboard */
+      HalpStartEnumerator();
+   }
+  else if (BootPhase == 2)
+    {
+      /* Go to blue screen */
+      HalClearDisplay (0x17); /* grey on blue */
+      
+      HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached);
+    }
+
+  return TRUE;
+}
+
+/* EOF */

reactos/hal/halx86/generic
ipi.c added at 1.1.2.1
diff -N ipi.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ipi.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,26 @@
+/* $Id: ipi.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:             See COPYING in the top level directory
+ * PROJECT:               ReactOS kernel
+ * FILE:                  hal/halx86/generic/ipi.c
+ * PURPOSE:               Miscellaneous hardware functions
+ * PROGRAMMER:            Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+  DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+}
+
+/* EOF */

reactos/hal/halx86/generic
irql.c added at 1.1.2.1
diff -N irql.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ irql.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,479 @@
+/* $Id: irql.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/irql.c
+ * PURPOSE:         Implements IRQLs
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <hal.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+/*
+ * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS 
+*/
+
+typedef union
+{
+   USHORT both;
+   struct
+   {
+      BYTE master;
+      BYTE slave;
+   };
+}
+PIC_MASK;
+   
+/* 
+ * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
+ *          - At startup enable timer and cascade 
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask = {.both = 0xFFFA};
+#else
+static PIC_MASK pic_mask = { 0xFFFA };
+#endif
+
+
+/*
+ * PURPOSE: Mask for disabling of acknowledged interrupts 
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask_intr = {.both = 0x0000};
+#else
+static PIC_MASK pic_mask_intr = { 0 };
+#endif
+
+static ULONG HalpPendingInterruptCount[NR_IRQS];
+
+#define DIRQL_TO_IRQ(x)  (PROFILE_LEVEL - x)
+#define IRQ_TO_DIRQL(x)  (PROFILE_LEVEL - x)
+
+VOID STDCALL
+KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+  return(KeGetCurrentKPCR()->Irql);
+}
+
+VOID HalpInitPICs(VOID)
+{
+  memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
+
+  /* Initialization sequence */
+  WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
+  WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
+  /* Start of hardware irqs (0x24) */
+  WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
+  WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
+  /* 8259-1 is master */
+  WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
+  /* 8259-2 is slave */
+  WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
+  /* 8086 mode */
+  WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
+  WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);   
+  /* Enable interrupts */
+  WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
+  WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
+  
+  /* We can now enable interrupts */
+  Ki386EnableInterrupts();
+}
+
+VOID HalpEndSystemInterrupt(KIRQL Irql)
+/*
+ * FUNCTION: Enable all irqs with higher priority.
+ */
+{
+  ULONG flags;
+  const USHORT mask[] = 
+  {
+     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+     0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
+     0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
+     0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+  };     
+
+  /* Interrupts should be disable while enabling irqs of both pics */
+  Ki386SaveFlags(flags);
+  Ki386DisableInterrupts();
+
+  pic_mask_intr.both &= mask[Irql];
+  WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+  WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+
+  /* restore flags */
+  Ki386RestoreFlags(flags);
+}
+
+VOID STATIC
+HalpExecuteIrqs(KIRQL NewIrql)
+{
+  ULONG IrqLimit, i;
+  
+  IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
+
+  /*
+   * For each irq if there have been any deferred interrupts then now
+   * dispatch them.
+   */
+  for (i = 0; i < IrqLimit; i++)
+    {
+      if (HalpPendingInterruptCount[i] > 0)
+	{
+	   KeGetCurrentKPCR()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
+
+           while (HalpPendingInterruptCount[i] > 0)
+	     {
+	       /*
+	        * For each deferred interrupt execute all the handlers at DIRQL.
+	        */
+	       HalpPendingInterruptCount[i]--;
+	       KiInterruptDispatch2(i + IRQ_BASE, NewIrql);
+	     }
+	   KeGetCurrentKPCR()->Irql--;
+	   HalpEndSystemInterrupt(KeGetCurrentKPCR()->Irql);
+	}
+    }
+
+}
+
+VOID STATIC
+HalpLowerIrql(KIRQL NewIrql)
+{
+  if (NewIrql >= PROFILE_LEVEL)
+    {
+      KeGetCurrentKPCR()->Irql = NewIrql;
+      return;
+    }
+  HalpExecuteIrqs(NewIrql);
+  if (NewIrql >= DISPATCH_LEVEL)
+    {
+      KeGetCurrentKPCR()->Irql = NewIrql;
+      return;
+    }
+  KeGetCurrentKPCR()->Irql = DISPATCH_LEVEL;
+  if (KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST])
+    {
+      KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = FALSE;
+      KiDispatchInterrupt();
+    }
+  KeGetCurrentKPCR()->Irql = APC_LEVEL;
+  if (NewIrql == APC_LEVEL)
+    {
+      return;
+    }
+  if (KeGetCurrentThread() != NULL && 
+      KeGetCurrentThread()->ApcState.KernelApcPending)
+    {
+      KiDeliverApc(KernelMode, NULL, NULL);
+    }
+  KeGetCurrentKPCR()->Irql = PASSIVE_LEVEL;
+}
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KfLowerIrql
+ *
+ * DESCRIPTION
+ *	Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ *	Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL	NewIrql)
+{
+  DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
+  
+  if (NewIrql > KeGetCurrentKPCR()->Irql)
+    {
+      DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
+		__FILE__, __LINE__, NewIrql, KeGetCurrentKPCR()->Irql);
+      KEBUGCHECK(0);
+      for(;;);
+    }
+  
+  HalpLowerIrql(NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeLowerIrql
+ *
+ * DESCRIPTION
+ *	Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+  KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KfRaiseIrql
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ *	previous irq level
+ *
+ * NOTES
+ *	Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL	NewIrql)
+{
+  KIRQL OldIrql;
+  
+  DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
+  
+  if (NewIrql < KeGetCurrentKPCR()->Irql)
+    {
+      DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
+		__FILE__,__LINE__,KeGetCurrentKPCR()->Irql,NewIrql);
+      KEBUGCHECK (0);
+      for(;;);
+    }
+  
+  OldIrql = KeGetCurrentKPCR()->Irql;
+  KeGetCurrentKPCR()->Irql = NewIrql;
+  return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrql
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to raise to
+ *	OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL	NewIrql,
+	     PKIRQL	OldIrql)
+{
+  *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ *	None
+ *
+ * RETURN VALUE
+ *	Previous irq level
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+  return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ *	None
+ *
+ * RETURN VALUE
+ *	Previous irq level
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+  return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL 
+HalBeginSystemInterrupt (ULONG Vector,
+			 KIRQL Irql,
+			 PKIRQL OldIrql)
+{
+  ULONG irq;
+  if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+    {
+      return(FALSE);
+    }
+  irq = Vector - IRQ_BASE;
+  pic_mask_intr.both |= ((1 << irq) & 0xfffe);	// do not disable the timer interrupt
+
+  if (irq < 8)
+  {
+     WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+     WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
+  }
+  else
+  {
+     WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+     /* Send EOI to the PICs */
+     WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
+     WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
+  }
+  
+  if (KeGetCurrentKPCR()->Irql >= Irql)
+    {
+      HalpPendingInterruptCount[irq]++;
+      return(FALSE);
+    }
+  *OldIrql = KeGetCurrentKPCR()->Irql;
+  KeGetCurrentKPCR()->Irql = Irql;
+
+  return(TRUE);
+}
+
+
+VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+  HalpLowerIrql(Irql);
+  HalpEndSystemInterrupt(Irql);
+}
+  
+BOOLEAN
+STDCALL
+HalDisableSystemInterrupt(
+  ULONG Vector,
+  KIRQL Irql)
+{
+  ULONG irq;
+  
+  if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+    return FALSE;
+
+  irq = Vector - IRQ_BASE;
+  pic_mask.both |= (1 << irq);
+  if (irq < 8)
+     {
+      WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
+     }
+  else
+    {
+      WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+    }
+  
+  return TRUE;
+}
+
+
+BOOLEAN
+STDCALL
+HalEnableSystemInterrupt(
+  ULONG Vector,
+  KIRQL Irql,
+  KINTERRUPT_MODE InterruptMode)
+{
+  ULONG irq;
+
+  if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+    return FALSE;
+
+  irq = Vector - IRQ_BASE;
+  pic_mask.both &= ~(1 << irq);
+  if (irq < 8)
+    {
+      WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+    }
+  else
+     {
+       WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+     }
+
+  return TRUE;
+}
+
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(
+  IN KIRQL Request)
+{
+  switch (Request)
+  {
+    case APC_LEVEL:
+      KeGetCurrentKPCR()->HalReserved[HAL_APC_REQUEST] = TRUE;
+      break;
+
+    case DISPATCH_LEVEL:
+      KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = TRUE;
+      break;
+      
+    default:
+      KEBUGCHECK(0);
+  }
+}
+
+/* EOF */

reactos/hal/halx86/generic
isa.c added at 1.1.2.1
diff -N isa.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ isa.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,78 @@
+/* $Id: isa.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/isa.c
+ * PURPOSE:         Interfaces to the ISA bus
+ * PROGRAMMER:      David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ *               05/06/98: Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOL HalIsaProbe(VOID)
+/*
+ * FUNCTION: Probes for an ISA bus
+ * RETURNS: True if detected
+ * NOTE: Since ISA is the default we are called last and always return
+ * true
+ */
+{
+   DbgPrint("Assuming ISA bus\n");
+   
+   /*
+    * Probe for plug and play support
+    */
+   return(TRUE);
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
+			   ULONG BusNumber,
+			   PHYSICAL_ADDRESS BusAddress,
+			   PULONG AddressSpace,
+			   PPHYSICAL_ADDRESS TranslatedAddress)
+{
+   BOOLEAN Result;
+
+   Result = HalTranslateBusAddress(PCIBus,
+				   BusNumber,
+				   BusAddress,
+				   AddressSpace,
+				   TranslatedAddress);
+   if (Result != FALSE)
+     return Result;
+
+   Result = HalTranslateBusAddress(Internal,
+				   BusNumber,
+				   BusAddress,
+				   AddressSpace,
+				   TranslatedAddress);
+   return Result;
+}
+
+ULONG STDCALL
+HalpGetIsaInterruptVector(PVOID BusHandler,
+			  ULONG BusNumber,
+			  ULONG BusInterruptLevel,
+			  ULONG BusInterruptVector,
+			  PKIRQL Irql,
+			  PKAFFINITY Affinity)
+{
+  ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+  *Irql = VECTOR2IRQL(Vector);
+  *Affinity = 0xFFFFFFFF;
+  return Vector;
+}
+/* EOF */

reactos/hal/halx86/generic
kdbg.c added at 1.1.2.1
diff -N kdbg.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ kdbg.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,548 @@
+/* $Id: kdbg.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/kdbg.c
+ * PURPOSE:         Serial i/o functions for the kernel debugger.
+ * PROGRAMMER:      Emanuele Aliberti
+ *                  Eric Kohl
+ * UPDATE HISTORY:
+ *                  Created 05/09/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+#define DEFAULT_BAUD_RATE    19200
+
+
+/* MACROS *******************************************************************/
+
+#define   SER_RBR(x)   ((x)+0)
+#define   SER_THR(x)   ((x)+0)
+#define   SER_DLL(x)   ((x)+0)
+#define   SER_IER(x)   ((x)+1)
+#define     SR_IER_ERDA   0x01
+#define     SR_IER_ETHRE  0x02
+#define     SR_IER_ERLSI  0x04
+#define     SR_IER_EMS    0x08
+#define     SR_IER_ALL    0x0F
+#define   SER_DLM(x)   ((x)+1)
+#define   SER_IIR(x)   ((x)+2)
+#define   SER_FCR(x)   ((x)+2)
+#define     SR_FCR_ENABLE_FIFO 0x01
+#define     SR_FCR_CLEAR_RCVR  0x02
+#define     SR_FCR_CLEAR_XMIT  0x04
+#define   SER_LCR(x)   ((x)+3)
+#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)
+#define     SR_MCR_DTR 0x01
+#define     SR_MCR_RTS 0x02
+#define     SR_MCR_OUT1 0x04
+#define     SR_MCR_OUT2 0x08
+#define     SR_MCR_LOOP 0x10
+#define   SER_LSR(x)   ((x)+5)
+#define     SR_LSR_DR  0x01
+#define     SR_LSR_TBE 0x20
+#define   SER_MSR(x)   ((x)+6)
+#define     SR_MSR_CTS 0x10
+#define     SR_MSR_DSR 0x20
+#define   SER_SCR(x)   ((x)+7)
+
+
+/* GLOBAL VARIABLES *********************************************************/
+
+ULONG EXPORTED KdComPortInUse = 0;
+
+
+/* STATIC VARIABLES *********************************************************/
+
+static ULONG ComPort = 0;
+static ULONG BaudRate = 0;
+static PUCHAR PortBase = (PUCHAR)0;
+
+/* The com port must only be initialized once! */
+static BOOLEAN PortInitialized = FALSE;
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+static BOOLEAN
+KdpDoesComPortExist (PUCHAR BaseAddress)
+{
+        BOOLEAN found;
+        BYTE mcr;
+        BYTE msr;
+
+        found = FALSE;
+
+        /* save Modem Control Register (MCR) */
+        mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
+
+        /* enable loop mode (set Bit 4 of the MCR) */
+        WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+        /* clear all modem output bits */
+        WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+        /* read the Modem Status Register */
+        msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+        /*
+         * the upper nibble of the MSR (modem output bits) must be
+         * equal to the lower nibble of the MCR (modem input bits)
+         */
+        if ((msr & 0xF0) == 0x00)
+        {
+                /* set all modem output bits */
+                WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
+
+                /* read the Modem Status Register */
+                msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+                /*
+                 * the upper nibble of the MSR (modem output bits) must be
+                 * equal to the lower nibble of the MCR (modem input bits)
+                 */
+                if ((msr & 0xF0) == 0xF0)
+                {
+                        /*
+                         * setup a resonable state for the port:
+                         * enable fifo and clear recieve/transmit buffers
+                         */
+                        WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
+                                (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
+                        WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
+                        READ_PORT_UCHAR (SER_RBR(BaseAddress));
+                        WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
+                        found = TRUE;
+                }
+        }
+
+        /* restore MCR */
+        WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
+
+        return (found);
+}
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* HAL.KdPortInitialize */
+BOOLEAN
+STDCALL
+KdPortInitialize (
+	PKD_PORT_INFORMATION	PortInformation,
+	DWORD	Unknown1,
+	DWORD	Unknown2
+	)
+{
+        ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+        char buffer[80];
+        ULONG divisor;
+        BYTE lcr;
+
+        if (PortInitialized == FALSE)
+        {
+                if (PortInformation->BaudRate != 0)
+                {
+                        BaudRate = PortInformation->BaudRate;
+                }
+                else
+                {
+                        BaudRate = DEFAULT_BAUD_RATE;
+                }
+
+                if (PortInformation->ComPort == 0)
+                {
+                        if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
+                        {
+                                PortBase = (PUCHAR)BaseArray[2];
+                                ComPort = 2;
+                                PortInformation->BaseAddress = (ULONG)PortBase;
+                                PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+                                sprintf (buffer,
+                                         "\nSerial port COM%ld found at 0x%lx\n",
+                                         ComPort,
+                                         (ULONG)PortBase);
+                                HalDisplayString (buffer);
+#endif /* NDEBUG */
+                        }
+                        else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
+                        {
+                                PortBase = (PUCHAR)BaseArray[1];
+                                ComPort = 1;
+                                PortInformation->BaseAddress = (ULONG)PortBase;
+                                PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+                                sprintf (buffer,
+                                         "\nSerial port COM%ld found at 0x%lx\n",
+                                         ComPort,
+                                         (ULONG)PortBase);
+                                HalDisplayString (buffer);
+#endif /* NDEBUG */
+                        }
+                        else
+                        {
+                                sprintf (buffer,
+                                         "\nKernel Debugger: No COM port found!!!\n\n");
+                                HalDisplayString (buffer);
+                                return FALSE;
+                        }
+                }
+                else
+                {
+                        if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+                        {
+                                PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+                                ComPort = PortInformation->ComPort;
+                                PortInformation->BaseAddress = (ULONG)PortBase;
+#ifndef NDEBUG
+                                sprintf (buffer,
+                                         "\nSerial port COM%ld found at 0x%lx\n",
+                                         ComPort,
+                                         (ULONG)PortBase);
+                                HalDisplayString (buffer);
+#endif /* NDEBUG */
+                        }
+                        else
+                        {
+                                sprintf (buffer,
+                                         "\nKernel Debugger: No serial port found!!!\n\n");
+                                HalDisplayString (buffer);
+                                return FALSE;
+                        }
+                }
+
+                PortInitialized = TRUE;
+        }
+
+        /*
+         * set baud rate and data format (8N1)
+         */
+
+        /*  turn on DTR and RTS  */
+        WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+        /* set DLAB */
+        lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
+        WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
+
+        /* set baud rate */
+        divisor = 115200 / BaudRate;
+        WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
+        WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+        /* reset DLAB and set 8N1 format */
+        WRITE_PORT_UCHAR (SER_LCR(PortBase),
+                          SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+        /* read junk out of the RBR */
+        lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+        /*
+         * set global info
+         */
+        KdComPortInUse = (ULONG)PortBase;
+
+        /*
+         * print message to blue screen
+         */
+        sprintf (buffer,
+                 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+                 ComPort,
+                 (ULONG)PortBase,
+                 BaudRate);
+
+        HalDisplayString (buffer);
+
+        return TRUE;
+}
+
+
+/* HAL.KdPortInitializeEx */
+BOOLEAN
+STDCALL
+KdPortInitializeEx (
+	PKD_PORT_INFORMATION	PortInformation,
+	DWORD	Unknown1,
+	DWORD	Unknown2
+	)
+{
+        ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+		PUCHAR ComPortBase;
+        char buffer[80];
+        ULONG divisor;
+        BYTE lcr;
+
+		if (PortInformation->BaudRate == 0)
+		{
+				PortInformation->BaudRate = DEFAULT_BAUD_RATE;
+		}
+
+		if (PortInformation->ComPort == 0)
+		{
+				return FALSE;
+		}
+		else
+		{
+				if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+				{
+						ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+						PortInformation->BaseAddress = (ULONG)ComPortBase;
+#ifndef NDEBUG
+						sprintf (buffer,
+								 "\nSerial port COM%ld found at 0x%lx\n",
+								 PortInformation->ComPort,
+								 (ULONG)ComPortBase];
+						HalDisplayString (buffer);
+#endif /* NDEBUG */
+				}
+				else
+				{
+						sprintf (buffer,
+								 "\nKernel Debugger: Serial port not found!!!\n\n");
+						HalDisplayString (buffer);
+						return FALSE;
+				}
+		}
+
+        /*
+         * set baud rate and data format (8N1)
+         */
+
+        /*  turn on DTR and RTS  */
+        WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+        /* set DLAB */
+        lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
+        WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
+
+        /* set baud rate */
+        divisor = 115200 / PortInformation->BaudRate;
+        WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
+        WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+        /* reset DLAB and set 8N1 format */
+        WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
+                          SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+        /* read junk out of the RBR */
+        lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+#ifndef NDEBUG
+
+        /*
+         * print message to blue screen
+         */
+        sprintf (buffer,
+                 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+                 PortInformation->ComPort,
+                 (ULONG)ComPortBase,
+                 PortInformation->BaudRate);
+
+        HalDisplayString (buffer);
+
+#endif /* NDEBUG */
+
+        return TRUE;
+}
+
+
+/* HAL.KdPortGetByte */
+BOOLEAN
+STDCALL
+KdPortGetByte (
+	PUCHAR	ByteRecieved
+	)
+{
+	if (PortInitialized == FALSE)
+		return FALSE;
+
+	if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
+	{
+		*ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+/* HAL.KdPortGetByteEx */
+BOOLEAN
+STDCALL
+KdPortGetByteEx (
+	PKD_PORT_INFORMATION	PortInformation,
+	PUCHAR	ByteRecieved
+	)
+{
+	PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+	if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
+	{
+		*ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+/* HAL.KdPortPollByte */
+BOOLEAN
+STDCALL
+KdPortPollByte (
+	PUCHAR	ByteRecieved
+	)
+{
+	if (PortInitialized == FALSE)
+		return FALSE;
+
+	while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
+		;
+
+	*ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+	return TRUE;
+}
+
+
+/* HAL.KdPortPollByteEx */
+BOOLEAN
+STDCALL
+KdPortPollByteEx (
+	PKD_PORT_INFORMATION	PortInformation,
+	PUCHAR	ByteRecieved
+	)
+{
+	PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+	while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
+		;
+
+	*ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+	return TRUE;
+}
+
+
+
+
+/* HAL.KdPortPutByte */
+VOID
+STDCALL
+KdPortPutByte (
+	UCHAR ByteToSend
+	)
+{
+	if (PortInitialized == FALSE)
+		return;
+
+	while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
+		;
+
+	WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
+}
+
+/* HAL.KdPortPutByteEx */
+VOID
+STDCALL
+KdPortPutByteEx (
+	PKD_PORT_INFORMATION	PortInformation,
+	UCHAR ByteToSend
+	)
+{
+	PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+	while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
+		;
+
+	WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
+}
+
+
+/* HAL.KdPortRestore */
+VOID
+STDCALL
+KdPortRestore (
+	VOID
+	)
+{
+}
+
+
+/* HAL.KdPortSave */
+VOID
+STDCALL
+KdPortSave (
+	VOID
+	)
+{
+}
+
+
+/* HAL.KdPortDisableInterrupts */
+BOOLEAN
+STDCALL
+KdPortDisableInterrupts()
+{
+  UCHAR ch;
+
+	if (PortInitialized == FALSE)
+		return FALSE;
+
+	ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+  ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
+	WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+	ch = READ_PORT_UCHAR (SER_IER (PortBase));
+  ch &= (~SR_IER_ALL);
+	WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+	return TRUE;
+}
+
+
+/* HAL.KdPortEnableInterrupts */
+BOOLEAN
+STDCALL
+KdPortEnableInterrupts()
+{
+  UCHAR ch;
+
+	if (PortInitialized == FALSE)
+		return FALSE;
+
+	ch = READ_PORT_UCHAR (SER_IER (PortBase));
+  ch &= (~SR_IER_ALL);
+  ch |= SR_IER_ERDA;
+	WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+	ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+  ch &= (~SR_MCR_LOOP);
+  ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
+	WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+	return TRUE;
+}
+
+/* EOF */

reactos/hal/halx86/generic
mca.c added at 1.1.2.1
diff -N mca.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mca.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,82 @@
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2002 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: mca.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS kernel
+ * FILE:        hal/halx86/mca.c
+ * PURPOSE:     Interfaces to the MicroChannel bus
+ * PROGRAMMER:  Eric Kohl (ekohl@rz-online.de)
+ */
+
+/*
+ * TODO:
+ *   What Adapter ID is read from an empty slot?
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
+			ULONG BusNumber,
+			ULONG SlotNumber,
+			PVOID Buffer,
+			ULONG Offset,
+			ULONG Length)
+{
+  PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer;
+
+  DPRINT("HalpGetMicroChannelData() called.\n");
+  DPRINT("  BusNumber %lu\n", BusNumber);
+  DPRINT("  SlotNumber %lu\n", SlotNumber);
+  DPRINT("  Offset 0x%lx\n", Offset);
+  DPRINT("  Length 0x%lx\n", Length);
+
+  if ((BusNumber != 0) ||
+      (SlotNumber == 0) || (SlotNumber > 8) ||
+      (Length < sizeof(CM_MCA_POS_DATA)))
+    return(0);
+
+  /* Enter Setup-Mode for given slot */
+  WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08));
+
+  /* Read POS data */
+  PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) +
+			READ_PORT_UCHAR((PUCHAR)0x100);
+  PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102);
+  PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103);
+  PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104);
+  PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105);
+
+  /* Leave Setup-Mode for given slot */
+  WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07));
+
+  return(sizeof(CM_MCA_POS_DATA));
+}
+
+/* EOF */

reactos/hal/halx86/generic
misc.c added at 1.1.2.1
diff -N misc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ misc.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,69 @@
+/* $Id: misc.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:             See COPYING in the top level directory
+ * PROJECT:               ReactOS kernel
+ * FILE:                  ntoskrnl/hal/x86/misc.c
+ * PURPOSE:               Miscellaneous hardware functions
+ * PROGRAMMER:            Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalHandleNMI(ULONG Unused)
+{
+  UCHAR ucStatus;
+
+  ucStatus = READ_PORT_UCHAR((PUCHAR) 0x61);
+
+  HalDisplayString ("\n*** Hardware Malfunction\n\n");
+  HalDisplayString ("Call your hardware vendor for support\n\n");
+
+  if (ucStatus & 0x80)
+    HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
+
+  if (ucStatus & 0x40)
+    HalDisplayString ("NMI: Channel Check / IOCHK\n");
+
+  HalDisplayString ("\n*** The system has halted ***\n");
+  KeEnterKernelDebugger ();
+}
+
+
+VOID STDCALL
+HalProcessorIdle(VOID)
+{
+#if 1
+  Ki386EnableInterrupts();
+  Ki386HaltProcessor();
+#else
+
+#endif
+}
+
+ULONG FASTCALL
+HalSystemVectorDispatchEntry (
+	ULONG	Unknown1,
+	ULONG	Unknown2,
+	ULONG	Unknown3
+	)
+{
+  return 0;
+}
+
+
+VOID STDCALL
+KeFlushWriteBuffer(VOID)
+{
+  return;
+}
+
+/* EOF */

reactos/hal/halx86/generic
pci.c added at 1.2.2.1
diff -N pci.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pci.c	13 Dec 2004 16:18:23 -0000	1.2.2.1
@@ -0,0 +1,816 @@
+/* $Id: pci.c,v 1.2.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/pci.c
+ * PURPOSE:         Interfaces to the PCI bus
+ * PROGRAMMER:      David Welch (welch@mcmail.com)
+ *                  Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  05/06/1998: Created
+ *                  17/08/2000: Added preliminary pci bus scanner
+ *                  13/06/2001: Implemented access to pci configuration space
+ */
+
+/*
+ * NOTES: Sections copied from the Linux pci support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* MACROS ******************************************************************/
+
+/* FIXME These are also defined in drivers/bus/pci/pcidef.h.
+   Maybe put PCI definitions in a central include file??? */
+
+/* access type 1 macros */
+#define CONFIG_CMD(bus, dev_fn, where) \
+	(0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
+
+/* access type 2 macros */
+#define IOADDR(dev_fn, where) \
+	(0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
+#define FUNC(dev_fn) \
+	((((dev_fn) & 0xE0) >> 4) | 0xf0)
+
+#define  PCI_BASE_ADDRESS_SPACE	0x01	/* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define  PCI_BASE_ADDRESS_MEM_TYPE_32	0x00	/* 32 bit address */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_1M	0x02	/* Below 1M [obsolete] */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
+#define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
+#define  PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
+#define  PCI_BASE_ADDRESS_IO_MASK	(~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+
+/* GLOBALS ******************************************************************/
+
+#define TAG_PCI  TAG('P', 'C', 'I', 'H')
+
+static ULONG BusConfigType = 0;  /* undetermined config type */
+static KSPIN_LOCK PciLock;
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+ReadPciConfigUchar(UCHAR Bus,
+		   UCHAR Slot,
+		   UCHAR Offset,
+		   PUCHAR Value)
+{
+   KIRQL oldIrql;
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	*Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	*Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUshort(UCHAR Bus,
+		    UCHAR Slot,
+		    UCHAR Offset,
+		    PUSHORT Value)
+{
+   KIRQL oldIrql;
+
+   if ((Offset & 1) != 0)
+     {
+	return STATUS_INVALID_PARAMETER;
+     }
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	*Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	*Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUlong(UCHAR Bus,
+		   UCHAR Slot,
+		   UCHAR Offset,
+		   PULONG Value)
+{
+   KIRQL oldIrql;
+
+   if ((Offset & 3) != 0)
+     {
+	return STATUS_INVALID_PARAMETER;
+     }
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	*Value = READ_PORT_ULONG((PULONG)0xCFC);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	*Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUchar(UCHAR Bus,
+		    UCHAR Slot,
+		    UCHAR Offset,
+		    UCHAR Value)
+{
+   KIRQL oldIrql;
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUshort(UCHAR Bus,
+		     UCHAR Slot,
+		     UCHAR Offset,
+		     USHORT Value)
+{
+   KIRQL oldIrql;
+
+   if ((Offset & 1) != 0)
+     {
+	return  STATUS_INVALID_PARAMETER;
+     }
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUlong(UCHAR Bus,
+		    UCHAR Slot,
+		    UCHAR Offset,
+		    ULONG Value)
+{
+   KIRQL oldIrql;
+
+   if ((Offset & 3) != 0)
+     {
+	return  STATUS_INVALID_PARAMETER;
+     }
+
+   switch (BusConfigType)
+     {
+     case 1:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+	WRITE_PORT_ULONG((PULONG)0xCFC, Value);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+
+     case 2:
+        KeAcquireSpinLock(&PciLock, &oldIrql);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+	WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+	WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
+	WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	return STATUS_SUCCESS;
+     }
+   return STATUS_UNSUCCESSFUL;
+}
+
+
+static ULONG STDCALL
+HalpGetPciData(PBUS_HANDLER BusHandler,
+	       ULONG BusNumber,
+	       ULONG SlotNumber,
+	       PVOID Buffer,
+	       ULONG Offset,
+	       ULONG Length)
+{
+   PVOID Ptr = Buffer;
+   ULONG Address = Offset;
+   ULONG Len = Length;
+   ULONG Vendor;
+   UCHAR HeaderType;
+
+   DPRINT("HalpGetPciData() called.\n");
+   DPRINT("  BusNumber %lu\n", BusNumber);
+   DPRINT("  SlotNumber %lu\n", SlotNumber);
+   DPRINT("  Offset 0x%lx\n", Offset);
+   DPRINT("  Length 0x%lx\n", Length);
+
+   if ((Length == 0) || (BusConfigType == 0))
+     return 0;
+
+   ReadPciConfigUlong((UCHAR)BusNumber,
+		      (UCHAR)(SlotNumber & 0x1F),
+		      0x00,
+		      &Vendor);
+   /* some broken boards return 0 if a slot is empty: */
+   if (Vendor == 0xFFFFFFFF || Vendor == 0)
+   {
+     if (BusNumber == 0 && Offset == 0 && Length >= 2)
+     {
+	*(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+	return 2;
+     }
+     return 0;
+   }
+
+   /* 0E=PCI_HEADER_TYPE */
+   ReadPciConfigUchar((UCHAR)BusNumber,
+		      (UCHAR)(SlotNumber & 0x1F),
+		      0x0E,
+		      &HeaderType);
+   if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+   {
+     if (Offset == 0 && Length >= 2)
+     {
+	*(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+	return 2;
+     }
+     return 0;
+   }
+   ReadPciConfigUlong((UCHAR)BusNumber,
+		      (UCHAR)SlotNumber,
+		      0x00,
+		      &Vendor);
+   /* some broken boards return 0 if a slot is empty: */
+   if (Vendor == 0xFFFFFFFF || Vendor == 0)
+   {
+     if (BusNumber == 0 && Offset == 0 && Length >= 2)
+     {
+	*(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+	return 2;
+     }
+     return 0;
+   }
+
+   if ((Address & 1) && (Len >= 1))
+     {
+	ReadPciConfigUchar((UCHAR)BusNumber,
+			   (UCHAR)SlotNumber,
+			   (UCHAR)Address,
+			   Ptr);
+	Ptr = (char*)Ptr + 1;
+	Address++;
+	Len--;
+     }
+
+   if ((Address & 2) && (Len >= 2))
+     {
+	ReadPciConfigUshort((UCHAR)BusNumber,
+			    (UCHAR)SlotNumber,
+			    (UCHAR)Address,
+			    Ptr);
+	Ptr = (char*)Ptr + 2;
+	Address += 2;
+	Len -= 2;
+     }
+
+   while (Len >= 4)
+     {
+	ReadPciConfigUlong((UCHAR)BusNumber,
+			   (UCHAR)SlotNumber,
+			   (UCHAR)Address,
+			   Ptr);
+	Ptr = (char*)Ptr + 4;
+	Address += 4;
+	Len -= 4;
+     }
+
+   if (Len >= 2)
+     {
+	ReadPciConfigUshort((UCHAR)BusNumber,
+			    (UCHAR)SlotNumber,
+			    (UCHAR)Address,
+			    Ptr);
+	Ptr = (char*)Ptr + 2;
+	Address += 2;
+	Len -= 2;
+     }
+
+   if (Len >= 1)
+     {
+	ReadPciConfigUchar((UCHAR)BusNumber,
+			   (UCHAR)SlotNumber,
+			   (UCHAR)Address,
+			   Ptr);
+	Ptr = (char*)Ptr + 1;
+	Address++;
+	Len--;
+     }
+
+   return Length - Len;
+}
+
+
+static ULONG STDCALL
+HalpSetPciData(PBUS_HANDLER BusHandler,
+	       ULONG BusNumber,
+	       ULONG SlotNumber,
+	       PVOID Buffer,
+	       ULONG Offset,
+	       ULONG Length)
+{
+   PVOID Ptr = Buffer;
+   ULONG Address = Offset;
+   ULONG Len = Length;
+   ULONG Vendor;
+   UCHAR HeaderType;
+
+   DPRINT("HalpSetPciData() called.\n");
+   DPRINT("  BusNumber %lu\n", BusNumber);
+   DPRINT("  SlotNumber %lu\n", SlotNumber);
+   DPRINT("  Offset 0x%lx\n", Offset);
+   DPRINT("  Length 0x%lx\n", Length);
+
+   if ((Length == 0) || (BusConfigType == 0))
+     return 0;
+
+   ReadPciConfigUlong((UCHAR)BusNumber,
+		      (UCHAR)(SlotNumber & 0x1F),
+		      0x00,
+		      &Vendor);
+   /* some broken boards return 0 if a slot is empty: */
+   if (Vendor == 0xFFFFFFFF || Vendor == 0)
+     return 0;
+
+
+   /* 0E=PCI_HEADER_TYPE */
+   ReadPciConfigUchar((UCHAR)BusNumber,
+		      (UCHAR)(SlotNumber & 0x1F),
+		      0x0E,
+		      &HeaderType);
+   if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+     return 0;
+
+   ReadPciConfigUlong((UCHAR)BusNumber,
+		      (UCHAR)SlotNumber,
+		      0x00,
+		      &Vendor);
+   /* some broken boards return 0 if a slot is empty: */
+   if (Vendor == 0xFFFFFFFF || Vendor == 0)
+     return 0;
+
+   if ((Address & 1) && (Len >= 1))
+     {
+	WritePciConfigUchar((UCHAR)BusNumber,
+			    (UCHAR)SlotNumber,
+			    (UCHAR)Address,
+			    *(PUCHAR)Ptr);
+	Ptr = (char*)Ptr + 1;
+	Address++;
+	Len--;
+     }
+
+   if ((Address & 2) && (Len >= 2))
+     {
+	WritePciConfigUshort((UCHAR)BusNumber,
+			     (UCHAR)SlotNumber,
+			     (UCHAR)Address,
+			     *(PUSHORT)Ptr);
+	Ptr = (char*)Ptr + 2;
+	Address += 2;
+	Len -= 2;
+     }
+
+   while (Len >= 4)
+     {
+	WritePciConfigUlong((UCHAR)BusNumber,
+			    (UCHAR)SlotNumber,
+			    (UCHAR)Address,
+			    *(PULONG)Ptr);
+	Ptr = (char*)Ptr + 4;
+	Address += 4;
+	Len -= 4;
+     }
+
+   if (Len >= 2)
+     {
+	WritePciConfigUshort((UCHAR)BusNumber,
+			     (UCHAR)SlotNumber,
+			     (UCHAR)Address,
+			     *(PUSHORT)Ptr);
+	Ptr = (char*)Ptr + 2;
+	Address += 2;
+	Len -= 2;
+     }
+
+   if (Len >= 1)
+     {
+	WritePciConfigUchar((UCHAR)BusNumber,
+			    (UCHAR)SlotNumber,
+			    (UCHAR)Address,
+			    *(PUCHAR)Ptr);
+	Ptr = (char*)Ptr + 1;
+	Address++;
+	Len--;
+     }
+
+   return Length - Len;
+}
+
+
+static ULONG
+GetBusConfigType(VOID)
+{
+   ULONG Value;
+   KIRQL oldIrql;
+
+   DPRINT("GetBusConfigType() called\n");
+
+   KeAcquireSpinLock(&PciLock, &oldIrql);
+ 
+   DPRINT("Checking configuration type 1:");
+   WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
+   Value = READ_PORT_ULONG((PULONG)0xCF8);
+   WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
+   if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
+     {
+	WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	DPRINT("  Success!\n");
+	return 1;
+     }
+   WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+   DPRINT("  Unsuccessful!\n");
+
+   DPRINT("Checking configuration type 2:");
+   WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
+   WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
+   WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
+   if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
+       READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
+     {
+	KeReleaseSpinLock(&PciLock, oldIrql);
+	DPRINT("  Success!\n");
+	return 2;
+     }
+   KeReleaseSpinLock(&PciLock, oldIrql);
+   DPRINT("  Unsuccessful!\n");
+
+   DPRINT("No pci bus found!\n");
+   return 0;
+}
+
+
+static ULONG STDCALL
+HalpGetPciInterruptVector(PVOID BusHandler,
+			  ULONG BusNumber,
+			  ULONG BusInterruptLevel,
+			  ULONG BusInterruptVector,
+			  PKIRQL Irql,
+			  PKAFFINITY Affinity)
+{
+  ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+  *Irql = VECTOR2IRQL(Vector);
+  *Affinity = 0xFFFFFFFF;
+  return Vector;
+}
+
+static BOOLEAN STDCALL
+HalpTranslatePciAddress(PBUS_HANDLER BusHandler,
+			ULONG BusNumber,
+			PHYSICAL_ADDRESS BusAddress,
+			PULONG AddressSpace,
+			PPHYSICAL_ADDRESS TranslatedAddress)
+{
+   if (*AddressSpace == 0)
+     {
+	/* memory space */
+
+     }
+   else if (*AddressSpace == 1)
+     {
+	/* io space */
+
+     }
+   else
+     {
+	/* other */
+	return FALSE;
+     }
+
+   TranslatedAddress->QuadPart = BusAddress.QuadPart;
+
+   return TRUE;
+}
+
+/*
+ * Find the extent of a PCI decode..
+ */
+static ULONG STDCALL
+PciSize(ULONG Base, ULONG Mask)
+{
+  ULONG Size = Mask & Base;   /* Find the significant bits */
+  Size = Size & ~(Size - 1);  /* Get the lowest of them to find the decode size */
+  return Size;
+}
+
+static NTSTATUS STDCALL
+HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler,
+			   IN ULONG BusNumber,
+			   IN PUNICODE_STRING RegistryPath,
+			   IN PUNICODE_STRING DriverClassName,
+			   IN PDRIVER_OBJECT DriverObject,
+			   IN PDEVICE_OBJECT DeviceObject,
+			   IN ULONG SlotNumber,
+			   IN OUT PCM_RESOURCE_LIST *AllocatedResources)
+{
+  ULONG DataSize;
+  PCI_COMMON_CONFIG PciConfig;
+  UINT Address;
+  UINT ResourceCount;
+  ULONG Size[PCI_TYPE0_ADDRESSES];
+  NTSTATUS Status = STATUS_SUCCESS;
+  UCHAR Offset;
+  PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+
+  /* FIXME: Should handle 64-bit addresses */
+
+  DataSize = HalpGetPciData(BusHandler,
+                            BusNumber,
+                            SlotNumber,
+                            &PciConfig,
+                            0,
+                            PCI_COMMON_HDR_LENGTH);
+  if (PCI_COMMON_HDR_LENGTH != DataSize)
+    {
+      return STATUS_UNSUCCESSFUL;
+    }
+
+  /* Read the PCI configuration space for the device and store base address and
+     size information in temporary storage. Count the number of valid base addresses */
+  ResourceCount = 0;
+  for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+    {
+      if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
+	{
+	  PciConfig.u.type0.BaseAddresses[Address] = 0;
+	}
+      if (0 != PciConfig.u.type0.BaseAddresses[Address])
+	{
+	  ResourceCount++;
+          Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
+	  Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, 0xffffffff);
+	  if (! NT_SUCCESS(Status))
+	    {
+	      WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+                                  PciConfig.u.type0.BaseAddresses[Address]);
+	      return Status;
+	    }
+	  Status = ReadPciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber,
+	                              Offset, Size + Address);
+	  if (! NT_SUCCESS(Status))
+	    {
+	      WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+                                  PciConfig.u.type0.BaseAddresses[Address]);
+	      return Status;
+	    }
+	  Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+                                       PciConfig.u.type0.BaseAddresses[Address]);
+	  if (! NT_SUCCESS(Status))
+	    {
+	      return Status;
+	    }
+	}
+    }
+
+  if (0 != PciConfig.u.type0.InterruptLine)
+    {
+      ResourceCount++;
+    }
+
+  /* Allocate output buffer and initialize */
+  *AllocatedResources = ExAllocatePoolWithTag(PagedPool,
+                                              sizeof(CM_RESOURCE_LIST) +
+                                              (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
+                                              TAG_PCI);
+  if (NULL == *AllocatedResources)
+    {
+      return STATUS_NO_MEMORY;
+    }
+  (*AllocatedResources)->Count = 1;
+  (*AllocatedResources)->List[0].InterfaceType = PCIBus;
+  (*AllocatedResources)->List[0].BusNumber = BusNumber;
+  (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
+  (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
+  (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
+  Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
+
+  /* Store configuration information */
+  for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+    {
+      if (0 != PciConfig.u.type0.BaseAddresses[Address])
+	{
+	  if (PCI_BASE_ADDRESS_SPACE_MEMORY ==
+              (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+	    {
+	      Descriptor->Type = CmResourceTypeMemory;
+	      Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+	      Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;             /* FIXME Just a guess */
+	      Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK);
+	      Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK);
+	    }
+	  else if (PCI_BASE_ADDRESS_SPACE_IO ==
+                   (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+	    {
+	      Descriptor->Type = CmResourceTypePort;
+	      Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+	      Descriptor->Flags = CM_RESOURCE_PORT_IO;                       /* FIXME Just a guess */
+	      Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK;
+	      Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff);
+	    }
+	  else
+	    {
+	      ASSERT(FALSE);
+	      return STATUS_UNSUCCESSFUL;
+	    }
+	  Descriptor++;
+	}
+    }
+
+  if (0 != PciConfig.u.type0.InterruptLine)
+    {
+      Descriptor->Type = CmResourceTypeInterrupt;
+      Descriptor->ShareDisposition = CmResourceShareShared;          /* FIXME Just a guess */
+      Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;     /* FIXME Just a guess */
+      Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
+      Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
+      Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+      Descriptor++;
+    }
+
+  ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
+
+  /* FIXME: Should store the resources in the registry resource map */
+
+  return Status;
+}
+
+
+VOID
+HalpInitPciBus(VOID)
+{
+  PBUS_HANDLER BusHandler;
+
+  DPRINT("HalpInitPciBus() called.\n");
+
+  KeInitializeSpinLock (&PciLock);
+
+  BusConfigType = GetBusConfigType();
+  if (BusConfigType == 0)
+    return;
+
+  DPRINT("Bus configuration %lu used\n", BusConfigType);
+
+  /* pci bus (bus 0) handler */
+  BusHandler = HalpAllocateBusHandler(PCIBus,
+				      PCIConfiguration,
+				      0);
+  BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+  BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+  BusHandler->GetInterruptVector =
+    (pGetInterruptVector)HalpGetPciInterruptVector;
+  BusHandler->TranslateBusAddress = 
+    (pTranslateBusAddress)HalpTranslatePciAddress;
+//	BusHandler->AdjustResourceList =
+//		(pGetSetBusData)HalpAdjustPciResourceList;
+  BusHandler->AssignSlotResources =
+    (pAssignSlotResources)HalpAssignPciSlotResources;
+  if (NULL != HalpHooks.InitPciBus)
+    {
+      HalpHooks.InitPciBus(0, BusHandler);
+    }
+
+
+  /* agp bus (bus 1) handler */
+  BusHandler = HalpAllocateBusHandler(PCIBus,
+				      PCIConfiguration,
+				      1);
+  BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+  BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+  BusHandler->GetInterruptVector =
+    (pGetInterruptVector)HalpGetPciInterruptVector;
+  BusHandler->TranslateBusAddress = 
+    (pTranslateBusAddress)HalpTranslatePciAddress;
+//	BusHandler->AdjustResourceList =
+//		(pGetSetBusData)HalpAdjustPciResourceList;
+  BusHandler->AssignSlotResources =
+    (pAssignSlotResources)HalpAssignPciSlotResources;
+  if (NULL != HalpHooks.InitPciBus)
+    {
+      HalpHooks.InitPciBus(1, BusHandler);
+    }
+
+
+  /* PCI bus (bus 2) handler */
+  BusHandler = HalpAllocateBusHandler(PCIBus,
+				      PCIConfiguration,
+				      2);
+  BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+  BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+  BusHandler->GetInterruptVector =
+    (pGetInterruptVector)HalpGetPciInterruptVector;
+  BusHandler->TranslateBusAddress = 
+    (pTranslateBusAddress)HalpTranslatePciAddress;
+//	BusHandler->AdjustResourceList =
+//		(pGetSetBusData)HalpAdjustPciResourceList;
+  BusHandler->AssignSlotResources =
+    (pAssignSlotResources)HalpAssignPciSlotResources;
+  if (NULL != HalpHooks.InitPciBus)
+    {
+      HalpHooks.InitPciBus(2, BusHandler);
+    }
+
+  DPRINT("HalpInitPciBus() finished.\n");
+}
+
+/* EOF */

reactos/hal/halx86/generic
portio.c added at 1.1.2.1
diff -N portio.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ portio.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,342 @@
+/* $Id: portio.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/portio.c
+ * PURPOSE:         Port I/O functions
+ * PROGRAMMER:      Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ *                  Created 18/10/99
+ */
+
+#include <ddk/ntddk.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ *		Linus
+ */
+
+#if defined(__GNUC__)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
+#endif
+
+#elif defined(_MSC_VER)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm jmp 1f  __asm jmp 1f  1f:
+#else
+#define __SLOW_DOWN_IO __asm out 0x80, al
+#endif
+
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+VOID STDCALL
+READ_PORT_BUFFER_UCHAR (PUCHAR Port,
+                        PUCHAR Buffer,
+                        ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; insb\n\t" 
+			 : "=D" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov edi, Buffer
+		mov ecx, Count
+		cld
+		rep ins byte ptr[edi], dx
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_USHORT (PUSHORT Port,
+                         PUSHORT Buffer,
+                         ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; insw"
+			 : "=D" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov edi, Buffer
+		mov ecx, Count
+		cld
+		rep ins word ptr[edi], dx
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_ULONG (PULONG Port,
+                        PULONG Buffer,
+                        ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; insl"
+			 : "=D" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov edi, Buffer
+		mov ecx, Count
+		cld
+		rep ins dword ptr[edi], dx
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+UCHAR STDCALL
+READ_PORT_UCHAR (PUCHAR Port)
+{
+   UCHAR Value;
+
+#if defined(__GNUC__)
+   __asm__("inb %w1, %0\n\t"
+	   : "=a" (Value)
+	   : "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		in al, dx
+		mov Value, al
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+   SLOW_DOWN_IO;
+   return(Value);
+}
+
+USHORT STDCALL
+READ_PORT_USHORT (PUSHORT Port)
+{
+   USHORT Value;
+
+#if defined(__GNUC__)
+   __asm__("inw %w1, %0\n\t"
+	   : "=a" (Value)
+	   : "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		in ax, dx
+		mov Value, ax
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+   SLOW_DOWN_IO;
+   return(Value);
+}
+
+ULONG STDCALL
+READ_PORT_ULONG (PULONG Port)
+{
+   ULONG Value;
+
+#if defined(__GNUC__)
+   __asm__("inl %w1, %0\n\t"
+	   : "=a" (Value)
+	   : "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		in eax, dx
+		mov Value, eax
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+   SLOW_DOWN_IO;
+   return(Value);
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
+                         PUCHAR Buffer,
+                         ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; outsb" 
+			 : "=S" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov esi, Buffer
+		mov ecx, Count
+		cld
+		rep outs
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
+                          PUSHORT Buffer,
+                          ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; outsw"
+			 : "=S" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov esi, Buffer
+		mov ecx, Count
+		cld
+		rep outsw
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_ULONG (PULONG Port,
+                         PULONG Buffer,
+                         ULONG Count)
+{
+#if defined(__GNUC__)
+   __asm__ __volatile__ ("cld ; rep ; outsl" 
+			 : "=S" (Buffer), "=c" (Count) 
+			 : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov esi, Buffer
+		mov ecx, Count
+		cld
+		rep outsd
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_UCHAR (PUCHAR Port,
+                  UCHAR Value)
+{
+#if defined(__GNUC__)
+   __asm__("outb %0, %w1\n\t"
+	   : 
+	   : "a" (Value),
+	     "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov al, Value
+		out dx,al
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+   SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_USHORT (PUSHORT Port,
+                   USHORT Value)
+{
+#if defined(__GNUC__)
+   __asm__("outw %0, %w1\n\t"
+	   : 
+	   : "a" (Value),
+	     "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov ax, Value
+		out dx,ax
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+   SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_ULONG (PULONG Port,
+                  ULONG Value)
+{
+#if defined(__GNUC__)
+   __asm__("outl %0, %w1\n\t"
+	   : 
+	   : "a" (Value),
+	     "d" (Port));
+#elif defined(_MSC_VER)
+	__asm
+	{
+		mov edx, Port
+		mov eax, Value
+		out dx,eax
+	}
+#else
+#error Unknown compiler for inline assembler
+#endif
+   SLOW_DOWN_IO;
+}
+
+/* EOF */

reactos/hal/halx86/generic
processor.c added at 1.1.2.1
diff -N processor.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ processor.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,50 @@
+/* $Id: processor.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            hal/halx86/generic/processor.c
+ * PURPOSE:         Intel MultiProcessor specification support
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
+ *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:           Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ *     22/05/1998  DW   Created
+ *     12/04/2001  CSH  Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+		       PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
+{
+  DPRINT("HalInitializeProcessor(%x %x)\n", ProcessorNumber, LoaderBlock);
+}
+
+BOOLEAN STDCALL
+HalAllProcessorsStarted (VOID)
+{
+  DPRINT("HalAllProcessorsStarted()\n");
+
+  return TRUE;
+}
+
+BOOLEAN STDCALL 
+HalStartNextProcessor(ULONG Unknown1,
+		      ULONG ProcessorStack)
+{
+  DPRINT("HalStartNextProcessor(%x %x)\n", ProcessorNumber, ProcessorStack);
+
+  return TRUE;
+}
+
+/* EOF */

reactos/hal/halx86/generic
pwroff.c added at 1.1.2.1
diff -N pwroff.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pwroff.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,121 @@
+/* $Id: pwroff.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * FILE       : reactos/hal/x86/apm.c
+ * DESCRIPTION: Turn CPU off...
+ * PROJECT    : ReactOS Operating System
+ * AUTHOR     : D. Lindauer (July 11 1997)
+ * NOTE       : This program is public domain
+ * REVISIONS  :
+ * 	1999-12-26
+ */
+
+#define APM_FUNCTION_AVAILABLE	0x5300
+#define APM_FUNCTION_CONNREAL	0x5301
+#define APM_FUNCTION_POWEROFF	0x5307
+#define APM_FUNCTION_ENABLECPU	0x530d
+#define APM_FUNCTION_ENABLEAPM	0x530e
+
+#define APM_DEVICE_BIOS 	0
+#define APM_DEVICE_ALL		1
+
+#define APM_MODE_DISABLE	0
+#define APM_MODE_ENABLE		1
+
+
+
+#if defined(__GNUC__)
+
+nopm	db	'No power management functionality',10,13,'$'
+errmsg	db	'Power management error',10,13,'$'
+wrongver db	'Need APM version 1.1 or better',10,13,'$'
+;
+; Entry point
+;
+go:
+	mov	dx,offset nopm
+	jc	error
+	cmp	ax,101h			; See if version 1.1 or greater
+	mov	dx,offset wrongver
+	jc	error
+	
+	mov	[ver],ax
+	mov	ax,5301h		; Do a real mode connection
+	mov	bx,0			; device = BIOS
+	int	15h
+	jnc	noconerr
+	
+	cmp	ah,2			; Pass if already connected
+	mov	dx,offset errmsg	; else error
+	jnz	error
+noconerr:
+	mov	ax,530eh		; Enable latest version of APM
+	mov	bx,0			; device = BIOS
+	mov	cx,[ver]		; version
+	int	15h
+	mov	dx,offset errmsg
+	jc	error
+	
+	mov	ax,530dh		; Now engage and enable CPU management
+	mov	bx,1			; device = all
+	mov	cx,1			; enable
+	int	15h
+	mov	dx,offset errmsg
+	jc	error
+	
+	mov	ax,530fh
+	mov	bx,1			; device = ALL
+	mov	cx,1			; enable
+	int	15h
+	mov	dx,offset errmsg
+	jc	error
+
+	mov	dx,offset errmsg
+error:
+	call	print
+	mov	ax,4c01h
+	int	21h
+	int 3
+	end start
+
+
+BOOLEAN
+ApmCall (
+	DWORD	Function,
+	DWORD	Device,
+	DWORD	Mode
+	)
+{
+	/* AX <== Function */
+	/* BX <== Device */
+	/* CX <== Mode */
+	__asm__("int 21\n"); /* 0x15 */
+}
+
+#elif defined(_MSC_VER)
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+BOOLEAN
+HalPowerOff (VOID)
+{
+	ApmCall (
+		APM_FUNCTION_AVAILABLE,
+		APM_DEVICE_BIOS,
+		0
+		);
+	ApmCall (
+		APM_FUNCTION_ENABLEAPM,
+		);
+	/* Shutdown CPU */
+	ApmCall (
+		APM_FUNCTION_POWEROFF,
+		APM_DEVICE_ALL,
+		3
+		);
+	return TRUE;
+}
+
+
+/* EOF */

reactos/hal/halx86/generic
reboot.c added at 1.1.2.1
diff -N reboot.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ reboot.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,72 @@
+/* $Id: reboot.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/reboot.c
+ * PURPOSE:         Reboot functions.
+ * PROGRAMMER:      Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ *                  Created 11/10/99
+ */
+
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+
+static VOID
+HalReboot (VOID)
+{
+    char data;
+    extern PVOID HalpZeroPageMapping;
+
+    /* enable warm reboot */
+    ((PUCHAR)HalpZeroPageMapping)[0x472] = 0x34;
+    ((PUCHAR)HalpZeroPageMapping)[0x473] = 0x12;
+
+    /* disable interrupts */
+    Ki386DisableInterrupts();
+
+
+    /* disable periodic interrupt (RTC) */
+    WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0b);
+    data = READ_PORT_UCHAR((PUCHAR)0x71);
+    WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)(data & 0xbf));
+
+    /* */
+    WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0a);
+    data = READ_PORT_UCHAR((PUCHAR)0x71);
+    WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)((data & 0xf0) | 0x06));
+
+    /* */
+    WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
+
+    /* generate RESET signal via keyboard controller */
+    WRITE_PORT_UCHAR((PUCHAR)0x64, 0xfe);
+
+    /* stop the processor */
+#if 1
+    Ki386HaltProcessor();
+    for(;;);
+#endif   
+}
+
+
+VOID STDCALL
+HalReturnToFirmware (
+	ULONG	Action
+	)
+{
+    if (Action == FIRMWARE_HALT)
+    {
+        DbgPrint ("HalReturnToFirmware called!\n");
+        DbgBreakPoint ();
+    }
+    else if (Action == FIRMWARE_REBOOT)
+    {
+        HalReleaseDisplayOwnership();
+        HalReboot ();
+    }
+}
+
+/* EOF */

reactos/hal/halx86/generic
resource.c added at 1.1.2.1
diff -N resource.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ resource.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,32 @@
+/* $Id: resource.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:             See COPYING in the top level directory
+ * PROJECT:               ReactOS kernel
+ * FILE:                  hal/halx86/generic/resource.c
+ * PURPOSE:               Miscellaneous resource functions
+ * PROGRAMMER:            Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+  /*
+   * FIXME: Report all resources used by hal.
+   *        Calls IoReportHalResourceUsage()
+   */
+
+  /* Initialize PCI bus. */
+  HalpInitPciBus ();
+}
+
+/* EOF */

reactos/hal/halx86/generic
spinlock.c added at 1.1.2.1
diff -N spinlock.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ spinlock.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,101 @@
+/* $Id: spinlock.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/spinlock.c
+ * PURPOSE:         Implements spinlocks
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
+ *                  Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  09/06/2000 Created
+ */
+
+/*
+ * NOTE: On a uniprocessor machine spinlocks are implemented by raising
+ * the irq level
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID STDCALL
+KeAcquireSpinLock (
+	PKSPIN_LOCK	SpinLock,
+	PKIRQL		OldIrql
+	)
+/*
+ * FUNCTION: Acquires a spinlock
+ * ARGUMENTS:
+ *         SpinLock = Spinlock to acquire
+ *         OldIrql (OUT) = Caller supplied storage for the previous irql
+ */
+{
+  *OldIrql = KfAcquireSpinLock(SpinLock);
+}
+
+KIRQL FASTCALL
+KeAcquireSpinLockRaiseToSynch (
+	PKSPIN_LOCK	SpinLock
+	)
+{
+  KIRQL OldIrql;
+
+  OldIrql = KfRaiseIrql(SYNCH_LEVEL);
+  KiAcquireSpinLock(SpinLock);
+
+  return OldIrql;
+}
+
+VOID STDCALL
+KeReleaseSpinLock (
+	PKSPIN_LOCK	SpinLock,
+	KIRQL		NewIrql
+	)
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ *        SpinLock = Spinlock to release
+ *        NewIrql = Irql level before acquiring the spinlock
+ */
+{
+   KfReleaseSpinLock(SpinLock, NewIrql);
+}
+
+KIRQL FASTCALL
+KfAcquireSpinLock (
+	PKSPIN_LOCK	SpinLock
+	)
+{
+   KIRQL OldIrql;
+
+   ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+   
+   OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
+   KiAcquireSpinLock(SpinLock);
+
+   return OldIrql;
+}
+
+VOID FASTCALL
+KfReleaseSpinLock (
+	PKSPIN_LOCK	SpinLock,
+	KIRQL		NewIrql
+	)
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ *        SpinLock = Spinlock to release
+ *        NewIrql = Irql level before acquiring the spinlock
+ */
+{
+   ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL || KeGetCurrentIrql() == SYNCH_LEVEL);
+   KiReleaseSpinLock(SpinLock);
+   KfLowerIrql(NewIrql);
+}
+
+/* EOF */

reactos/hal/halx86/generic
sysbus.c added at 1.1.2.1
diff -N sysbus.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sysbus.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,69 @@
+/* $Id: sysbus.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/sysbus.c
+ * PURPOSE:         System bus handler functions
+ * PROGRAMMER:      Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  09/04/2000 Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetSystemInterruptVector(PVOID BusHandler,
+			     ULONG BusNumber,
+			     ULONG BusInterruptLevel,
+			     ULONG BusInterruptVector,
+			     PKIRQL Irql,
+			     PKAFFINITY Affinity)
+{
+  ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+  *Irql = VECTOR2IRQL(Vector);
+  *Affinity = 0xFFFFFFFF;
+  return Vector;
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
+			      ULONG BusNumber,
+			      PHYSICAL_ADDRESS BusAddress,
+			      PULONG AddressSpace,
+			      PPHYSICAL_ADDRESS TranslatedAddress)
+{
+   ULONG BaseAddress = 0;
+
+   if (*AddressSpace == 0)
+     {
+	/* memory space */
+
+     }
+   else if (*AddressSpace == 1)
+     {
+	/* io space */
+
+     }
+   else
+     {
+	/* other */
+	return FALSE;
+     }
+
+   TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
+
+   return TRUE;
+}
+
+/* EOF */

reactos/hal/halx86/generic
sysinfo.c added at 1.1.2.1
diff -N sysinfo.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sysinfo.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,76 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/sysinfo.c
+ * PURPOSE:         Getting system information
+ * PROGRAMMER:      David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ *                  Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS STDCALL
+HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
+			   IN ULONG BufferSize,
+			   IN OUT PVOID Buffer,
+			   OUT PULONG ReturnedLength)
+{
+  ULONG DataLength;
+  NTSTATUS Status;
+
+  DPRINT1("HalpQuerySystemInformation() called\n");
+
+  *ReturnedLength = 0;
+
+  DataLength = 0;
+
+  switch(InformationClass)
+    {
+#if 0
+      case HalInstalledBusInformation:
+	Status = HalpQueryBusInformation(BufferSize,
+					 Buffer,
+					 ReturnedLength);
+	break;
+#endif
+
+      default:
+	DataLength = 0;
+	Status = STATUS_INVALID_LEVEL;
+	break;
+    }
+
+  if (DataLength != 0)
+    {
+      if (DataLength > BufferSize)
+	DataLength = BufferSize;
+
+//      RtlCopyMemory();
+
+      *ReturnedLength = DataLength;
+    }
+
+  return(Status);
+}
+
+
+#if 0
+NTSTATUS
+HalpSetSystemInformation(VOID)
+{
+   UNIMPLEMENTED;
+}
+#endif
+
+/* EOF */

reactos/hal/halx86/generic
time.c added at 1.1.2.1
diff -N time.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ time.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,359 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/time.c
+ * PURPOSE:         Getting time information
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <string.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* MACROS and CONSTANTS ******************************************************/
+
+/* macro BCD_INT : convert bcd to int */
+#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+
+/* macro INT_BCD : convert int to bcd */
+#define INT_BCD(int) (((int / 10) << 4) + (int % 10))
+
+
+#define RTC_REGISTER_A   0x0A
+#define   RTC_REG_A_UIP  0x80  /* Update In Progress bit */
+
+#define RTC_REGISTER_B   0x0B
+
+#define RTC_REGISTER_CENTURY   0x32
+
+/* GLOBALS ******************************************************************/
+
+static KSPIN_LOCK CmosLock = {0};
+
+/* FUNCTIONS *****************************************************************/
+
+
+static UCHAR
+HalpQueryCMOS(UCHAR Reg)
+{
+  UCHAR Val;
+  ULONG Flags;
+
+  Reg |= 0x80;
+
+  /* save flags and disable interrupts */
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+  Val = READ_PORT_UCHAR((PUCHAR)0x71);
+  WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+  
+  /* restore flags */
+  Ki386RestoreFlags(Flags);
+
+  return(Val);
+}
+
+
+static VOID
+HalpSetCMOS(UCHAR Reg,
+	    UCHAR Val)
+{
+  ULONG Flags;
+
+  Reg |= 0x80;
+
+  /* save flags and disable interrupts */
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+  WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
+  WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+  
+  /* restore flags */
+  Ki386RestoreFlags(Flags);
+}
+
+
+static UCHAR
+HalpQueryECMOS(USHORT Reg)
+{
+  UCHAR Val;
+  ULONG Flags;
+
+  /* save flags and disable interrupts */
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+  WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+  Val = READ_PORT_UCHAR((PUCHAR)0x76);
+  
+  /* restore flags */
+  Ki386RestoreFlags(Flags);
+
+  return(Val);
+}
+
+
+static VOID
+HalpSetECMOS(USHORT Reg,
+	     UCHAR Val)
+{
+  ULONG Flags;
+
+  /* save flags and disable interrupts */
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+  WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+  WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
+  
+  /* restore flags */
+  Ki386RestoreFlags(Flags);
+}
+
+
+VOID STDCALL
+HalQueryRealTimeClock(PTIME_FIELDS Time)
+{
+    KIRQL oldIrql;
+
+    KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+    /* check 'Update In Progress' bit */
+    while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+    Time->Second = BCD_INT(HalpQueryCMOS (0));
+    Time->Minute = BCD_INT(HalpQueryCMOS (2));
+    Time->Hour = BCD_INT(HalpQueryCMOS (4));
+    Time->Weekday = BCD_INT(HalpQueryCMOS (6));
+    Time->Day = BCD_INT(HalpQueryCMOS (7));
+    Time->Month = BCD_INT(HalpQueryCMOS (8));
+    Time->Year = BCD_INT(HalpQueryCMOS (9));
+
+    if (Time->Year > 80)
+        Time->Year += 1900;
+    else
+        Time->Year += 2000;
+
+#if 0
+    /* Century */
+    Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
+#endif
+
+    KeReleaseSpinLock(&CmosLock, oldIrql);
+
+#ifndef NDEBUG
+    DbgPrint ("HalQueryRealTimeClock() %d:%d:%d %d/%d/%d\n",
+              Time->Hour,
+              Time->Minute,
+              Time->Second,
+              Time->Day,
+              Time->Month,
+              Time->Year
+             );
+#endif
+
+    Time->Milliseconds = 0;
+}
+
+
+VOID STDCALL
+HalSetRealTimeClock(PTIME_FIELDS Time)
+{
+    KIRQL oldIrql;
+
+    KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+    /* check 'Update In Progress' bit */
+    while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+    HalpSetCMOS (0, (UCHAR)INT_BCD(Time->Second));
+    HalpSetCMOS (2, (UCHAR)INT_BCD(Time->Minute));
+    HalpSetCMOS (4, (UCHAR)INT_BCD(Time->Hour));
+    HalpSetCMOS (6, (UCHAR)INT_BCD(Time->Weekday));
+    HalpSetCMOS (7, (UCHAR)INT_BCD(Time->Day));
+    HalpSetCMOS (8, (UCHAR)INT_BCD(Time->Month));
+    HalpSetCMOS (9, (UCHAR)INT_BCD(Time->Year % 100));
+
+#if 0
+    /* Century */
+    HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
+#endif
+    KeReleaseSpinLock(&CmosLock, oldIrql);
+
+}
+
+
+BOOLEAN STDCALL
+HalGetEnvironmentVariable(PCH Name,
+			  PCH Value,
+			  USHORT ValueLength)
+{
+   KIRQL oldIrql;
+
+
+   if (_stricmp(Name, "LastKnownGood") != 0)
+     {
+	return FALSE;
+     }
+
+   KeAcquireSpinLock(&CmosLock, &oldIrql);
+   if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
+     {
+	strncpy(Value, "FALSE", ValueLength);
+     }
+   else
+     {
+	strncpy(Value, "TRUE", ValueLength);
+     }
+   KeReleaseSpinLock(&CmosLock, oldIrql);
+
+   return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalSetEnvironmentVariable(PCH Name,
+			  PCH Value)
+{
+  UCHAR Val;
+  KIRQL oldIrql;
+  BOOLEAN result = TRUE;
+
+  if (_stricmp(Name, "LastKnownGood") != 0)
+    return FALSE;
+
+  KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+  Val = HalpQueryCMOS(RTC_REGISTER_B);
+
+  if (_stricmp(Value, "TRUE") == 0)
+    HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val | 0x01));
+  else if (_stricmp(Value, "FALSE") == 0)
+    HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val & ~0x01));
+  else
+    result = FALSE;
+
+  KeReleaseSpinLock(&CmosLock, oldIrql);
+
+  return result;
+}
+
+
+ULONG STDCALL
+HalpGetCmosData(PBUS_HANDLER BusHandler,
+		ULONG BusNumber,
+		ULONG SlotNumber,
+		PVOID Buffer,
+		ULONG Offset,
+		ULONG Length)
+{
+  PUCHAR Ptr = Buffer;
+  ULONG Address = SlotNumber;
+  ULONG Len = Length;
+  KIRQL oldIrql;
+
+  DPRINT("HalpGetCmosData() called.\n");
+  DPRINT("  BusNumber %lu\n", BusNumber);
+  DPRINT("  SlotNumber %lu\n", SlotNumber);
+  DPRINT("  Offset 0x%lx\n", Offset);
+  DPRINT("  Length 0x%lx\n", Length);
+
+  if (Length == 0)
+    return 0;
+
+  if (BusNumber == 0)
+    {
+      /* CMOS */
+      KeAcquireSpinLock(&CmosLock, &oldIrql);
+      while ((Len > 0) && (Address < 0x100))
+	{
+	  *Ptr = HalpQueryCMOS((UCHAR)Address);
+	  Ptr = Ptr + 1;
+	  Address++;
+	  Len--;
+	}
+      KeReleaseSpinLock(&CmosLock, oldIrql);
+    }
+  else if (BusNumber == 1)
+    {
+      /* Extended CMOS */
+      KeAcquireSpinLock(&CmosLock, &oldIrql);
+      while ((Len > 0) && (Address < 0x1000))
+	{
+	  *Ptr = HalpQueryECMOS((USHORT)Address);
+	  Ptr = Ptr + 1;
+	  Address++;
+	  Len--;
+	}
+      KeReleaseSpinLock(&CmosLock, oldIrql);
+    }
+
+  return(Length - Len);
+}
+
+
+ULONG STDCALL
+HalpSetCmosData(PBUS_HANDLER BusHandler,
+		ULONG BusNumber,
+		ULONG SlotNumber,
+		PVOID Buffer,
+		ULONG Offset,
+		ULONG Length)
+{
+  PUCHAR Ptr = (PUCHAR)Buffer;
+  ULONG Address = SlotNumber;
+  ULONG Len = Length;
+  KIRQL oldIrql;
+
+  DPRINT("HalpSetCmosData() called.\n");
+  DPRINT("  BusNumber %lu\n", BusNumber);
+  DPRINT("  SlotNumber %lu\n", SlotNumber);
+  DPRINT("  Offset 0x%lx\n", Offset);
+  DPRINT("  Length 0x%lx\n", Length);
+
+  if (Length == 0)
+    return 0;
+
+  if (BusNumber == 0)
+    {
+      /* CMOS */
+      KeAcquireSpinLock(&CmosLock, &oldIrql);
+      while ((Len > 0) && (Address < 0x100))
+	{
+	  HalpSetCMOS((UCHAR)Address, *Ptr);
+	  Ptr = Ptr + 1;
+	  Address++;
+	  Len--;
+	}
+      KeReleaseSpinLock(&CmosLock, oldIrql);
+    }
+  else if (BusNumber == 1)
+    {
+      /* Extended CMOS */
+      KeAcquireSpinLock(&CmosLock, &oldIrql);
+      while ((Len > 0) && (Address < 0x1000))
+	{
+	  HalpSetECMOS((USHORT)Address, *Ptr);
+	  Ptr = Ptr + 1;
+	  Address++;
+	  Len--;
+	}
+      KeReleaseSpinLock(&CmosLock, oldIrql);
+    }
+
+  return(Length - Len);
+}
+
+/* EOF */

reactos/hal/halx86/generic
timer.c added at 1.1.2.1
diff -N timer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ timer.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,366 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2000 David Welch <welch@cwcom.net>
+ * Copyright (C) 1999 Gareth Owen <gaz@athene.co.uk>, Ramon von Handel
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * 
+ * This software 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 software 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 software; see the file COPYING. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.  
+ *
+ */
+/* $Id: timer.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * PROJECT:        ReactOS kernel
+ * FILE:           ntoskrnl/hal/x86/udelay.c
+ * PURPOSE:        Busy waiting
+ * PROGRAMMER:     David Welch (david.welch@seh.ox.ac.uk)
+ * UPDATE HISTORY:
+ *                 06/11/99 Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+static unsigned int delay_count = 1;
+
+#define 	TMR_CTRL	0x43	/*	I/O for control		*/
+#define		TMR_CNT0	0x40	/*	I/O for counter 0	*/
+#define		TMR_CNT1	0x41	/*	I/O for counter 1	*/
+#define		TMR_CNT2	0x42	/*	I/O for counter 2	*/
+
+#define		TMR_SC0		0	/*	Select channel 0 	*/
+#define		TMR_SC1		0x40	/*	Select channel 1 	*/
+#define		TMR_SC2		0x80	/*	Select channel 2 	*/
+
+#define		TMR_LOW		0x10	/*	RW low byte only 	*/
+#define		TMR_HIGH	0x20	/*	RW high byte only 	*/
+#define		TMR_BOTH	0x30	/*	RW both bytes 		*/
+
+#define		TMR_MD0		0	/*	Mode 0 			*/
+#define		TMR_MD1		0x2	/*	Mode 1 			*/
+#define		TMR_MD2		0x4	/*	Mode 2 			*/
+#define		TMR_MD3		0x6	/*	Mode 3 			*/
+#define		TMR_MD4		0x8	/*	Mode 4 			*/
+#define		TMR_MD5		0xA	/*	Mode 5 			*/
+
+#define		TMR_BCD		1	/*	BCD mode 		*/
+
+#define		TMR_LATCH	0	/*	Latch command 		*/
+
+#define		TMR_READ	0xF0	/*    Read command 		*/
+#define		TMR_CNT		0x20	/*    CNT bit  (Active low, subtract it) */
+#define		TMR_STAT	0x10	/*    Status bit  (Active low, subtract it) */
+#define		TMR_CH2		0x8	/*    Channel 2 bit 		*/
+#define		TMR_CH1		0x4	/*    Channel 1 bit 		*/
+#define		TMR_CH0		0x2	/*    Channel 0 bit 		*/
+
+#define MILLISEC        10                     /* Number of millisec between interrupts */
+#define HZ              (1000 / MILLISEC)      /* Number of interrupts per second */
+#define CLOCK_TICK_RATE 1193182                /* Clock frequency of the timer chip */
+#define LATCH           (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */
+#define PRECISION       8                      /* Number of bits to calibrate for delay loop */
+
+static BOOLEAN UdelayCalibrated = FALSE;
+
+/* FUNCTIONS **************************************************************/
+
+/*
+ * NOTE: This function MUST NOT be optimized by the compiler!
+ * If it is, it obviously will not delay AT ALL, and the system
+ * will appear completely frozen at boot since
+ * HalpCalibrateStallExecution will never return.
+ * There are three options to stop optimization:
+ * 1. Use a volatile automatic variable. Making it delay quite a bit
+ *    due to memory accesses, and keeping the code portable. However,
+ *    as this involves memory access it depends on both the CPU cache,
+ *    e.g. if the stack used is already in a cache line or not, and
+ *    whether or not we're MP. If MP, another CPU could (probably would)
+ *    also access RAM at the same time - making the delay imprecise.
+ * 2. Use compiler-specific #pragma's to disable optimization.
+ * 3. Use inline assembly, making it equally unportable as #2.
+ * For supported compilers we use inline assembler. For the others,
+ * portable plain C.
+ */
+VOID STDCALL
+__KeStallExecutionProcessor(ULONG Loops)
+{
+  if (!Loops)
+  {
+    return;
+  }
+#if defined(__GNUC__)
+  __asm__ __volatile__ (
+    "mov %0, %%eax\n"
+    "ROSL1: dec %%eax\n"
+    "jnz ROSL1" : : "d" (Loops));
+
+#elif defined(_MSC_VER)
+  __asm mov eax, Loops
+ROSL1:
+  __asm dec eax
+  __asm jnz ROSL1
+#else
+   volatile unsigned int target = Loops;
+   unsigned int i;
+   for (i=0; i<target;i++);
+#endif
+}
+
+VOID STDCALL KeStallExecutionProcessor(ULONG Microseconds)
+{
+   PKPCR Pcr = KeGetCurrentKPCR();
+
+   if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+   {
+      LARGE_INTEGER EndCount, CurrentCount;
+      Ki386RdTSC(EndCount);
+      EndCount.QuadPart += Microseconds * (ULONGLONG)Pcr->PrcbData.MHz;
+      do
+      {
+         Ki386RdTSC(CurrentCount);
+      }
+      while (CurrentCount.QuadPart < EndCount.QuadPart);
+   }
+   else
+   {
+      __KeStallExecutionProcessor((Pcr->StallScaleFactor*Microseconds)/1000);
+   }
+}
+
+static ULONG Read8254Timer(VOID)
+{
+  ULONG Count;
+  ULONG flags;
+
+  /* save flags and disable interrupts */
+  Ki386SaveFlags(flags);
+  Ki386DisableInterrupts();
+
+  WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_LATCH);
+  Count = READ_PORT_UCHAR((PUCHAR) TMR_CNT0);
+  Count |= READ_PORT_UCHAR((PUCHAR) TMR_CNT0) << 8;
+
+  /* restore flags */
+  Ki386RestoreFlags(flags);
+
+  return Count;
+}
+
+
+static 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);
+}
+
+VOID HalpCalibrateStallExecution(VOID)
+{
+  ULONG i;
+  ULONG calib_bit;
+  ULONG CurCount;
+  PKPCR Pcr;
+  LARGE_INTEGER StartCount, EndCount;
+
+  if (UdelayCalibrated)
+    {
+      return;
+    }
+
+  UdelayCalibrated = TRUE;
+  Pcr = KeGetCurrentKPCR();
+
+  /* Initialise timer interrupt with MILLISEC ms interval        */
+  WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_BOTH | TMR_MD2);  /* binary, mode 2, LSB/MSB, ch 0 */
+  WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH & 0xff); /* LSB */
+  WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH >> 8); /* MSB */
+
+  if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+  {
+      
+     WaitFor8254Wraparound();
+     Ki386RdTSC(StartCount);
+
+     WaitFor8254Wraparound();
+     Ki386RdTSC(EndCount);
+
+     Pcr->PrcbData.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000;
+     DPRINT("%dMHz\n", Pcr->PrcbData.MHz);
+     return;
+
+  }
+
+  DbgPrint("Calibrating delay loop... [");
+
+  /* Stage 1:  Coarse calibration					    */
+
+  WaitFor8254Wraparound();
+
+  delay_count = 1;
+
+  do
+    {
+      delay_count <<= 1;                  /* Next delay count to try */
+
+      WaitFor8254Wraparound();
+
+      __KeStallExecutionProcessor(delay_count);      /* Do the delay */
+
+      CurCount = Read8254Timer();
+    }
+  while (CurCount > LATCH / 2);
+
+  delay_count >>= 1;              /* Get bottom value for delay     */
+
+  /* Stage 2:  Fine calibration                                     */
+  DbgPrint("delay_count: %d", delay_count);
+
+  calib_bit = delay_count;        /* Which bit are we going to test */
+
+  for (i = 0; i < PRECISION; i++)
+    {
+      calib_bit >>= 1;            /* Next bit to calibrate          */
+      if (!calib_bit)
+	{
+	  break;                  /* If we have done all bits, stop */
+	}
+
+      delay_count |= calib_bit;   /* Set the bit in delay_count */
+
+      WaitFor8254Wraparound();
+
+      __KeStallExecutionProcessor(delay_count);      /* Do the delay */
+
+      CurCount = Read8254Timer();
+      if (CurCount <= LATCH / 2)   /* If a tick has passed, turn the */
+	{                          /* calibrated bit back off        */
+	  delay_count &= ~calib_bit;
+	}
+    }
+
+  /* We're finished:  Do the finishing touches                      */
+
+  delay_count /= (MILLISEC / 2);   /* Calculate delay_count for 1ms */
+
+  DbgPrint("]\n");
+  DbgPrint("delay_count: %d\n", delay_count);
+  DbgPrint("CPU speed: %d\n", delay_count / 250);
+#if 0
+  DbgPrint("About to start delay loop test\n");
+  DbgPrint("Waiting for five minutes...");
+  for (i = 0; i < (5*60*1000*20); i++)
+    {
+      KeStallExecutionProcessor(50);
+    }
+  DbgPrint("finished\n");
+  for(;;);
+#endif
+}
+
+
+VOID STDCALL
+HalCalibratePerformanceCounter(ULONG Count)
+{
+   ULONG flags;
+
+   /* save flags and disable interrupts */
+   Ki386SaveFlags(flags);
+   Ki386DisableInterrupts();
+
+   __KeStallExecutionProcessor(Count);
+
+   /* restore flags */
+   Ki386RestoreFlags(flags);
+}
+
+
+LARGE_INTEGER STDCALL
+KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
+/*
+ * FUNCTION: Queries the finest grained running count available in the system
+ * ARGUMENTS:
+ *         PerformanceFreq (OUT) = The routine stores the number of 
+ *                                 performance counter ticks per second here
+ * RETURNS: The number of performance counter ticks since boot
+ */
+{
+  PKPCR Pcr;
+  LARGE_INTEGER Value;
+  ULONG Flags;
+
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  Pcr = KeGetCurrentKPCR();
+
+  if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+  {
+     Ki386RestoreFlags(Flags);
+     if (NULL != PerformanceFreq)
+     {
+        PerformanceFreq->QuadPart = Pcr->PrcbData.MHz * (ULONGLONG)1000000;   
+     }
+     Ki386RdTSC(Value);
+  }
+  else
+  {
+     LARGE_INTEGER TicksOld;
+     LARGE_INTEGER TicksNew;
+     ULONG CountsLeft;
+
+     Ki386RestoreFlags(Flags);
+
+     if (NULL != PerformanceFreq)
+     {
+        PerformanceFreq->QuadPart = CLOCK_TICK_RATE;
+     }
+
+     do
+     {
+        KeQueryTickCount(&TicksOld);
+        CountsLeft = Read8254Timer();
+        Value.QuadPart = TicksOld.QuadPart * LATCH + (LATCH - CountsLeft);
+        KeQueryTickCount(&TicksNew);
+     }
+     while (TicksOld.QuadPart != TicksNew.QuadPart);
+  }
+  return Value;
+}
+
+/* EOF */

reactos/hal/halx86/mp
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map

reactos/hal/halx86/mp
Makefile added at 1.4.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:23 -0000	1.4.2.1
@@ -0,0 +1,90 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:23 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halmp
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DMP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DMP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+ifneq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+	adapter.o \
+	beep.o \
+	bus.o \
+	display.o \
+	dma.o \
+	drive.o \
+	enum.o \
+	fmutex.o \
+	halinit.o \
+	isa.o \
+	kdbg.o \
+	mca.o \
+	misc.o \
+	pci.o \
+	portio.o \
+	reboot.o \
+	spinlock.o \
+	sysbus.o \
+	sysinfo.o \
+	time.o \
+	timer.o
+
+MP_OBJECTS = \
+	apic.o \
+	halinit_mp.o \
+	ipi_mp.o \
+	mpsirql.o \
+	mpsboot.o \
+	mps.o \
+	processor_mp.o \
+	resource_mp.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(MP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF

reactos/hal/halx86/mp
apic.c added at 1.1.2.1
diff -N apic.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ apic.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,853 @@
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2004 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: apic.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS kernel
+ * FILE:        hal/halx86/apic.c
+ * PURPOSE:     
+ * PROGRAMMER:  
+ */
+
+#include <ddk/ntddk.h>
+#include <internal/i386/ps.h>
+
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+BOOLEAN VerifyLocalAPIC(VOID);
+VOID APICCalibrateTimer(ULONG CPU);
+
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
+
+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 */
+
+extern CHAR *APstart, *APend;
+extern VOID (*APflush)(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); \
+})
+
+#define BIOS_AREA    0x0
+#define COMMON_AREA  0x2000
+
+
+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];
+
+ULONG APICGetMaxLVT(VOID)
+{
+  ULONG tmp, ver, maxlvt;
+
+  tmp = APICRead(APIC_VER);
+  ver = GET_APIC_VERSION(tmp);
+  /* 82489DXs do not report # of LVT entries. */
+  maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
+
+  return maxlvt;
+}
+
+VOID APICClear(VOID)
+{
+  ULONG tmp, maxlvt;
+
+  maxlvt = APICGetMaxLVT();
+
+  /*
+   * Careful: we have to set masks only first to deassert
+   * any level-triggered sources.
+   */
+
+  if (maxlvt >= 3) 
+  {
+    tmp = ERROR_VECTOR;
+    APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
+  }
+
+  tmp = APICRead(APIC_LVTT);
+  APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
+
+  tmp = APICRead(APIC_LINT0);
+  APICWrite(APIC_LINT0, tmp | APIC_LVT_MASKED);
+
+  tmp = APICRead(APIC_LINT1);
+  APICWrite(APIC_LINT1, tmp | APIC_LVT_MASKED);
+
+  if (maxlvt >= 4) 
+  {
+    tmp = APICRead(APIC_LVTPC);
+    APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
+  }
+#if 0
+  if (maxlvt >= 5)
+  {
+    tmp = APICRead(APIC_LVTTHMR);
+    APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
+  }
+#endif
+  /*
+   * Clean APIC state for other OSs:
+   */
+  APICWrite(APIC_LVTT, APIC_LVT_MASKED);
+  APICWrite(APIC_LINT0, APIC_LVT_MASKED);
+  APICWrite(APIC_LINT1, APIC_LVT_MASKED);
+
+  if (maxlvt >= 3) 
+  {
+    APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
+  }
+
+  if (maxlvt >= 4) 
+  {
+    APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
+  }
+#if 0
+  if (maxlvt >= 5) 
+  {
+    APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
+  }
+#endif
+}
+
+/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
+VOID EnableSMPMode(VOID)
+{
+   /*
+    * Do not trust the local APIC being empty at bootup.
+    */
+   APICClear();
+
+   WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+   WRITE_PORT_UCHAR((PUCHAR)0x23, 0x01);
+}
+
+/* Disable symetric I/O mode ie. go to PIC mode */
+inline VOID DisableSMPMode(VOID)
+{
+   /*
+    * Put the board back into PIC mode (has an effect
+    * only on certain older boards).  Note that APIC
+    * interrupts, including IPIs, won't work beyond
+    * this point!  The only exception are INIT IPIs.
+    */
+   WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+   WRITE_PORT_UCHAR((PUCHAR)0x23, 0x00);
+}
+
+VOID DumpESR(VOID)
+{
+  ULONG tmp;
+
+  if (APICGetMaxLVT() > 3)
+  {
+    APICWrite(APIC_ESR, 0);
+  }
+  tmp = APICRead(APIC_ESR);
+  DbgPrint("ESR %08x\n", tmp);
+}
+
+
+VOID APICDisable(VOID)
+{
+  ULONG tmp;
+
+  APICClear();
+
+  /*
+   * Disable APIC (implies clearing of registers for 82489DX!).
+   */
+  tmp = APICRead(APIC_SIVR);
+  tmp &= ~APIC_SIVR_ENABLE;
+  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);
+}
+
+volatile inline ULONG _APICRead(ULONG Offset)
+{
+   PULONG p;
+
+   p = (PULONG)((ULONG)APICBase + Offset);
+   return *p;
+}
+
+#if 0
+inline VOID APICWrite(ULONG Offset,
+		      ULONG Value)
+{
+   PULONG p;
+
+   p = (PULONG)((ULONG)APICBase + Offset);
+
+   *p = Value;
+}
+#else
+inline VOID APICWrite(ULONG Offset,
+		      ULONG Value)
+{
+   PULONG p;
+   ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+   lastregw[CPU] = Offset;
+   lastvalw[CPU] = Value;
+
+   p = (PULONG)((ULONG)APICBase + Offset);
+
+   *p = Value;
+}
+#endif
+
+
+#if 0
+volatile inline ULONG APICRead(ULONG Offset)
+{
+   PULONG p;
+
+   p = (PULONG)((ULONG)APICBase + Offset);
+   return *p;
+}
+#else
+volatile inline ULONG APICRead(ULONG Offset)
+{
+   PULONG p;
+   ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+   lastregr[CPU] = Offset;
+   lastvalr[CPU] = 0;
+
+   p = (PULONG)((ULONG)APICBase + Offset);
+
+   lastvalr[CPU] = *p;
+   return lastvalr[CPU];
+}
+#endif
+
+inline VOID APICSendEOI(VOID)
+{
+  // Send the EOI
+  APICWrite(APIC_EOI, 0);
+}
+
+static VOID APICDumpBit(ULONG base)
+{
+	ULONG v, i, j;
+
+	DbgPrint("0123456789abcdef0123456789abcdef\n");
+	for (i = 0; i < 8; i++) 
+	{
+		v = APICRead(base + i*0x10);
+		for (j = 0; j < 32; j++) 
+		{
+			if (v & (1<<j))
+				DbgPrint("1");
+			else
+				DbgPrint("0");
+		}
+		DbgPrint("\n");
+	}
+}
+
+
+VOID APICDump(VOID)
+/*
+ * Dump the contents of the local APIC registers
+ */
+{
+  ULONG v, ver, maxlvt;
+  ULONG r1, r2, w1, w2;
+  ULONG CPU = ThisCPU();;
+
+
+
+  r1 = lastregr[CPU];
+  r2 = lastvalr[CPU];
+  w1 = lastregw[CPU];
+  w2 = lastvalw[CPU];
+
+  DbgPrint("\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
+  v = APICRead(APIC_ID);
+  DbgPrint("... ID     : %08x (%01x) ", v, GET_APIC_ID(v));
+  v = APICRead(APIC_VER);
+  DbgPrint("... VERSION: %08x\n", v);
+  ver = GET_APIC_VERSION(v);
+  maxlvt = APICGetMaxLVT();
+
+  v = APICRead(APIC_TPR);
+  DbgPrint("... TPR    : %08x (%02x)", v, v & ~0);
+
+  if (APIC_INTEGRATED(ver)) 
+  {
+     /* !82489DX */
+     v = APICRead(APIC_APR);
+     DbgPrint("... APR    : %08x (%02x)\n", v, v & ~0);
+     v = APICRead(APIC_PPR);
+     DbgPrint("... PPR    : %08x\n", v);
+  }
+
+  v = APICRead(APIC_EOI);
+  DbgPrint("... EOI    : %08x  !  ", v);
+  v = APICRead(APIC_LDR);
+  DbgPrint("... LDR    : %08x\n", v);
+  v = APICRead(APIC_DFR);
+  DbgPrint("... DFR    : %08x  !  ", v);
+  v = APICRead(APIC_SIVR);
+  DbgPrint("... SIVR   : %08x\n", v);
+
+  if (0)
+  {
+  	DbgPrint("... ISR field:\n");
+  	APICDumpBit(APIC_ISR);
+  	DbgPrint("... TMR field:\n");
+  	APICDumpBit(APIC_TMR);
+  	DbgPrint("... IRR field:\n");
+  	APICDumpBit(APIC_IRR);
+  }
+
+  if (APIC_INTEGRATED(ver)) 
+  {
+     /* !82489DX */
+     if (maxlvt > 3)		
+     {
+	/* Due to the Pentium erratum 3AP. */
+	APICWrite(APIC_ESR, 0);
+     }
+     v = APICRead(APIC_ESR);
+     DbgPrint("... ESR    : %08x\n", v);
+  }
+ 
+  v = APICRead(APIC_ICR0);
+  DbgPrint("... ICR0   : %08x  !  ", v);
+  v = APICRead(APIC_ICR1);
+  DbgPrint("... ICR1   : %08x  !  ", v);
+
+  v = APICRead(APIC_LVTT);
+  DbgPrint("... LVTT   : %08x\n", v);
+
+  if (maxlvt > 3) 
+  {
+     /* PC is LVT#4. */
+     v = APICRead(APIC_LVTPC);
+     DbgPrint("... LVTPC  : %08x  !  ", v);
+  }
+  v = APICRead(APIC_LINT0);
+  DbgPrint("... LINT0  : %08x  !  ", v);
+  v = APICRead(APIC_LINT1);
+  DbgPrint("... LINT1  : %08x\n", v);
+
+  if (maxlvt > 2) 
+  {
+     v = APICRead(APIC_LVT3);
+     DbgPrint("... LVT3   : %08x\n", v);
+  }
+
+  v = APICRead(APIC_ICRT);
+  DbgPrint("... ICRT   : %08x  !  ", v);
+  v = APICRead(APIC_CCRT);
+  DbgPrint("... CCCT   : %08x  !  ", v);
+  v = APICRead(APIC_TDCR);
+  DbgPrint("... TDCR   : %08x\n", v);
+  DbgPrint("\n");
+  DbgPrint("Last register read (offset): 0x%08X\n", r1);
+  DbgPrint("Last register read (value): 0x%08X\n", r2);
+  DbgPrint("Last register written (offset): 0x%08X\n", w1);
+  DbgPrint("Last register written (value): 0x%08X\n", w2);
+  DbgPrint("\n");
+}
+
+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);
+   APICWrite(APIC_VER, reg0 ^ APIC_VER_MASK);
+   reg1 = APICRead(APIC_VER);
+   DPRINT1("Getting VERSION: %x\n", reg1);
+
+   /*
+    * The two version reads above should print the same
+    * numbers.  If the second one is different, then we
+    * poke at a non-APIC.
+    */
+
+   if (reg1 != reg0)
+   {
+      return FALSE;
+   }
+
+   /*
+    * Check if the version looks reasonably.
+    */
+   reg1 = GET_APIC_VERSION(reg0);
+   if (reg1 == 0x00 || reg1 == 0xff)
+   {
+      return FALSE;
+   }
+   reg1 = APICGetMaxLVT();
+   if (reg1 < 0x02 || reg1 == 0xff)
+   {
+      return FALSE;
+   }
+
+   /*
+    * The ID register is read/write in a real APIC.
+    */
+   reg0 = APICRead(APIC_ID);
+   DPRINT1("Getting ID: %x\n", reg0);
+   APICWrite(APIC_ID, reg0 ^ APIC_ID_MASK);
+   reg1 = APICRead(APIC_ID);
+   DPRINT1("Getting ID: %x\n", reg1);
+   APICWrite(APIC_ID, reg0);
+   if (reg1 != (reg0 ^ APIC_ID_MASK))
+   {
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+VOID APICSendIPI(ULONG Target, ULONG Mode)
+{
+   ULONG tmp, i, flags;
+
+   /* save flags and disable interrupts */
+   Ki386SaveFlags(flags);
+   Ki386DisableInterrupts();
+
+   /* Wait up to 100ms for the APIC to become ready */
+   for (i = 0; i < 10000; i++) 
+   {
+      tmp = APICRead(APIC_ICR0);
+      /* Check Delivery Status */
+      if ((tmp & APIC_ICR0_DS) == 0)
+         break;
+      KeStallExecutionProcessor(10);
+   }
+
+   if (i == 10000) 
+   {
+      DPRINT1("CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
+   }
+
+   /* Setup the APIC to deliver the IPI */
+   DPRINT("%08x %x\n", SET_APIC_DEST_FIELD(Target), Target);
+   APICWrite(APIC_ICR1, SET_APIC_DEST_FIELD(Target));
+
+   if (Target == APIC_TARGET_SELF) 
+   {
+      Mode |= APIC_ICR0_DESTS_SELF;
+   } 
+   else if (Target == APIC_TARGET_ALL) 
+   {
+      Mode |= APIC_ICR0_DESTS_ALL;
+   } 
+   else if (Target == APIC_TARGET_ALL_BUT_SELF) 
+   {
+      Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
+   } 
+   else 
+   {
+      Mode |= APIC_ICR0_DESTS_FIELD;
+   }
+
+   /* Now, fire off the IPI */
+   APICWrite(APIC_ICR0, Mode);
+
+   /* Wait up to 100ms for the APIC to become ready */
+   for (i = 0; i < 10000; i++) 
+   {
+      tmp = APICRead(APIC_ICR0);
+      /* Check Delivery Status */
+      if ((tmp & APIC_ICR0_DS) == 0)
+         break;
+      KeStallExecutionProcessor(10);
+   }
+
+   if (i == 10000) 
+   {
+      DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
+   }
+   Ki386RestoreFlags(flags);
+}
+
+VOID APICSetup(VOID)
+{
+   ULONG CPU, tmp;
+
+   CPU = ThisCPU();
+
+//   APICDump();
+  
+   DPRINT1("CPU%d:\n", CPU);
+   DPRINT1("  Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+   DPRINT1("  Logical APIC id:  %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+   DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+
+   /*
+    * Intel recommends to set DFR, LDR and TPR before enabling
+    * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+    * document number 292116).  So here it goes...
+    */
+
+   /*
+    * Put the APIC into flat delivery mode.
+    * Must be "all ones" explicitly for 82489DX.
+    */
+   APICWrite(APIC_DFR, 0xFFFFFFFF);
+
+   /*
+    * Set up the logical destination ID.
+    */
+   tmp = APICRead(APIC_LDR);
+   tmp &= ~APIC_LDR_MASK;
+   /* 
+    * FIXME:
+    *   This works only up to 8 CPU's
+    */
+   tmp |= (1 << (KeGetCurrentProcessorNumber() + 24));
+   APICWrite(APIC_LDR, tmp);
+
+
+   DPRINT1("CPU%d:\n", CPU);
+   DPRINT1("  Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+   DPRINT1("  Logical APIC id:  %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+   DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+   DPRINT1("%d\n", CPUMap[CPU].APICId);
+
+   /* Accept only higher interrupts */
+   APICWrite(APIC_TPR, 0xef);
+
+   /* Enable local APIC */
+   tmp = APICRead(APIC_SIVR);
+   tmp &= ~0xff;
+   tmp |= APIC_SIVR_ENABLE;
+
+#if 0
+   tmp &= ~APIC_SIVR_FOCUS;
+#else
+   tmp |= APIC_SIVR_FOCUS;
+#endif
+
+  /* Set spurious interrupt vector */
+  tmp |= SPURIOUS_VECTOR;
+  APICWrite(APIC_SIVR, tmp);
+
+  /*
+   * Set up LVT0, LVT1:
+   *
+   * set up through-local-APIC on the BP's LINT0. This is not
+   * strictly necessery in pure symmetric-IO mode, but sometimes
+   * we delegate interrupts to the 8259A.
+   */
+  tmp = APICRead(APIC_LINT0) & APIC_LVT_MASKED;
+  if (CPU == BootCPU && (APICMode == amPIC || !tmp)) 
+  {
+     tmp = APIC_DM_EXTINT;
+     DPRINT1("enabled ExtINT on CPU#%d\n", CPU);
+  } 
+  else 
+  {
+     tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
+     DPRINT1("masked ExtINT on CPU#%d\n", CPU);
+  }
+  APICWrite(APIC_LINT0, tmp);
+
+
+  /*
+   * Only the BSP should see the LINT1 NMI signal, obviously.
+   */
+  if (CPU == BootCPU)
+  {
+     tmp = APIC_DM_NMI;
+  }
+  else
+  {
+     tmp = APIC_DM_NMI | APIC_LVT_MASKED;
+  }
+  if (!APIC_INTEGRATED(CPUMap[CPU].APICVersion)) 
+  {
+     /* 82489DX */
+     tmp |= APIC_LVT_LEVEL_TRIGGER;
+  }
+  APICWrite(APIC_LINT1, tmp);
+
+  if (APIC_INTEGRATED(CPUMap[CPU].APICVersion)) 
+  {	
+     /* !82489DX */
+     if (APICGetMaxLVT() > 3) 
+     {
+	/* Due to the Pentium erratum 3AP */
+	APICWrite(APIC_ESR, 0);
+     }
+
+     tmp = APICRead(APIC_ESR);
+     DPRINT("ESR value before enabling vector: 0x%X\n", tmp);
+
+     /* Enable sending errors */
+     tmp = ERROR_VECTOR;
+     APICWrite(APIC_LVT3, tmp);
+
+     /*
+      * Spec says clear errors after enabling vector
+      */
+     if (APICGetMaxLVT() > 3)
+     {
+        APICWrite(APIC_ESR, 0);
+     }
+     tmp = APICRead(APIC_ESR);
+     DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
+  }
+}
+
+VOID APICSyncArbIDs(VOID)
+{
+   ULONG i, tmp;
+
+   /* Wait up to 100ms for the APIC to become ready */
+   for (i = 0; i < 10000; i++) 
+   {
+      tmp = APICRead(APIC_ICR0);
+      /* Check Delivery Status */
+      if ((tmp & APIC_ICR0_DS) == 0)
+         break;
+      KeStallExecutionProcessor(10);
+   }
+
+   if (i == 10000) 
+   {
+      DPRINT("CPU(%d) APIC busy for 100ms.\n", ThisCPU());
+   }
+
+   DPRINT("Synchronizing Arb IDs.\n");
+   APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
+}
+
+VOID MpsErrorHandler(VOID)
+{
+  ULONG tmp1, tmp2;
+
+  APICDump();
+
+  tmp1 = APICRead(APIC_ESR);
+  APICWrite(APIC_ESR, 0);
+  tmp2 = APICRead(APIC_ESR);
+  DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+
+  /*
+   * Acknowledge the interrupt
+   */
+  APICSendEOI();
+
+  /* Here is what the APIC error bits mean:
+   *   0: Send CS error
+   *   1: Receive CS error
+   *   2: Send accept error
+   *   3: Receive accept error
+   *   4: Reserved
+   *   5: Send illegal vector
+   *   6: Received illegal vector
+   *   7: Illegal register address
+   */
+  DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+  for (;;);
+}
+
+VOID MpsSpuriousHandler(VOID)
+{
+  ULONG tmp;
+
+  DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU());
+  
+  tmp = APICRead(APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
+  if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
+  {
+      APICSendEOI();
+      return;
+  }
+#if 0
+  /* No need to send EOI here */
+  APICDump();
+#endif
+}
+
+VOID MpsIpiHandler(VOID)
+{
+   KIRQL oldIrql;
+
+   HalBeginSystemInterrupt(IPI_VECTOR, 
+                           VECTOR2IRQL(IPI_VECTOR), 
+			   &oldIrql);
+   Ki386EnableInterrupts();
+#if 0
+   DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n", 
+            __FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
+#endif   
+
+   KiIpiServiceRoutine(NULL, NULL);
+
+#if 0
+   DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
+#endif
+
+   Ki386DisableInterrupts();
+   HalEndSystemInterrupt(oldIrql, 0);
+}
+
+VOID
+MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
+			   PKTRAP_FRAME TrapFrame)
+{
+   TrapFrame->Gs     = (USHORT)IrqTrapFrame->Gs;
+   TrapFrame->Fs     = (USHORT)IrqTrapFrame->Fs;
+   TrapFrame->Es     = (USHORT)IrqTrapFrame->Es;
+   TrapFrame->Ds     = (USHORT)IrqTrapFrame->Ds;
+   TrapFrame->Eax    = IrqTrapFrame->Eax;
+   TrapFrame->Ecx    = IrqTrapFrame->Ecx;
+   TrapFrame->Edx    = IrqTrapFrame->Edx;
+   TrapFrame->Ebx    = IrqTrapFrame->Ebx;
+   TrapFrame->Esp    = IrqTrapFrame->Esp;
+   TrapFrame->Ebp    = IrqTrapFrame->Ebp;
+   TrapFrame->Esi    = IrqTrapFrame->Esi;
+   TrapFrame->Edi    = IrqTrapFrame->Edi;
+   TrapFrame->Eip    = IrqTrapFrame->Eip;
+   TrapFrame->Cs     = IrqTrapFrame->Cs;
+   TrapFrame->Eflags = IrqTrapFrame->Eflags;
+}
+
+VOID
+MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
+{
+   KIRQL oldIrql;
+   KTRAP_FRAME KernelTrapFrame;
+#if 0
+   ULONG CPU;
+   static ULONG Count[MAX_CPU] = {0,};
+#endif
+   HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR, 
+                           VECTOR2IRQL(LOCAL_TIMER_VECTOR), 
+			   &oldIrql);
+   Ki386EnableInterrupts();
+
+#if 0
+   CPU = ThisCPU();
+   if ((Count[CPU] % 100) == 0)
+   {
+     DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetCurrentKPCR());
+   }
+   Count[CPU]++;
+#endif
+
+   MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+   if (KeGetCurrentProcessorNumber() == 0)
+   {
+      KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
+   }
+   else
+   {
+      KeUpdateRunTime(&KernelTrapFrame, oldIrql);
+   }
+
+   Ki386DisableInterrupts();
+   HalEndSystemInterrupt (oldIrql, 0);
+}
+
+/* EOF */

reactos/hal/halx86/mp
halinit_mp.c added at 1.1.2.1
diff -N halinit_mp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halinit_mp.c	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,29 @@
+/* $Id: halinit_mp.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          ntoskrnl/hal/x86/halinit.c
+ * PURPOSE:       Initalize the x86 hal
+ * PROGRAMMER:    David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ *              11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <mps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+  HalpInitMPS();
+}
+
+/* EOF */

reactos/hal/halx86/mp
halmp.rc added at 1.1.2.1
diff -N halmp.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halmp.rc	13 Dec 2004 16:18:23 -0000	1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"X86 Multiprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME	"halx86mp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"halx86mp.dll\0"
+#include <reactos/version.rc>

reactos/hal/halx86/mp
ipi_mp.c added at 1.1.2.1
diff -N ipi_mp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ipi_mp.c	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,29 @@
+/* $Id: ipi_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT:             See COPYING in the top level directory
+ * PROJECT:               ReactOS kernel
+ * FILE:                  hal/halx86/mp/ipi_mp.c
+ * PURPOSE:               IPI functions for MP
+ * PROGRAMMER:            Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+  DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+  APICSendIPI(1 << ProcessorNo,
+	      IPI_VECTOR|APIC_ICR0_LEVEL_DEASSERT|APIC_ICR0_DESTM);
+}
+
+/* EOF */

reactos/hal/halx86/mp
mps.S added at 1.1.2.1
diff -N mps.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mps.S	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,109 @@
+/* $Id: mps.S,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/mps.S
+ * PURPOSE:         Intel MultiProcessor specification support
+ * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ *                  Created 12/04/2001
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <internal/i386/segment.h>
+
+/* FUNCTIONS *****************************************************************/
+
+#define BEFORE \
+  cld; \
+  pusha; \
+  pushl %ds; \
+  pushl %es; \
+  pushl %fs; \
+  pushl %gs; \
+  movl  $(KERNEL_DS), %eax; \
+  movl  %eax, %ds; \
+  movl  %eax, %es; \
+  movl  %eax, %gs; \
+  movl  $(PCR_SELECTOR), %eax; \
+  movl  %eax, %fs;
+  
+#define AFTER \
+  popl  %gs; \
+  popl  %fs; \
+  popl  %es; \
+  popl  %ds; \
+  popa;
+
+.global _MpsIpiInterrupt
+_MpsIpiInterrupt:
+  /* Save registers */	
+  BEFORE
+
+  /* Call the C handler */
+  call  _MpsIpiHandler
+
+	/* Return to the caller */
+  AFTER
+  iret
+  
+  
+.globl _MpsErrorInterrupt
+_MpsErrorInterrupt:
+  /* Save registers */	
+  BEFORE
+
+  /* Call the C handler */
+  call  _MpsErrorHandler
+
+	/* Return to the caller */
+  AFTER
+  iret
+
+
+.globl _MpsSpuriousInterrupt
+_MpsSpuriousInterrupt:
+  /* Save registers */	
+  BEFORE
+
+  /* Call the C handler */
+  call  _MpsSpuriousHandler
+
+	/* Return to the caller */
+  AFTER
+  iret
+
+.global _MpsTimerInterrupt
+_MpsTimerInterrupt:
+	cld
+	pusha	
+	movl	$0xef,%ebx		
+  	pushl 	%ds
+  	pushl 	%es
+  	pushl 	%fs
+  	pushl	%gs
+  	movl	$0xceafbeef,%eax
+  	pushl 	%eax
+  	movl	$(KERNEL_DS),%eax
+  	movl	%eax,%ds
+  	movl	%eax,%es
+  	movl	%eax,%gs
+  	movl	$(PCR_SELECTOR),%eax
+  	movl	%eax,%fs
+  	pushl 	%esp
+  	pushl 	%ebx
+  	call	_MpsTimerHandler
+    	popl	%eax
+  	popl	%eax
+  	popl	%eax
+  	popl	%gs
+  	popl	%fs
+  	popl	%es
+  	popl	%ds
+  	popa
+  	iret
+  
+  
+  
+/* EOF */

reactos/hal/halx86/mp
mpsboot.asm added at 1.1.2.1
diff -N mpsboot.asm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mpsboot.asm	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,106 @@
+;
+; COPYRIGHT:       See COPYING in the top level directory
+; PROJECT:         ReactOS kernel
+; FILE:            ntoskrnl/hal/x86/mpsboot.c
+; PURPOSE:         Bootstrap code for application processors
+; PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
+; UPDATE HISTORY:
+;                  Created 12/04/2001
+;
+
+;
+; Memory map at this stage is:
+;     0x2000  Location of our stack
+;     0x3000  Startup code for the APs (this code)
+;
+
+;
+; Base address of common area for BSP and APs
+;
+LOAD_BASE   equ 00200000h
+
+;
+; Magic value to be put in EAX when multiboot.S is called as part of the
+; application processor initialization process
+;
+AP_MAGIC    equ 12481020h
+
+;
+; Segment selectors
+;
+%define KERNEL_CS     (0x8)
+%define KERNEL_DS     (0x10)
+
+section .text
+
+global _APstart
+global _APend
+
+; 16 bit code
+BITS 16
+
+_APstart:
+	cli		; Just in case
+
+  xor   ax, ax
+	mov		ds, ax
+	mov		ss, ax
+
+  mov   eax, 3000h + APgdt - _APstart
+	lgdt  [eax]
+
+  mov   eax, cr0
+  or    eax, 00010001h    ; Turn on protected mode and write protection
+  mov   cr0, eax
+
+  db    0eah
+  dw    3000h + flush - _APstart, KERNEL_CS
+
+; 32 bit code
+BITS 32
+
+flush:
+  mov   ax, KERNEL_DS
+  mov		ds, ax
+  mov		es, ax
+  mov		fs, ax
+  mov		gs, ax
+  mov		ss, ax
+
+  ; Setup a stack for the AP
+  mov   eax, 2000h
+  mov   eax, [eax]
+  mov   esp, eax
+
+  ; Jump to start of the kernel with AP magic in eax
+  mov      eax, AP_MAGIC
+  jmp      dword KERNEL_CS:(LOAD_BASE + 0x1000)
+
+  ; Never get here
+
+
+; Temporary GDT descriptor for the APs
+
+APgdt:
+; Limit
+  dw  (3*8)-1
+; Base
+  dd	3000h + gdt - _APstart
+
+gdt:
+  dw	0x0       ; Null descriptor
+  dw	0x0
+  dw	0x0
+  dw	0x0
+
+  dw	0xffff    ; Kernel code descriptor
+  dw	0x0000
+  dw	0x9a00
+  dw	0x00cf
+
+  dw	0xffff    ;  Kernel data descriptor
+  dw	0x0000
+  dw	0x9200
+  dw	0x00cf
+
+_APend:

reactos/hal/halx86/mp
mpsirql.c added at 1.1.2.1
diff -N mpsirql.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mpsirql.c	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,400 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/hal/x86/mpsirql.c
+ * PURPOSE:         Implements IRQLs for multiprocessor systems
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ *     12/04/2001  CSH  Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <halirq.h>
+#include <hal.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/;
+
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+  KIRQL irql;
+  ULONG Flags;
+
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  irql = Ki386ReadFsByte(offsetof(KPCR, Irql));
+  if (irql > HIGH_LEVEL)
+    {
+      DPRINT1 ("CurrentIrql %x\n", irql);
+      KEBUGCHECK (0);
+    }
+  if (Flags & X86_EFLAGS_IF)
+    {
+      Ki386EnableInterrupts();
+    }
+  return irql;
+}
+
+
+VOID KeSetCurrentIrql (KIRQL NewIrql)
+/*
+ * PURPOSE: Sets the current irq level without taking any action
+ */
+{
+  ULONG Flags;
+  if (NewIrql > HIGH_LEVEL)
+  {
+    DPRINT1 ("NewIrql %x\n", NewIrql);
+    KEBUGCHECK (0);
+  }
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+  Ki386WriteFsByte(offsetof(KPCR, Irql), NewIrql);
+  if (Flags & X86_EFLAGS_IF)
+    {
+      Ki386EnableInterrupts();
+    }
+}
+
+VOID 
+HalpLowerIrql(KIRQL NewIrql, BOOL FromHalEndSystemInterrupt)
+{
+  ULONG Flags;
+  if (NewIrql >= DISPATCH_LEVEL)
+    {
+      KeSetCurrentIrql (NewIrql);
+      APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
+      return;
+    }
+  Ki386SaveFlags(Flags);
+  if (KeGetCurrentIrql() > APC_LEVEL)
+    {
+      KeSetCurrentIrql (DISPATCH_LEVEL);
+      APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
+      if (FromHalEndSystemInterrupt || Ki386ReadFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST])))
+        {
+          Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 0);
+          Ki386EnableInterrupts();
+          KiDispatchInterrupt();
+          if (!(Flags & X86_EFLAGS_IF))
+            {
+              Ki386DisableInterrupts();
+            }
+	}
+      KeSetCurrentIrql (APC_LEVEL);
+    }
+  if (NewIrql == APC_LEVEL)
+    {
+      return;
+    }
+  if (KeGetCurrentThread () != NULL && 
+      KeGetCurrentThread ()->ApcState.KernelApcPending)
+    {
+      Ki386EnableInterrupts();
+      KiDeliverApc(KernelMode, NULL, NULL);
+      if (!(Flags & X86_EFLAGS_IF))
+        {
+          Ki386DisableInterrupts();
+        }
+    }
+  KeSetCurrentIrql (PASSIVE_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KfLowerIrql
+ *
+ * DESCRIPTION
+ *	Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ *	Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL	NewIrql)
+{
+  KIRQL oldIrql = KeGetCurrentIrql();
+  if (NewIrql > oldIrql)
+    {
+      DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
+      KEBUGCHECK (0);
+    }
+  HalpLowerIrql (NewIrql, FALSE);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeLowerIrql
+ *
+ * DESCRIPTION
+ *	Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+  KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KfRaiseIrql
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ *	previous irq level
+ *
+ * NOTES
+ *	Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL	NewIrql)
+{
+  KIRQL OldIrql;
+  ULONG Flags;
+ 
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  OldIrql = KeGetCurrentIrql ();
+
+  if (NewIrql < OldIrql)
+    {
+      DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
+      KEBUGCHECK (0);
+    }
+
+
+  if (NewIrql > DISPATCH_LEVEL)
+    {
+      APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI);
+    }
+  KeSetCurrentIrql (NewIrql);
+  if (Flags & X86_EFLAGS_IF)
+    {
+      Ki386EnableInterrupts();
+    }
+
+  return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrql
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ *	NewIrql = Irql to raise to
+ *	OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ *	None
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL	NewIrql,
+	PKIRQL	OldIrql)
+{
+  *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ *	None
+ *
+ * RETURN VALUE
+ *	Previous irq level
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+  return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME							EXPORTED
+ *	KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ *	Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ *	None
+ *
+ * RETURN VALUE
+ *	Previous irq level
+ *
+ * NOTES
+ *	Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+  return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+HalBeginSystemInterrupt (ULONG Vector,
+			 KIRQL Irql,
+			 PKIRQL OldIrql)
+{
+  ULONG Flags;
+  DPRINT("Vector (0x%X)  Irql (0x%X)\n", Vector, Irql);
+  
+  if (KeGetCurrentIrql () >= Irql)
+  {
+    DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
+    KEBUGCHECK(0);
+  }
+
+  Ki386SaveFlags(Flags);
+  if (Flags & X86_EFLAGS_IF)
+  {
+     DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
+     KEBUGCHECK(0);
+  }
+  APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
+  *OldIrql = KeGetCurrentIrql ();
+  KeSetCurrentIrql (Irql);
+  return(TRUE);
+}
+
+
+VOID STDCALL
+HalEndSystemInterrupt (KIRQL Irql,
+		       ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+  ULONG Flags;
+  Ki386SaveFlags(Flags);
+
+  if (Flags & X86_EFLAGS_IF)
+  {
+     DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
+     KEBUGCHECK(0);
+  }
+  APICSendEOI();
+  HalpLowerIrql (Irql, TRUE);
+}
+  
+BOOLEAN STDCALL
+HalDisableSystemInterrupt (ULONG Vector,
+			   KIRQL Irql)
+{
+  ULONG irq;
+
+  DPRINT ("Vector (0x%X)\n", Vector);
+
+  if (Vector < FIRST_DEVICE_VECTOR ||
+      Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)  
+  {
+    DPRINT1("Not a device interrupt, vector=%x\n", Vector);
+    return FALSE;
+  }
+
+  irq = VECTOR2IRQ (Vector);
+  IOAPICMaskIrq (irq);
+
+  return TRUE;  
+}
+
+
+BOOLEAN STDCALL
+HalEnableSystemInterrupt (ULONG Vector,
+			  KIRQL Irql,
+			  KINTERRUPT_MODE InterruptMode)
+{
+  ULONG irq;
+
+  if (Vector < FIRST_DEVICE_VECTOR ||
+      Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) 
+  {
+    DPRINT("Not a device interrupt\n");
+    return FALSE;
+  }
+
+  irq = VECTOR2IRQ (Vector);
+  IOAPICUnmaskIrq (irq);
+
+  return TRUE;
+}
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(IN KIRQL Request)
+{
+  switch (Request)
+  {
+    case APC_LEVEL:
+      Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_APC_REQUEST]), 1);
+      break;
+
+    case DISPATCH_LEVEL:
+      Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 1);
+      break;
+      
+    default:
+      KEBUGCHECK(0);
+  }
+}

reactos/hal/halx86/mp
processor_mp.c added at 1.1.2.1
diff -N processor_mp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ processor_mp.c	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,1807 @@
+/* $Id: processor_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            hal/halx86/mp/processor_mp.c
+ * PURPOSE:         Intel MultiProcessor specification support
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
+ *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:           Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ *     22/05/1998  DW   Created
+ *     12/04/2001  CSH  Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#include <internal/ntoskrnl.h>
+#include <internal/i386/segment.h>
+#include <internal/ke.h>
+#include <internal/ps.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 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); \
+})
+
+
+/* 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 */
+
+volatile 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) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
+  Entry.mask = 1;
+  IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
+}
+
+
+/* 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) = IOAPICRead(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq]);
+  Entry.mask = 0;
+  IOAPICWrite(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq], *((PULONG)&Entry));
+}
+
+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;
+	 entry.dest_mode = 1;  /* logical delivery */
+	 entry.mask = 1;       /* disable IRQ */
+#if 0
+	 /*
+	  * FIXME:
+	  *   Some drivers are not able to deal with more than one cpu.
+	  */
+	 entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+	 entry.dest.logical.logical_dest = 1 << 0;
+#endif
+	 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
+#if 0
+	    entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+	    entry.dest.logical.logical_dest = 1 << 0;
+#endif
+	 }
+
+	 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)
+{
+   ULONG CPU;
+
[truncated at 1000 lines; 811 more skipped]

reactos/hal/halx86/mp
resource_mp.c added at 1.1.2.1
diff -N resource_mp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ resource_mp.c	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,38 @@
+/* $Id: resource_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT:             See COPYING in the top level directory
+ * PROJECT:               ReactOS kernel
+ * FILE:                  hal/halx86/mp/resource_mp.c
+ * PURPOSE:               Miscellaneous resource functions for MP
+ * PROGRAMMER:            Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID
+HaliReconfigurePciInterrupts(VOID);
+
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+  /*
+   * FIXME: Report all resources used by hal.
+   *        Calls IoReportHalResourceUsage()
+   */
+
+  /* Initialize PCI bus. */
+  HalpInitPciBus ();
+
+  HaliReconfigurePciInterrupts();
+}
+
+/* EOF */

reactos/hal/halx86/up
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map

reactos/hal/halx86/up
Makefile added at 1.4.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:24 -0000	1.4.2.1
@@ -0,0 +1,89 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:24 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halup
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_BOOTSTRAP = yes
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DUP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DUP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+ifeq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+	adapter.o \
+	beep.o \
+	bus.o \
+	display.o \
+	dma.o \
+	drive.o \
+	enum.o \
+	fmutex.o \
+	halinit.o \
+	ipi.o \
+	irql.o \
+	isa.o \
+	kdbg.o \
+	mca.o \
+	misc.o \
+	pci.o \
+	portio.o \
+	processor.o \
+	reboot.o \
+	resource.o \
+	spinlock.o \
+	sysbus.o \
+	sysinfo.o \
+	time.o \
+	timer.o
+
+UP_OBJECTS = \
+	halinit_up.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(UP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF

reactos/hal/halx86/up
halinit_up.c added at 1.1.2.1
diff -N halinit_up.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halinit_up.c	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,31 @@
+/* $Id: halinit_up.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          ntoskrnl/hal/x86/halinit.c
+ * PURPOSE:       Initalize the x86 hal
+ * PROGRAMMER:    David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ *              11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+  HalpInitPICs();
+
+  /* Setup busy waiting */
+  HalpCalibrateStallExecution();
+}
+
+/* EOF */

reactos/hal/halx86/up
halup.rc added at 1.1.2.1
diff -N halup.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halup.rc	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"X86 Uniprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME	"halup\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"halup.dll\0"
+#include <reactos/version.rc>

reactos/hal/halx86/xbox
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:24 -0000	1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map

reactos/hal/halx86/xbox
Makefile added at 1.4.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:25 -0000	1.4.2.1
@@ -0,0 +1,89 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:25 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halxbox
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_BOOTSTRAP = yes
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DUP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DUP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+TARGET_INSTALL = no
+TARGET_BOOTSTRAP = no
+
+GENERIC_OBJECTS = \
+	adapter.o \
+	beep.o \
+	bus.o \
+	dma.o \
+	drive.o \
+	enum.o \
+	fmutex.o \
+	halinit.o \
+	ipi.o \
+	irql.o \
+	isa.o \
+	kdbg.o \
+	mca.o \
+	misc.o \
+	pci.o \
+	portio.o \
+	processor.o \
+	reboot.o \
+	resource.o \
+	spinlock.o \
+	sysbus.o \
+	sysinfo.o \
+	time.o \
+	timer.o
+
+XBOX_OBJECTS = \
+	display_xbox.o \
+	font.o \
+	halinit_xbox.o \
+	part_xbox.o \
+	pci_xbox.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(XBOX_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF

reactos/hal/halx86/xbox
display_xbox.c added at 1.3.2.1
diff -N display_xbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ display_xbox.c	13 Dec 2004 16:18:25 -0000	1.3.2.1
@@ -0,0 +1,520 @@
+/* $Id: display_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            hal/halx86/xbox/display_xbox.c
+ * PURPOSE:         Blue screen display
+ * PROGRAMMER:      Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ *                  Created 08/10/99
+ *                  Modified for Xbox 2004/12/02 GvG
+ */
+
+/* For an explanation about display ownership see generic/display.c */
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define I2C_IO_BASE 0xc000
+
+#define CONTROL_FRAMEBUFFER_ADDRESS_OFFSET 0x600800
+
+#define MAKE_COLOR(Red, Green, Blue) (0xff000000 | (((Red) & 0xff) << 16) | (((Green) & 0xff) << 8) | ((Blue) & 0xff))
+
+/* Default to grey on blue */
+#define DEFAULT_FG_COLOR MAKE_COLOR(127, 127, 127)
+#define DEFAULT_BG_COLOR MAKE_COLOR(0, 0, 127)
+
+#define TAG_HALX     TAG('H', 'A', 'L', 'X')
+
+/* VARIABLES ****************************************************************/
+
+static ULONG CursorX = 0;      /* Cursor Position */
+static ULONG CursorY = 0;
+static ULONG SizeX;            /* Display size (characters) */
+static ULONG SizeY;
+
+static BOOLEAN DisplayInitialized = FALSE;
+static BOOLEAN HalOwnsDisplay = TRUE;
+
+static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
+
+#define CHAR_WIDTH  8
+#define CHAR_HEIGHT 16
+
+static PVOID FrameBuffer;
+static ULONG BytesPerPixel;
+static ULONG Delta;
+
+/*
+ * It turns out that reading from the frame buffer is a pretty expensive
+ * operation. So, we're keeping shadow arrays of the contents and use
+ * those when needed (only for scrolling) instead of reading from the fb.
+ * This cuts down boot time from about 45 sec to about 6 sec.
+ */
+static PUCHAR CellContents;
+static PULONG CellFgColor;
+static PULONG CellBgColor;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+static VOID FASTCALL
+HalpXboxOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG BgColor)
+{
+  PUCHAR FontPtr;
+  PULONG Pixel;
+  UCHAR Mask;
+  unsigned Line;
+  unsigned Col;
+
+  FontPtr = XboxFont8x16 + Char * 16;
+  Pixel = (PULONG) ((char *) FrameBuffer + Y * CHAR_HEIGHT * Delta
+                  + X * CHAR_WIDTH * BytesPerPixel);
+  for (Line = 0; Line < CHAR_HEIGHT; Line++)
+    {
+      Mask = 0x80;
+      for (Col = 0; Col < CHAR_WIDTH; Col++)
+        {
+          Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
+          Mask = Mask >> 1;
+        }
+      Pixel = (PULONG) ((char *) Pixel + Delta);
+    }
+
+  if (NULL != CellContents)
+    {
+      CellContents[Y * SizeX + X] = Char;
+      CellFgColor[Y * SizeX + X] = FgColor;
+      CellBgColor[Y * SizeX + X] = BgColor;
+    }
+}
+
+static ULONG FASTCALL
+HalpXboxAttrToSingleColor(UCHAR Attr)
+{
+  UCHAR Intensity;
+
+  Intensity = (0 == (Attr & 0x08) ? 127 : 255);
+
+  return 0xff000000 |
+         (0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
+         (0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
+         (0 == (Attr & 0x01) ? 0 : Intensity);
+}
+
+static VOID FASTCALL
+HalpXboxAttrToColors(UCHAR Attr, ULONG *FgColor, ULONG *BgColor)
+{
+  *FgColor = HalpXboxAttrToSingleColor(Attr & 0xf);
+  *BgColor = HalpXboxAttrToSingleColor((Attr >> 4) & 0xf);
+}
+
+static VOID FASTCALL
+HalpXboxClearScreenColor(ULONG Color)
+{
+  ULONG Line, Col;
+  PULONG p;
+
+  for (Line = 0; Line < SizeY * CHAR_HEIGHT; Line++)
+    {
+      p = (PULONG) ((char *) FrameBuffer + Line * Delta);
+      for (Col = 0; Col < SizeX * CHAR_WIDTH; Col++)
+        {
+          *p++ = Color;
+        }
+    }
+
+  if (NULL != CellContents)
+    {
+      for (Line = 0; Line < SizeY; Line++)
+        {
+          for (Col = 0; Col < SizeX; Col++)
+            {
+              CellContents[Line * SizeX + Col] = ' ';
+              CellFgColor[Line * SizeX + Col] = Color;
+              CellBgColor[Line * SizeX + Col] = Color;
+            }
+        }
+    }
+}
+
+VOID FASTCALL
+HalClearDisplay(UCHAR CharAttribute)
+{
+  ULONG FgColor, BgColor;
+
+  HalpXboxAttrToColors(CharAttribute, &FgColor, &BgColor);
+
+  HalpXboxClearScreenColor(BgColor);
+
+  CursorX = 0;
+  CursorY = 0;
+}
+
+VOID STATIC
+HalScrollDisplay (VOID)
+{
+  ULONG Line, Col;
+  PULONG p;
+
+  if (NULL == CellContents)
+    {
+      p = (PULONG) ((char *) FrameBuffer + (Delta * CHAR_HEIGHT));
+      RtlMoveMemory(FrameBuffer,
+                    p,
+                    (Delta * CHAR_HEIGHT) * (SizeY - 1));
+
+      for (Line = 0; Line < CHAR_HEIGHT; Line++)
+        {
+          p = (PULONG) ((char *) FrameBuffer + (CHAR_HEIGHT * (SizeY - 1 ) + Line) * Delta);
+          for (Col = 0; Col < SizeX * CHAR_WIDTH; Col++)
+            {
+              *p++ = DEFAULT_BG_COLOR;
+            }
+        }
+    }
+  else
+    {
+      for (Line = 0; Line < SizeY - 1; Line++)
+        {
+          for (Col = 0; Col < SizeX; Col++)
+            {
+              HalpXboxOutputChar(CellContents[(Line + 1) * SizeX + Col], Col, Line,
+                                 CellFgColor[(Line + 1) * SizeX + Col],
+                                 CellBgColor[(Line + 1) * SizeX + Col]);
+            }
+        }
+      for (Col = 0; Col < SizeX; Col++)
+        {
+          HalpXboxOutputChar(' ', Col, SizeY - 1, DEFAULT_FG_COLOR, DEFAULT_BG_COLOR);
+        }
+    }
+}
+
+static VOID FASTCALL
+HalPutCharacter(UCHAR Character)
+{
+  HalpXboxOutputChar(Character, CursorX, CursorY, DEFAULT_FG_COLOR, DEFAULT_BG_COLOR);
+}
+
+static BOOL
+ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus)
+{
+  int nRetriesToLive=50;
+
+  while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800))
+    {
+      ;  /* Franz's spin while bus busy with any master traffic */
+    }
+
+  while (0 != nRetriesToLive--)
+    {
+      UCHAR b;
+      int temp;
+
+      WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
+      WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister);
+
+      temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0));
+      WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp);  /* clear down all preexisting errors */
+
+      switch (Size)
+        {
+          case 4:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d);      /* DWORD modus ? */
+            break;
+          case 2:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b);      /* WORD modus */
+            break;
+          default:
+            WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a);      // BYTE
+            break;
+        }
+
+      b = 0;
+
+      while (0 == (b & 0x36))
+        {
+          b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0));
+        }
+
+      if (0 != (b & 0x24))
+        {
+          /* printf("I2CTransmitByteGetReturn error %x\n", b); */
+        }
+
+      if(0 == (b & 0x10))
+        {
+          /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
+        }
+      else
+        {
+          switch (Size)
+            {
+              case 4:
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+                break;
+              case 2:
+                *Data_to_smbus = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6));
+                break;
+              default:
+                *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+                break;
+            }
+
+
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+
+static BOOL
+I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return)
+{
+  return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
+}
+
+VOID FASTCALL
+HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
+/*
+ * FUNCTION: Initalize the display
+ * ARGUMENTS:
+ *         InitParameters = Parameters setup by the boot loader
+ */
+{
+  ULONG ScreenWidthPixels;
+  ULONG ScreenHeightPixels;
+  PHYSICAL_ADDRESS PhysControl;
+  PHYSICAL_ADDRESS PhysBuffer;
+  ULONG AvMode;
+  PVOID ControlBuffer;
+
+  if (! DisplayInitialized)
+    {
+      PhysBuffer.u.HighPart = 0;
+      if (0 != (LoaderBlock->Flags & MB_FLAGS_MEM_INFO))
+        {
+          PhysBuffer.u.LowPart = (LoaderBlock->MemHigher + 1024) * 1024;
+        }
+      else
+        {
+          /* Assume a 64Mb Xbox, last 4MB for video buf */
+          PhysBuffer.u.LowPart = 60 * 1024 * 1024;
+        }
+      PhysBuffer.u.LowPart |= 0xf0000000;
+
+      /* Tell the nVidia controller about the framebuffer */
+      PhysControl.u.HighPart = 0;
+      PhysControl.u.LowPart = 0xfd000000;
+      ControlBuffer = MmMapIoSpace(PhysControl, 0x1000000, MmNonCached);
+      if (NULL == ControlBuffer)
+        {
+          return;
+        }
+      *((PULONG) ((char *) ControlBuffer + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = (ULONG) PhysBuffer.u.LowPart;
+      MmUnmapIoSpace(ControlBuffer, 0x1000000);
+
+      FrameBuffer = MmMapIoSpace(PhysBuffer, 4 * 1024 * 1024, MmNonCached);
+      if (NULL == FrameBuffer)
+        {
+          return;
+        }
+
+      if (I2CTransmitByteGetReturn(0x10, 0x04, &AvMode))
+        {
+          if (1 == AvMode) /* HDTV */
+            {
+              ScreenWidthPixels = 720;
+            }
+          else
+            {
+              /* FIXME Other possible values of AvMode:
+               * 0 - AV_SCART_RGB
+               * 2 - AV_VGA_SOG
+               * 4 - AV_SVIDEO
+               * 6 - AV_COMPOSITE
+               * 7 - AV_VGA
+               * other AV_COMPOSITE
+               */
+              ScreenWidthPixels = 640;
+            }
+        }
+      else
+        {
+          ScreenWidthPixels = 640;
+        }
+      ScreenHeightPixels = 480;
+      BytesPerPixel = 4;
+
+      SizeX = ScreenWidthPixels / CHAR_WIDTH;
+      SizeY = ScreenHeightPixels / CHAR_HEIGHT;
+      Delta = (ScreenWidthPixels * BytesPerPixel + 3) & ~ 0x3;
+
+      CellFgColor = (PULONG) ExAllocatePoolWithTag(PagedPool,
+                                                   SizeX * SizeY * (sizeof(ULONG) + sizeof(ULONG) + sizeof(UCHAR)),
+                                                   TAG_HALX);
+      if (NULL != CellFgColor)
+        {
+          CellBgColor = CellFgColor + SizeX * SizeY;
+          CellContents = (PUCHAR) (CellBgColor + SizeX * SizeY);
+        }
+      else
+        {
+          CellBgColor = NULL;
+          CellContents = NULL;
+        }
+
+      HalpXboxClearScreenColor(MAKE_COLOR(0, 0, 0));
+
+      DisplayInitialized = TRUE;
+    }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+VOID STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+  if (HalOwnsDisplay || NULL == HalResetDisplayParameters)
+    {
+      return;
+    }
+
+  HalResetDisplayParameters(SizeX, SizeY);
+
+  HalOwnsDisplay = TRUE;
+  HalpXboxClearScreenColor(DEFAULT_BG_COLOR);
+
+  CursorX = 0;
+  CursorY = 0;
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION: 
+ * ARGUMENTS:
+ *         ResetDisplayParameters = Pointer to a driver specific
+ *         reset routine.
+ */
+{
+  HalOwnsDisplay = FALSE;
+  HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+HalDisplayString(IN PCH String)
+/*
+ * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
+ * already and displays a string
+ * ARGUMENT:
+ *        string = ASCII string to display
+ * NOTE: Use with care because there is no support for returning from BSOD
+ * mode
+ */
+{
+  PCH pch;
+  static KSPIN_LOCK Lock;
+  KIRQL OldIrql;
+  ULONG Flags;
+
+  if (! HalOwnsDisplay || ! DisplayInitialized)
+    {
+      return;
+    }
+
+  pch = String;
+
+  OldIrql = KfRaiseIrql(HIGH_LEVEL);
+  KiAcquireSpinLock(&Lock);
+
+  Ki386SaveFlags(Flags);
+  Ki386DisableInterrupts();
+
+  while (*pch != 0)
+    {
+      if (*pch == '\n')
+	{
+	  CursorY++;
+	  CursorX = 0;
+	}
+      else if (*pch == '\b')
+	{
+	  if (CursorX > 0)
+	    {
+	      CursorX--;
+	    }
+	}
+      else if (*pch != '\r')
+	{
+	  HalPutCharacter(*pch);
+	  CursorX++;
+	  
+	  if (SizeX <= CursorX)
+	    {
+	      CursorY++;
+	      CursorX = 0;
+	    }
+	}
+
+      if (SizeY <= CursorY)
+	{
+	  HalScrollDisplay ();
+	  CursorY = SizeY - 1;
+	}
+  
+      pch++;
+    }
+  
+  Ki386RestoreFlags(Flags);
+
+  KiReleaseSpinLock(&Lock);
+  KfLowerIrql(OldIrql);
+}
+
+VOID STDCALL
+HalQueryDisplayParameters(OUT PULONG DispSizeX,
+			  OUT PULONG DispSizeY,
+			  OUT PULONG CursorPosX,
+			  OUT PULONG CursorPosY)
+{
+  if (DispSizeX)
+    *DispSizeX = SizeX;
+  if (DispSizeY)
+    *DispSizeY = SizeY;
+  if (CursorPosX)
+    *CursorPosX = CursorX;
+  if (CursorPosY)
+    *CursorPosY = CursorY;
+}
+
+
+VOID STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+			IN ULONG CursorPosY)
+{
+  CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+  CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+  return ! HalOwnsDisplay;
+}
+
+/* EOF */

reactos/hal/halx86/xbox
font.c added at 1.1.2.1
diff -N font.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ font.c	13 Dec 2004 16:18:25 -0000	1.1.2.1
@@ -0,0 +1,281 @@
+/* $Id: font.c,v 1.1.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Xbox HAL
+ * FILE:            hal/halx86/xbox/font.h
+ * PURPOSE:         Font glyphs
+ * PROGRAMMER:      Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ *                  Created 2004/12/02
+ *
+ * Note: Converted from the XFree vga.bdf font
+ */
+
+#include <ddk/ntddk.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+BYTE XboxFont8x16[256 * 16] =
+{
+  0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* 0x00 */
+  0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xa5,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* 0x01 */
+  0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xdb,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* 0x02 */
+  0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, /* 0x03 */
+  0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x04 */
+  0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x05 */
+  0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x06 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x07 */
+  0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x08 */
+  0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, /* 0x09 */
+  0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, /* 0x0a */
+  0x00,0x00,0x1e,0x06,0x0e,0x1a,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* 0x0b */
+  0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0c */
+  0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, /* 0x0d */
+  0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, /* 0x0e */
+  0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0f */
+  0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, /* 0x10 */
+  0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* 0x11 */
+  0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, /* 0x12 */
+  0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, /* 0x13 */
+  0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, /* 0x14 */
+  0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, /* 0x15 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, /* 0x16 */
+  0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0x17 */
+  0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x18 */
+  0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0x19 */
+  0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1a */
+  0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1b */
+  0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1c */
+  0x00,0x00,0x00,0x00,0x00,0x28,0x6c,0xfe,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1d */
+  0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x1e */
+  0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x1f */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   */
+  0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ! */
+  0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* " */
+  0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, /* # */
+  0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, /* $ */
+  0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, /* % */
+  0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* & */
+  0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ' */
+  0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, /* ( */
+  0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, /* ) */
+  0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, /* * */
+  0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* + */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, /* , */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* . */
+  0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, /* / */
+  0x00,0x00,0x38,0x6c,0xc6,0xc6,0xd6,0xd6,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0 */
+  0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, /* 1 */
+  0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 2 */
+  0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 3 */
+  0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, /* 4 */
+  0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 5 */
+  0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 6 */
+  0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, /* 7 */
+  0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 8 */
+  0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, /* 9 */
+  0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* : */
+  0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, /* ; */
+  0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, /* < */
+  0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* = */
+  0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, /* > */
+  0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ? */
+  0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* @ */
+  0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* A */
+  0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, /* B */
+  0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, /* C */
+  0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, /* D */
+  0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* E */
+  0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* F */
+  0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, /* G */
+  0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* H */
+  0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* I */
+  0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* J */
+  0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* K */
+  0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* L */
+  0x00,0x00,0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* M */
+  0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* N */
+  0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* O */
+  0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* P */
+  0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, /* Q */
+  0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* R */
+  0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* S */
+  0x00,0x00,0x7e,0x7e,0x5a,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* T */
+  0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* U */
+  0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x10,0x00,0x00,0x00,0x00, /* V */
+  0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0xee,0x6c,0x00,0x00,0x00,0x00, /* W */
+  0x00,0x00,0xc6,0xc6,0x6c,0x7c,0x38,0x38,0x7c,0x6c,0xc6,0xc6,0x00,0x00,0x00,0x00, /* X */
+  0x00,0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* Y */
+  0x00,0x00,0xfe,0xc6,0x86,0x0c,0x18,0x30,0x60,0xc2,0xc6,0xfe,0x00,0x00,0x00,0x00, /* Z */
+  0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, /* [ */
+  0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* \ */
+  0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, /* ] */
+  0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, /* _ */
+  0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ` */
+  0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* a */
+  0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, /* b */
+  0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* c */
+  0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* d */
+  0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* e */
+  0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* f */
+  0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, /* g */
+  0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* h */
+  0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* i */
+  0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, /* j */
+  0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, /* k */
+  0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* l */
+  0x00,0x00,0x00,0x00,0x00,0xec,0xfe,0xd6,0xd6,0xd6,0xd6,0xc6,0x00,0x00,0x00,0x00, /* m */
+  0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* n */
+  0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* o */
+  0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, /* p */
+  0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, /* q */
+  0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* r */
+  0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, /* s */
+  0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, /* t */
+  0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* u */
+  0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, /* v */
+  0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0x6c,0x00,0x00,0x00,0x00, /* w */
+  0x00,0x00,0x00,0x00,0x00,0xc6,0x6c,0x38,0x38,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00, /* x */
+  0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, /* y */
+  0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* z */
+  0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, /* { */
+  0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* | */
+  0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /* } */
+  0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ~ */
+  0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x7f */
+  0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, /* 0x80 */
+  0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x81 */
+  0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x82 */
+  0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x83 */
+  0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x84 */
+  0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x85 */
+  0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x86 */
+  0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, /* 0x87 */
+  0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x88 */
+  0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x89 */
+  0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x8a */
+  0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8b */
+  0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8c */
+  0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8d */
+  0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8e */
+  0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8f */
+  0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, /* 0x90 */
+  0x00,0x00,0x00,0x00,0x00,0xcc,0x76,0x36,0x7e,0xd8,0xd8,0x6e,0x00,0x00,0x00,0x00, /* 0x91 */
+  0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, /* 0x92 */
+  0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x93 */
+  0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x94 */
+  0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x95 */
+  0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x96 */
+  0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x97 */
+  0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, /* 0x98 */
+  0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x99 */
+  0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x9a */
+  0x00,0x18,0x18,0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9b */
+  0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, /* 0x9c */
+  0x00,0x00,0x66,0x66,0x3c,0x18,0x7e,0x18,0x7e,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9d */
+  0x00,0xf8,0xcc,0xcc,0xf8,0xc4,0xcc,0xde,0xcc,0xcc,0xcc,0xc6,0x00,0x00,0x00,0x00, /* 0x9e */
+  0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, /* 0x9f */
+  0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa0 */
+  0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0xa1 */
+  0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa2 */
+  0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa3 */
+  0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* 0xa4 */
+  0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xa5 */
+  0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa6 */
+  0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa7 */
+  0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa8 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, /* 0xa9 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, /* 0xaa */
+  0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xdc,0x86,0x0c,0x18,0x3e,0x00,0x00, /* 0xab */
+  0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x9e,0x3e,0x06,0x06,0x00,0x00, /* 0xac */
+  0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0xad */
+  0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xae */
+  0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xaf */
+  0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, /* 0xb0 */
+  0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, /* 0xb1 */
+  0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, /* 0xb2 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb3 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb4 */
+  0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb5 */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb6 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb7 */
+  0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb8 */
+  0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb9 */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xba */
+  0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xbb */
+  0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbc */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbd */
+  0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbe */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xbf */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc0 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc1 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc2 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc3 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc4 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc5 */
+  0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc6 */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc7 */
+  0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc8 */
+  0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc9 */
+  0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xca */
+  0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcb */
+  0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcc */
+  0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcd */
+  0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xce */
+  0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcf */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd0 */
+  0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd1 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd2 */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd3 */
+  0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd4 */
+  0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd5 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd6 */
+  0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd7 */
+  0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd8 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd9 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xda */
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdb */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdc */
+  0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, /* 0xdd */
+  0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, /* 0xde */
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdf */
+  0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, /* 0xe0 */
+  0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, /* 0xe1 */
+  0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, /* 0xe2 */
+  0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, /* 0xe3 */
+  0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 0xe4 */
+  0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xe5 */
+  0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, /* 0xe6 */
+  0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0xe7 */
+  0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0xe8 */
+  0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0xe9 */
+  0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, /* 0xea */
+  0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, /* 0xeb */
+  0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xec */
+  0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, /* 0xed */
+  0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, /* 0xee */
+  0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xef */
+  0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0xf0 */
+  0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, /* 0xf1 */
+  0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf2 */
+  0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf3 */
+  0x00,0x00,0x0e,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xf4 */
+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xf5 */
+  0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 0xf6 */
+  0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf7 */
+  0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf8 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf9 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfa */
+  0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, /* 0xfb */
+  0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfc */
+  0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfd */
+  0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, /* 0xfe */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  /* 0xff */
+};
+
+/* EOF */
+

reactos/hal/halx86/xbox
halinit_xbox.c added at 1.3.2.1
diff -N halinit_xbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halinit_xbox.c	13 Dec 2004 16:18:25 -0000	1.3.2.1
@@ -0,0 +1,36 @@
+/* $Id: halinit_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          ntoskrnl/hal/x86/halinit.c
+ * PURPOSE:       Initalize the x86 hal
+ * PROGRAMMER:    David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ *              11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+  HalpHooks.InitPciBus = HalpXboxInitPciBus;
+
+  HalpInitPICs();
+
+  /* Setup busy waiting */
+  HalpCalibrateStallExecution();
+
+  HalpXboxInitPartIo();
+}
+
+/* EOF */

reactos/hal/halx86/xbox
halxbox.h added at 1.3.2.1
diff -N halxbox.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halxbox.h	13 Dec 2004 16:18:25 -0000	1.3.2.1
@@ -0,0 +1,22 @@
+/* $Id: halxbox.h,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Xbox HAL
+ * FILE:            hal/halx86/xbox/halxbox.h
+ * PURPOSE:         Xbox specific routines
+ * PROGRAMMER:      Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ *                  Created 2004/12/02
+ */
+
+#ifndef HALXBOX_H_INCLUDED
+#define HALXBOX_H_INCLUDED
+
+extern BYTE XboxFont8x16[256 * 16];
+
+void HalpXboxInitPciBus(ULONG BusNumber, PBUS_HANDLER BusHandler);
+void HalpXboxInitPartIo(void);
+
+#endif /* HALXBOX_H_INCLUDED */
+
+/* EOF */

reactos/hal/halx86/xbox
halxbox.rc added at 1.1.2.1
diff -N halxbox.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ halxbox.rc	13 Dec 2004 16:18:25 -0000	1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"Xbox Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME	"halxbox\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"halxbox.dll\0"
+#include <reactos/version.rc>

reactos/hal/halx86/xbox
part_xbox.c added at 1.1.2.1
diff -N part_xbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ part_xbox.c	13 Dec 2004 16:18:25 -0000	1.1.2.1
@@ -0,0 +1,322 @@
+/* $Id: part_xbox.c,v 1.1.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          hal/halx86/xbox/part_xbox.c
+ * PURPOSE:       Xbox specific handling of partition tables
+ * PROGRAMMER:    Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ *             2004/12/04: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#define XBOX_SIGNATURE_SECTOR 3
+#define XBOX_SIGNATURE        ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))
+#define PARTITION_SIGNATURE   0xaa55
+
+/* VARIABLES ***************************************************************/
+
+static pHalExamineMBR NtoskrnlExamineMBR;
+static pHalIoReadPartitionTable NtoskrnlIoReadPartitionTable;
+static pHalIoSetPartitionInformation NtoskrnlIoSetPartitionInformation;
+static pHalIoWritePartitionTable NtoskrnlIoWritePartitionTable;
+
+static struct
+{
+  ULONG SectorStart;
+  ULONG SectorCount;
+  BYTE PartitionType;
+} XboxPartitions[] =
+{
+  /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
+  { 0x0055F400, 0x0098f800, PARTITION_FAT32  }, /* Store, E: */
+  { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
+  { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
+  { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
+  { 0x002EE400, 0x00177000, PARTITION_FAT_16 }  /* Cache3, Z: */
+};
+
+#define XBOX_PARTITION_COUNT (sizeof(XboxPartitions) / sizeof(XboxPartitions[0]))
+
+/* FUNCTIONS ***************************************************************/
+
+
+static NTSTATUS
+HalpXboxReadSector(IN PDEVICE_OBJECT DeviceObject,
+                   IN ULONG SectorSize,
+                   IN PLARGE_INTEGER SectorOffset,
+                   IN PVOID Sector)
+{
+  IO_STATUS_BLOCK StatusBlock;
+  KEVENT Event;
+  PIRP Irp;
+  NTSTATUS Status;
+
+  DPRINT("HalpXboxReadSector(%p %lu 0x%08x%08x %p)\n",
+         DeviceObject, SectorSize, SectorOffset->u.HighPart, SectorOffset->u.LowPart, Sector);
+
+  ASSERT(DeviceObject);
+  ASSERT(Sector);
+
+  KeInitializeEvent(&Event,
+		    NotificationEvent,
+		    FALSE);
+
+  /* Read the sector */
+  Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+				     DeviceObject,
+				     Sector,
+				     SectorSize,
+				     SectorOffset,
+				     &Event,
+				     &StatusBlock);
+
+  Status = IoCallDriver(DeviceObject,
+			Irp);
+  if (Status == STATUS_PENDING)
+    {
+      KeWaitForSingleObject(&Event,
+			    Executive,
+			    KernelMode,
+			    FALSE,
+			    NULL);
+      Status = StatusBlock.Status;
+    }
+
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("Reading sector failed (Status 0x%08lx)\n",
+	     Status);
+      return Status;
+    }
+
+  return Status;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxDeviceHasXboxPartitioning(PDEVICE_OBJECT DeviceObject,
+                                  ULONG SectorSize,
+                                  BOOLEAN *HasXboxPartitioning)
+{
+  PVOID SectorData;
+  LARGE_INTEGER Offset;
+  NTSTATUS Status;
+
+  DPRINT("HalpXboxDeviceHasXboxPartitioning(%p %lu %p)\n",
+	 DeviceObject,
+	 SectorSize,
+	 HasXboxPartitioning);
+
+  SectorData = ExAllocatePool(PagedPool, SectorSize);
+  if (NULL == SectorData)
+    {
+      return STATUS_NO_MEMORY;
+    }
+
+  Offset.QuadPart = XBOX_SIGNATURE_SECTOR * SectorSize;
+  Status = HalpXboxReadSector(DeviceObject, SectorSize, &Offset, SectorData);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  DPRINT("Signature 0x%02x 0x%02x 0x%02x 0x%02x\n",
+         *((UCHAR *) SectorData), *((UCHAR *) SectorData + 1), *((UCHAR *) SectorData + 2), *((UCHAR *) SectorData + 3));
+  *HasXboxPartitioning = (XBOX_SIGNATURE == *((ULONG *) SectorData));
+  ExFreePool(SectorData);
+  DPRINT("%s partitioning found\n", *HasXboxPartitioning ? "Xbox" : "MBR");
+
+  return STATUS_SUCCESS;
+}
+
+static VOID FASTCALL
+HalpXboxExamineMBR(IN PDEVICE_OBJECT DeviceObject,
+                   IN ULONG SectorSize,
+                   IN ULONG MBRTypeIdentifier,
+                   OUT PVOID *Buffer)
+{
+  BOOLEAN HasXboxPartitioning;
+  NTSTATUS Status;
+
+  DPRINT("HalpXboxExamineMBR(%p %lu %lx %p)\n",
+	 DeviceObject,
+	 SectorSize,
+	 MBRTypeIdentifier,
+	 Buffer);
+
+  *Buffer = NULL;
+
+  Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+  if (! NT_SUCCESS(Status))
+    {
+      return;
+    }
+
+  if (! HasXboxPartitioning)
+    {
+      DPRINT("Delegating to standard MBR code\n");
+      NtoskrnlExamineMBR(DeviceObject, SectorSize, MBRTypeIdentifier, Buffer);
+      return;
+    }
+
+  /* Buffer already set to NULL */
+  return;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
+                             ULONG SectorSize,
+                             BOOLEAN ReturnRecognizedPartitions,
+                             PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
+{
+  BOOLEAN HasXboxPartitioning;
+  NTSTATUS Status;
+  unsigned Part;
+  PPARTITION_INFORMATION PartInfo;
+
+  DPRINT("HalpXboxIoReadPartitionTable(%p %lu %x %p)\n",
+	 DeviceObject,
+	 SectorSize,
+	 ReturnRecognizedPartitions,
+	 PartitionBuffer);
+
+  Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  if (! HasXboxPartitioning)
+    {
+      DPRINT("Delegating to standard MBR code\n");
+      return NtoskrnlIoReadPartitionTable(DeviceObject, SectorSize,
+                                          ReturnRecognizedPartitions, PartitionBuffer);
+    }
+
+  *PartitionBuffer = (PDRIVE_LAYOUT_INFORMATION)
+                     ExAllocatePool(PagedPool,
+                                    sizeof(DRIVE_LAYOUT_INFORMATION) +
+                                    XBOX_PARTITION_COUNT * sizeof(PARTITION_INFORMATION));
+  if (NULL == *PartitionBuffer)
+    {
+      return STATUS_NO_MEMORY;
+    }
+  (*PartitionBuffer)->PartitionCount = XBOX_PARTITION_COUNT;
+  (*PartitionBuffer)->Signature = PARTITION_SIGNATURE;
+  for (Part = 0; Part < XBOX_PARTITION_COUNT; Part++)
+    {
+      PartInfo = (*PartitionBuffer)->PartitionEntry + Part;
+      PartInfo->StartingOffset.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorStart *
+                                          (ULONGLONG) SectorSize;
+      PartInfo->PartitionLength.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorCount *
+                                           (ULONGLONG) SectorSize;
+      PartInfo->HiddenSectors = 0;
+      PartInfo->PartitionNumber = Part + 1;
+      PartInfo->PartitionType = XboxPartitions[Part].PartitionType;
+      PartInfo->BootIndicator = FALSE;
+      PartInfo->RecognizedPartition = TRUE;
+      PartInfo->RewritePartition = FALSE;
+      DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
+             Part,
+             PartInfo->PartitionNumber,
+             PartInfo->BootIndicator,
+             PartInfo->PartitionType,
+             PartInfo->StartingOffset.QuadPart,
+             PartInfo->PartitionLength.QuadPart,
+             PartInfo->RecognizedPartition);
+    }
+
+  return STATUS_SUCCESS;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
+                                  IN ULONG SectorSize,
+                                  IN ULONG PartitionNumber,
+                                  IN ULONG PartitionType)
+{
+  BOOLEAN HasXboxPartitioning;
+  NTSTATUS Status;
+
+  DPRINT("HalpXboxIoSetPartitionInformation(%p %lu %lu %lu)\n",
+	 DeviceObject,
+	 SectorSize,
+	 PartitionNumber,
+	 PartitionType);
+
+  Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  if (! HasXboxPartitioning)
+    {
+      DPRINT("Delegating to standard MBR code\n");
+      return NtoskrnlIoSetPartitionInformation(DeviceObject, SectorSize,
+                                               PartitionNumber, PartitionType);
+    }
+
+  /* Can't change the partitioning */
+  DPRINT1("Xbox partitions are fixed, can't change them\n");
+  return STATUS_ACCESS_DENIED;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
+                              IN ULONG SectorSize,
+                              IN ULONG SectorsPerTrack,
+                              IN ULONG NumberOfHeads,
+                              IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
+{
+  BOOLEAN HasXboxPartitioning;
+  NTSTATUS Status;
+
+  DPRINT("HalpXboxIoWritePartitionTable(%p %lu %lu %lu %p)\n",
+	 DeviceObject,
+	 SectorSize,
+	 SectorsPerTrack,
+         NumberOfHeads,
+	 PartitionBuffer);
+
+  Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  if (! HasXboxPartitioning)
+    {
+      DPRINT("Delegating to standard MBR code\n");
+      return NtoskrnlIoWritePartitionTable(DeviceObject, SectorSize,
+                                           SectorsPerTrack, NumberOfHeads,
+                                           PartitionBuffer);
+    }
+
+  /* Can't change the partitioning */
+  DPRINT1("Xbox partitions are fixed, can't change them\n");
+  return STATUS_ACCESS_DENIED;
+}
+
+void
+HalpXboxInitPartIo(void)
+{
+  NtoskrnlExamineMBR = HalExamineMBR;
+  HalExamineMBR = HalpXboxExamineMBR;
+  NtoskrnlIoReadPartitionTable = HalIoReadPartitionTable;
+  HalIoReadPartitionTable = HalpXboxIoReadPartitionTable;
+  NtoskrnlIoSetPartitionInformation = HalIoSetPartitionInformation;
+  HalIoSetPartitionInformation = HalpXboxIoSetPartitionInformation;
+  NtoskrnlIoWritePartitionTable = HalIoWritePartitionTable;
+  HalIoWritePartitionTable = HalpXboxIoWritePartitionTable;
+}
+
+/* EOF */

reactos/hal/halx86/xbox
pci_xbox.c added at 1.3.2.1
diff -N pci_xbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pci_xbox.c	13 Dec 2004 16:18:25 -0000	1.3.2.1
@@ -0,0 +1,112 @@
+/* $Id: pci_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT:     See COPYING in the top level directory
+ * PROJECT:       ReactOS kernel
+ * FILE:          hal/halx86/xbox/pci_xbox.c
+ * PURPOSE:       Xbox specific handling of PCI cards
+ * PROGRAMMER:    Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ *             2004/12/04: Created
+ *
+ * Trying to get PCI config data from devices 0:0:1 and 0:0:2 will completely
+ * hang the Xbox. Also, the device number doesn't seem to be decoded for the
+ * video card, so it appears to be present on 1:0:0 - 1:31:0.
+ * We hack around these problems by indicating "device not present" for devices
+ * 0:0:1, 0:0:2, 1:1:0, 1:2:0, 1:3:0, ...., 1:31:0
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* VARIABLES ***************************************************************/
+
+static ULONG (STDCALL *GenericGetPciData)(PBUS_HANDLER BusHandler,
+                                          ULONG BusNumber,
+                                          ULONG SlotNumber,
+                                          PVOID Buffer,
+                                          ULONG Offset,
+                                          ULONG Length);
+static ULONG (STDCALL *GenericSetPciData)(PBUS_HANDLER BusHandler,
+                                          ULONG BusNumber,
+                                          ULONG SlotNumber,
+                                          PVOID Buffer,
+                                          ULONG Offset,
+                                          ULONG Length);
+
+/* FUNCTIONS ***************************************************************/
+
+static ULONG STDCALL
+HalpXboxGetPciData(PBUS_HANDLER BusHandler,
+                   ULONG BusNumber,
+                   ULONG SlotNumber,
+                   PVOID Buffer,
+                   ULONG Offset,
+                   ULONG Length)
+{
+  DPRINT("HalpXboxGetPciData() called.\n");
+  DPRINT("  BusNumber %lu\n", BusNumber);
+  DPRINT("  SlotNumber %lu\n", SlotNumber);
+  DPRINT("  Offset 0x%lx\n", Offset);
+  DPRINT("  Length 0x%lx\n", Length);
+
+  if ((0 == BusNumber && 0 == (SlotNumber & 0x1f) &&
+       (1 == ((SlotNumber >> 5) & 0x07) || 2 == ((SlotNumber >> 5) & 0x07))) ||
+      (1 == BusNumber && 0 != (SlotNumber & 0x1f)))
+    {
+      DPRINT("Blacklisted PCI slot\n");
+      if (0 == Offset && 2 <= Length)
+        {
+          *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+          return 2;
+        }
+      return 0;
+    }
+
+  return GenericGetPciData(BusHandler, BusNumber, SlotNumber, Buffer, Offset, Length);
+}
+
+static ULONG STDCALL
+HalpXboxSetPciData(PBUS_HANDLER BusHandler,
+                   ULONG BusNumber,
+                   ULONG SlotNumber,
+                   PVOID Buffer,
+                   ULONG Offset,
+                   ULONG Length)
+{
+  DPRINT("HalpXboxSetPciData() called.\n");
+  DPRINT("  BusNumber %lu\n", BusNumber);
+  DPRINT("  SlotNumber %lu\n", SlotNumber);
+  DPRINT("  Offset 0x%lx\n", Offset);
+  DPRINT("  Length 0x%lx\n", Length);
+
+  if ((0 == BusNumber && 0 == (SlotNumber & 0x1f) &&
+       (1 == ((SlotNumber >> 5) & 0x07) || 2 == ((SlotNumber >> 5) & 0x07))) ||
+      (1 == BusNumber && 0 != (SlotNumber & 0x1f)))
+    {
+      DPRINT1("Trying to set data on blacklisted PCI slot\n");
+      return 0;
+    }
+
+  return GenericSetPciData(BusHandler, BusNumber, SlotNumber, Buffer, Offset, Length);
+}
+
+void
+HalpXboxInitPciBus(ULONG BusNumber, PBUS_HANDLER BusHandler)
+{
+  if (0 == BusNumber || 1 == BusNumber)
+    {
+      GenericGetPciData = BusHandler->GetBusData;
+      BusHandler->GetBusData = HalpXboxGetPciData;
+      GenericSetPciData = BusHandler->SetBusData;
+      BusHandler->SetBusData = HalpXboxSetPciData;
+    }
+}
+
+/* EOF */

reactos/include/internal
port.h added at 1.5.6.1
diff -N port.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ port.h	13 Dec 2004 16:18:25 -0000	1.5.6.1
@@ -0,0 +1,151 @@
+#ifndef __INCLUDE_INTERNAL_PORT_H
+#define __INCLUDE_INTERNAL_PORT_H
+
+#include <napi/lpc.h>
+
+typedef
+struct _EPORT
+{
+	KSPIN_LOCK	Lock;
+	KEVENT		Event;
+
+	ULONG		State;
+
+	struct _EPORT	* OtherPort;
+   
+	ULONG		QueueLength;
+	LIST_ENTRY	QueueListHead;
+   
+	ULONG		ConnectQueueLength;
+	LIST_ENTRY	ConnectQueueListHead;
+
+	ULONG		MaxDataLength;
+	ULONG		MaxConnectInfoLength;
+
+} EPORT, * PEPORT;
+
+
+typedef struct _EPORT_TERMINATION_REQUEST
+{
+	LIST_ENTRY	ThreadListEntry;
+	PEPORT		Port;
+	
+} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
+
+
+NTSTATUS
+STDCALL
+LpcRequestPort (
+	PEPORT		Port,
+	PLPC_MESSAGE	LpcMessage
+	);
+NTSTATUS
+STDCALL
+LpcSendTerminationPort (
+	PEPORT	Port,
+	TIME	CreationTime
+	);
+
+
+/* Port Object Access */
+
+#define PORT_ALL_ACCESS               (0x1)
+
+
+/* EPORT.State */
+
+#define EPORT_INACTIVE                (0)
+#define EPORT_WAIT_FOR_CONNECT        (1)
+#define EPORT_WAIT_FOR_ACCEPT         (2)
+#define EPORT_WAIT_FOR_COMPLETE_SRV   (3)
+#define EPORT_WAIT_FOR_COMPLETE_CLT   (4)
+#define EPORT_CONNECTED_CLIENT        (5)
+#define EPORT_CONNECTED_SERVER        (6)
+#define EPORT_DISCONNECTED            (7)
+
+typedef
+struct _QUEUEDMESSAGE
+{
+	PEPORT		Sender;
+	LIST_ENTRY	QueueListEntry;
+	LPC_MESSAGE	Message;
+	UCHAR		MessageData [MAX_MESSAGE_DATA];
+	
+} QUEUEDMESSAGE,  *PQUEUEDMESSAGE;
+
+/* Code in ntoskrnl/lpc/close.c */
+
+VOID
+NiClosePort (
+	PVOID	ObjectBody,
+	ULONG	HandleCount
+	);
+VOID
+NiDeletePort (
+	IN	PVOID	ObjectBody
+	);
+
+
+/* Code in ntoskrnl/lpc/queue.c */
+
+VOID
+STDCALL
+EiEnqueueConnectMessagePort (
+	IN OUT	PEPORT		Port,
+	IN	PQUEUEDMESSAGE	Message
+	);
+VOID
+STDCALL
+EiEnqueueMessagePort (
+	IN OUT	PEPORT		Port,
+	IN	PQUEUEDMESSAGE	Message
+	);
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueConnectMessagePort (
+	IN OUT	PEPORT	Port
+	);
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueMessagePort (
+	IN OUT	PEPORT	Port
+	);
+
+/* Code in ntoskrnl/lpc/create.c */
+
+NTSTATUS
+NiCreatePort (
+	PVOID			ObjectBody,
+	PVOID			Parent,
+	PWSTR			RemainingPath,
+	POBJECT_ATTRIBUTES	ObjectAttributes
+	);
+
+/* Code in ntoskrnl/lpc/port.c */
+
+NTSTATUS
+STDCALL
+NiInitializePort (
+	IN OUT	PEPORT	Port
+	);
+NTSTATUS
+NiInitPort (
+	VOID
+	);
+
+extern POBJECT_TYPE	ExPortType;
+extern ULONG		EiNextLpcMessageId;
+
+/* Code in ntoskrnl/lpc/reply.c */
+
+NTSTATUS
+STDCALL
+EiReplyOrRequestPort (
+	IN	PEPORT		Port, 
+	IN	PLPC_MESSAGE	LpcReply, 
+	IN	ULONG		MessageType,
+	IN	PEPORT		Sender
+	);
+
+
+#endif /* __INCLUDE_INTERNAL_PORT_H */

reactos/lib/advapi32/crypt
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:25 -0000	1.1.2.1
@@ -0,0 +1,2 @@
+*.o
+.*.d

reactos/lib/advapi32/crypt
crypt.c added at 1.2.2.1
diff -N crypt.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,1926 @@
+/*
+ * Copyright 1999 Ian Schmidt
+ * Copyright 2001 Travis Michielsen
+ *
+ * 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:
+ *  - Reference counting
+ *  - Thread-safing
+ *  - Signature checking
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+HWND crypt_hWindow = 0;
+
+#define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;}
+
+#define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
+#define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
+
+static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName)
+{
+	PCSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
+	PSTR keyname;
+
+	keyname = CRYPT_Alloc(strlen(KEYSTR) + strlen(pProvName) +1);
+	if (keyname)
+	{
+		strcpy(keyname, KEYSTR);
+		strcpy(keyname + strlen(KEYSTR), pProvName);
+	}
+	else
+	{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+	}
+
+	return keyname;
+}
+
+static inline PSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user)
+{
+	PCSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
+	PCSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
+	PSTR keyname;
+	PSTR ptr;
+
+	keyname = CRYPT_Alloc( (user ? strlen(USERSTR) : strlen(MACHINESTR)) +1);
+	if (keyname)
+	{
+		user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR);
+		ptr = keyname + strlen(keyname);
+		*(--ptr) = (dwType % 10) + '0';
+		*(--ptr) = ((dwType / 10) % 10) + '0';
+		*(--ptr) = (dwType / 100) + '0';
+	}
+	else
+	{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+	}
+	return keyname;
+}
+
+/* CRYPT_UnicodeTOANSI
+ * wstr - unicode string
+ * str - pointer to ANSI string
+ * strsize - size of buffer pointed to by str or -1 if we have to do the allocation
+ *
+ * returns TRUE if unsuccessfull, FALSE otherwise.
+ * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
+ */
+static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize)
+{
+	int count;
+
+	if (!wstr)
+	{
+		*str = NULL;
+		return TRUE;
+	}
+	count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
+	count = count < strsize ? count : strsize;
+	if (strsize == -1)
+		*str = CRYPT_Alloc(count * sizeof(CHAR));
+	if (*str)
+	{
+		WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL);
+		return TRUE;
+	}
+	SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+	return FALSE;
+}
+
+/* CRYPT_ANSITOUnicode
+ * str - ANSI string
+ * wstr - pointer to unicode string
+ * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
+ */
+static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize)
+{
+	int wcount;
+
+	if (!str)
+	{
+		*wstr = NULL;
+		return TRUE;
+	}
+	wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+	wcount = wcount < wstrsize/sizeof(WCHAR) ? wcount : wstrsize/sizeof(WCHAR);
+	if (wstrsize == -1)
+		*wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
+	if (*wstr)
+	{
+		MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
+		return TRUE;
+	}
+	SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+	return FALSE;
+}
+
+/* These next 2 functions are used by the VTableProvStruc structure */
+static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData)
+{
+	if (!lpszImage || !pData)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+
+	DPRINT1("FIXME (%s, %p): not verifying image\n", lpszImage, pData);
+
+	return TRUE;
+}
+
+static BOOL CALLBACK CRYPT_ReturnhWnd(HWND *phWnd)
+{
+	if (!phWnd)
+		return FALSE;
+	*phWnd = crypt_hWindow;
+	return TRUE;
+}
+
+#define CRYPT_GetProvFunc(name) \
+	if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
+
+#define CRYPT_GetProvFuncOpt(name) \
+	provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
+PCRYPTPROV CRYPT_LoadProvider(PSTR pImage)
+{
+	PCRYPTPROV provider;
+	DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY;
+
+	if (!(provider = CRYPT_Alloc(sizeof(CRYPTPROV))))
+		goto error;
+	if (!(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))))
+		goto error;
+	if (!(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))))
+		goto error;
+	if (!(provider->hModule = LoadLibraryA(pImage)))
+	{
+		errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL;
+		DPRINT1("Failed to load dll %s\n", pImage);
+		goto error;
+	}
+	provider->refcount = 1;
+
+	errorcode = NTE_PROVIDER_DLL_FAIL;
+	CRYPT_GetProvFunc(CPAcquireContext);
+	CRYPT_GetProvFunc(CPCreateHash);
+	CRYPT_GetProvFunc(CPDecrypt);
+	CRYPT_GetProvFunc(CPDeriveKey);
+	CRYPT_GetProvFunc(CPDestroyHash);
+	CRYPT_GetProvFunc(CPDestroyKey);
+	CRYPT_GetProvFuncOpt(CPDuplicateHash);
+	CRYPT_GetProvFuncOpt(CPDuplicateKey);
+	CRYPT_GetProvFunc(CPEncrypt);
+	CRYPT_GetProvFunc(CPExportKey);
+	CRYPT_GetProvFunc(CPGenKey);
+	CRYPT_GetProvFunc(CPGenRandom);
+	CRYPT_GetProvFunc(CPGetHashParam);
+	CRYPT_GetProvFunc(CPGetKeyParam);
+	CRYPT_GetProvFunc(CPGetProvParam);
+	CRYPT_GetProvFunc(CPGetUserKey);
+	CRYPT_GetProvFunc(CPHashData);
+	CRYPT_GetProvFunc(CPHashSessionKey);
+	CRYPT_GetProvFunc(CPImportKey);
+	CRYPT_GetProvFunc(CPReleaseContext);
+	CRYPT_GetProvFunc(CPSetHashParam);
+	CRYPT_GetProvFunc(CPSetKeyParam);
+	CRYPT_GetProvFunc(CPSetProvParam);
+	CRYPT_GetProvFunc(CPSignHash);
+	CRYPT_GetProvFunc(CPVerifySignature);
+
+	/* FIXME: Not sure what the pbContextInfo field is for.
+	 *        Does it need memory allocation?
+	 */
+	provider->pVTable->Version = 3;
+	provider->pVTable->pFuncVerifyImage = (FARPROC)CRYPT_VerifyImage;
+	provider->pVTable->pFuncReturnhWnd = (FARPROC)CRYPT_ReturnhWnd;
+	provider->pVTable->dwProvType = 0;
+	provider->pVTable->pbContextInfo = NULL;
+	provider->pVTable->cbContextInfo = 0;
+	provider->pVTable->pszProvName = NULL;
+	return provider;
+
+error:
+	SetLastError(errorcode);
+	if (provider)
+	{
+		if (provider->hModule)
+			FreeLibrary(provider->hModule);
+		CRYPT_Free(provider->pVTable);
+		CRYPT_Free(provider->pFuncs);
+		CRYPT_Free(provider);
+	}
+	return NULL;
+}
+#undef CRYPT_GetProvFunc
+#undef CRYPT_GetProvFuncOpt
+
+
+/******************************************************************************
+ * CryptAcquireContextA (ADVAPI32.@)
+ * Acquire a crypto provider context handle.
+ *
+ * PARAMS
+ * phProv: Pointer to HCRYPTPROV for the output.
+ * pszContainer: Key Container Name
+ * pszProvider: Cryptographic Service Provider Name
+ * dwProvType: Crypto provider type to get a handle.
+ * dwFlags: flags for the operation
+ *
+ * RETURNS TRUE on success, FALSE on failure.
+ */
+BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
+		LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
+{
+	PCRYPTPROV pProv = NULL;
+	HKEY key;
+	PSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL;
+	BYTE* signature;
+	DWORD keytype, type, len;
+	ULONG r;
+
+	DPRINT("(%p, %s, %s, %ld, %08lx)\n", phProv, pszContainer,
+		pszProvider, dwProvType, dwFlags);
+
+	if (dwProvType < 1 || dwProvType > MAXPROVTYPES)
+	{
+		SetLastError(NTE_BAD_PROV_TYPE);
+		return FALSE;
+	}
+	
+	if (!phProv)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+
+	if (!pszProvider || !*pszProvider)
+	{
+		/* No CSP name specified so try the user default CSP first
+		 * then try the machine default CSP
+		 */
+		if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)))
+		{
+			DPRINT("No provider registered for crypto provider type %ld.\n", dwProvType);
+			SetLastError(NTE_PROV_TYPE_NOT_DEF);
+			return FALSE;
+		}
+
+		if (RegOpenKeyA(HKEY_CURRENT_USER, keyname, &key))
+		{
+			CRYPT_Free(keyname);
+			if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)))
+			{
+				DPRINT("No type registered for crypto provider type %ld.\n", dwProvType);
+				RegCloseKey(key);
+				SetLastError(NTE_PROV_TYPE_NOT_DEF);
+				goto error;
+			}
+
+			if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key))
+			{
+				DPRINT("Did not find registry entry of crypto provider for %S.\n", keyname);
+				CRYPT_Free(keyname);
+				RegCloseKey(key);
+				SetLastError(NTE_PROV_TYPE_NOT_DEF);
+				goto error;
+			}
+		}
+
+		CRYPT_Free(keyname);
+		r = RegQueryValueExA(key, "Name", NULL, &keytype, NULL, &len);
+		if (r != ERROR_SUCCESS || !len || keytype != REG_SZ)
+		{
+			DPRINT("error %ld reading size of 'Name' from registry\n", r );
+			RegCloseKey(key);
+			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+			goto error;
+		}
+		if (!(provname = CRYPT_Alloc(len)))
+		{
+			RegCloseKey(key);
+			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+			goto error;
+		}
+		r = RegQueryValueExA(key, "Name", NULL, NULL, provname, &len);
+		if (r != ERROR_SUCCESS)
+		{
+			DPRINT("error %ld reading 'Name' from registry\n", r );
+			RegCloseKey(key);
+			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+			goto error;
+		}
+		RegCloseKey(key);
+	}
+	else
+	{
+		if (!(provname = CRYPT_Alloc(strlen(pszProvider) +1)))
+		{
+			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+			goto error;
+		}
+		strcpy(provname, pszProvider);
+	}
+
+	keyname = CRYPT_GetProvKeyName(provname);
+	r = RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key);
+	CRYPT_Free(keyname);
+	if (r != ERROR_SUCCESS)
+	{
+		SetLastError(NTE_KEYSET_NOT_DEF);
+		goto error;
+	}
+	len = sizeof(DWORD);
+	r = RegQueryValueExA(key, "Type", NULL, NULL, (BYTE*)&type, &len);
+	if (r != ERROR_SUCCESS)
+	{
+		SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+		goto error;
+	}
+	if (type != dwProvType)
+	{
+		DPRINT("Crypto provider has wrong type (%ld vs expected %ld).\n", type, dwProvType);
+		SetLastError(NTE_PROV_TYPE_NO_MATCH);
+		goto error;
+	}
+
+	r = RegQueryValueExA(key, "Image Path", NULL, &keytype, NULL, &len);
+	if ( r != ERROR_SUCCESS || keytype != REG_SZ)
+	{
+		DPRINT("error %ld reading size of 'Image Path' from registry\n", r );
+		RegCloseKey(key);
+		SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+		goto error;
+	}
+	if (!(temp = CRYPT_Alloc(len)))
+	{
+		RegCloseKey(key);
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		goto error;
+	}
+	r = RegQueryValueExA(key, "Image Path", NULL, NULL, temp, &len);
+	if (r != ERROR_SUCCESS)
+	{
+		DPRINT("error %ld reading 'Image Path' from registry\n", r );
+		RegCloseKey(key);
+		SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+		goto error;
+	}
+
+	r = RegQueryValueExA(key, "Signature", NULL, &keytype, NULL, &len);
+	if (r == ERROR_SUCCESS && keytype == REG_BINARY)
+	{
+		if (!(signature = CRYPT_Alloc(len)))
+		{
+			RegCloseKey(key);
+			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+			goto error;
+		}
+		r = RegQueryValueExA(key, "Signature", NULL, NULL, signature, &len);
+		if (r != ERROR_SUCCESS)
+		{
+			DPRINT("error %ld reading 'Signature'\n", r );
+			CRYPT_Free(signature);
+			RegCloseKey(key);
+			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+			goto error;
+		}
+	}
+	else
+	{
+		r = RegQueryValueExA(key, "SigInFile", NULL, &keytype, NULL, &len);
+		if (r != ERROR_SUCCESS)
+		{
+			DPRINT("error %ld reading size of 'SigInFile'\n", r );
+			RegCloseKey(key);
+			SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+			goto error;
+		}
+		else
+		{
+			/* FIXME: The presence of the SigInFile value indicates the
+			 * provider's signature is in its resources, so need to read it.
+			 * But since CRYPT_VerifyImage is stubbed, provide any old thing
+			 * for now.
+			 */
+			if (!(signature = CRYPT_Alloc(1)))
+			{
+				RegCloseKey(key);
+				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+				goto error;
+			}
+		}
+	}
+	RegCloseKey(key);
+	len = ExpandEnvironmentStringsA(temp, NULL, 0);
+	if (!(imagepath = CRYPT_Alloc(len)))
+	{
+		CRYPT_Free(signature);
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		goto error;
+	}
+	if (!ExpandEnvironmentStringsA(temp, imagepath, len))
+	{
+		CRYPT_Free(signature);
+		/* ExpandEnvironmentStrings will call SetLastError */
+		goto error;
+	}
+
+	if (!CRYPT_VerifyImage(imagepath, signature))
+	{
+		CRYPT_Free(signature);
+		SetLastError(NTE_SIGNATURE_FILE_BAD);
+		goto error;
+	}
+	pProv = CRYPT_LoadProvider(imagepath);
+	CRYPT_Free(signature);
+	if (!pProv)
+	{
+		/* CRYPT_LoadProvider calls SetLastError */
+		goto error;
+	}
+	pProv->pVTable->dwProvType = dwProvType;
+	pProv->pVTable->pszProvName = provname;
+	if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, (CHAR*)pszContainer, dwFlags, pProv->pVTable))
+	{
+		/* MSDN: When this flag is set, the value returned in phProv is undefined,
+		 *       and thus, the CryptReleaseContext function need not be called afterwards.
+		 *       Therefore, we must clean up everything now.
+		 */
+		if (dwFlags & CRYPT_DELETEKEYSET)
+		{
+			FreeLibrary(pProv->hModule);
+			CRYPT_Free(provname);
+			CRYPT_Free(pProv->pFuncs);
+			CRYPT_Free(pProv);
+		}
+		else
+		{
+			*phProv = (HCRYPTPROV)pProv;
+		}
+		CRYPT_Free(temp);
+		CRYPT_Free(imagepath);
+		return TRUE;
+	}
+	/* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
+error:
+	if (pProv)
+	{
+		if (pProv->hModule)
+			FreeLibrary(pProv->hModule);
+		if (pProv->pVTable)
+			CRYPT_Free(pProv->pVTable);
+		if (pProv->pFuncs)
+			CRYPT_Free(pProv->pFuncs);
+		CRYPT_Free(pProv);
+	}
+	if (provname)
+		CRYPT_Free(provname);
+	if (temp)
+		CRYPT_Free(temp);
+	if (imagepath)
+		CRYPT_Free(imagepath);
+	return FALSE;
+}
+
+/******************************************************************************
+ * CryptAcquireContextW (ADVAPI32.@)
+ *
+ * see CryptAcquireContextA
+ */
+BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
+		LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
+{
+	PSTR pProvider = NULL, pContainer = NULL;
+	BOOL ret = FALSE;
+
+	DPRINT("(%p, %S, %S, %ld, %08lx)\n", phProv, pszContainer,
+		pszProvider, dwProvType, dwFlags);
+
+	if (!CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1))
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+	if (!CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1))
+	{
+		CRYPT_Free(pContainer);
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+	}
+
+	ret = CryptAcquireContextA(phProv, pContainer, pProvider, dwProvType, dwFlags);
+
+	if (pContainer)
+		CRYPT_Free(pContainer);
+	if (pProvider)
+		CRYPT_Free(pProvider);
+
+	return ret;
+}
+
+/******************************************************************************
+ * CryptContextAddRef (ADVAPI32.@)
+ *
+ * Increases reference count of a cryptographic service provider handle
+ * by one.
+ *
+ * PARAMS
+ *  hProv       [I] Handle to the CSP whose reference is being incremented.
+ *  pdwReserved [IN] Reserved for future use and must be NULL.
+ *  dwFlags     [I] Reserved for future use and must be NULL.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags)
+{
+	PCRYPTPROV pProv = (PCRYPTPROV)hProv;
+
+	DPRINT("(0x%lx, %p, %08lx)\n", hProv, pdwReserved, dwFlags);
+
+	if (!pProv)
+	{
+		SetLastError(NTE_BAD_UID);
+		return FALSE;
+	}
+
+	pProv->refcount++;
+	return TRUE;
+}
+
+/******************************************************************************
+ * CryptReleaseContext (ADVAPI32.@)
+ *
+ * Releases the handle of a CSP.  Reference count is decreased.
+ *
+ * PARAMS
+ *  hProv   [I] Handle of a CSP.
+ *  dwFlags [I] Reserved for future use and must be NULL.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
+{
+	PCRYPTPROV pProv = (PCRYPTPROV)hProv;
+	BOOL ret = TRUE;
+
+	DPRINT("(0x%lx, %08ld)\n", hProv, dwFlags);
+
+	if (!pProv)
+	{
+		SetLastError(NTE_BAD_UID);
+		return FALSE;
+	}
+
+	pProv->refcount--;
+	if (pProv->refcount <= 0)
+	{
+		ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
+		FreeLibrary(pProv->hModule);
+#if 0
+		CRYPT_Free(pProv->pVTable->pContextInfo);
+#endif
+		CRYPT_Free(pProv->pVTable->pszProvName);
+		CRYPT_Free(pProv->pVTable);
+		CRYPT_Free(pProv->pFuncs);
+		CRYPT_Free(pProv);
+	}
+	return ret;
+}
+
+/******************************************************************************
+ * CryptGenRandom (ADVAPI32.@)
+ *
+ * Fills a buffer with cryptographically random bytes.
+ *
+ * PARAMS
+ *  hProv    [I] Handle of a CSP.
+ *  dwLen    [I] Number of bytes to generate.
+ *  pbBuffer [I/O] Buffer to contain random bytes.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ * NOTES
+ *  pdBuffer must be at least dwLen bytes long.
+ */
+BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
+{
+	PCRYPTPROV prov = (PCRYPTPROV)hProv;
+
+	DPRINT("(0x%lx, %ld, %p)\n", hProv, dwLen, pbBuffer);
+
+	if (!hProv)
+		CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+	return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
+}
+
+/******************************************************************************
+ * CryptCreateHash (ADVAPI32.@)
+ *
+ * Initiates the hashing of a stream of data.
+ *
+ * PARAMS
+ *  hProv   [I] Handle of a CSP.
+ *  Algid   [I] Identifies the hash algorithm to use.
+ *  hKey    [I] Key for the hash (if required).
+ *  dwFlags [I] Reserved for future use and must be NULL.
+ *  phHash  [O] Address of the future handle to the new hash object.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ * NOTES
+ *  If the algorithm is a keyed hash, hKey is the key.
+ */
+BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
+		DWORD dwFlags, HCRYPTHASH *phHash)
+{
+	PCRYPTPROV prov = (PCRYPTPROV)hProv;
+	PCRYPTKEY key = (PCRYPTKEY)hKey;
+	PCRYPTHASH hash;
+
+	DPRINT("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
+
+	if (!prov)
+		CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+	if (!phHash)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+	if (dwFlags)
+		CRYPT_ReturnLastError(NTE_BAD_FLAGS);
+	if (!(hash = CRYPT_Alloc(sizeof(CRYPTHASH))))
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+	hash->pProvider = prov;
+
+	if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid,
+			key ? key->hPrivate : 0, 0, &hash->hPrivate))
+	{
+		*phHash = (HCRYPTHASH)hash;
+		return TRUE;
+	}
+
+	/* CSP error! */
+	CRYPT_Free(hash);
+	*phHash = 0;
+	return FALSE;
+}
+
+/******************************************************************************
+ * CryptDecrypt (ADVAPI32.@)
+ *
+ * Decrypts data encrypted by CryptEncrypt.
+ *
+ * PARAMS
+ *  hKey       [I] Handle to the decryption key.
+ *  hHash      [I] Handle to a hash object.
+ *  Final      [I] TRUE if this is the last section to be decrypted.
+ *  dwFlags    [I] Reserved for future use. Can be CRYPT_OAEP.
+ *  pbData     [I/O] Buffer that holds the encrypted data. Holds decrypted
+ *                   data on return
+ *  pdwDataLen [I/O] Length of pbData before and after the call.
+ *
+ *  RETURNS
+ *   Success: TRUE
+ *   Failure: FALSE
+ */
+BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
+		DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
+{
+	PCRYPTPROV prov;
+	PCRYPTKEY key = (PCRYPTKEY)hKey;
+	PCRYPTHASH hash = (PCRYPTHASH)hHash;
+
+	DPRINT("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
+
+	if (!key || !pbData || !pdwDataLen)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+	prov = key->pProvider;
+	return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
+			Final, dwFlags, pbData, pdwDataLen);
+}
+
+/******************************************************************************
+ * CryptDeriveKey (ADVAPI32.@)
+ *
+ * Generates session keys derived from a base data value.
+ *
+ * PARAMS
+ *  hProv     [I] Handle to a CSP.
+ *  Algid     [I] Identifies the symmetric encryption algorithm to use.
+ *  hBaseData [I] Handle to a hash object.
+ *  dwFlags   [I] Type of key to generate.
+ *  phKey     [I/O] Address of the newly generated key.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData,
+		DWORD dwFlags, HCRYPTKEY *phKey)
+{
+	PCRYPTPROV prov = (PCRYPTPROV)hProv;
+	PCRYPTHASH hash = (PCRYPTHASH)hBaseData;
+	PCRYPTKEY key;
+
+	DPRINT("(0x%lx, 0x%08x, 0x%lx, 0x%08lx, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
+
+	if (!prov || !hash)
+		CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+	if (!phKey)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+	if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+	key->pProvider = prov;
+	if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate))
+	{
+		*phKey = (HCRYPTKEY)key;
+		return TRUE;
+	}
+
+	/* CSP error! */
+	CRYPT_Free(key);
+	*phKey = 0;
+	return FALSE;
+}
+
+/******************************************************************************
+ * CryptDestroyHash (ADVAPI32.@)
+ *
+ * Destroys the hash object referenced by hHash.
+ *
+ * PARAMS
+ *  hHash [I] Handle of the hash object to be destroyed.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
+{
+	PCRYPTHASH hash = (PCRYPTHASH)hHash;
+	PCRYPTPROV prov;
+	BOOL ret;
+
+	DPRINT("(0x%lx)\n", hHash);
+
+	if (!hash)
+		CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+	prov = hash->pProvider;
+	ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
+	CRYPT_Free(hash);
+	return ret;
+}
+
+/******************************************************************************
+ * CryptDestroyKey (ADVAPI32.@)
+ *
+ * Releases the handle referenced by hKey.
+ *
+ * PARAMS
+ *  hKey [I] Handle of the key to be destroyed.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
+{
+	PCRYPTKEY key = (PCRYPTKEY)hKey;
+	PCRYPTPROV prov;
+	BOOL ret;
+
+	DPRINT("(0x%lx)\n", hKey);
+
+	if (!key)
+		CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+	prov = key->pProvider;
+	ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
+	CRYPT_Free(key);
+	return ret;
+}
+
+/******************************************************************************
+ * CryptDuplicateHash (ADVAPI32.@)
+ *
+ * Duplicates a hash.
+ *
+ * PARAMS
+ *  hHash       [I] Handle to the hash to be copied.
+ *  pdwReserved [I] Reserved for future use and must be zero.
+ *  dwFlags     [I] Reserved for future use and must be zero.
+ *  phHash      [O] Address of the handle to receive the copy.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
+		DWORD dwFlags, HCRYPTHASH *phHash)
+{
+	PCRYPTPROV prov;
+	PCRYPTHASH orghash, newhash;
+
+	DPRINT("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
+
+	orghash = (PCRYPTHASH)hHash;
+	if (!orghash || pdwReserved || !phHash)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+	prov = orghash->pProvider;
+	if (!prov->pFuncs->pCPDuplicateHash)
+		CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+	if (!(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))))
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+	newhash->pProvider = prov;
+	if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate))
+	{
+		*phHash = (HCRYPTHASH)newhash;
+		return TRUE;
+	}
+	CRYPT_Free(newhash);
+	return FALSE;
+}
+
+/******************************************************************************
+ * CryptDuplicateKey (ADVAPI32.@)
+ *
+ * Duplicate a key and the key's state.
+ *
+ * PARAMS
+ *  hKey        [I] Handle of the key to copy.
+ *  pdwReserved [I] Reserved for future use and must be NULL.
+ *  dwFlags     [I] Reserved for future use and must be zero.
+ *  phKey       [I] Address of the handle to the duplicated key.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
+{
+	PCRYPTPROV prov;
+	PCRYPTKEY orgkey, newkey;
+
+	DPRINT("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
+
+	orgkey = (PCRYPTKEY)hKey;
+	if (!orgkey || pdwReserved || !phKey)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+	prov = orgkey->pProvider;
+	if (!prov->pFuncs->pCPDuplicateKey)
+		CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+	if (!(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))))
+		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+	newkey->pProvider = prov;
+	if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate))
+	{
+		*phKey = (HCRYPTKEY)newkey;
+		return TRUE;
+	}
+	CRYPT_Free(newkey);
+	return FALSE;
+}
+
+/******************************************************************************
+ * CryptEncrypt (ADVAPI32.@)
+ *
+ * Encrypts data.
+ *
+ * PARAMS
+ *  hKey       [I] Handle to the enryption key.
+ *  hHash      [I] Handle to a hash object.
+ *  Final      [I] TRUE if this is the last section to encrypt.
+ *  dwFlags    [I] Can be CRYPT_OAEP.
+ *  pbData     [I/O] Data to be encrypted. Contains encrypted data after call.
+ *  pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
+ *                   encrypted data after call.
+ *  dwBufLen   [I] Length of the input pbData buffer.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ *  NOTES
+ *   If pbData is NULL, CryptEncrypt determines stores the number of bytes
+ *   required for the returned data in pdwDataLen.
+ */
+BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
+		DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
+{
+	PCRYPTPROV prov;
+	PCRYPTKEY key = (PCRYPTKEY)hKey;
+	PCRYPTHASH hash = (PCRYPTHASH)hHash;
+
+	DPRINT("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
+
+	if (!key || !pdwDataLen)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+	prov = key->pProvider;
+	return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
+			Final, dwFlags, pbData, pdwDataLen, dwBufLen);
+}
+
+/******************************************************************************
+ * CryptEnumProvidersW (ADVAPI32.@)
+ *
+ * Returns the next availabe CSP.
+ *
+ * PARAMS
+ *  dwIndex     [I] Index of the next provider to be enumerated.
+ *  pdwReserved [I] Reserved for future use and must be NULL.
+ *  dwFlags     [I] Reserved for future use and must be zero.
+ *  pdwProvType [O] DWORD designating the type of the provider.
+ *  pszProvName [O] Buffer that receives data from the provider.
+ *  pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
+ *                    of bytes stored in the buffer on return.
+ *
+ *  RETURNS
+ *   Success: TRUE
+ *   Failure: FALSE
+ *
+ *  NOTES
+ *   If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
+ *   for memory allocation purposes.
+ */
+BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved,
+		DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
+{
+	HKEY hKey;
+
+	DPRINT("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
+		pdwProvType, pszProvName, pcbProvName);
+
+	if (pdwReserved || !pcbProvName)
+		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+	if (dwFlags)
+		CRYPT_ReturnLastError(NTE_BAD_FLAGS);
+
+	if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
+			L"Software\\Microsoft\\Cryptography\\Defaults\\Provider",
[truncated at 1000 lines; 930 more skipped]

reactos/lib/advapi32/crypt
crypt.h added at 1.2.2.1
diff -N crypt.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt.h	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,86 @@
+/*
+ * Driver routines
+ *
+ * Copyright 2001 - Travis Michielsen
+ *
+ * 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_CRYPT_H
+#define __WINE_CRYPT_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+
+typedef struct tagPROVFUNCS
+{
+	BOOL (WINAPI *pCPAcquireContext)(HCRYPTPROV *phProv, LPSTR pszContainer, DWORD dwFlags, PVTableProvStruc pVTable);
+	BOOL (WINAPI *pCPCreateHash)(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash);
+	BOOL (WINAPI *pCPDecrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen);
+	BOOL (WINAPI *pCPDeriveKey)(HCRYPTPROV hProv, ALG_ID     Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey);
+	BOOL (WINAPI *pCPDestroyHash)(HCRYPTPROV hProv, HCRYPTHASH hHash);
+	BOOL (WINAPI *pCPDestroyKey)(HCRYPTPROV hProv, HCRYPTKEY hKey);
+	BOOL (WINAPI *pCPDuplicateHash)(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash);
+	BOOL (WINAPI *pCPDuplicateKey)(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey);
+	BOOL (WINAPI *pCPEncrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen);
+	BOOL (WINAPI *pCPExportKey)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen);
+	BOOL (WINAPI *pCPGenKey)(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey);
+	BOOL (WINAPI *pCPGenRandom)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);
+	BOOL (WINAPI *pCPGetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+	BOOL (WINAPI *pCPGetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+	BOOL (WINAPI *pCPGetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+	BOOL (WINAPI *pCPGetUserKey)(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey);
+	BOOL (WINAPI *pCPHashData)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags);
+	BOOL (WINAPI *pCPHashSessionKey)(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags);
+	BOOL (WINAPI *pCPImportKey)(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey);
+	BOOL (WINAPI *pCPReleaseContext)(HCRYPTPROV hProv, DWORD dwFlags);
+	BOOL (WINAPI *pCPSetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+	BOOL (WINAPI *pCPSetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+	BOOL (WINAPI *pCPSetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+	BOOL (WINAPI *pCPSignHash)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen);
+	BOOL (WINAPI *pCPVerifySignature)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags);
+} PROVFUNCS, *PPROVFUNCS;
+
+typedef struct tagCRYPTPROV
+{
+	UINT refcount;
+	HMODULE hModule;
+	PPROVFUNCS pFuncs;
+	HCRYPTPROV hPrivate;  /*CSP's handle - Should not be given to application under any circumstances!*/
+	PVTableProvStruc pVTable;
+} CRYPTPROV, *PCRYPTPROV;
+
+typedef struct tagCRYPTKEY
+{
+	PCRYPTPROV pProvider;
+	HCRYPTKEY hPrivate;    /*CSP's handle - Should not be given to application under any circumstances!*/
+} CRYPTKEY, *PCRYPTKEY;
+
+typedef struct tagCRYPTHASH
+{
+	PCRYPTPROV pProvider;
+	HCRYPTHASH hPrivate;    /*CSP's handle - Should not be given to application under any circumstances!*/
+} CRYPTHASH, *PCRYPTHASH;
+
+#define MAXPROVTYPES 999
+
+extern unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key );
+extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key,
+                                     const unsigned char *src );
+
+#endif /* __WINE_CRYPT_H_ */

reactos/lib/advapi32/crypt
crypt_des.c added at 1.2.2.1
diff -N crypt_des.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt_des.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,291 @@
+/*
+ *  Copyright 2004 Hans Leidekker
+ *
+ *  Based on DES.c from libcifs
+ *
+ *  Copyright (C) 2003, 2004 by Christopher R. Hertel
+ *
+ *  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 "advapi32.h"
+#include "crypt.h"
+
+static const unsigned char InitialPermuteMap[64] =
+{
+    57, 49, 41, 33, 25, 17,  9, 1,
+    59, 51, 43, 35, 27, 19, 11, 3,
+    61, 53, 45, 37, 29, 21, 13, 5,
+    63, 55, 47, 39, 31, 23, 15, 7,
+    56, 48, 40, 32, 24, 16,  8, 0,
+    58, 50, 42, 34, 26, 18, 10, 2,
+    60, 52, 44, 36, 28, 20, 12, 4,
+    62, 54, 46, 38, 30, 22, 14, 6
+ };
+
+static const unsigned char KeyPermuteMap[56] =
+{
+    49, 42, 35, 28, 21, 14,  7,  0,
+    50, 43, 36, 29, 22, 15,  8,  1,
+    51, 44, 37, 30, 23, 16,  9,  2,
+    52, 45, 38, 31, 55, 48, 41, 34,
+    27, 20, 13,  6, 54, 47, 40, 33,
+    26, 19, 12,  5, 53, 46, 39, 32,
+    25, 18, 11,  4, 24, 17, 10,  3,
+};
+
+static const unsigned char KeyRotation[16] =
+    { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
+
+static const unsigned char KeyCompression[48] =
+{
+    13, 16, 10, 23,  0,  4,  2, 27,
+    14,  5, 20,  9, 22, 18, 11,  3,
+    25,  7, 15,  6, 26, 19, 12,  1,
+    40, 51, 30, 36, 46, 54, 29, 39,
+    50, 44, 32, 47, 43, 48, 38, 55,
+    33, 52, 45, 41, 49, 35, 28, 31
+};
+
+static const unsigned char DataExpansion[48] =
+{
+    31,  0,  1,  2,  3,  4,  3,  4,
+     5,  6,  7,  8,  7,  8,  9, 10,
+    11, 12, 11, 12, 13, 14, 15, 16,
+    15, 16, 17, 18, 19, 20, 19, 20,
+    21, 22, 23, 24, 23, 24, 25, 26,
+    27, 28, 27, 28, 29, 30, 31,  0
+};
+
+static const unsigned char SBox[8][64] =
+{
+    {  /* S0 */
+        14,  0,  4, 15, 13,  7,  1,  4,  2, 14, 15,  2, 11, 13,  8,  1,
+         3, 10, 10,  6,  6, 12, 12, 11,  5,  9,  9,  5,  0,  3,  7,  8,
+         4, 15,  1, 12, 14,  8,  8,  2, 13,  4,  6,  9,  2,  1, 11,  7,
+        15,  5, 12, 11,  9,  3,  7, 14,  3, 10, 10,  0,  5,  6,  0, 13
+    },
+    {  /* S1 */
+        15,  3,  1, 13,  8,  4, 14,  7,  6, 15, 11,  2,  3,  8,  4, 14,
+         9, 12,  7,  0,  2,  1, 13, 10, 12,  6,  0,  9,  5, 11, 10,  5,
+         0, 13, 14,  8,  7, 10, 11,  1, 10,  3,  4, 15, 13,  4,  1,  2,
+         5, 11,  8,  6, 12,  7,  6, 12,  9,  0,  3,  5,  2, 14, 15,  9
+    },
+    {  /* S2 */
+        10, 13,  0,  7,  9,  0, 14,  9,  6,  3,  3,  4, 15,  6,  5, 10,
+         1,  2, 13,  8, 12,  5,  7, 14, 11, 12,  4, 11,  2, 15,  8,  1,
+        13,  1,  6, 10,  4, 13,  9,  0,  8,  6, 15,  9,  3,  8,  0,  7,
+        11,  4,  1, 15,  2, 14, 12,  3,  5, 11, 10,  5, 14,  2,  7, 12
+    },
+    {  /* S3 */
+         7, 13, 13,  8, 14, 11,  3,  5,  0,  6,  6, 15,  9,  0, 10,  3,
+         1,  4,  2,  7,  8,  2,  5, 12, 11,  1, 12, 10,  4, 14, 15,  9,
+        10,  3,  6, 15,  9,  0,  0,  6, 12, 10, 11,  1,  7, 13, 13,  8,
+        15,  9,  1,  4,  3,  5, 14, 11,  5, 12,  2,  7,  8,  2,  4, 14
+    },
+    {  /* S4 */
+         2, 14, 12, 11,  4,  2,  1, 12,  7,  4, 10,  7, 11, 13,  6,  1,
+         8,  5,  5,  0,  3, 15, 15, 10, 13,  3,  0,  9, 14,  8,  9,  6,
+         4, 11,  2,  8,  1, 12, 11,  7, 10,  1, 13, 14,  7,  2,  8, 13,
+        15,  6,  9, 15, 12,  0,  5,  9,  6, 10,  3,  4,  0,  5, 14,  3
+    },
+    {  /* S5 */
+        12, 10,  1, 15, 10,  4, 15,  2,  9,  7,  2, 12,  6,  9,  8,  5,
+         0,  6, 13,  1,  3, 13,  4, 14, 14,  0,  7, 11,  5,  3, 11,  8,
+         9,  4, 14,  3, 15,  2,  5, 12,  2,  9,  8,  5, 12, 15,  3, 10,
+         7, 11,  0, 14,  4,  1, 10,  7,  1,  6, 13,  0, 11,  8,  6, 13
+    },
+    {  /* S6 */
+         4, 13, 11,  0,  2, 11, 14,  7, 15,  4,  0,  9,  8,  1, 13, 10,
+         3, 14, 12,  3,  9,  5,  7, 12,  5,  2, 10, 15,  6,  8,  1,  6,
+         1,  6,  4, 11, 11, 13, 13,  8, 12,  1,  3,  4,  7, 10, 14,  7,
+        10,  9, 15,  5,  6,  0,  8, 15,  0, 14,  5,  2,  9,  3,  2, 12
+    },
+    {  /* S7 */
+        13,  1,  2, 15,  8, 13,  4,  8,  6, 10, 15,  3, 11,  7,  1,  4,
+        10, 12,  9,  5,  3,  6, 14, 11,  5,  0,  0, 14, 12,  9,  7,  2,
+         7,  2, 11,  1,  4, 14,  1,  7,  9,  4, 12, 10, 14,  8,  2, 13,
+         0, 15,  6, 12, 10,  9, 13,  0, 15,  3,  3,  5,  5,  6,  8, 11
+    }
+};
+
+static const unsigned char PBox[32] =
+{
+    15,  6, 19, 20, 28, 11, 27, 16,
+     0, 14, 22, 25,  4, 17, 30,  9,
+     1,  7, 23, 13, 31, 26,  2,  8,
+    18, 12, 29,  5, 21, 10,  3, 24
+};
+
+static const unsigned char FinalPermuteMap[64] =
+{
+     7, 39, 15, 47, 23, 55, 31, 63,
+     6, 38, 14, 46, 22, 54, 30, 62,
+     5, 37, 13, 45, 21, 53, 29, 61,
+     4, 36, 12, 44, 20, 52, 28, 60,
+     3, 35, 11, 43, 19, 51, 27, 59,
+     2, 34, 10, 42, 18, 50, 26, 58,
+     1, 33,  9, 41, 17, 49, 25, 57,
+     0, 32,  8, 40, 16, 48, 24, 56
+};
+
+#define CLRBIT(STR, IDX) ((STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))))
+#define SETBIT(STR, IDX) ((STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))))
+#define GETBIT(STR, IDX) ((((STR)[(IDX)/8]) >> (7 - ((IDX)%8))) & 0x01)
+
+static void Permute(unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize)
+{
+    int bitcount, i;
+
+    for (i = 0; i < mapsize; i++)
+        dst[i] = 0;
+
+    bitcount = mapsize * 8;
+
+    for (i = 0; i < bitcount; i++)
+    {
+        if (GETBIT(src, map[i]))
+            SETBIT(dst, i);
+    }
+}
+
+static void KeyShift(unsigned char *key, const int numbits)
+{
+    int i;
+    unsigned char keep = key[0];
+
+    for (i = 0; i < numbits; i++)
+    {
+        int j;
+
+        for (j = 0; j < 7; j++)
+        {
+            if (j && (key[j] & 0x80))
+                key[j-1] |=  0x01;
+            key[j] <<= 1;
+        }
+
+        if (GETBIT(key, 27))
+        {
+            CLRBIT(key, 27);
+            SETBIT(key, 55);
+        }
+
+        if (keep & 0x80)
+            SETBIT(key, 27);
+
+        keep <<= 1;
+    }
+}
+
+static void sbox(unsigned char *dst, const unsigned char *src)
+{
+    int i;
+
+    for (i = 0; i < 4; i++)
+        dst[i] = 0;
+
+    for (i = 0; i < 8; i++)
+    {
+        int j, Snum, bitnum;
+
+        for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
+        {
+            Snum <<= 1;
+            Snum |= GETBIT(src, bitnum);
+        }
+
+        if (0 == (i%2))
+            dst[i/2] |= ((SBox[i][Snum]) << 4);
+        else
+            dst[i/2] |= SBox[i][Snum];
+    }
+}
+
+static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++)
+        dst[i] = a[i] ^ b[i];
+}
+
+unsigned char *CRYPT_DESkey8to7(unsigned char *dst, const unsigned char *key)
+{
+    int i;
+    unsigned char tmp[7];
+    static const unsigned char map8to7[56] =
+    {
+         0,  1,  2,  3,  4,  5,  6,
+         8,  9, 10, 11, 12, 13, 14,
+        16, 17, 18, 19, 20, 21, 22,
+        24, 25, 26, 27, 28, 29, 30,
+        32, 33, 34, 35, 36, 37, 38,
+        40, 41, 42, 43, 44, 45, 46,
+        48, 49, 50, 51, 52, 53, 54,
+        56, 57, 58, 59, 60, 61, 62
+    };
+
+    if ((dst == NULL) || (key == NULL))
+        return NULL;
+
+    Permute(tmp, key, map8to7, 7);
+
+    for (i = 0; i < 7; i++)
+        dst[i] = tmp[i];
+
+    return dst;
+}
+
+
+unsigned char *CRYPT_DEShash(unsigned char *dst, const unsigned char *key, const unsigned char *src)
+{
+    int i;
+    unsigned char K[7];
+    unsigned char D[8];
+
+    Permute(K, key, KeyPermuteMap, 7);
+    Permute(D, src, InitialPermuteMap, 8);
+
+    for (i = 0; i < 16; i++)
+    {
+        int j;
+        unsigned char *L = D;
+        unsigned char *R = &(D[4]);
+        unsigned char  Rexp[6];
+        unsigned char  Rn[4];
+        unsigned char  SubK[6];
+
+        KeyShift(K, KeyRotation[i]);
+        Permute(SubK, K, KeyCompression, 6);
+
+        Permute(Rexp, R, DataExpansion, 6);
+        xor(Rexp, Rexp, SubK, 6);
+
+        sbox(Rn, Rexp);
+        Permute(Rexp, Rn, PBox, 4);
+        xor(Rn, L, Rexp, 4);
+
+        for (j = 0; j < 4; j++)
+        {
+            L[j] = R[j];
+            R[j] = Rn[j];
+        }
+    }
+
+    Permute(dst, D, FinalPermuteMap, 8);
+
+    return dst;
+}

reactos/lib/advapi32/crypt
crypt_lmhash.c added at 1.2.2.1
diff -N crypt_lmhash.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt_lmhash.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,49 @@
+/*
+ *  Copyright 2004 Hans Leidekker
+ *
+ *  Based on LMHash.c from libcifs
+ *
+ *  Copyright (C) 2004 by Christopher R. Hertel
+ *
+ *  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 "advapi32.h"
+#include "crypt.h"
+
+
+static const unsigned char CRYPT_LMhash_Magic[8] =
+    { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
+
+static void CRYPT_LMhash(unsigned char *dst, const unsigned char *pwd, const int len)
+{
+    int i, max = 14;
+    unsigned char tmp_pwd[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+
+    max = len > max ? max : len;
+
+    for (i = 0; i < max; i++)
+        tmp_pwd[i] = pwd[i];
+
+    CRYPT_DEShash(dst, tmp_pwd, CRYPT_LMhash_Magic);
+    CRYPT_DEShash(&dst[8], &tmp_pwd[7], CRYPT_LMhash_Magic);
+}
+
+NTSTATUS WINAPI SystemFunction006(LPCSTR password, LPSTR hash)
+{
+    CRYPT_LMhash(hash, password, strlen(password));
+
+    return STATUS_SUCCESS;
+}

reactos/lib/advapi32/crypt
crypt_md4.c added at 1.2.2.1
diff -N crypt_md4.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt_md4.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2001 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 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
+ */
+
+/*
+ * This code implements the MD4 message-digest algorithm.
+ * It is based on code in the public domain written by Colin
+ * Plumb in 1993. The algorithm is due to Ron Rivest.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD4_CTX structure, pass it to MD4Init, call MD4Update as
+ * needed on buffers full of bytes, and then call MD4Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+typedef struct
+{
+    unsigned int buf[4];
+    unsigned int i[2];
+    unsigned char in[64];
+    unsigned char digest[16];
+} MD4_CTX;
+
+
+/* The three core functions */
+
+#define rotl32(x,n)  (((x) << ((unsigned int)(n))) | ((x) >> (32 - (unsigned int)(n))))
+
+#define F( x, y, z ) (((x) & (y)) | ((~x) & (z)))
+#define G( x, y, z ) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H( x, y, z ) ((x) ^ (y) ^ (z))
+
+#define FF( a, b, c, d, x, s ) { \
+    (a) += F( (b), (c), (d) ) + (x); \
+    (a) = rotl32( (a), (s) ); \
+  }
+#define GG( a, b, c, d, x, s ) { \
+    (a) += G( (b), (c), (d) ) + (x) + (unsigned int)0x5a827999; \
+    (a) = rotl32( (a), (s) ); \
+  }
+#define HH( a, b, c, d, x, s ) { \
+    (a) += H( (b), (c), (d) ) + (x) + (unsigned int)0x6ed9eba1; \
+    (a) = rotl32( (a), (s) ); \
+  }
+
+/*
+ * The core of the MD4 algorithm
+ */
+static VOID MD4Transform(unsigned int buf[4], const unsigned int in[16])
+{
+    register unsigned int a, b, c, d;
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    FF( a, b, c, d, in[0], 3 );
+    FF( d, a, b, c, in[1], 7 );
+    FF( c, d, a, b, in[2], 11 );
+    FF( b, c, d, a, in[3], 19 );
+    FF( a, b, c, d, in[4], 3 );
+    FF( d, a, b, c, in[5], 7 );
+    FF( c, d, a, b, in[6], 11 );
+    FF( b, c, d, a, in[7], 19 );
+    FF( a, b, c, d, in[8], 3 );
+    FF( d, a, b, c, in[9], 7 );
+    FF( c, d, a, b, in[10], 11 );
+    FF( b, c, d, a, in[11], 19 );
+    FF( a, b, c, d, in[12], 3 );
+    FF( d, a, b, c, in[13], 7 );
+    FF( c, d, a, b, in[14], 11 );
+    FF( b, c, d, a, in[15], 19 );
+
+    GG( a, b, c, d, in[0], 3 );
+    GG( d, a, b, c, in[4], 5 );
+    GG( c, d, a, b, in[8], 9 );
+    GG( b, c, d, a, in[12], 13 );
+    GG( a, b, c, d, in[1], 3 );
+    GG( d, a, b, c, in[5], 5 );
+    GG( c, d, a, b, in[9], 9 );
+    GG( b, c, d, a, in[13], 13 );
+    GG( a, b, c, d, in[2], 3 );
+    GG( d, a, b, c, in[6], 5 );
+    GG( c, d, a, b, in[10], 9 );
+    GG( b, c, d, a, in[14], 13 );
+    GG( a, b, c, d, in[3], 3 );
+    GG( d, a, b, c, in[7], 5 );
+    GG( c, d, a, b, in[11], 9 );
+    GG( b, c, d, a, in[15], 13 );
+
+    HH( a, b, c, d, in[0], 3 );
+    HH( d, a, b, c, in[8], 9 );
+    HH( c, d, a, b, in[4], 11 );
+    HH( b, c, d, a, in[12], 15 );
+    HH( a, b, c, d, in[2], 3 );
+    HH( d, a, b, c, in[10], 9 );
+    HH( c, d, a, b, in[6], 11 );
+    HH( b, c, d, a, in[14], 15 );
+    HH( a, b, c, d, in[1], 3 );
+    HH( d, a, b, c, in[9], 9 );
+    HH( c, d, a, b, in[5], 11 );
+    HH( b, c, d, a, in[13], 15 );
+    HH( a, b, c, d, in[3], 3 );
+    HH( d, a, b, c, in[11], 9 );
+    HH( c, d, a, b, in[7], 11 );
+    HH( b, c, d, a, in[15], 15 );
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static VOID byteReverse(unsigned char *buf, unsigned longs)
+{
+    unsigned int t;
+
+    do
+    {
+        t = (unsigned int)((unsigned)buf[3] << 8 | buf[2]) << 16 |
+            ((unsigned)buf[1] << 8 | buf[0]);
+        *(unsigned int *)buf = t;
+        buf += 4;
+    } while (--longs);
+}
+
+/*
+ * Start MD4 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+VOID WINAPI MD4Init(MD4_CTX *ctx)
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->i[0] = ctx->i[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+VOID WINAPI MD4Update(MD4_CTX *ctx, const unsigned char *buf, unsigned int len)
+{
+    register unsigned int t;
+
+    /* Update bitcount */
+    t = ctx->i[0];
+
+    if ((ctx->i[0] = t + ((unsigned int)len << 3)) < t)
+        ctx->i[1]++;        /* Carry from low to high */
+
+    ctx->i[1] += len >> 29;
+    t = (t >> 3) & 0x3f;
+
+    /* Handle any leading odd-sized chunks */
+    if (t)
+    {
+        unsigned char *p = (unsigned char *)ctx->in + t;
+        t = 64 - t;
+
+        if (len < t)
+        {
+            memcpy(p, buf, len);
+            return;
+        }
+
+        memcpy(p, buf, t);
+        byteReverse(ctx->in, 16);
+
+        MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        buf += t;
+        len -= t;
+    }
+
+    /* Process data in 64-byte chunks */
+    while (len >= 64)
+    {
+        memcpy(ctx->in, buf, 64);
+        byteReverse(ctx->in, 16);
+
+        MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        buf += 64;
+        len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+VOID WINAPI MD4Final(MD4_CTX *ctx)
+{
+    unsigned int count;
+    unsigned char *p;
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->i[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if (count < 8)
+    {
+        /* Two lots of padding:  Pad the first block to 64 bytes */
+        memset( p, 0, count );
+        byteReverse(ctx->in, 16);
+        MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        /* Now fill the next block with 56 bytes */
+        memset(ctx->in, 0, 56);
+    }
+    else
+    {
+        /* Pad block to 56 bytes */
+        memset(p, 0, count - 8);
+    }
+
+    byteReverse(ctx->in, 14);
+
+    /* Append length in bits and transform */
+    ((unsigned int *)ctx->in)[14] = ctx->i[0];
+    ((unsigned int *)ctx->in)[15] = ctx->i[1];
+
+    MD4Transform( ctx->buf, (unsigned int *)ctx->in );
+    byteReverse( (unsigned char *)ctx->buf, 4 );
+    memcpy(ctx->digest, ctx->buf, 16);
+}

reactos/lib/advapi32/crypt
crypt_md5.c added at 1.2.2.1
diff -N crypt_md5.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt_md5.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2001 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 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
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * It is based on code in the public domain written by Colin
+ * Plumb in 1993. The algorithm is due to Ron Rivest.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5_CTX structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+typedef struct
+{
+    unsigned int i[2];
+    unsigned int buf[4];
+    unsigned char in[64];
+    unsigned char digest[16];
+} MD5_CTX;
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1( x, y, z ) (x & y | ~x & z) */
+#define F1( x, y, z ) (z ^ (x & (y ^ z)))
+#define F2( x, y, z ) F1( z, x, y )
+#define F3( x, y, z ) (x ^ y ^ z)
+#define F4( x, y, z ) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP( f, w, x, y, z, data, s ) \
+        ( w += f( x, y, z ) + data,  w = w << s | w >> (32 - s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(unsigned int buf[4], const unsigned int in[16])
+{
+    register unsigned int a, b, c, d;
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    MD5STEP( F1, a, b, c, d, in[0] + 0xd76aa478, 7 );
+    MD5STEP( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 );
+    MD5STEP( F1, c, d, a, b, in[2] + 0x242070db, 17 );
+    MD5STEP( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 );
+    MD5STEP( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 );
+    MD5STEP( F1, d, a, b, c, in[5] + 0x4787c62a, 12 );
+    MD5STEP( F1, c, d, a, b, in[6] + 0xa8304613, 17 );
+    MD5STEP( F1, b, c, d, a, in[7] + 0xfd469501, 22 );
+    MD5STEP( F1, a, b, c, d, in[8] + 0x698098d8, 7 );
+    MD5STEP( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 );
+    MD5STEP( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 );
+    MD5STEP( F1, b, c, d, a, in[11] + 0x895cd7be, 22 );
+    MD5STEP( F1, a, b, c, d, in[12] + 0x6b901122, 7 );
+    MD5STEP( F1, d, a, b, c, in[13] + 0xfd987193, 12 );
+    MD5STEP( F1, c, d, a, b, in[14] + 0xa679438e, 17 );
+    MD5STEP( F1, b, c, d, a, in[15] + 0x49b40821, 22 );
+
+    MD5STEP( F2, a, b, c, d, in[1] + 0xf61e2562, 5 );
+    MD5STEP( F2, d, a, b, c, in[6] + 0xc040b340, 9 );
+    MD5STEP( F2, c, d, a, b, in[11] + 0x265e5a51, 14 );
+    MD5STEP( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 );
+    MD5STEP( F2, a, b, c, d, in[5] + 0xd62f105d, 5 );
+    MD5STEP( F2, d, a, b, c, in[10] + 0x02441453, 9 );
+    MD5STEP( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 );
+    MD5STEP( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 );
+    MD5STEP( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 );
+    MD5STEP( F2, d, a, b, c, in[14] + 0xc33707d6, 9 );
+    MD5STEP( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 );
+    MD5STEP( F2, b, c, d, a, in[8] + 0x455a14ed, 20 );
+    MD5STEP( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 );
+    MD5STEP( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 );
+    MD5STEP( F2, c, d, a, b, in[7] + 0x676f02d9, 14 );
+    MD5STEP( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 );
+
+    MD5STEP( F3, a, b, c, d, in[5] + 0xfffa3942, 4 );
+    MD5STEP( F3, d, a, b, c, in[8] + 0x8771f681, 11 );
+    MD5STEP( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 );
+    MD5STEP( F3, b, c, d, a, in[14] + 0xfde5380c, 23 );
+    MD5STEP( F3, a, b, c, d, in[1] + 0xa4beea44, 4 );
+    MD5STEP( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 );
+    MD5STEP( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 );
+    MD5STEP( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 );
+    MD5STEP( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 );
+    MD5STEP( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 );
+    MD5STEP( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 );
+    MD5STEP( F3, b, c, d, a, in[6] + 0x04881d05, 23 );
+    MD5STEP( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 );
+    MD5STEP( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 );
+    MD5STEP( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 );
+    MD5STEP( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 );
+
+    MD5STEP( F4, a, b, c, d, in[0] + 0xf4292244, 6 );
+    MD5STEP( F4, d, a, b, c, in[7] + 0x432aff97, 10 );
+    MD5STEP( F4, c, d, a, b, in[14] + 0xab9423a7, 15 );
+    MD5STEP( F4, b, c, d, a, in[5] + 0xfc93a039, 21 );
+    MD5STEP( F4, a, b, c, d, in[12] + 0x655b59c3, 6 );
+    MD5STEP( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 );
+    MD5STEP( F4, c, d, a, b, in[10] + 0xffeff47d, 15 );
+    MD5STEP( F4, b, c, d, a, in[1] + 0x85845dd1, 21 );
+    MD5STEP( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 );
+    MD5STEP( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 );
+    MD5STEP( F4, c, d, a, b, in[6] + 0xa3014314, 15 );
+    MD5STEP( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 );
+    MD5STEP( F4, a, b, c, d, in[4] + 0xf7537e82, 6 );
+    MD5STEP( F4, d, a, b, c, in[11] + 0xbd3af235, 10 );
+    MD5STEP( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 );
+    MD5STEP( F4, b, c, d, a, in[9] + 0xeb86d391, 21 );
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static VOID byteReverse(unsigned char *buf, unsigned longs)
+{
+    unsigned int t;
+
+    do
+    {
+        t = (unsigned int)((unsigned)buf[3] << 8 | buf[2]) << 16 |
+            ((unsigned)buf[1] << 8 | buf[0]);
+        *(unsigned int *)buf = t;
+        buf += 4;
+    } while (--longs);
+}
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+VOID WINAPI MD5Init(MD5_CTX *ctx)
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->i[0] = ctx->i[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+VOID WINAPI MD5Update(MD5_CTX *ctx, const unsigned char *buf, unsigned int len)
+{
+    register unsigned int t;
+
+    /* Update bitcount */
+    t = ctx->i[0];
+
+    if ((ctx->i[0] = t + ((unsigned int)len << 3)) < t)
+        ctx->i[1]++;        /* Carry from low to high */
+
+    ctx->i[1] += len >> 29;
+    t = (t >> 3) & 0x3f;
+
+    /* Handle any leading odd-sized chunks */
+    if (t)
+    {
+        unsigned char *p = (unsigned char *)ctx->in + t;
+        t = 64 - t;
+
+        if (len < t)
+        {
+            memcpy(p, buf, len);
+            return;
+        }
+
+        memcpy(p, buf, t);
+        byteReverse(ctx->in, 16);
+
+        MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        buf += t;
+        len -= t;
+    }
+
+    /* Process data in 64-byte chunks */
+    while (len >= 64)
+    {
+        memcpy(ctx->in, buf, 64);
+        byteReverse(ctx->in, 16);
+
+        MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        buf += 64;
+        len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+VOID WINAPI MD5Final( MD5_CTX *ctx )
+{
+    unsigned int count;
+    unsigned char *p;
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->i[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if (count < 8)
+    {
+        /* Two lots of padding:  Pad the first block to 64 bytes */
+        memset(p, 0, count);
+        byteReverse(ctx->in, 16);
+        MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+        /* Now fill the next block with 56 bytes */
+        memset(ctx->in, 0, 56);
+    }
+    else
+    {
+        /* Pad block to 56 bytes */
+        memset(p, 0, count - 8);
+    }
+
+    byteReverse(ctx->in, 14);
+
+    /* Append length in bits and transform */
+    ((unsigned int *)ctx->in)[14] = ctx->i[0];
+    ((unsigned int *)ctx->in)[15] = ctx->i[1];
+
+    MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+    byteReverse((unsigned char *)ctx->buf, 4);
+    memcpy(ctx->digest, ctx->buf, 16);
+}

reactos/lib/advapi32/crypt
crypt_sha.c added at 1.2.2.1
diff -N crypt_sha.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ crypt_sha.c	13 Dec 2004 16:18:25 -0000	1.2.2.1
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2004 Filip Navara
+ * Based on public domain SHA code by Steve Reid <steve@edmweb.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 "advapi32.h"
+#include "crypt.h"
+
+
+/* SHA Context Structure Declaration */
+
+typedef struct {
+   ULONG Unknown[6];
+   ULONG State[5];
+   ULONG Count[2];
+   UCHAR Buffer[64];
+} SHA_CTX, *PSHA_CTX;
+
+/* SHA1 Helper Macros */
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+/* FIXME: This definition of DWORD2BE is little endian specific! */
+#define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000);
+/* FIXME: This definition of blk0 is little endian specific! */
+#define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF))
+#define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1))
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static VOID
+SHA1Transform(ULONG State[5], CHAR Buffer[64])
+{
+   ULONG a, b, c, d, e;
+   ULONG *Block;
+
+   Block = (ULONG*)Buffer;
+
+   /* Copy Context->State[] to working variables */
+   a = State[0];
+   b = State[1];
+   c = State[2];
+   d = State[3];
+   e = State[4];
+
+   /* 4 rounds of 20 operations each. Loop unrolled. */
+   R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+   R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+   R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+   R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+   R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+   R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+   R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+   R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+   R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+   R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+   R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+   R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+   R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+   R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+   R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+   R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+   R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+   R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+   R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+   R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+   /* Add the working variables back into Context->State[] */
+   State[0] += a;
+   State[1] += b;
+   State[2] += c;
+   State[3] += d;
+   State[4] += e;
+
+   /* Wipe variables */
+   a = b = c = d = e = 0;
+}
+
+
+/******************************************************************************
+ * A_SHAInit [ADVAPI32.@]
+ *
+ * Initialize a SHA context structure.
+ */
+VOID WINAPI
+A_SHAInit(PSHA_CTX Context)
+{
+   /* SHA1 initialization constants */
+   Context->State[0] = 0x67452301;
+   Context->State[1] = 0xEFCDAB89;
+   Context->State[2] = 0x98BADCFE;
+   Context->State[3] = 0x10325476;
+   Context->State[4] = 0xC3D2E1F0;
+   Context->Count[0] =
+   Context->Count[1] = 0;
+}
+
+/******************************************************************************
+ * A_SHAUpdate [ADVAPI32.@]
+ *
+ * Update a SHA context with a hashed data from supplied buffer.
+ */
+VOID WINAPI
+A_SHAUpdate(PSHA_CTX Context, PCHAR Buffer, UINT BufferSize)
+{
+   ULONG BufferContentSize;
+
+   BufferContentSize = Context->Count[1] & 63;
+   Context->Count[1] += BufferSize;
+   if (Context->Count[1] < BufferSize)
+      Context->Count[0]++;
+   Context->Count[0] += (BufferSize >> 29);
+
+   if (BufferContentSize + BufferSize < 64)
+   {
+      RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer,
+                    BufferSize);
+   }
+   else
+   {
+      while (BufferContentSize + BufferSize >= 64)
+      {
+         RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer,
+                       64 - BufferContentSize);
+         Buffer += 64 - BufferContentSize;
+         BufferSize -= 64 - BufferContentSize;
+         SHA1Transform(Context->State, Context->Buffer);
+         BufferContentSize = 0;
+      }
+      RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, BufferSize);
+   }
+}
+
+/******************************************************************************
+ * A_SHAFinal [ADVAPI32.@]
+ *
+ * Finalize SHA context and return the resulting hash.
+ */
+VOID WINAPI
+A_SHAFinal(PSHA_CTX Context, PULONG Result)
+{
+   INT Pad, Index;
+   UCHAR Buffer[72];
+   ULONG *Count;
+   ULONG BufferContentSize, LengthHi, LengthLo;
+
+   BufferContentSize = Context->Count[1] & 63;
+   if (BufferContentSize >= 56)
+      Pad = 56 + 64 - BufferContentSize;
+   else
+      Pad = 56 - BufferContentSize;
+
+   LengthHi = (Context->Count[0] << 3) | (Context->Count[1] >> (32 - 3));
+   LengthLo = (Context->Count[1] << 3);
+
+   RtlZeroMemory(Buffer + 1, Pad - 1);
+   Buffer[0] = 0x80;
+   Count = (ULONG*)(Buffer + Pad);
+   Count[0] = DWORD2BE(LengthHi);
+   Count[1] = DWORD2BE(LengthLo);
+   A_SHAUpdate(Context, Buffer, Pad + 8);
+
+   for (Index = 0; Index < 5; Index++)
+      Result[Index] = DWORD2BE(Context->State[Index]);
+
+   A_SHAInit(Context);
+}

reactos/lib/dinput8
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:25 -0000	1.1.2.1
@@ -0,0 +1,11 @@
+*.coff
+*.dll
+*.d
+*.a
+*.o
+*.sym
+*.map
+*.tmp
+Makefile.ros
+dinput8.spec.def
+dinput8.stubs.c

reactos/lib/dinput8
Makefile.in added at 1.1.2.1
diff -N Makefile.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile.in	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,16 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = dinput8.dll
+IMPORTS   = dinput
+EXTRALIBS = -luuid
+
+C_SRCS = \
+	dinput8_main.c
+
+RC_SRCS = version.rc
+
+@MAKE_DLL_RULES@
+
+### Dependencies:

reactos/lib/dinput8
Makefile.ros-template added at 1.2.2.1
diff -N Makefile.ros-template
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile.ros-template	13 Dec 2004 16:18:26 -0000	1.2.2.1
@@ -0,0 +1,28 @@
+# $Id: Makefile.ros-template,v 1.2.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+TARGET_NAME = dinput8
+
+TARGET_OBJECTS = @C_SRCS@
+
+TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
+
+TARGET_SDKLIBS = wine.a @IMPORTS@ ole32.a wine_uuid.a ntdll.a  winmm.a dxguid.a
+
+
+
+TARGET_RC_SRCS = @RC_SRCS@
+TARGET_RC_BINSRC = @RC_BINSRC@
+TARGET_RC_BINARIES = @RC_BINARIES@
+
+default: all
+
+authors.c:
+ifeq ($(HOST),mingw32-linux)
+	echo 'const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 };' > authors.c
+else
+	echo const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 }; > authors.c
+endif
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk

reactos/lib/dinput8
dinput8.spec added at 1.1.2.1
diff -N dinput8.spec
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dinput8.spec	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,5 @@
+@ stdcall DirectInput8Create(long long ptr ptr ptr)
+@ stdcall -private DllCanUnloadNow() DINPUT8_DllCanUnloadNow
+@ stdcall -private DllGetClassObject(ptr ptr ptr) DINPUT8_DllGetClassObject
+@ stdcall -private DllRegisterServer() DINPUT8_DllRegisterServer
+@ stdcall -private DllUnregisterServer() DINPUT8_DllUnregisterServer

reactos/lib/dinput8
dinput8_main.c added at 1.1.2.1
diff -N dinput8_main.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dinput8_main.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,83 @@
+/* DirectInput 8
+ *
+ * Copyright 2002 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 "config.h"
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "wine/debug.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "dinput.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+/******************************************************************************
+ *	DirectInput8Create (DINPUT8.@)
+ */
+HRESULT WINAPI DirectInput8Create(
+	HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
+	LPUNKNOWN punkOuter
+) {
+	return DirectInputCreateEx(hinst, dwVersion, riid, ppDI, punkOuter);
+}
+
+/***********************************************************************
+ *		DllCanUnloadNow (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllCanUnloadNow(void)
+{
+    FIXME("(void): stub\n");
+
+    return S_FALSE;
+}
+
+/***********************************************************************
+ *		DllGetClassObject (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllGetClassObject(REFCLSID rclsid, REFIID riid,
+					 LPVOID *ppv)
+{
+    FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
+	  debugstr_guid(riid), ppv);
+
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/***********************************************************************
+ *		DllRegisterServer (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllRegisterServer(void)
+{
+    FIXME("(void): stub\n");
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *		DllUnregisterServer (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllUnregisterServer(void)
+{
+    FIXME("(void): stub\n");
+
+    return S_OK;
+}

reactos/lib/dinput8
makefile added at 1.1.2.1
diff -N makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ makefile	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,9 @@
+# $Id: makefile,v 1.1.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = winedll
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk

reactos/lib/dinput8
version.rc added at 1.1.2.1
diff -N version.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ version.rc	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004 Tom Wickline
+ *
+ * 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
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine DirectInput 8"
+#define WINE_FILENAME_STR "dinput8.dll"
+#define WINE_FILEVERSION 5,1,2600,881
+#define WINE_FILEVERSION_STR "5.1.2600.881"
+#define WINE_PRODUCTVERSION 5,1,2600,881
+#define WINE_PRODUCTVERSION_STR "5.1"
+#define WINE_PRODUCTNAME_STR "DirectX"
+
+#include "wine/wine_common_ver.rc"

reactos/lib/dinput8
winehq2ros.patch added at 1.1.2.1
diff -N winehq2ros.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,14 @@
+Index: version.rc
+===================================================================
+RCS file: /home/wine/wine/dlls/dinput8/version.rc,v
+retrieving revision 1.4
+diff -u -r1.4 version.rc
+--- version.rc	23 Nov 2004 13:59:36 -0000	1.4
++++ version.rc	7 Dec 2004 22:27:53 -0000
+@@ -22,5 +22,6 @@
+ #define WINE_FILEVERSION_STR "5.1.2600.881"
+ #define WINE_PRODUCTVERSION 5,1,2600,881
+ #define WINE_PRODUCTVERSION_STR "5.1"
++#define WINE_PRODUCTNAME_STR "DirectX"
+ 
+ #include "wine/wine_common_ver.rc"

reactos/lib/msi
.cvsignore added at 1.2.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:26 -0000	1.2.2.1
@@ -0,0 +1,11 @@
+*.coff
+*.dll
+*.d
+*.a
+*.o
+*.sym
+*.map
+*.tmp
+Makefile.ros
+msi.spec.def
+msi.stubs.c

reactos/lib/msi
Makefile added at 1.1.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,9 @@
+# $Id: Makefile,v 1.1.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = winedll
+	
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk

reactos/lib/msi
Makefile.in added at 1.1.2.1
diff -N Makefile.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile.in	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,50 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = msi.dll
+IMPORTS   = shell32 cabinet oleaut32 ole32 version user32 advapi32 kernel32
+EXTRALIBS = -luuid $(LIBUNICODE)
+
+C_SRCS = \
+	action.c \
+	create.c \
+	distinct.c \
+	handle.c \
+	insert.c \
+	msi.c \
+	msiquery.c \
+	order.c \
+	package.c \
+	record.c \
+	regsvr.c \
+	select.c \
+	string.c \
+	suminfo.c \
+	table.c \
+	tokenize.c \
+	update.c \
+	where.c
+
+RC_SRCS = version.rc
+
+EXTRA_SRCS = sql.y cond.y
+EXTRA_OBJS = sql.tab.o cond.tab.o
+
+@MAKE_DLL_RULES@
+
+sql.tab.c sql.tab.h: sql.y
+	$(BISON) -p SQL_ -d $(SRCDIR)/sql.y -o sql.tab.c
+
+cond.tab.c cond.tab.h: cond.y
+	$(BISON) -p COND_ -d $(SRCDIR)/cond.y -o cond.tab.c
+
+# hack to allow parallel make
+sql.tab.h: sql.tab.c
+sql.tab.o: sql.tab.h
+cond.tab.h: cond.tab.c
+cond.tab.o: cond.tab.h
+
+tokenize.o: sql.tab.h
+
+### Dependencies:

reactos/lib/msi
Makefile.ros-template added at 1.3.2.1
diff -N Makefile.ros-template
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile.ros-template	13 Dec 2004 16:18:26 -0000	1.3.2.1
@@ -0,0 +1,39 @@
+# $Id: Makefile.ros-template
+
+TARGET_NAME = msi
+
+TARGET_OBJECTS = @C_SRCS@ @EXTRA_OBJS@
+
+TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
+
+TARGET_SDKLIBS = @IMPORTS@ winmm.a wine.a wine_uuid.a wine_unicode.a ntdll.a
+
+TARGET_BASE = $(TARGET_BASE_LIB_WINMM)
+
+TARGET_RC_SRCS = @RC_SRCS@
+TARGET_RC_BINSRC = @RC_BINSRC@
+TARGET_RC_BINARIES = @RC_BINARIES@
+
+#TARGET_CLEAN = *.tab.c *.tab.h
+
+default: all
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk
+
+#
+#	Optional use of bison, this will allow independent building from
+#	Wine.
+#
+#	Bison is requiered for building msi.dll. If MingW32 for windows,
+#	download bison from http://gnuwin32.sourceforge.net/
+#	Make sure bison.exe is placed in your command path for execution.
+#
+#
+
+#sql.tab.c sql.tab.h: sql.y
+#	bison -p SQL_ -d ./sql.y -o sql.tab.c
+
+#cond.tab.c cond.tab.h: cond.y
+#	bison -p COND_ -d ./cond.y -o cond.tab.c

reactos/lib/msi
action.c added at 1.3.2.1
diff -N action.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ action.c	13 Dec 2004 16:18:26 -0000	1.3.2.1
@@ -0,0 +1,4877 @@
+/*
+ * 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>
+#include <fcntl.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 "msvcrt/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 "ver.h"
+
+#define CUSTOM_ACTION_TYPE_MASK 0x3F
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tagMSIFEATURE
+{
+    WCHAR Feature[96];
+    WCHAR Feature_Parent[96];
+    WCHAR Title[0x100];
+    WCHAR Description[0x100];
+    INT Display;
+    INT Level;
+    WCHAR Directory[96];
+    INT Attributes;
+    
+    INSTALLSTATE State;
+    BOOL Enabled;
+    INT ComponentCount;
+    INT Components[1024]; /* yes hardcoded limit.... I am bad */
+    INT Cost;
+} MSIFEATURE;
+
+typedef struct tagMSICOMPONENT
+{
+    WCHAR Component[96];
+    WCHAR ComponentId[96];
+    WCHAR Directory[96];
+    INT Attributes;
+    WCHAR Condition[0x100];
+    WCHAR KeyPath[96];
+
+    INSTALLSTATE State;
+    BOOL FeatureState;
+    BOOL Enabled;
+    INT  Cost;
+} MSICOMPONENT;
+
+typedef struct tagMSIFOLDER
+{
+    WCHAR Directory[96];
+    WCHAR TargetDefault[96];
+    WCHAR SourceDefault[96];
+
+    WCHAR ResolvedTarget[MAX_PATH];
+    WCHAR ResolvedSource[MAX_PATH];
+    WCHAR Property[MAX_PATH];   /* initially set property */
+    INT   ParentIndex;
+    INT   State;
+        /* 0 = uninitialized */
+        /* 1 = existing */
+        /* 2 = created remove if empty */
+        /* 3 = created persist if empty */
+    INT   Cost;
+    INT   Space;
+}MSIFOLDER;
+
+typedef struct tagMSIFILE
+{
+    WCHAR File[72];
+    INT ComponentIndex;
+    WCHAR FileName[MAX_PATH];
+    INT FileSize;
+    WCHAR Version[72];
+    WCHAR Language[20];
+    INT Attributes;
+    INT Sequence;   
+
+    INT State;
+       /* 0 = uninitialize */
+       /* 1 = not present */
+       /* 2 = present but replace */
+       /* 3 = present do not replace */
+       /* 4 = Installed */
+    WCHAR   SourcePath[MAX_PATH];
+    WCHAR   TargetPath[MAX_PATH];
+    BOOL    Temporary; 
+}MSIFILE;
+
+/*
+ * Prototypes
+ */
+static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);
+static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
+
+UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action);
+
+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_CustomAction(MSIPACKAGE *package,const WCHAR *action);
+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_CreateShortcuts(MSIPACKAGE *package);
+static UINT ACTION_PublishProduct(MSIPACKAGE *package);
+
+static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source, 
+                                const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source, 
+                                const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source, 
+                                const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType50(MSIPACKAGE *package, const LPWSTR source, 
+                                const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source, 
+                                const LPWSTR target, const INT type);
+
+static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data);
+static UINT resolve_folder(MSIPACKAGE *package, LPCWSTR name, LPWSTR path, 
+                           BOOL source, BOOL set_prop, MSIFOLDER **folder);
+
+static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
+ 
+/*
+ * 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_collen[] = {'C',':','\\',0};
+ 
+static const WCHAR cszlsb[]={'[',0};
+static const WCHAR cszrsb[]={']',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};
+
+/******************************************************** 
+ * helper functions to get around current HACKS and such
+ ********************************************************/
+inline static void reduce_to_longfilename(WCHAR* filename)
+{
+    if (strchrW(filename,'|'))
+    {
+        WCHAR newname[MAX_PATH];
+        strcpyW(newname,strchrW(filename,'|')+1);
+        strcpyW(filename,newname);
+    }
+}
+
+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;
+}
+
+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 WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
+{
+    UINT rc;
+    DWORD sz;
+    LPWSTR ret;
+   
+    sz = 0; 
+    rc = MSI_RecordGetStringW(row,index,NULL,&sz);
+    if (sz <= 0)
+        return NULL;
+
+    sz ++;
+    ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
+    rc = MSI_RecordGetStringW(row,index,ret,&sz);
+    return ret;
+}
+
+inline static 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;
+}
+
+inline static 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;
+}
+
+inline static 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;
+}
+
+static 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));
+
+    strcpyW(package->files[index].File,name);
+    strcpyW(package->files[index].TargetPath,path);
+    package->files[index].Temporary = TRUE;
+
+    TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));  
+
+    return 0;
+}
+
+void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package)
+{
+    DWORD i;
+
+    if (!package)
+        return;
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        if (package->files[i].Temporary)
+            DeleteFileW(package->files[i].TargetPath);
+
+    }
+}
+
+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);
+}
+
+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;
+    static WCHAR *ActionFormat=NULL;
+    static WCHAR LastAction[0x100] = {0};
+    WCHAR Query[1024];
+    LPWSTR ptr;
+
+    if (strcmpW(LastAction,action)!=0)
+    {
+        sprintfW(Query,Query_t,action);
+        rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+        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;
+        }
+
+        if (ActionFormat)
+            HeapFree(GetProcessHeap(),0,ActionFormat);
+
+        ActionFormat = load_dynamic_stringW(row,3);
+        strcpyW(LastAction,action);
+        msiobj_release(&row->hdr);
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    message[0]=0;
+    ptr = ActionFormat;
+    while (*ptr)
+    {
+        LPWSTR ptr2;
+        LPWSTR data=NULL;
+        WCHAR tmp[1023];
+        INT field;
+
+        ptr2 = strchrW(ptr,'[');
+        if (ptr2)
+        {
+            strncpyW(tmp,ptr,ptr2-ptr);
+            tmp[ptr2-ptr]=0;
+            strcatW(message,tmp);
+            ptr2++;
+            field = atoiW(ptr2);
+            data = load_dynamic_stringW(record,field);
+            if (data)
+            {
+                strcatW(message,data);
+                HeapFree(GetProcessHeap(),0,data);
+            }
+            ptr=strchrW(ptr2,']');
+            ptr++;
+        }
+        else
+        {
+            strcatW(message,ptr);
+            break;
+        }
+    }
+
+    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;
+    WCHAR Query[1024];
+
+    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
+
+    sprintfW(Query,Query_t,action);
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    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);
+}
+
+/****************************************************
+ * 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};
+
+    if (szPackagePath)   
+    {
+        LPWSTR p;
+        WCHAR check[MAX_PATH];
+        WCHAR pth[MAX_PATH];
+        DWORD size;
+ 
+        strcpyW(pth,szPackagePath);
+        p = strrchrW(pth,'\\');    
+        if (p)
+        {
+            p++;
+            *p=0;
+        }
+
+        size = MAX_PATH;
+        if (MSI_GetPropertyW(package,cszSourceDir,check,&size) 
+            != ERROR_SUCCESS )
+            MSI_SetPropertyW(package, cszSourceDir, pth);
+    }
+
+    if (szCommandLine)
+    {
+        LPWSTR ptr,ptr2;
+        ptr = (LPWSTR)szCommandLine;
+       
+        while (*ptr)
+        {
+            WCHAR prop[0x100];
+            WCHAR val[0x100];
+
+            TRACE("Looking at %s\n",debugstr_w(ptr));
+
+            ptr2 = strchrW(ptr,'=');
+            if (ptr2)
+            {
+                BOOL quote=FALSE;
+                DWORD len = 0;
+
+                while (*ptr == ' ') ptr++;
+                strncpyW(prop,ptr,ptr2-ptr);
+                prop[ptr2-ptr]=0;
+                ptr2++;
+            
+                ptr = ptr2; 
+                while (*ptr && (quote || (!quote && *ptr!=' ')))
+                {
+                    if (*ptr == '"')
+                        quote = !quote;
+                    ptr++;
+                    len++;
+                }
+               
+                if (*ptr2=='"')
+                {
+                    ptr2++;
+                    len -= 2;
+                }
+                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);
+                }
+            }
+            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);
+
+    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 };
+    WCHAR Query[1024];
+    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};
+
+    if (UIran)
+    {
+        INT seq = 0;
+        
+        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);
+        sprintfW(Query,ExecSeqQuery,seq);
+    }
+    else
+        sprintfW(Query,ExecSeqQuery,0);
+    
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &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;
+
+            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_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;
+}
+
+/********************************************************
+ * ACTION helper functions and functions that perform the actions
+ *******************************************************/
+
+/* 
+ * Alot 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 translated 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; 
+
+    TRACE("Performing action (%s)\n",debugstr_w(action));
+    ui_actioninfo(package, action, TRUE, 0);
+    ui_actionstart(package, action);
+    ui_progress(package,2,1,0,0);
+
+    /* pre install, setup and configuration block */
+    if (strcmpW(action,szLaunchConditions)==0)
+        rc = ACTION_LaunchConditions(package);
+    else if (strcmpW(action,szCostInitialize)==0)
+        rc = ACTION_CostInitialize(package);
+    else if (strcmpW(action,szFileCost)==0)
+        rc = ACTION_FileCost(package);
+    else if (strcmpW(action,szCostFinalize)==0)
+        rc = ACTION_CostFinalize(package);
+    else if (strcmpW(action,szInstallValidate)==0)
+        rc = ACTION_InstallValidate(package);
+
+    /* install block */
+    else if (strcmpW(action,szProcessComponents)==0)
+        rc = ACTION_ProcessComponents(package);
+    else if (strcmpW(action,szInstallInitialize)==0)
+        rc = ACTION_InstallInitialize(package);
+    else if (strcmpW(action,szCreateFolders)==0)
+        rc = ACTION_CreateFolders(package);
+    else if (strcmpW(action,szInstallFiles)==0)
+        rc = ACTION_InstallFiles(package);
+    else if (strcmpW(action,szDuplicateFiles)==0)
+        rc = ACTION_DuplicateFiles(package);
+    else if (strcmpW(action,szWriteRegistryValues)==0)
+        rc = ACTION_WriteRegistryValues(package);
+     else if (strcmpW(action,szRegisterTypeLibraries)==0)
+        rc = ACTION_RegisterTypeLibraries(package);
+     else if (strcmpW(action,szRegisterClassInfo)==0)
+        rc = ACTION_RegisterClassInfo(package);
+     else if (strcmpW(action,szRegisterProgIdInfo)==0)
+        rc = ACTION_RegisterProgIdInfo(package);
+     else if (strcmpW(action,szCreateShortcuts)==0)
+        rc = ACTION_CreateShortcuts(package);
+    else if (strcmpW(action,szPublishProduct)==0)
+        rc = ACTION_PublishProduct(package);
+
+    /*
+     Called during iTunes but unimplemented and seem important
+
+     ResolveSource  (sets SourceDir)
+     RegisterProduct
+     InstallFinalize
+     */
+     else if ((rc = ACTION_CustomAction(package,action)) != ERROR_SUCCESS)
+     {
+        FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+        rc = ERROR_FUNCTION_NOT_CALLED;
+     }
+
+    ui_actioninfo(package, action, FALSE, rc);
+    return rc;
+}
+
+
+static UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action)
+{
+    UINT rc = ERROR_SUCCESS;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    WCHAR ExecSeqQuery[1024] = 
+    {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','C','u','s','t','o'
+,'m','A','c','t','i','o','n',' ','w','h','e','r','e',' ','`','A','c','t','i'
+,'o','n','`',' ','=',' ','`',0};
+    static const WCHAR end[]={'`',0};
+    UINT type;
+    LPWSTR source;
+    LPWSTR target;
+    WCHAR *deformated=NULL;
+
+    strcatW(ExecSeqQuery,action);
+    strcatW(ExecSeqQuery,end);
+
+    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;
+    }
+
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
[truncated at 1000 lines; 3881 more skipped]

reactos/lib/msi
cond.tab.c added at 1.1.2.1
diff -N cond.tab.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cond.tab.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,2022 @@
+/* A Bison parser, made from ./cond.y
+   by GNU bison 1.35.  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define yyparse COND_parse
+#define yylex COND_lex
+#define yyerror COND_error
+#define yylval COND_lval
+#define yychar COND_char
+#define yydebug COND_debug
+#define yynerrs COND_nerrs
+# define	COND_SPACE	257
+# define	COND_EOF	258
+# define	COND_OR	259
+# define	COND_AND	260
+# define	COND_NOT	261
+# define	COND_LT	262
+# define	COND_GT	263
+# define	COND_EQ	264
+# define	COND_LPAR	265
+# define	COND_RPAR	266
+# define	COND_TILDA	267
+# define	COND_PERCENT	268
+# define	COND_DOLLARS	269
+# define	COND_QUESTION	270
+# define	COND_AMPER	271
+# define	COND_EXCLAM	272
+# define	COND_IDENT	273
+# define	COND_NUMBER	274
+# define	COND_LITER	275
+# define	COND_ERROR	276
+
+#line 1 "./cond.y"
+
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2003 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 "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+    MSIPACKAGE *package;
+    LPCWSTR str;
+    INT    n;
+    MSICONDITION result;
+} COND_input;
+
+struct cond_str {
+    LPCWSTR data;
+    INT len;
+};
+
+static LPWSTR COND_GetString( struct cond_str *str );
+static LPWSTR COND_GetLiteral( struct cond_str *str );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
+typedef INT (*comp_m1)(LPWSTR a,int b);
+typedef INT (*comp_m2)(int a,LPWSTR b);
+
+static INT comp_lt_i(INT a, INT b);
+static INT comp_gt_i(INT a, INT b);
+static INT comp_le_i(INT a, INT b);
+static INT comp_ge_i(INT a, INT b);
+static INT comp_eq_i(INT a, INT b);
+static INT comp_ne_i(INT a, INT b);
+static INT comp_bitand(INT a, INT b);
+static INT comp_highcomp(INT a, INT b);
+static INT comp_lowcomp(INT a, INT b);
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
+
+static INT comp_eq_m1(LPWSTR a, INT b);
+static INT comp_ne_m1(LPWSTR a, INT b);
+static INT comp_lt_m1(LPWSTR a, INT b);
+static INT comp_gt_m1(LPWSTR a, INT b);
+static INT comp_le_m1(LPWSTR a, INT b);
+static INT comp_ge_m1(LPWSTR a, INT b);
+
+static INT comp_eq_m2(INT a, LPWSTR b);
+static INT comp_ne_m2(INT a, LPWSTR b);
+static INT comp_lt_m2(INT a, LPWSTR b);
+static INT comp_gt_m2(INT a, LPWSTR b);
+static INT comp_le_m2(INT a, LPWSTR b);
+static INT comp_ge_m2(INT a, LPWSTR b);
+
+
+#line 105 "./cond.y"
+#ifndef YYSTYPE
+typedef union
+{
+    struct cond_str str;
+    LPWSTR    string;
+    INT       value;
+    comp_int  fn_comp_int;
+    comp_str  fn_comp_str;
+    comp_m1   fn_comp_m1;
+    comp_m2   fn_comp_m2;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define	YYFINAL		74
+#define	YYFLAG		-32768
+#define	YYNTBASE	23
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 39)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+       0,     0,     2,     4,     8,    10,    14,    16,    19,    21,
+      23,    27,    31,    36,    40,    44,    48,    50,    53,    55,
+      57,    60,    63,    66,    69,    72,    74,    77,    79,    81,
+      84,    87,    90,    93,    96,    98,   101,   103,   105,   108,
+     111,   114,   117,   120,   122,   125,   127,   129,   132,   135,
+     138,   141,   144,   146,   148,   150,   152,   154,   157,   160,
+     163,   166,   168,   171,   173
+};
+static const short yyrhs[] =
+{
+      24,     0,    25,     0,    25,     5,    24,     0,    26,     0,
+      25,     6,    26,     0,    27,     0,     7,    27,     0,    32,
+       0,    33,     0,    32,    28,    32,     0,    33,    29,    33,
+       0,    33,    13,    29,    33,     0,    33,    30,    32,     0,
+      32,    31,    33,     0,    11,    24,    12,     0,    10,     0,
+       8,     9,     0,     8,     0,     9,     0,     8,    10,     0,
+       9,    10,     0,     9,     8,     0,     8,     8,     0,     9,
+       9,     0,    10,     0,     8,     9,     0,     8,     0,     9,
+       0,     8,    10,     0,     9,    10,     0,     9,     8,     0,
+       8,     8,     0,     9,     9,     0,    10,     0,     8,     9,
+       0,     8,     0,     9,     0,     8,    10,     0,     9,    10,
+       0,     9,     8,     0,     8,     8,     0,     9,     9,     0,
+      10,     0,     8,     9,     0,     8,     0,     9,     0,     8,
+      10,     0,     9,    10,     0,     9,     8,     0,     8,     8,
+       0,     9,     9,     0,    35,     0,    38,     0,    36,     0,
+      34,     0,    21,     0,    15,    37,     0,    16,    37,     0,
+      17,    37,     0,    18,    37,     0,    37,     0,    14,    37,
+       0,    19,     0,    20,     0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+       0,   135,   143,   148,   154,   159,   165,   170,   177,   182,
+     186,   190,   194,   198,   202,   206,   212,   218,   222,   226,
+     230,   234,   239,   243,   247,   253,   259,   263,   267,   271,
+     275,   280,   284,   288,   294,   300,   304,   308,   312,   316,
+     321,   325,   329,   335,   341,   345,   349,   353,   357,   362,
+     366,   370,   376,   381,   387,   392,   398,   407,   417,   426,
+     435,   446,   462,   475,   484
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+  "$", "error", "$undefined.", "COND_SPACE", "COND_EOF", "COND_OR", 
+  "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR", 
+  "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS", 
+  "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", 
+  "COND_NUMBER", "COND_LITER", "COND_ERROR", "condition", "expression", 
+  "boolean_term", "boolean_factor", "term", "comp_op_i", "comp_op_s", 
+  "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", "symbol_i", 
+  "symbol_s", "identifier", "integer", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+       0,    23,    24,    24,    25,    25,    26,    26,    27,    27,
+      27,    27,    27,    27,    27,    27,    28,    28,    28,    28,
+      28,    28,    28,    28,    28,    29,    29,    29,    29,    29,
+      29,    29,    29,    29,    30,    30,    30,    30,    30,    30,
+      30,    30,    30,    31,    31,    31,    31,    31,    31,    31,
+      31,    31,    32,    32,    33,    33,    34,    35,    35,    35,
+      35,    36,    36,    37,    38
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+       0,     1,     1,     3,     1,     3,     1,     2,     1,     1,
+       3,     3,     4,     3,     3,     3,     1,     2,     1,     1,
+       2,     2,     2,     2,     2,     1,     2,     1,     1,     2,
+       2,     2,     2,     2,     1,     2,     1,     1,     2,     2,
+       2,     2,     2,     1,     2,     1,     1,     2,     2,     2,
+       2,     2,     1,     1,     1,     1,     1,     2,     2,     2,
+       2,     1,     2,     1,     1
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+   doesn't specify something else to do.  Zero means the default is an
+   error. */
+static const short yydefact[] =
+{
+       0,     0,     0,     0,     0,     0,     0,     0,    63,    64,
+      56,     1,     2,     4,     6,     8,     9,    55,    52,    54,
+      61,    53,     7,     0,    62,    57,    58,    59,    60,     0,
+       0,    18,    19,    16,     0,     0,    36,    37,    34,     0,
+       0,     0,    15,     3,     5,    23,    17,    20,    22,    24,
+      21,    10,    14,    41,    35,    38,    40,    42,    39,    27,
+      28,    25,     0,    11,    13,    32,    26,    29,    31,    33,
+      30,    12,     0,     0,     0
+};
+
+static const short yydefgoto[] =
+{
+      72,    11,    12,    13,    14,    34,    40,    41,    35,    15,
+      16,    17,    18,    19,    20,    21
+};
+
+static const short yypact[] =
+{
+      -5,    50,    -5,   -12,   -12,   -12,   -12,   -12,-32768,-32768,
+  -32768,-32768,    -2,-32768,-32768,    48,   123,-32768,-32768,-32768,
+  -32768,-32768,-32768,    -4,-32768,-32768,-32768,-32768,-32768,    -5,
+      -5,    10,    24,    33,   110,    58,    27,    41,    59,   135,
+      58,   110,-32768,-32768,-32768,    62,    68,    71,    72,    80,
+      81,-32768,-32768,    84,    90,    93,    94,   102,   103,   138,
+     141,-32768,    58,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,    17,    21,-32768
+};
+
+static const short yypgoto[] =
+{
+  -32768,    -1,-32768,    -8,    25,-32768,   -14,-32768,-32768,   -11,
+     -35,-32768,-32768,-32768,   134,-32768
+};
+
+
+#define	YYLAST		151
+
+
+static const short yytable[] =
+{
+      52,    23,     1,    29,    30,    63,     2,     8,    42,     3,
+       4,     5,     6,     7,     8,     9,    10,    73,    45,    46,
+      47,    74,    44,    51,   -45,    62,    22,    71,    43,   -45,
+      64,   -45,    48,    49,    50,    53,    54,    55,   -46,     0,
+       0,   -27,     0,   -46,     0,   -46,   -27,   -43,   -27,    56,
+      57,    58,   -43,     0,   -43,   -28,    31,    32,    33,     0,
+     -28,     2,   -28,     0,     3,     4,     5,     6,     7,     8,
+       9,    10,     3,   -25,     0,     0,   -50,     8,   -25,    10,
+     -25,   -50,   -44,   -50,     0,   -47,   -49,   -44,     0,   -44,
+     -47,   -49,   -47,   -49,   -51,   -48,     0,     0,   -32,   -51,
+     -48,   -51,   -48,   -32,   -26,   -32,     0,   -29,   -31,   -26,
+       0,   -26,   -29,   -31,   -29,   -31,   -33,   -30,     0,     0,
+       0,   -33,   -30,   -33,   -30,     4,     5,     6,     7,     0,
+       9,    36,    37,    38,     0,     0,    39,    24,    25,    26,
+      27,    28,     0,    59,    60,    61,    65,    66,    67,    68,
+      69,    70
+};
+
+static const short yycheck[] =
+{
+      35,     2,     7,     5,     6,    40,    11,    19,    12,    14,
+      15,    16,    17,    18,    19,    20,    21,     0,     8,     9,
+      10,     0,    30,    34,    14,    39,     1,    62,    29,    19,
+      41,    21,     8,     9,    10,     8,     9,    10,    14,    -1,
+      -1,    14,    -1,    19,    -1,    21,    19,    14,    21,     8,
+       9,    10,    19,    -1,    21,    14,     8,     9,    10,    -1,
+      19,    11,    21,    -1,    14,    15,    16,    17,    18,    19,
+      20,    21,    14,    14,    -1,    -1,    14,    19,    19,    21,
+      21,    19,    14,    21,    -1,    14,    14,    19,    -1,    21,
+      19,    19,    21,    21,    14,    14,    -1,    -1,    14,    19,
+      19,    21,    21,    19,    14,    21,    -1,    14,    14,    19,
+      -1,    21,    19,    19,    21,    21,    14,    14,    -1,    -1,
+      -1,    19,    19,    21,    21,    15,    16,    17,    18,    -1,
+      20,     8,     9,    10,    -1,    -1,    13,     3,     4,     5,
+       6,     7,    -1,     8,     9,    10,     8,     9,    10,     8,
+       9,    10
+};
+#define YYPURE 1
+
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
+
+   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, 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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser when
+   the %semantic_parser declaration is not specified in the grammar.
+   It was written by Richard Stallman by simplifying the hairy parser
+   used when %semantic_parser is specified.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+# if YYLSP_NEEDED
+  YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# if YYLSP_NEEDED
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))	\
+      + 2 * YYSTACK_GAP_MAX)
+# else
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;	\
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");			\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).
+
+   When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+   first token.  By default, to implement support for ranges, extend
+   its range to the last symbol.  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)       	\
+   Current.last_line   = Rhs[N].last_line;	\
+   Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#if YYPURE
+# if YYLSP_NEEDED
+#  ifdef YYLEX_PARAM
+#   define YYLEX		yylex (&yylval, &yylloc, YYLEX_PARAM)
+#  else
+#   define YYLEX		yylex (&yylval, &yylloc)
+#  endif
+# else /* !YYLSP_NEEDED */
+#  ifdef YYLEX_PARAM
+#   define YYLEX		yylex (&yylval, YYLEX_PARAM)
+#  else
+#   define YYLEX		yylex (&yylval)
+#  endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX			yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+#endif
+
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL
+# else
+#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+   variables are global, or local to YYPARSE.  */
+
+#define YY_DECL_NON_LSP_VARIABLES			\
+/* The lookahead symbol.  */				\
+int yychar;						\
+							\
+/* The semantic value of the lookahead symbol. */	\
+YYSTYPE yylval;						\
+							\
+/* Number of parse errors so far.  */			\
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES			\
+YY_DECL_NON_LSP_VARIABLES			\
+						\
+/* Location data for the lookahead symbol.  */	\
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES			\
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  /* If reentrant, generate the variables here. */
+#if YYPURE
+  YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yychar1 = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack. */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+#if YYLSP_NEEDED
+  YYLTYPE yyloc;
+#endif
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule. */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+#if YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  */
+# if YYLSP_NEEDED
+	YYLTYPE *yyls1 = yyls;
+	/* This used to be a conditional around just the two extra args,
+	   but that might be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+	yyls = yyls1;
+# else
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yystacksize);
+# endif
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+# if YYLSP_NEEDED
+	YYSTACK_RELOCATE (yyls);
+# endif
+# undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+#if YYLSP_NEEDED
+      yylsp = yyls + yysize - 1;
+#endif
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE (yychar);
+
+#if YYDEBUG
+     /* We have to keep this `#if YYDEBUG', since we use variables
+	which are defined only if `YYDEBUG' is set.  */
+      if (yydebug)
+	{
+	  YYFPRINTF (stderr, "Next token is %d (%s",
+		     yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise
+	     meaning of a token, for further debugging info.  */
+# ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+# endif
+	  YYFPRINTF (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
[truncated at 1000 lines; 1026 more skipped]

reactos/lib/msi
cond.tab.h added at 1.1.2.1
diff -N cond.tab.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cond.tab.h	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,40 @@
+#ifndef BISON_COND_TAB_H
+# define BISON_COND_TAB_H
+
+#ifndef YYSTYPE
+typedef union
+{
+    struct cond_str str;
+    LPWSTR    string;
+    INT       value;
+    comp_int  fn_comp_int;
+    comp_str  fn_comp_str;
+    comp_m1   fn_comp_m1;
+    comp_m2   fn_comp_m2;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define	COND_SPACE	257
+# define	COND_EOF	258
+# define	COND_OR	259
+# define	COND_AND	260
+# define	COND_NOT	261
+# define	COND_LT	262
+# define	COND_GT	263
+# define	COND_EQ	264
+# define	COND_LPAR	265
+# define	COND_RPAR	266
+# define	COND_TILDA	267
+# define	COND_PERCENT	268
+# define	COND_DOLLARS	269
+# define	COND_QUESTION	270
+# define	COND_AMPER	271
+# define	COND_EXCLAM	272
+# define	COND_IDENT	273
+# define	COND_NUMBER	274
+# define	COND_LITER	275
+# define	COND_ERROR	276
+
+
+#endif /* not BISON_COND_TAB_H */

reactos/lib/msi
cond.y added at 1.1.2.1
diff -N cond.y
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cond.y	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,774 @@
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2003 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 "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+    MSIPACKAGE *package;
+    LPCWSTR str;
+    INT    n;
+    MSICONDITION result;
+} COND_input;
+
+struct cond_str {
+    LPCWSTR data;
+    INT len;
+};
+
+static LPWSTR COND_GetString( struct cond_str *str );
+static LPWSTR COND_GetLiteral( struct cond_str *str );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
+typedef INT (*comp_m1)(LPWSTR a,int b);
+typedef INT (*comp_m2)(int a,LPWSTR b);
+
+static INT comp_lt_i(INT a, INT b);
+static INT comp_gt_i(INT a, INT b);
+static INT comp_le_i(INT a, INT b);
+static INT comp_ge_i(INT a, INT b);
+static INT comp_eq_i(INT a, INT b);
+static INT comp_ne_i(INT a, INT b);
+static INT comp_bitand(INT a, INT b);
+static INT comp_highcomp(INT a, INT b);
+static INT comp_lowcomp(INT a, INT b);
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
+
+static INT comp_eq_m1(LPWSTR a, INT b);
+static INT comp_ne_m1(LPWSTR a, INT b);
+static INT comp_lt_m1(LPWSTR a, INT b);
+static INT comp_gt_m1(LPWSTR a, INT b);
+static INT comp_le_m1(LPWSTR a, INT b);
+static INT comp_ge_m1(LPWSTR a, INT b);
+
+static INT comp_eq_m2(INT a, LPWSTR b);
+static INT comp_ne_m2(INT a, LPWSTR b);
+static INT comp_lt_m2(INT a, LPWSTR b);
+static INT comp_gt_m2(INT a, LPWSTR b);
+static INT comp_le_m2(INT a, LPWSTR b);
+static INT comp_ge_m2(INT a, LPWSTR b);
+
+%}
+
+%pure-parser
+
+%union
+{
+    struct cond_str str;
+    LPWSTR    string;
+    INT       value;
+    comp_int  fn_comp_int;
+    comp_str  fn_comp_str;
+    comp_m1   fn_comp_m1;
+    comp_m2   fn_comp_m2;
+}
+
+%token COND_SPACE COND_EOF COND_SPACE
+%token COND_OR COND_AND COND_NOT
+%token COND_LT COND_GT COND_EQ 
+%token COND_LPAR COND_RPAR COND_TILDA
+%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
+%token <str> COND_IDENT <str> COND_NUMBER <str> COND_LITER
+
+%nonassoc COND_EOF COND_ERROR
+
+%type <value> expression boolean_term boolean_factor 
+%type <value> term value_i symbol_i integer
+%type <string> identifier value_s symbol_s literal
+%type <fn_comp_int> comp_op_i
+%type <fn_comp_str> comp_op_s 
+%type <fn_comp_m1>  comp_op_m1 
+%type <fn_comp_m2>  comp_op_m2
+
+%%
+
+condition:
+    expression
+        {
+            COND_input* cond = (COND_input*) info;
+            cond->result = $1;
+        }
+    ;
+
+expression:
+    boolean_term 
+        {
+            $$ = $1;
+        }
+  | boolean_term COND_OR expression
+        {
+            $$ = $1 || $3;
+        }
+    ;
+
+boolean_term:
+    boolean_factor
+        {
+            $$ = $1;
+        }
+    | boolean_term COND_AND boolean_factor
+        {
+            $$ = $1 && $3;
+        }
+    ;
+
+boolean_factor:
+    term
+        {
+            $$ = $1;
+        }
+  | COND_NOT term
+        {
+            $$ = ! $2;
+        }
+    ;
+
+
+term:
+    value_i
+        {
+            $$ = $1;
+        }
+  | value_s
+        {
+            $$ = atoiW($1);
+        }
+  | value_i comp_op_i value_i
+        {
+            $$ = $2( $1, $3 );
+        }
+  | value_s comp_op_s value_s
+        {
+            $$ = $2( $1, $3, FALSE );
+        }
+  | value_s COND_TILDA comp_op_s value_s
+        {
+            $$ = $3( $1, $4, TRUE );
+        }
+  | value_s comp_op_m1 value_i
+        {
+            $$ = $2( $1, $3 );
+        }
+  | value_i comp_op_m2 value_s
+        {
+            $$ = $2( $1, $3 );
+        }
+  | COND_LPAR expression COND_RPAR
+        {
+            $$ = $2;
+        }
+    ;
+
+comp_op_i:
+    /* common functions */
+   COND_EQ
+        {
+            $$ = comp_eq_i;
+        }
+  | COND_LT COND_GT
+        {
+            $$ = comp_ne_i;
+        }
+  | COND_LT
+        {
+            $$ = comp_lt_i;
+        }
+  | COND_GT
+        {
+            $$ = comp_gt_i;
+        }
+  | COND_LT COND_EQ
+        {
+            $$ = comp_le_i;
+        }
+  | COND_GT COND_EQ
+        {
+            $$ = comp_ge_i;
+        }
+  /*Int only*/
+  | COND_GT COND_LT
+        {
+            $$ = comp_bitand;
+        }
+  | COND_LT COND_LT
+        {
+            $$ = comp_highcomp;
+        }
+  | COND_GT COND_GT
+        {
+            $$ = comp_lowcomp;
+        }
+    ;
+
+comp_op_s:
+    /* common functions */
+   COND_EQ
+        {
+            $$ = comp_eq_s;
+        }
+  | COND_LT COND_GT
+        {
+            $$ = comp_ne_s;
+        }
+  | COND_LT
+        {
+            $$ = comp_lt_s;
+        }
+  | COND_GT
+        {
+            $$ = comp_gt_s;
+        }
+  | COND_LT COND_EQ
+        {
+            $$ = comp_le_s;
+        }
+  | COND_GT COND_EQ
+        {
+            $$ = comp_ge_s;
+        }
+  /*string only*/
+  | COND_GT COND_LT
+        {
+            $$ = comp_substring;
+        }
+  | COND_LT COND_LT
+        {
+            $$ = comp_start;
+        }
+  | COND_GT COND_GT
+        {
+            $$ = comp_end;
+        }
+    ;
+
+comp_op_m1:
+    /* common functions */
+   COND_EQ
+        {
+            $$ = comp_eq_m1;
+        }
+  | COND_LT COND_GT
+        {
+            $$ = comp_ne_m1;
+        }
+  | COND_LT
+        {
+            $$ = comp_lt_m1;
+        }
+  | COND_GT
+        {
+            $$ = comp_gt_m1;
+        }
+  | COND_LT COND_EQ
+        {
+            $$ = comp_le_m1;
+        }
+  | COND_GT COND_EQ
+        {
+            $$ = comp_ge_m1;
+        }
+  /*Not valid for mixed compares*/
+  | COND_GT COND_LT
+        {
+            $$ = 0;
+        }
+  | COND_LT COND_LT
+        {
+            $$ = 0;
+        }
+  | COND_GT COND_GT
+        {
+            $$ = 0;
+        }
+    ;
+
+comp_op_m2:
+    /* common functions */
+   COND_EQ
+        {
+            $$ = comp_eq_m2;
+        }
+  | COND_LT COND_GT
+        {
+            $$ = comp_ne_m2;
+        }
+  | COND_LT
+        {
+            $$ = comp_lt_m2;
+        }
+  | COND_GT
+        {
+            $$ = comp_gt_m2;
+        }
+  | COND_LT COND_EQ
+        {
+            $$ = comp_le_m2;
+        }
+  | COND_GT COND_EQ
+        {
+            $$ = comp_ge_m2;
+        }
+  /*Not valid for mixed compares*/
+  | COND_GT COND_LT
+        {
+            $$ = 0;
+        }
+  | COND_LT COND_LT
+        {
+            $$ = 0;
+        }
+  | COND_GT COND_GT
+        {
+            $$ = 0;
+        }
+    ;
+
+value_i:
+    symbol_i
+        {
+            $$ = $1;
+        }
+  | integer
+        {
+            $$ = $1;
+        }
+    ;
+
+value_s:
+  symbol_s
+    {
+        $$ = $1;
+    } 
+  | literal
+    {
+        $$ = $1;
+    }
+    ;
+
+literal:
+    COND_LITER
+        {
+            $$ = COND_GetLiteral(&$1);
+            if( !$$ )
+                YYABORT;
+        }
+    ;
+
+symbol_i:
+    COND_DOLLARS identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MSI_GetComponentStateW(cond->package, $2, &install, &action );
+            $$ = action;
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+  | COND_QUESTION identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MSI_GetComponentStateW(cond->package, $2, &install, &action );
+            $$ = install;
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+  | COND_AMPER identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+            $$ = action;
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+  | COND_EXCLAM identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+            $$ = install;
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+    ;
+
+symbol_s:
+    identifier
+        {
+            DWORD sz;
+            COND_input* cond = (COND_input*) info;
+            $$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
+
+            /* Lookup the identifier */
+
+            sz=0x100;
+            if (MSI_GetPropertyW(cond->package,$1,$$,&sz) != ERROR_SUCCESS)
+            {
+                $$[0]=0;
+            }
+            HeapFree( GetProcessHeap(), 0, $1 );
+        }
+    | COND_PERCENT identifier
+        {
+            UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
+            if( len++ )
+            {
+                $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+                if( $$ )
+                    GetEnvironmentVariableW( $2, $$, len );
+            }
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+    ;
+
+identifier:
+    COND_IDENT
+        {
+            $$ = COND_GetString(&$1);
+            if( !$$ )
+                YYABORT;
+        }
+    ;
+
+integer:
+    COND_NUMBER
+        {
+            LPWSTR szNum = COND_GetString(&$1);
+            if( !szNum )
+                YYABORT;
+            $$ = atoiW( szNum );
+            HeapFree( GetProcessHeap(), 0, szNum );
+        }
+    ;
+
+%%
+
+
+static int COND_IsAlpha( WCHAR x )
+{
+    return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+            ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
+            ( ( x == '_' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+    return( (( x >= '0' ) && ( x <= '9' ))  || (x =='-') || (x =='.') );
+}
+
+
+/* the mess of comparison functions */
+
+static INT comp_lt_i(INT a, INT b)
+{ return (a < b); }
+static INT comp_gt_i(INT a, INT b)
+{ return (a > b); }
+static INT comp_le_i(INT a, INT b)
+{ return (a <= b); }
+static INT comp_ge_i(INT a, INT b)
+{ return (a >= b); }
+static INT comp_eq_i(INT a, INT b)
+{ return (a == b); }
+static INT comp_ne_i(INT a, INT b)
+{ return (a != b); }
+static INT comp_bitand(INT a, INT b)
+{ return a & b;}
+static INT comp_highcomp(INT a, INT b)
+{ return HIWORD(a)==b; }
+static INT comp_lowcomp(INT a, INT b)
+{ return LOWORD(a)==b; }
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);}
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b); else  return strcmpW(a,b);}
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;}
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;}
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;}
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>=0; else return  strcmpW(a,b)>=0;}
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless)
+/* ERROR NOT WORKING REWRITE */
+{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;}
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strncmpiW(a,b,strlenW(b))==0; 
+  else return strncmpW(a,b,strlenW(b))==0;}
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless)
+{ 
+    int i = strlenW(a); 
+    int j = strlenW(b); 
+    if (j>i)
+        return 0;
+    if (casless) return (!strcmpiW(&a[i-j-1],b));
+    else  return (!strcmpW(&a[i-j-1],b));
+}
+
+
+static INT comp_eq_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}
+static INT comp_ne_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}
+static INT comp_lt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}
+static INT comp_gt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}
+static INT comp_le_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}
+static INT comp_ge_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}
+
+static INT comp_eq_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}
+static INT comp_ne_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}
+static INT comp_lt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}
+static INT comp_gt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}
+static INT comp_le_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}
+static INT comp_ge_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}
+
+
+
+static int COND_IsIdent( WCHAR x )
+{
+    return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) 
+            || ( x == '#' ) || (x == '.') );
+}
+
+static int COND_GetOne( struct cond_str *str, COND_input *cond )
+{
+    static const WCHAR szNot[] = {'N','O','T',0};
+    static const WCHAR szAnd[] = {'A','N','D',0};
+    static const WCHAR szOr[] = {'O','R',0};
+    WCHAR ch;
+    int rc, len = 1;
+
+    str->data = &cond->str[cond->n];
+
+    ch = str->data[0];
+    switch( ch )
+    {
+    case 0: return 0;
+    case '(': rc = COND_LPAR; break;
+    case ')': rc = COND_RPAR; break;
+    case '&': rc = COND_AMPER; break;
+    case '!': rc = COND_EXCLAM; break;
+    case '$': rc = COND_DOLLARS; break;
+    case '?': rc = COND_QUESTION; break;
+    case '%': rc = COND_PERCENT; break;
+    case ' ': rc = COND_SPACE; break;
+    case '=': rc = COND_EQ; break;
+    case '~': rc = COND_TILDA; break;
+    case '<': rc = COND_LT; break;
+    case '>': rc = COND_GT; break;
+    case '"':
+	{
+	    const WCHAR *ch2 = str->data + 1;
+
+
+	    while ( *ch2 && *ch2 != '"' )
+	    	++ch2;
+	    if (*ch2 == '"')
+	    {
+	        len = ch2 - str->data + 1;
+		rc = COND_LITER;
+		break;
+	    }
+	}
+	ERR("Unterminated string\n");
+	rc = COND_ERROR;
+    	break;
+    default: 
+        if( COND_IsAlpha( ch ) )
+        {
+            while( COND_IsIdent( str->data[len] ) )
+                len++;
+            rc = COND_IDENT;
+            break;
+        }
+
+        if( COND_IsNumber( ch ) )
+        {
+            while( COND_IsNumber( str->data[len] ) )
+                len++;
+            rc = COND_NUMBER;
+            break;
+        }
+
+        ERR("Got unknown character %c(%x)\n",ch,ch);
+        rc = COND_ERROR;
+        break;
+    }
+
+    /* keyword identifiers */
+    if( rc == COND_IDENT )
+    {
+        if( (len==3) && (strncmpiW(str->data,szNot,len)==0) )
+            rc = COND_NOT;
+        else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) )
+            rc = COND_AND;
+        else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) )
+            rc = COND_OR;
+    }
+
+    cond->n += len;
+    str->len = len;
+
+    return rc;
+}
+
+static int COND_lex( void *COND_lval, COND_input *cond )
+{
+    int rc;
+    struct cond_str *str = COND_lval;
+
+    do {
+        rc = COND_GetOne( str, cond );
+    } while (rc == COND_SPACE);
+    
+    return rc;
+}
+
+static LPWSTR COND_GetString( struct cond_str *str )
+{
+    LPWSTR ret;
+
+    ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );
+    if( ret )
+    {
+        strncpyW( ret, str->data, str->len );
+        ret[str->len]=0;
+    }
+    TRACE("Got identifier %s\n",debugstr_w(ret));
+    return ret;
+}
+
+static LPWSTR COND_GetLiteral( struct cond_str *str )
+{
+    LPWSTR ret;
+
+    ret = HeapAlloc( GetProcessHeap(), 0, (str->len-1) * sizeof (WCHAR) );
+    if( ret )
+    {
+        memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
+        ret[str->len - 2]=0;
+    }
+    TRACE("Got literal %s\n",debugstr_w(ret));
+    return ret;
+}
+
+static int COND_error(char *str)
+{
+    return 0;
+}
+
+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
+{
+    COND_input cond;
+    MSICONDITION r;
+
+    cond.package = package;
+    cond.str   = szCondition;
+    cond.n     = 0;
+    cond.result = -1;
+    
+    TRACE("Evaluating %s\n",debugstr_w(szCondition));    
+
+    if( !COND_parse( &cond ) )
+        r = cond.result;
+    else
+        r = MSICONDITION_ERROR;
+
+    TRACE("Evaluates to %i\n",r);
+    return r;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
+{
+    MSIPACKAGE *package;
+    UINT ret;
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+    if( !package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_EvaluateConditionW( package, szCondition );
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
+{
+    LPWSTR szwCond = NULL;
+    MSICONDITION r;
+
+    if( szCondition )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
+        szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
+    }
+
+    r = MsiEvaluateConditionW( hInstall, szwCond );
+
+    if( szwCond )
+        HeapFree( GetProcessHeap(), 0, szwCond );
+
+    return r;
+}

reactos/lib/msi
create.c added at 1.1.2.1
diff -N create.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ create.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,258 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSICREATEVIEW
+{
+    MSIVIEW          view;
+    MSIDATABASE     *db;
+    LPWSTR           name;
+    BOOL             bIsTemp;
+    create_col_info *col_info;
+} MSICREATEVIEW;
+
+static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+    TRACE("%p %d %d %p\n", cv, row, col, val );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+    create_col_info *col;
+    UINT r, nField, row, table_val, column_val;
+    static const WCHAR szTables[] =  { '_','T','a','b','l','e','s',0 };
+    static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+    MSIVIEW *tv = NULL;
+
+    TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name), 
+          cv->bIsTemp?"temporary":"permanent");
+
+    /* only add tables that don't exist already */
+    if( TABLE_Exists(cv->db, cv->name ) )
+        return ERROR_BAD_QUERY_SYNTAX;
+
+    /* add the name to the _Tables table */
+    table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
+    TRACE("New string %s -> %d\n", debugstr_w( cv->name ), table_val );
+    if( table_val < 0 )
+        return ERROR_FUNCTION_FAILED;
+
+    r = TABLE_CreateView( cv->db, szTables, &tv );
+    TRACE("CreateView returned %x\n", r);
+    if( r )
+        return r;
+
+    r = tv->ops->execute( tv, 0 );
+    TRACE("tv execute returned %x\n", r);
+    if( r )
+        return r;
+
+    row = -1;
+    r = tv->ops->insert_row( tv, &row );
+    TRACE("insert_row returned %x\n", r);
+    if( r )
+        goto err;
+
+    r = tv->ops->set_int( tv, row, 1, table_val );
+    if( r )
+        goto err;
+    tv->ops->delete( tv );
+    tv = NULL;
+
+    /* add each column to the _Columns table */
+    r = TABLE_CreateView( cv->db, szColumns, &tv );
+    if( r )
+        return r;
+
+    r = tv->ops->execute( tv, 0 );
+    TRACE("tv execute returned %x\n", r);
+    if( r )
+        return r;
+
+    /*
+     * need to set the table, column number, col name and type
+     * for each column we enter in the table
+     */
+    nField = 1;
+    for( col = cv->col_info; col; col = col->next )
+    {
+        row = -1;
+        r = tv->ops->insert_row( tv, &row );
+        if( r )
+            goto err;
+
+        column_val = msi_addstringW( cv->db->strings, 0, col->colname, -1, 1 );
+        TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
+        if( column_val < 0 )
+            break;
+
+        /* add the string again here so we increase the reference count */
+        table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
+        if( table_val < 0 )
+            break;
+
+        r = tv->ops->set_int( tv, row, 1, table_val );
+        if( r )
+            break;
+
+        r = tv->ops->set_int( tv, row, 2, 0x8000|nField );
+        if( r )
+            break;
+
+        r = tv->ops->set_int( tv, row, 3, column_val );
+        if( r )
+            break;
+
+        r = tv->ops->set_int( tv, row, 4, 0x8000|col->type );
+        if( r )
+            break;
+
+        nField++;
+    }
+    if( !col )
+        r = ERROR_SUCCESS;
+
+err:
+    /* FIXME: remove values from the string table on error */
+    if( tv )
+        tv->ops->delete( tv );
+    return r;
+}
+
+static UINT CREATE_close( struct tagMSIVIEW *view )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+    TRACE("%p\n", cv);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+    TRACE("%p %p %p\n", cv, rows, cols );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+    TRACE("%p %d %p %p\n", cv, n, name, type );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+    TRACE("%p %d %ld\n", cv, eModifyMode, hrec );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_delete( struct tagMSIVIEW *view )
+{
+    MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+    create_col_info *col;
+
+    TRACE("%p\n", cv );
+
+    col = cv->col_info; 
+    while( col )
+    {
+        create_col_info *t = col;
+        col = col->next;
+        HeapFree( GetProcessHeap(), 0, t->colname );
+        HeapFree( GetProcessHeap(), 0, t );
+    }
+    msiobj_release( &cv->db->hdr );
+    HeapFree( GetProcessHeap(), 0, cv->name );
+    HeapFree( GetProcessHeap(), 0, cv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS create_ops =
+{
+    CREATE_fetch_int,
+    NULL,
+    NULL,
+    NULL,
+    CREATE_execute,
+    CREATE_close,
+    CREATE_get_dimensions,
+    CREATE_get_column_info,
+    CREATE_modify,
+    CREATE_delete
+};
+
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+                        create_col_info *col_info, BOOL temp )
+{
+    MSICREATEVIEW *cv = NULL;
+
+    TRACE("%p\n", cv );
+
+    cv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *cv );
+    if( !cv )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    cv->view.ops = &create_ops;
+    msiobj_addref( &db->hdr );
+    cv->db = db;
+    cv->name = table;  /* FIXME: strdupW it? */
+    cv->col_info = col_info;
+    cv->bIsTemp = temp;
+    *view = (MSIVIEW*) cv;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
distinct.c added at 1.1.2.1
diff -N distinct.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ distinct.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,293 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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 <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);
+
+typedef struct tagDISTINCTSET
+{
+    UINT val;
+    UINT count;
+    UINT row;
+    struct tagDISTINCTSET *nextrow;
+    struct tagDISTINCTSET *nextcol;
+} DISTINCTSET;
+
+typedef struct tagMSIDISTINCTVIEW
+{
+    MSIVIEW        view;
+    MSIDATABASE   *db;
+    MSIVIEW       *table;
+    UINT           row_count;
+    UINT          *translation;
+} MSIDISTINCTVIEW;
+
+static DISTINCTSET ** distinct_insert( DISTINCTSET **x, UINT val, UINT row )
+{
+    /* horrible O(n) find */
+    while( *x )
+    {
+        if( (*x)->val == val )
+        {
+            (*x)->count++;
+            return x;
+        }
+        x = &(*x)->nextrow;
+    }
+
+    /* nothing found, so add one */
+    *x = HeapAlloc( GetProcessHeap(), 0, sizeof (DISTINCTSET) );
+    if( *x )
+    {
+        (*x)->val = val;
+        (*x)->count = 1;
+        (*x)->row = row;
+        (*x)->nextrow = NULL;
+        (*x)->nextcol = NULL;
+    }
+    return x;
+}
+
+static void distinct_free( DISTINCTSET *x )
+{
+    while( x )
+    {
+        DISTINCTSET *next = x->nextrow;
+        distinct_free( x->nextcol );
+        HeapFree( GetProcessHeap(), 0, x );
+        x = next;
+    }
+}
+
+static UINT DISTINCT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+    TRACE("%p %d %d %p\n", dv, row, col, val );
+
+    if( !dv->table )
+        return ERROR_FUNCTION_FAILED;
+
+    if( row >= dv->row_count )
+        return ERROR_INVALID_PARAMETER;
+
+    row = dv->translation[ row ];
+
+    return dv->table->ops->fetch_int( dv->table, row, col, val );
+}
+
+static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+    UINT r, i, j, r_count, c_count;
+    DISTINCTSET *rowset = NULL;
+
+    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, &r_count, &c_count );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    dv->translation = HeapAlloc( GetProcessHeap(), 0, r_count*sizeof(UINT) );
+    if( !dv->translation )
+        return ERROR_FUNCTION_FAILED;
+
+    /* build it */
+    for( i=0; i<r_count; i++ )
+    {
+        DISTINCTSET **x = &rowset;
+
+        for( j=1; j<=c_count; j++ )
+        {
+            UINT val = 0;
+            r = dv->table->ops->fetch_int( dv->table, i, j, &val );
+            if( r != ERROR_SUCCESS )
+            {
+                ERR("Failed to fetch int at %d %d\n", i, j );
+                distinct_free( rowset );
+                return r;
+            }
+            x = distinct_insert( x, val, i );
+            if( !*x )
+            {
+                ERR("Failed to insert at %d %d\n", i, j );
+                distinct_free( rowset );
+                return ERROR_FUNCTION_FAILED;
+            }
+            if( j != c_count )
+                x = &(*x)->nextcol;
+        }
+
+        /* check if it was distinct and if so, include it */
+        if( (*x)->row == i )
+        {
+            TRACE("Row %d -> %d\n", dv->row_count, i);
+            dv->translation[dv->row_count++] = i;
+        }
+    }
+
+    distinct_free( rowset );
+
+    return ERROR_SUCCESS;
+}
+
+static UINT DISTINCT_close( struct tagMSIVIEW *view )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+    TRACE("%p\n", dv );
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( dv->translation )
+        HeapFree( GetProcessHeap(), 0, dv->translation );
+    dv->translation = NULL;
+    dv->row_count = 0;
+
+    return dv->table->ops->close( dv->table );
+}
+
+static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+    TRACE("%p %p %p\n", dv, rows, cols );
+
+    if( !dv->table )
+        return ERROR_FUNCTION_FAILED;
+
+    if( rows )
+    {
+        if( !dv->translation )
+            return ERROR_FUNCTION_FAILED;
+        *rows = dv->row_count;
+    }
+
+    return dv->table->ops->get_dimensions( dv->table, NULL, cols );
+}
+
+static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)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 DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+    TRACE("%p %d %ld\n", dv, eModifyMode, hrec );
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return dv->table->ops->modify( dv->table, eModifyMode, hrec );
+}
+
+static UINT DISTINCT_delete( struct tagMSIVIEW *view )
+{
+    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+    TRACE("%p\n", dv );
+
+    if( dv->table )
+        dv->table->ops->delete( dv->table );
+
+    if( dv->translation )
+        HeapFree( GetProcessHeap(), 0, dv->translation );
+    msiobj_release( &dv->db->hdr );
+    HeapFree( GetProcessHeap(), 0, dv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS distinct_ops =
+{
+    DISTINCT_fetch_int,
+    NULL,
+    NULL,
+    NULL,
+    DISTINCT_execute,
+    DISTINCT_close,
+    DISTINCT_get_dimensions,
+    DISTINCT_get_column_info,
+    DISTINCT_modify,
+    DISTINCT_delete
+};
+
+UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+    MSIDISTINCTVIEW *dv = NULL;
+    UINT count = 0, r;
+
+    TRACE("%p\n", dv );
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("can't get table dimensions\n");
+        return r;
+    }
+
+    dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+    if( !dv )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    dv->view.ops = &distinct_ops;
+    msiobj_addref( &db->hdr );
+    dv->db = db;
+    dv->table = table;
+    dv->translation = NULL;
+    dv->row_count = 0;
+    *view = (MSIVIEW*) dv;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
handle.c added at 1.1.2.1
diff -N handle.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ handle.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,215 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static CRITICAL_SECTION MSI_handle_cs;
+static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
+{
+    0, 0, &MSI_handle_cs,
+    { &MSI_handle_cs_debug.ProcessLocksList, 
+      &MSI_handle_cs_debug.ProcessLocksList },
+      0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
+};
+static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
+
+MSIOBJECTHDR *msihandletable[MSIMAXHANDLES];
+
+MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
+{
+    MSIHANDLE ret = 0;
+    UINT i;
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    /* find a slot */
+    for(i=0; i<MSIMAXHANDLES; i++)
+        if( !msihandletable[i] )
+            break;
+    if( (i>=MSIMAXHANDLES) || msihandletable[i] )
+        goto out;
+
+    msiobj_addref( obj );
+    msihandletable[i] = obj;
+    ret = (MSIHANDLE) (i+1);
+out:
+    TRACE("%p -> %ld\n", obj, ret );
+
+    LeaveCriticalSection( &MSI_handle_cs );
+    return ret;
+}
+
+void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
+{
+    MSIOBJECTHDR *ret = NULL;
+
+    EnterCriticalSection( &MSI_handle_cs );
+    handle--;
+    if( handle<0 )
+        goto out;
+    if( handle>=MSIMAXHANDLES )
+        goto out;
+    if( !msihandletable[handle] )
+        goto out;
+    if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
+        goto out;
+    if( type && (msihandletable[handle]->type != type) )
+        goto out;
+    ret = msihandletable[handle];
+    msiobj_addref( ret );
+    
+out:
+    LeaveCriticalSection( &MSI_handle_cs );
+
+    return (void*) ret;
+}
+
+MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
+{
+    MSIHANDLE ret = 0;
+    UINT i;
+
+    TRACE("%p\n", hdr);
+
+    EnterCriticalSection( &MSI_handle_cs );
+    for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
+        if( msihandletable[i] == hdr )
+            ret = i+1;
+    LeaveCriticalSection( &MSI_handle_cs );
+
+    TRACE("%p -> %ld\n", hdr, ret);
+
+    msiobj_addref( hdr );
+    return ret;
+}
+
+void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
+{
+    MSIOBJECTHDR *info;
+
+    info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
+    if( info )
+    {
+        info->magic = MSIHANDLE_MAGIC;
+        info->type = type;
+        info->refcount = 1;
+        info->destructor = destroy;
+    }
+
+    return info;
+}
+
+void msiobj_addref( MSIOBJECTHDR *info )
+{
+    TRACE("%p\n", info);
+
+    if( !info )
+        return;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        return;
+    }
+
+    info->refcount++;
+}
+
+int msiobj_release( MSIOBJECTHDR *info )
+{
+    int ret;
+
+    TRACE("%p\n",info);
+
+    if( !info )
+        return -1;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        return -1;
+    }
+
+    ret = info->refcount--;
+    if (info->refcount == 0)
+    {
+    if( info->destructor )
+            info->destructor( info );
+    HeapFree( GetProcessHeap(), 0, info );
+        TRACE("object %p destroyed\n", info);
+    }
+
+    return ret;
+}
+
+UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
+{
+    MSIOBJECTHDR *info;
+    UINT ret = ERROR_INVALID_HANDLE;
+
+    TRACE("%lx\n",handle);
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    info = msihandle2msiinfo(handle, 0);
+    if( !info )
+        goto out;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        goto out;
+    }
+
+    msiobj_release( info );
+    msihandletable[handle-1] = NULL;
+    ret = ERROR_SUCCESS;
+
+    TRACE("handle %lx Destroyed\n", handle);
+out:
+    LeaveCriticalSection( &MSI_handle_cs );
+    if( info )
+        msiobj_release( info );
+
+    return ret;
+}
+
+UINT WINAPI MsiCloseAllHandles(void)
+{
+    UINT i;
+
+    TRACE("\n");
+
+    for(i=0; i<MSIMAXHANDLES; i++)
+        MsiCloseHandle( i+1 );
+
+    return 0;
+}

reactos/lib/msi
insert.c added at 1.1.2.1
diff -N insert.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ insert.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,238 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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
+ */
+
+#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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIINSERTVIEW
+{
+    MSIVIEW          view;
+    MSIDATABASE     *db;
+    BOOL             bIsTemp;
+    MSIVIEW         *sv;
+    value_list      *vals;   /* looks like these may be ignored... */
+} MSIINSERTVIEW;
+
+static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+
+    TRACE("%p %d %d %p\n", iv, row, col, val );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+    UINT n, type, val, r, row, col_count = 0;
+    MSIVIEW *sv;
+
+    TRACE("%p %p\n", iv, record );
+
+    sv = iv->sv;
+    if( !sv )
+        return ERROR_FUNCTION_FAILED;
+
+    r = sv->ops->execute( sv, 0 );
+    TRACE("tv execute returned %x\n", r);
+    if( r )
+        return r;
+
+    r = sv->ops->get_dimensions( sv, NULL, &col_count );
+    if( r )
+        goto err;
+
+    n = MSI_RecordGetFieldCount( record );
+    if( n != col_count )
+    {
+        ERR("Number of fields do not match\n");
+        goto err;
+    }
+
+    row = -1;
+    r = sv->ops->insert_row( sv, &row );
+    TRACE("insert_row returned %x\n", r);
+    if( r )
+        goto err;
+
+    for( n = 1; n <= col_count; n++ )
+    {
+        r = sv->ops->get_column_info( sv, n, NULL, &type );
+        if( r )
+            break;
+
+        if( type & MSITYPE_STRING )
+        {
+            const WCHAR *str = MSI_RecordGetString( record, n );
+            val = msi_addstringW( iv->db->strings, 0, str, -1, 1 );
+        }
+        else
+        {
+            val = MSI_RecordGetInteger( record, n );
+            val |= 0x8000;
+        }
+        r = sv->ops->set_int( sv, row, n, val );
+        if( r )
+            break;
+    }
+
+err:
+    return ERROR_SUCCESS;
+}
+
+
+static UINT INSERT_close( struct tagMSIVIEW *view )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+    MSIVIEW *sv;
+
+    TRACE("%p\n", iv);
+
+    sv = iv->sv;
+    if( !sv )
+        return ERROR_FUNCTION_FAILED;
+
+    return sv->ops->close( sv );
+}
+
+static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+    MSIVIEW *sv;
+
+    TRACE("%p %p %p\n", iv, rows, cols );
+
+    sv = iv->sv;
+    if( !sv )
+        return ERROR_FUNCTION_FAILED;
+
+    return sv->ops->get_dimensions( sv, rows, cols );
+}
+
+static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+    MSIVIEW *sv;
+
+    TRACE("%p %d %p %p\n", iv, n, name, type );
+
+    sv = iv->sv;
+    if( !sv )
+        return ERROR_FUNCTION_FAILED;
+
+    return sv->ops->get_column_info( sv, n, name, type );
+}
+
+static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+
+    TRACE("%p %d %ld\n", iv, eModifyMode, hrec );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT INSERT_delete( struct tagMSIVIEW *view )
+{
+    MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+    MSIVIEW *sv;
+
+    TRACE("%p\n", iv );
+
+    sv = iv->sv;
+    if( sv )
+        sv->ops->delete( sv );
+    delete_value_list( iv->vals );
+    msiobj_release( &iv->db->hdr );
+    HeapFree( GetProcessHeap(), 0, iv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS insert_ops =
+{
+    INSERT_fetch_int,
+    NULL,
+    NULL,
+    NULL,
+    INSERT_execute,
+    INSERT_close,
+    INSERT_get_dimensions,
+    INSERT_get_column_info,
+    INSERT_modify,
+    INSERT_delete
+};
+
+UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+                        string_list *columns, value_list *values, BOOL temp )
+{
+    MSIINSERTVIEW *iv = NULL;
+    UINT r;
+    MSIVIEW *tv = NULL, *sv = NULL;
+
+    TRACE("%p\n", iv );
+
+    r = TABLE_CreateView( db, table, &tv );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    r = SELECT_CreateView( db, &sv, tv, columns );
+    if( r != ERROR_SUCCESS )
+    {
+        if( tv )
+            tv->ops->delete( tv );
+        return r;
+    }
+    
+    iv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *iv );
+    if( !iv )
+        return ERROR_FUNCTION_FAILED;
+
+    /* fill the structure */
+    iv->view.ops = &insert_ops;
+    msiobj_addref( &db->hdr );
+    iv->db = db;
+    iv->vals = values;
+    iv->bIsTemp = temp;
+    iv->sv = sv;
+    *view = (MSIVIEW*) iv;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
msi.c added at 1.3.2.1
diff -N msi.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msi.c	13 Dec 2004 16:18:26 -0000	1.3.2.1
@@ -0,0 +1,1587 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002,2003,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
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "wincrypt.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+#include "winver.h"
+
+#include "initguid.h"
+
+UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf);
+
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
+ *  which is a problem because LPCTSTR isn't defined when compiling wine.
+ * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
+ *  and make sure to only use it in W functions.
+ */
+#define LPCTSTR LPCWSTR
+
+DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+static const WCHAR szInstaller[] = {
+'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',0 };
+
+static const WCHAR szFeatures[] = {
+'F','e','a','t','u','r','e','s',0 };
+static const WCHAR szComponents[] = {
+'C','o','m','p','o','n','e','n','t','s',0 };
+
+/* the UI level */
+INSTALLUILEVEL gUILevel;
+HWND           gUIhwnd;
+INSTALLUI_HANDLERA gUIHandler;
+DWORD gUIFilter;
+LPVOID gUIContext;
+WCHAR gszLogFile[MAX_PATH];
+
+/*
+ *  .MSI  file format
+ *
+ *  A .msi file is a structured storage file.
+ *  It should contain a number of streams.
+ */
+
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
+{
+    DWORD i,n=0;
+
+    out[n++]='{';
+    for(i=0; i<8; i++)
+        out[n++] = in[7-i];
+    out[n++]='-';
+    for(i=0; i<4; i++)
+        out[n++] = in[11-i];
+    out[n++]='-';
+    for(i=0; i<4; i++)
+        out[n++] = in[15-i];
+    out[n++]='-';
+    for(i=0; i<2; i++)
+    {
+        out[n++] = in[17+i*2];
+        out[n++] = in[16+i*2];
+    }
+    out[n++]='-';
+    for( ; i<8; i++)
+    {
+        out[n++] = in[17+i*2];
+        out[n++] = in[16+i*2];
+    }
+    out[n++]='}';
+    out[n]=0;
+    return TRUE;
+}
+
+BOOL squash_guid(LPCWSTR in, LPWSTR out)
+{
+    DWORD i,n=0;
+
+    if(in[n++] != '{')
+        return FALSE;
+    for(i=0; i<8; i++)
+        out[7-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<4; i++)
+        out[11-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<4; i++)
+        out[15-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<2; i++)
+    {
+        out[17+i*2] = in[n++];
+        out[16+i*2] = in[n++];
+    }
+    if(in[n++] != '-')
+        return FALSE;
+    for( ; i<8; i++)
+    {
+        out[17+i*2] = in[n++];
+        out[16+i*2] = in[n++];
+    }
+    out[32]=0;
+    if(in[n++] != '}')
+        return FALSE;
+    if(in[n])
+        return FALSE;
+    return TRUE;
+}
+
+/* tables for encoding and decoding base85 */
+static const unsigned char table_dec85[0x80] = {
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
+0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
+0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
+0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
+0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
+};
+
+static const char table_enc85[] =
+"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
+"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
+"yz{}~";
+
+/*
+ *  Converts a base85 encoded guid into a GUID pointer
+ *  Base85 encoded GUIDs should be 20 characters long.
+ *
+ *  returns TRUE if successful, FALSE if not
+ */
+BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
+{
+    DWORD i, val = 0, base = 1, *p;
+
+    p = (DWORD*) guid;
+    for( i=0; i<20; i++ )
+    {
+        if( (i%5) == 0 )
+        {
+            val = 0;
+            base = 1;
+        }
+        val += table_dec85[str[i]] * base;
+        if( str[i] >= 0x80 )
+            return FALSE;
+        if( table_dec85[str[i]] == 0xff )
+            return FALSE;
+        if( (i%5) == 4 )
+            p[i/5] = val;
+        base *= 85;
+    }
+    return TRUE;
+}
+
+/*
+ *  Encodes a base85 guid given a GUID pointer
+ *  Caller should provide a 21 character buffer for the encoded string.
+ *
+ *  returns TRUE if successful, FALSE if not
+ */
+BOOL encode_base85_guid( GUID *guid, LPWSTR str )
+{
+    unsigned int x, *p, i;
+
+    p = (unsigned int*) guid;
+    for( i=0; i<4; i++ )
+    {
+        x = p[i];
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+    }
+    *str = 0;
+    
+    return TRUE;
+}
+
+
+VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
+{
+    MSIDATABASE *db = (MSIDATABASE *) arg;
+
+    free_cached_tables( db );
+    IStorage_Release( db->storage );
+}
+
+UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
+{
+    IStorage *stg = NULL;
+    HRESULT r;
+    MSIDATABASE *db = NULL;
+    UINT ret = ERROR_FUNCTION_FAILED;
+    LPWSTR szMode;
+    STATSTG stat;
+
+    TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
+
+    if( !pdb )
+        return ERROR_INVALID_PARAMETER;
+
+    szMode = (LPWSTR) szPersist;
+    if( HIWORD( szPersist ) )
+    {
+        /* UINT len = lstrlenW( szPerist ) + 1; */
+        FIXME("don't support persist files yet\b");
+        return ERROR_INVALID_PARAMETER;
+        /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
+    }
+    else if( szPersist == MSIDBOPEN_READONLY )
+    {
+        r = StgOpenStorage( szDBPath, NULL,
+              STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
+    }
+    else if( szPersist == MSIDBOPEN_CREATE )
+    {
+        r = StgCreateDocfile( szDBPath, 
+              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
+        if( r == ERROR_SUCCESS )
+        {
+            IStorage_SetClass( stg, &CLSID_MsiDatabase );
+            r = init_string_table( stg );
+        }
+    }
+    else if( szPersist == MSIDBOPEN_TRANSACT )
+    {
+        r = StgOpenStorage( szDBPath, NULL,
+              STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
+    }
+    else
+    {
+        ERR("unknown flag %p\n",szPersist);
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    if( FAILED( r ) )
+    {
+        FIXME("open failed r = %08lx!\n",r);
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
+    if( FAILED( r ) )
+    {
+        FIXME("Failed to stat storage\n");
+        goto end;
+    }
+
+    if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
+    {
+        ERR("storage GUID is not a MSI database GUID %s\n",
+             debugstr_guid(&stat.clsid) );
+        goto end;
+    }
+
+
+    db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
+                              MSI_CloseDatabase );
+    if( !db )
+    {
+        FIXME("Failed to allocate a handle\n");
+        goto end;
+    }
+
+    if( TRACE_ON( msi ) )
+        enum_stream_names( stg );
+
+    db->storage = stg;
+    db->mode = szMode;
+
+    ret = load_string_table( db );
+    if( ret != ERROR_SUCCESS )
+        goto end;
+
+    msiobj_addref( &db->hdr );
+    IStorage_AddRef( stg );
+    *pdb = db;
+
+end:
+    if( db )
+        msiobj_release( &db->hdr );
+    if( stg )
+        IStorage_Release( stg );
+
+    return ret;
+}
+
+UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
+{
+    MSIDATABASE *db;
+    UINT ret;
+
+    TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
+
+    ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
+    if( ret == ERROR_SUCCESS )
+    {
+        *phDB = alloc_msihandle( &db->hdr );
+        msiobj_release( &db->hdr );
+    }
+
+    return ret;
+}
+
+UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
+{
+    HRESULT r = ERROR_FUNCTION_FAILED;
+    LPWSTR szwDBPath = NULL, szwPersist = NULL;
+    UINT len;
+
+    TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
+
+    if( szDBPath )
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
+        szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwDBPath )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
+    }
+
+    if( HIWORD(szPersist) )
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
+        szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwPersist )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
+    }
+    else
+        szwPersist = (LPWSTR) szPersist;
+
+    r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
+
+end:
+    if( szwPersist )
+        HeapFree( GetProcessHeap(), 0, szwPersist );
+    if( szwDBPath )
+        HeapFree( GetProcessHeap(), 0, szwDBPath );
+
+    return r;
+}
+
+UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
+{
+    UINT len, ret;
+    LPWSTR szwProd = NULL;
+
+    TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
+
+    if( szProduct )
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+        szwProd = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        if( szwProd )
+            MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProd, len );
+    }
+
+    ret = MsiOpenProductW( szwProd, phProduct );
+
+    if( szwProd )
+        HeapFree( GetProcessHeap(), 0, szwProd );
+
+    return ret;
+}
+
+UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
+{
+    static const WCHAR szKey[] = {
+        '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','\\',
+        'U','n','i','n','s','t','a','l','l',0 };
+    static const WCHAR szLocalPackage[] = {
+        'L','o','c','a','l','P','a','c','k','a','g','e', 0
+    };
+    LPWSTR path = NULL;
+    UINT r;
+    HKEY hKeyProduct = NULL, hKeyUninstall = NULL;
+    DWORD count, type;
+
+    TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
+
+    r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
+    if( r != ERROR_SUCCESS )
+        return ERROR_UNKNOWN_PRODUCT;
+
+    r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
+    if( r != ERROR_SUCCESS )
+    {
+        r = ERROR_UNKNOWN_PRODUCT;
+        goto end;
+    }
+
+    /* find the size of the path */
+    type = count = 0;
+    r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+                          NULL, &type, NULL, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        r = ERROR_UNKNOWN_PRODUCT;
+        goto end;
+    }
+
+    /* now alloc and fetch the path of the database to open */
+    path = HeapAlloc( GetProcessHeap(), 0, count );
+    if( !path )
+        goto end;
+
+    r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+                          NULL, &type, (LPBYTE) path, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        r = ERROR_UNKNOWN_PRODUCT;
+        goto end;
+    }
+
+    r = MsiOpenPackageW( path, phProduct );
+
+end:
+    if( path )
+        HeapFree( GetProcessHeap(), 0, path );
+    if( hKeyProduct )
+        RegCloseKey( hKeyProduct );
+    RegCloseKey( hKeyUninstall );
+
+    return r;
+}
+
+UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage)
+{
+    FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
+{
+    FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
+{
+    FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
+	debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage, dwPlatform, dwOptions);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
+{
+    FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
+	debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage, dwPlatform, dwOptions);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
+{
+    LPWSTR szwPath = NULL, szwCommand = NULL;
+    UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
+
+    TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
+
+    if( szPackagePath )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, NULL, 0 );
+        szwPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwPath )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, szwPath, len );
+    }
+
+    if( szCommandLine )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
+        szwCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwCommand )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommand, len );
+    }
+ 
+    r = MsiInstallProductW( szwPath, szwCommand );
+
+end:
+    if( szwPath )
+        HeapFree( GetProcessHeap(), 0, szwPath );
+    
+    if( szwCommand )
+        HeapFree( GetProcessHeap(), 0, szwCommand );
+
+    return r;
+}
+
+UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
+{
+    MSIPACKAGE *package = NULL;
+    UINT rc = ERROR_SUCCESS; 
+    MSIHANDLE handle;
+
+    FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
+
+    rc = MsiVerifyPackageW(szPackagePath);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_OpenPackageW(szPackagePath,&package);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    handle = alloc_msihandle( &package->hdr );
+
+    rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
+
+    MsiCloseHandle(handle);
+    msiobj_release( &package->hdr );
+    return rc;
+}
+
+UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
+{
+	FIXME("%s 0x%08lx\n", debugstr_a(szProduct), dwReinstallMode);
+	return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
+{
+	FIXME("%s 0x%08lx\n", debugstr_w(szProduct), dwReinstallMode);
+	return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage, INSTALLTYPE eInstallType, LPCSTR szCommandLine)
+{
+	FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage), eInstallType, debugstr_a(szCommandLine));
+	return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+{
+	FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage), eInstallType, debugstr_w(szCommandLine));
+	return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
+{
+    LPWSTR szwProduct = NULL;
+    UINT hr = ERROR_SUCCESS;
+
+    FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
+
+    if( szProduct )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwProduct )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+    }
+
+    hr = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
+
+end:
+    if( szwProduct )
+        HeapFree( GetProcessHeap(), 0, szwProduct );
+
+    return hr;
+}
+
+UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
+{
+    FIXME("%s %d %d\n",debugstr_w(szProduct), iInstallLevel, eInstallState);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
+{
+    LPWSTR szwComponent = NULL, szwBuffer = NULL;
+    UINT hr = ERROR_INSTALL_FAILURE;
+
+    FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
+
+    if( szComponent )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
+        szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwComponent )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
+    } else {
+      return ERROR_INVALID_PARAMETER;
+    }
+
+    {
+        szwBuffer = HeapAlloc( GetProcessHeap(), 0, GUID_SIZE * sizeof(WCHAR) );
+        if( !szwBuffer )	 
+            goto end;
+    }
+
+    hr = MsiGetProductCodeW( szwComponent, szwBuffer );
+
+    if( ERROR_SUCCESS == hr )
+    {
+        WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
+    }
+
+end:
+    if( szwComponent )
+        HeapFree( GetProcessHeap(), 0, szwComponent );
+    if( szwBuffer )
+        HeapFree( GetProcessHeap(), 0, szwBuffer );
+
+    return hr;
+}
+
+UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
+{
+    FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
+    if (NULL == szComponent) {
+      return ERROR_INVALID_PARAMETER;
+    }
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+
+
+UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
+{
+    LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
+    UINT hr = ERROR_INSTALL_FAILURE;
+
+    FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute), szBuffer, pcchValueBuf);
+
+    if (NULL != szBuffer && NULL == pcchValueBuf) {
+      return ERROR_INVALID_PARAMETER;
+    }
+    if( szProduct )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwProduct )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+    } else {
+      return ERROR_INVALID_PARAMETER;
+    }
+    
+    if( szAttribute )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, NULL, 0 );
+        szwAttribute = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwAttribute )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, szwAttribute, len );
+    } else {
+      return ERROR_INVALID_PARAMETER;
+    }
+
+    if( szBuffer )
+    {
+        szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
+        if( !szwBuffer )	 
+            goto end;
+    }
+
+    hr = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
+
+    if( ERROR_SUCCESS == hr )
+    {
+        WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
+    }
+
+end:
+    if( szwProduct )
+        HeapFree( GetProcessHeap(), 0, szwProduct );
+    if( szwAttribute )
+        HeapFree( GetProcessHeap(), 0, szwAttribute );
+    if( szwBuffer )
+        HeapFree( GetProcessHeap(), 0, szwBuffer );
+
+    return hr;    
+}
+
+UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szBuffer, DWORD *pcchValueBuf)
+{
+    MSIHANDLE hProduct;
+    UINT hr;
+    
+    FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf);
+
+    if (NULL != szBuffer && NULL == pcchValueBuf) {
+      return ERROR_INVALID_PARAMETER;
+    }
+    if (NULL == szProduct || NULL == szAttribute) {
+      return ERROR_INVALID_PARAMETER;
+    }
+
+    hr = MsiOpenProductW(szProduct, &hProduct);
+    if (ERROR_SUCCESS != hr) return hr;
+
+    hr = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
+    MsiCloseHandle(hProduct);
+    return hr;
+}
+
+UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
+{
+    FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
+{
+    FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
+{
+    LPWSTR szwLogFile = NULL;
+    UINT hr = ERROR_INSTALL_FAILURE;
+
+    FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
+
+    if( szLogFile )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, NULL, 0 );
+        szwLogFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwLogFile )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, szwLogFile, len );
+    } else {
+      return ERROR_INVALID_PARAMETER;
+    }
+
+    hr = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
+
+end:
+    if( szwLogFile )
+        HeapFree( GetProcessHeap(), 0, szwLogFile );
+
+    return hr;
+}
+
+UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
+{
+    HANDLE the_file = INVALID_HANDLE_VALUE;
+    TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
+    strcpyW(gszLogFile,szLogFile);
+    if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
+        DeleteFileW(szLogFile);
+    the_file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
+                           FILE_ATTRIBUTE_NORMAL, NULL);
+    if (the_file != INVALID_HANDLE_VALUE)
+        CloseHandle(the_file);
+    else
+        ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
+
+    return ERROR_SUCCESS;
+}
+
+INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
+{
+    FIXME("%s\n", debugstr_a(szProduct));
+    return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
+{
+    FIXME("%s\n", debugstr_w(szProduct));
+    return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
+{
+    INSTALLUILEVEL old = gUILevel;
+    HWND oldwnd = gUIhwnd;
+    TRACE("%08x %p\n", dwUILevel, phWnd);
+
+    gUILevel = dwUILevel;
+    if (phWnd)
+    {
+        gUIhwnd = *phWnd;
+        *phWnd = oldwnd;
+    }
+    return old;
+}
+
+INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, 
+                                  DWORD dwMessageFilter, LPVOID pvContext)
+{
+    INSTALLUI_HANDLERA prev = gUIHandler;
+
+    TRACE("(%p %lx %p)\n",puiHandler,dwMessageFilter,pvContext);
+    gUIHandler = puiHandler;
+    gUIFilter = dwMessageFilter;
+    gUIContext = pvContext;
+
+    return prev;
+}
+
+UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
+{
+    /*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
+    FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiLoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax, DWORD e)
+{
+    FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
+    /*
+    int ret =  LoadStringW(hInstance,uID,lpBuffer,nBufferMax);
+    FIXME("%s\n",debugstr_w(lpBuffer));
+    return ret;
+    */
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
+{
+    FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
+    return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
+{
+    FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
+    return INSTALLSTATE_UNKNOWN;
+}
+
+#include "winuser.h"
+
+UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, WORD wLanguageId, DWORD f)
+{
+    FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),uType,wLanguageId,f);
+    /*
+    MessageBoxExA(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
+    */
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD f)
+{
+    /*FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);*/
+    FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),uType,wLanguageId,f);
+    /*
+    MessageBoxExW(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
+    */
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+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 hkey = 0, hkeyFeatures = 0;
+    DWORD r;
+    WCHAR szKeyName[33];
+
+    TRACE("%ld %p\n",index,lpguid);
+
+    if (NULL == lpguid) {
+      return ERROR_INVALID_PARAMETER;
+    }
+    r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
+
+    unsquash_guid(szKeyName, lpguid);
+
+end:
+
+    if( hkeyFeatures )
+        RegCloseKey(hkeyFeatures);
+    if( hkey )
+        RegCloseKey(hkey);
+
+    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);
+    }
+
+    if( szwProduct )
+        HeapFree( GetProcessHeap(), 0, szwProduct);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index, 
+      LPWSTR szFeature, LPWSTR szParent)
+{
+    HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
+    DWORD r, sz;
+    WCHAR szRegName[GUID_SIZE];
+
+    TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
+
+    if( !squash_guid(szProduct, szRegName) )
+        return ERROR_INVALID_PARAMETER;
[truncated at 1000 lines; 591 more skipped]

reactos/lib/msi
msi.spec added at 1.1.2.1
diff -N msi.spec
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msi.spec	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,236 @@
+1 stdcall -private DllCanUnloadNow() MSI_DllCanUnloadNow
+2 stdcall -private DllGetClassObject(ptr ptr ptr) MSI_DllGetClassObject
+3 stdcall -private DllRegisterServer() MSI_DllRegisterServer
+4 stdcall -private DllUnregisterServer() MSI_DllUnregisterServer
+5 stdcall MsiAdvertiseProductA(str str str long)
+6 stdcall MsiAdvertiseProductW(wstr wstr wstr long)
+7 stdcall MsiCloseAllHandles()
+8 stdcall MsiCloseHandle(long)
+9 stub MsiCollectUserInfoA
+10 stub MsiCollectUserInfoW
+11 stub MsiConfigureFeatureA
+12 stub MsiConfigureFeatureFromDescriptorA
+13 stub MsiConfigureFeatureFromDescriptorW
+14 stub MsiConfigureFeatureW
+15 stdcall MsiConfigureProductA(str long long)
+16 stdcall MsiConfigureProductW(wstr long long)
+17 stdcall MsiCreateRecord(long)
+18 stdcall MsiDatabaseApplyTransformA(long str long)
+19 stdcall MsiDatabaseApplyTransformW(long wstr long)
+20 stdcall MsiDatabaseCommit(long)
+21 stub MsiDatabaseExportA
+22 stub MsiDatabaseExportW
+23 stdcall MsiDatabaseGenerateTransformA(long long str long long)
+24 stdcall MsiDatabaseGenerateTransformW(long long wstr long long)
+25 stdcall MsiDatabaseGetPrimaryKeysA(long str ptr)
+26 stdcall MsiDatabaseGetPrimaryKeysW(long wstr ptr)
+27 stdcall MsiDatabaseImportA(str str)
+28 stdcall MsiDatabaseImportW(wstr wstr)
+29 stub MsiDatabaseMergeA
+30 stub MsiDatabaseMergeW
+31 stdcall MsiDatabaseOpenViewA(long str ptr)
+32 stdcall MsiDatabaseOpenViewW(long wstr ptr)
+33 stdcall MsiDoActionA(long str)
+34 stdcall MsiDoActionW(long wstr)
+35 stub MsiEnableUIPreview
+36 stdcall MsiEnumClientsA(str long ptr)
+37 stdcall MsiEnumClientsW(wstr long ptr)
+38 stdcall MsiEnumComponentQualifiersA(str long str ptr str ptr)
+39 stdcall MsiEnumComponentQualifiersW(wstr long wstr ptr wstr ptr)
+40 stdcall MsiEnumComponentsA(long ptr)
+41 stdcall MsiEnumComponentsW(long ptr)
+42 stdcall MsiEnumFeaturesA(str long ptr ptr)
+43 stdcall MsiEnumFeaturesW(wstr long ptr ptr)
+44 stdcall MsiEnumProductsA(long ptr)
+45 stdcall MsiEnumProductsW(long ptr)
+46 stdcall MsiEvaluateConditionA(long str)
+47 stdcall MsiEvaluateConditionW(long wstr)
+48 stub MsiGetLastErrorRecord
+49 stdcall MsiGetActiveDatabase(long)
+50 stdcall MsiGetComponentStateA(long str ptr ptr)
+51 stdcall MsiGetComponentStateW(long wstr ptr ptr)
+52 stub MsiGetDatabaseState
+53 stub MsiGetFeatureCostA
+54 stub MsiGetFeatureCostW
+55 stub MsiGetFeatureInfoA
+56 stub MsiGetFeatureInfoW
+57 stdcall MsiGetFeatureStateA(long str ptr ptr)
+58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
+59 stub MsiGetFeatureUsageA
+60 stub MsiGetFeatureUsageW
+61 stub MsiGetFeatureValidStatesA
+62 stub MsiGetFeatureValidStatesW
+63 stub MsiGetLanguage
+64 stdcall MsiGetMode(long long)
+65 stdcall MsiGetProductCodeA(str str)
+66 stdcall MsiGetProductCodeW(wstr wstr)
+67 stdcall MsiGetProductInfoA(str str str long)
+68 stub MsiGetProductInfoFromScriptA
+69 stub MsiGetProductInfoFromScriptW
+70 stdcall MsiGetProductInfoW(wstr wstr wstr long)
+71 stdcall MsiGetProductPropertyA(long str ptr ptr)
+72 stdcall MsiGetProductPropertyW(long wstr ptr ptr)
+73 stdcall MsiGetPropertyA(ptr str str ptr)
+74 stdcall MsiGetPropertyW(ptr wstr wstr ptr)
+75 stdcall MsiGetSourcePathA(long str ptr ptr)
+76 stdcall MsiGetSourcePathW(long wstr ptr ptr)
+77 stdcall MsiGetSummaryInformationA(long str long ptr)
+78 stdcall MsiGetSummaryInformationW(long wstr long ptr)
+79 stdcall MsiGetTargetPathA(long str ptr ptr)
+80 stdcall MsiGetTargetPathW(long wstr ptr ptr)
+81 stub MsiGetUserInfoA
+82 stub MsiGetUserInfoW
+83 stub MsiInstallMissingComponentA
+84 stub MsiInstallMissingComponentW
+85 stub MsiInstallMissingFileA
+86 stub MsiInstallMissingFileW
+87 stdcall MsiInstallProductA(str str)
+88 stdcall MsiInstallProductW(wstr wstr)
+89 stdcall MsiLocateComponentA(str ptr long)
+90 stdcall MsiLocateComponentW(wstr ptr long)
+91 stdcall MsiOpenDatabaseA(str str ptr)
+92 stdcall MsiOpenDatabaseW(wstr wstr ptr)
+93 stdcall MsiOpenPackageA(str ptr)
+94 stdcall MsiOpenPackageW(wstr ptr)
+95 stdcall MsiOpenProductA(str ptr)
+96 stdcall MsiOpenProductW(wstr ptr)
+97 stub MsiPreviewBillboardA
+98 stub MsiPreviewBillboardW
+99 stub MsiPreviewDialogA
+100 stub MsiPreviewDialogW
+101 stub MsiProcessAdvertiseScriptA
+102 stub MsiProcessAdvertiseScriptW
+103 stdcall MsiProcessMessage(long long long)
+104 stub MsiProvideComponentA
+105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
+106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
+107 stub MsiProvideComponentW
+108 stub MsiProvideQualifiedComponentA
+109 stub MsiProvideQualifiedComponentW
+110 stdcall MsiQueryFeatureStateA(str str)
+111 stdcall MsiQueryFeatureStateW(wstr wstr)
+112 stdcall MsiQueryProductStateA(str)
+113 stdcall MsiQueryProductStateW(wstr)
+114 stdcall MsiRecordDataSize(long long)
+115 stdcall MsiRecordGetFieldCount(long)
+116 stdcall MsiRecordGetInteger(long long)
+117 stdcall MsiRecordGetStringA(long long ptr ptr)
+118 stdcall MsiRecordGetStringW(long long ptr ptr)
+119 stdcall MsiRecordIsNull(long long)
+120 stdcall MsiRecordReadStream(long long ptr ptr)
+121 stdcall MsiRecordSetInteger(long long long)
+122 stdcall MsiRecordSetStreamA(long long str)
+123 stdcall MsiRecordSetStreamW(long long wstr)
+124 stdcall MsiRecordSetStringA(long long str)
+125 stdcall MsiRecordSetStringW(long long wstr)
+126 stub MsiReinstallFeatureA
+127 stub MsiReinstallFeatureFromDescriptorA
+128 stub MsiReinstallFeatureFromDescriptorW
+129 stub MsiReinstallFeatureW
+130 stdcall MsiReinstallProductA(str long)
+131 stdcall MsiReinstallProductW(wstr long)
+132 stub MsiSequenceA
+133 stub MsiSequenceW
+134 stub MsiSetComponentStateA
+135 stub MsiSetComponentStateW
+136 stdcall MsiSetExternalUIA(ptr long ptr)
+137 stub MsiSetExternalUIW
+138 stdcall MsiSetFeatureStateA(long str long)
+139 stdcall MsiSetFeatureStateW(long wstr long)
+140 stub MsiSetInstallLevel
+141 stdcall MsiSetInternalUI(long ptr)
+142 stub MsiVerifyDiskSpace
+143 stub MsiSetMode
+144 stdcall MsiSetPropertyA(long str str)
+145 stdcall MsiSetPropertyW(long wstr wstr)
+146 stdcall MsiSetTargetPathA(long str str)
+147 stdcall MsiSetTargetPathW(long wstr wstr)
+148 stdcall MsiSummaryInfoGetPropertyA(long long ptr ptr ptr ptr ptr)
+149 stdcall MsiSummaryInfoGetPropertyCount(long ptr)
+150 stdcall MsiSummaryInfoGetPropertyW(long long ptr ptr ptr ptr ptr)
+151 stub MsiSummaryInfoPersist
+152 stub MsiSummaryInfoSetPropertyA
+153 stub MsiSummaryInfoSetPropertyW
+154 stub MsiUseFeatureA
+155 stub MsiUseFeatureW
+156 stdcall MsiVerifyPackageA(str)
+157 stdcall MsiVerifyPackageW(wstr)
+158 stdcall MsiViewClose(long)
+159 stdcall MsiViewExecute(long long)
+160 stdcall MsiViewFetch(long ptr)
+161 stub MsiViewGetErrorA
+162 stub MsiViewGetErrorW
+163 stdcall MsiViewModify(long long long)
+164 stdcall MsiDatabaseIsTablePersistentA(long str)
+165 stdcall MsiDatabaseIsTablePersistentW(long wstr)
+166 stdcall MsiViewGetColumnInfo(long long ptr)
+167 stdcall MsiRecordClearData(long)
+168 stdcall MsiEnableLogA(long str long)
+169 stdcall MsiEnableLogW(long wstr long)
+170 stdcall MsiFormatRecordA(long long ptr ptr)
+171 stdcall MsiFormatRecordW(long long ptr ptr)
+172 stdcall MsiGetComponentPathA(str str ptr ptr)
+173 stdcall MsiGetComponentPathW(wstr wstr ptr ptr)
+174 stdcall MsiApplyPatchA(str str long str)
+175 stdcall MsiApplyPatchW(wstr wstr long wstr)
+176 stub MsiAdvertiseScriptA
+177 stub MsiAdvertiseScriptW
+178 stub MsiGetPatchInfoA
+179 stub MsiGetPatchInfoW
+180 stub MsiEnumPatchesA
+181 stub MsiEnumPatchesW
+182 stdcall DllGetVersion(ptr) MSI_DllGetVersion
+183 stub MsiGetProductCodeFromPackageCodeA
+184 stub MsiGetProductCodeFromPackageCodeW
+185 stub MsiCreateTransformSummaryInfoA
+186 stub MsiCreateTransformSummaryInfoW
+187 stub MsiQueryFeatureStateFromDescriptorA
+188 stub MsiQueryFeatureStateFromDescriptorW
+189 stub MsiConfigureProductExA
+190 stub MsiConfigureProductExW
+191 stub MsiInvalidateFeatureCache
+192 stub MsiUseFeatureExA
+193 stub MsiUseFeatureExW
+194 stdcall MsiGetFileVersionA(str str ptr str ptr)
+195 stdcall MsiGetFileVersionW(wstr wstr ptr wstr ptr)
+196 stdcall MsiLoadStringA(long long long long long)
+197 stdcall MsiLoadStringW(long long long long long)
+198 stdcall MsiMessageBoxA(long long long long long long)
+199 stdcall MsiMessageBoxW(long long long long long long)
+200 stub MsiDecomposeDescriptorA
+201 stub MsiDecomposeDescriptorW
+202 stub MsiProvideQualifiedComponentExA
+203 stub MsiProvideQualifiedComponentExW
+204 stdcall MsiEnumRelatedProductsA(str long long str)
+205 stub MsiEnumRelatedProductsW
+206 stub MsiSetFeatureAttributesA
+207 stub MsiSetFeatureAttributesW
+208 stub MsiSourceListClearAllA
+209 stub MsiSourceListClearAllW
+210 stub MsiSourceListAddSourceA
+211 stub MsiSourceListAddSourceW
+212 stub MsiSourceListForceResolutionA
+213 stub MsiSourceListForceResolutionW
+214 stub MsiIsProductElevatedA
+215 stub MsiIsProductElevatedW
+216 stub MsiGetShortcutTargetA
+217 stub MsiGetShortcutTargetW
+218 stub MsiGetFileHashA
+219 stub MsiGetFileHashW
+220 stub MsiEnumComponentCostsA
+221 stub MsiEnumComponentCostsW
+222 stub MsiCreateAndVerifyInstallerDirectory
+223 stdcall MsiGetFileSignatureInformationA(str long ptr ptr ptr)
+224 stdcall MsiGetFileSignatureInformationW(wstr long ptr ptr ptr)
+225 stdcall MsiProvideAssemblyA(str str long long str ptr)
+226 stdcall MsiProvideAssemblyW(wstr wstr long long wstr ptr)
+227 stdcall MsiAdvertiseProductExA(str str str long long long)
+228 stdcall MsiAdvertiseProductExW(wstr wstr wstr long long long)
+229 stub MsiNotifySidChangeA
+230 stub MsiNotifySidChangeW
+231 stdcall MsiOpenPackageExA(str long ptr)
+232 stdcall MsiOpenPackageExW(wstr long ptr)
+233 stub MsiDeleteUserDataA
+234 stub MsiDeleteUserDataW
+235 stub Migrate10CachedPackagesA
+236 stub Migrate10CachedPackagesW

reactos/lib/msi
msipriv.h added at 1.1.2.1
diff -N msipriv.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msipriv.h	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,325 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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
+ */
+
+#ifndef __WINE_MSI_PRIVATE__
+#define __WINE_MSI_PRIVATE__
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+
+#define MSI_DATASIZEMASK 0x00ff
+#define MSITYPE_VALID    0x0100
+#define MSITYPE_STRING   0x0800
+#define MSITYPE_NULLABLE 0x1000
+#define MSITYPE_KEY      0x2000
+
+#define MSITYPE_BINARY 0x8900
+
+struct tagMSITABLE;
+typedef struct tagMSITABLE MSITABLE;
+
+struct string_table;
+typedef struct string_table string_table;
+
+struct tagMSIOBJECTHDR;
+typedef struct tagMSIOBJECTHDR MSIOBJECTHDR;
+
+typedef VOID (*msihandledestructor)( MSIOBJECTHDR * );
+
+struct tagMSIOBJECTHDR
+{
+    UINT magic;
+    UINT type;
+    UINT refcount;
+    msihandledestructor destructor;
+    struct tagMSIOBJECTHDR *next;
+    struct tagMSIOBJECTHDR *prev;
+};
+
+typedef struct tagMSIDATABASE
+{
+    MSIOBJECTHDR hdr;
+    IStorage *storage;
+    string_table *strings;
+    LPWSTR mode;
+    MSITABLE *first_table, *last_table;
+} MSIDATABASE;
+
+typedef struct tagMSIVIEW MSIVIEW;
+
+typedef struct tagMSIQUERY
+{
+    MSIOBJECTHDR hdr;
+    MSIVIEW *view;
+    UINT row;
+    MSIDATABASE *db;
+} MSIQUERY;
+
+/* maybe we can use a Variant instead of doing it ourselves? */
+typedef struct tagMSIFIELD
+{
+    UINT type;
+    union
+    {
+        INT iVal;
+        LPWSTR szwVal;
+        IStream *stream;
+    } u;
+} MSIFIELD;
+
+typedef struct tagMSIRECORD
+{
+    MSIOBJECTHDR hdr;
+    UINT count;       /* as passed to MsiCreateRecord */
+    MSIFIELD fields[1]; /* nb. array size is count+1 */
+} MSIRECORD;
+
+typedef struct tagMSIVIEWOPS
+{
+    /*
+     * fetch_int - reads one integer from {row,col} in the table
+     *
+     *  This function should be called after the execute method.
+     *  Data returned by the function should not change until 
+     *   close or delete is called.
+     *  To get a string value, query the database's string table with
+     *   the integer value returned from this function.
+     */
+    UINT (*fetch_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT *val );
+
+    /*
+     * fetch_int - reads one integer from {row,col} in the table
+     *
+     *  This function is similar to fetch_int, except fetches a
+     *    stream instead of an integer.
+     */
+    UINT (*fetch_stream)( struct tagMSIVIEW *, UINT row, UINT col, IStream **stm );
+
+    /*
+     * get_int - sets one integer at {row,col} in the table
+     *
+     *  Similar semantics to fetch_int
+     */
+    UINT (*set_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT val );
+
+    /*
+     * Inserts a new, blank row into the database
+     *  *row receives the number of the new row
+     */
+    UINT (*insert_row)( struct tagMSIVIEW *, UINT *row );
+
+    /*
+     * execute - loads the underlying data into memory so it can be read
+     */
+    UINT (*execute)( struct tagMSIVIEW *, MSIRECORD * );
+
+    /*
+     * close - clears the data read by execute from memory
+     */
+    UINT (*close)( struct tagMSIVIEW * );
+
+    /*
+     * get_dimensions - returns the number of rows or columns in a table.
+     *
+     *  The number of rows can only be queried after the execute method
+     *   is called. The number of columns can be queried at any time.
+     */
+    UINT (*get_dimensions)( struct tagMSIVIEW *, UINT *rows, UINT *cols );
+
+    /*
+     * get_column_info - returns the name and type of a specific column
+     *
+     *  The name is HeapAlloc'ed by this function and should be freed by
+     *   the caller.
+     *  The column information can be queried at any time.
+     */
+    UINT (*get_column_info)( struct tagMSIVIEW *, UINT n, LPWSTR *name, UINT *type );
+
+    /*
+     * modify - not yet implemented properly
+     */
+    UINT (*modify)( struct tagMSIVIEW *, MSIMODIFY, MSIHANDLE );
+
+    /*
+     * delete - destroys the structure completely
+     */
+    UINT (*delete)( struct tagMSIVIEW * );
+
+} MSIVIEWOPS;
+
+typedef struct tagMSISUMMARYINFO
+{
+    MSIOBJECTHDR hdr;
+    IPropertyStorage *propstg;
+} MSISUMMARYINFO;
+
+struct tagMSIVIEW
+{
+    MSIOBJECTHDR hdr;
+    MSIVIEWOPS   *ops;
+};
+
+typedef struct tagMSIPACKAGE
+{
+    MSIOBJECTHDR hdr;
+    MSIDATABASE *db;
+    struct tagMSIFEATURE *features;
+    UINT loaded_features;
+    struct tagMSIFOLDER  *folders;
+    UINT loaded_folders;
+    struct tagMSICOMPONENT *components;
+    UINT loaded_components;
+    struct tagMSIFILE *files;
+    UINT loaded_files;
+} MSIPACKAGE;
+
+#define MSIHANDLETYPE_ANY 0
+#define MSIHANDLETYPE_DATABASE 1
+#define MSIHANDLETYPE_SUMMARYINFO 2
+#define MSIHANDLETYPE_VIEW 3
+#define MSIHANDLETYPE_RECORD 4
+#define MSIHANDLETYPE_PACKAGE 5
+
+#define MSI_MAJORVERSION 2
+#define MSI_MINORVERSION 0
+#define MSI_BUILDNUMBER 2600
+
+#define GUID_SIZE 39
+
+#define MSIHANDLE_MAGIC 0x4d434923
+#define MSIMAXHANDLES 0x80
+
+#define MSISUMINFO_OFFSET 0x30LL
+
+DEFINE_GUID(CLSID_IMsiServer,   0x000C101C,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX1, 0x000C103E,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX2, 0x000C1090,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+
+/* handle functions */
+extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
+extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
+extern void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy );
+extern void msiobj_addref(MSIOBJECTHDR *);
+extern int msiobj_release(MSIOBJECTHDR *);
+extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
+
+/* add this table to the list of cached tables in the database */
+extern void add_table(MSIDATABASE *db, MSITABLE *table);
+extern void remove_table( MSIDATABASE *db, MSITABLE *table );
+extern void free_table( MSIDATABASE *db, MSITABLE *table );
+extern void free_cached_tables( MSIDATABASE *db );
+extern UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
+extern UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
+extern UINT load_string_table( MSIDATABASE *db );
+extern UINT MSI_CommitTables( MSIDATABASE *db );
+extern HRESULT init_string_table( IStorage *stg );
+
+
+/* string table functions */
+extern BOOL msi_addstring( string_table *st, int string_no, const CHAR *data, int len, UINT refcount );
+extern BOOL msi_addstringW( string_table *st, int string_no, const WCHAR *data, int len, UINT refcount );
+extern UINT msi_id2stringW( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz );
+extern UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz );
+
+extern LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid);
+extern UINT msi_string2idW( string_table *st, LPCWSTR buffer, UINT *id );
+extern UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id );
+extern string_table *msi_init_stringtable( int entries, UINT codepage );
+extern VOID msi_destroy_stringtable( string_table *st );
+extern UINT msi_string_count( string_table *st );
+extern UINT msi_id_refcount( string_table *st, UINT i );
+extern UINT msi_string_totalsize( string_table *st, UINT *last );
+extern UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res );
+extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id );
+extern UINT msi_string_get_codepage( string_table *st );
+
+
+extern UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n );
+
+extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
+
+extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
+                              USHORT **pdata, UINT *psz );
+extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
+
+/* record internals */
+extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
+extern const WCHAR *MSI_RecordGetString( MSIRECORD *, unsigned int );
+extern MSIRECORD *MSI_CreateRecord( unsigned int );
+extern UINT MSI_RecordSetInteger( MSIRECORD *, unsigned int, int );
+extern UINT MSI_RecordSetStringW( MSIRECORD *, unsigned int, LPCWSTR );
+extern BOOL MSI_RecordIsNull( MSIRECORD *, unsigned int );
+extern UINT MSI_RecordGetStringW( MSIRECORD * , unsigned int, LPWSTR, DWORD *);
+extern UINT MSI_RecordGetStringA( MSIRECORD *, unsigned int, LPSTR, DWORD *);
+extern int MSI_RecordGetInteger( MSIRECORD *, unsigned int );
+extern UINT MSI_RecordReadStream( MSIRECORD *, unsigned int, char *, DWORD *);
+extern unsigned int MSI_RecordGetFieldCount( MSIRECORD *rec );
+
+/* stream internals */
+extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
+extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
+extern void enum_stream_names( IStorage *stg );
+
+/* database internals */
+extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** );
+extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
+
+/* view internals */
+extern UINT MSI_ViewExecute( MSIQUERY*, MSIRECORD * );
+extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
+extern UINT MSI_ViewClose( MSIQUERY* );
+
+/* package internals */
+extern UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE ** );
+extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR);
+extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD* );
+extern UINT MSI_GetPropertyW( MSIPACKAGE *, LPCWSTR, LPWSTR, DWORD*);
+extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR );
+extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern UINT MSI_GetComponentStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
+extern UINT MSI_GetFeatureStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
+
+/* registry data encoding/decoding functions */
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
+BOOL squash_guid(LPCWSTR in, LPWSTR out);
+BOOL encode_base85_guid(GUID *,LPWSTR);
+BOOL decode_base85_guid(LPCWSTR,GUID*);
+
+/* UI globals */
+extern INSTALLUILEVEL gUILevel;
+extern HWND gUIhwnd;
+extern INSTALLUI_HANDLERA gUIHandler;
+extern DWORD gUIFilter;
+extern LPVOID gUIContext;
+extern WCHAR gszLogFile[MAX_PATH];
+
+#endif /* __WINE_MSI_PRIVATE__ */

reactos/lib/msi
msiquery.c added at 1.1.2.1
diff -N msiquery.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msiquery.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,485 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.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);
+
+#if 0
+typedef struct tagMSIQUERY
+{
+    MSIOBJECTHDR hdr;
+    MSIVIEW *view;
+    UINT row;
+    MSIDATABASE *db;
+} MSIQUERY;
+#endif
+
+UINT WINAPI MsiDatabaseIsTablePersistentA(
+              MSIHANDLE hDatabase, LPSTR szTableName)
+{
+    FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseIsTablePersistentW(
+              MSIHANDLE hDatabase, LPWSTR szTableName)
+{
+    FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+void MSI_CloseView( MSIOBJECTHDR *arg )
+{
+    MSIQUERY *query = (MSIQUERY*) arg;
+
+    if( query->view && query->view->ops->delete )
+        query->view->ops->delete( query->view );
+    msiobj_release( &query->db->hdr );
+}
+
+UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
+{
+    LPWSTR col_name;
+    UINT i, count, r;
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    for( i=1; i<=count; i++ )
+    {
+        INT x;
+
+        col_name = NULL;
+        r = table->ops->get_column_info( table, i, &col_name, NULL );
+        if( r != ERROR_SUCCESS )
+            return r;
+        x = lstrcmpW( name, col_name );
+        HeapFree( GetProcessHeap(), 0, col_name );
+        if( !x )
+        {
+            *n = i;
+            return ERROR_SUCCESS;
+        }
+    }
+
+    return ERROR_INVALID_PARAMETER;
+}
+
+UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
+              LPCSTR szQuery, MSIHANDLE *phView)
+{
+    UINT r;
+    LPWSTR szwQuery;
+
+    TRACE("%ld %s %p\n", hdb, debugstr_a(szQuery), phView);
+
+    if( szQuery )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
+        szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+        if( !szwQuery )
+            return ERROR_FUNCTION_FAILED;
+        MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
+    }
+    else
+        szwQuery = NULL;
+
+    r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
+
+    return r;
+}
+
+UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
+              LPCWSTR szQuery, MSIQUERY **pView)
+{
+    MSIQUERY *query;
+    UINT r;
+
+    TRACE("%s %p\n", debugstr_w(szQuery), pView);
+
+    if( !szQuery)
+        return ERROR_INVALID_PARAMETER;
+
+    /* pre allocate a handle to hold a pointer to the view */
+    query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
+                              MSI_CloseView );
+    if( !query )
+        return ERROR_FUNCTION_FAILED;
+
+    msiobj_addref( &db->hdr );
+    query->row = 0;
+    query->db = db;
+    query->view = NULL;
+
+    r = MSI_ParseSQL( db, szQuery, &query->view );
+    if( r == ERROR_SUCCESS )
+    {
+        msiobj_addref( &query->hdr );
+        *pView = query;
+    }
+
+    msiobj_release( &query->hdr );
+    return r;
+}
+
+UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
+              LPCWSTR szQuery, MSIHANDLE *phView)
+{
+    MSIDATABASE *db;
+    MSIQUERY *query = NULL;
+    UINT ret;
+
+    TRACE("%s %p\n", debugstr_w(szQuery), phView);
+
+    db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
+    if( !db )
+        return ERROR_INVALID_HANDLE;
+
+    ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
+    if( ret == ERROR_SUCCESS )
+    {
+        *phView = alloc_msihandle( &query->hdr );
+        msiobj_release( &query->hdr );
+    }
+    msiobj_release( &db->hdr );
+
+    return ret;
+}
+
+UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
+{
+    MSIVIEW *view;
+    MSIRECORD *rec;
+    UINT row_count = 0, col_count = 0, i, ival, ret, type;
+
+    TRACE("%p %p\n", query, prec );
+
+    view = query->view;
+    if( !view )
+        return ERROR_FUNCTION_FAILED;
+
+    ret = view->ops->get_dimensions( view, &row_count, &col_count );
+    if( ret )
+        return ret;
+    if( !col_count )
+        return ERROR_INVALID_PARAMETER;
+
+    if( query->row >= row_count )
+        return ERROR_NO_MORE_ITEMS;
+
+    rec = MSI_CreateRecord( col_count );
+    if( !rec )
+        return ERROR_FUNCTION_FAILED;
+
+    for( i=1; i<=col_count; i++ )
+    {
+        ret = view->ops->get_column_info( view, i, NULL, &type );
+        if( ret )
+        {
+            ERR("Error getting column type for %d\n", i );
+            continue;
+        }
+        if (( type != MSITYPE_BINARY) && (type != (MSITYPE_BINARY |
+                                                   MSITYPE_NULLABLE)))
+        {
+            ret = view->ops->fetch_int( view, query->row, i, &ival );
+            if( ret )
+            {
+                ERR("Error fetching data for %d\n", i );
+                continue;
+            }
+            if( ! (type & MSITYPE_VALID ) )
+                ERR("Invalid type!\n");
+
+            /* check if it's nul (0) - if so, don't set anything */
+            if( !ival )
+                continue;
+
+            if( type & MSITYPE_STRING )
+            {
+                LPWSTR sval;
+
+                sval = MSI_makestring( query->db, ival );
+                MSI_RecordSetStringW( rec, i, sval );
+                HeapFree( GetProcessHeap(), 0, sval );
+            }
+            else
+            {
+                if( (type & MSI_DATASIZEMASK) == 2 )
+                    MSI_RecordSetInteger( rec, i, ival - (1<<15) );
+                else
+                    MSI_RecordSetInteger( rec, i, ival - (1<<31) );
+            }
+        }
+        else
+        {
+            IStream *stm = NULL;
+
+            ret = view->ops->fetch_stream( view, query->row, i, &stm );
+            if( ( ret == ERROR_SUCCESS ) && stm )
+            {
+                MSI_RecordSetIStream( rec, i, stm );
+                IStream_Release( stm );
+            }
+            else
+                ERR("failed to get stream\n");
+        }
+    }
+    query->row ++;
+
+    *prec = rec;
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
+{
+    MSIQUERY *query;
+    MSIRECORD *rec = NULL;
+    UINT ret;
+
+    TRACE("%ld %p\n", hView, record);
+
+    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+    if( !query )
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_ViewFetch( query, &rec );
+    if( ret == ERROR_SUCCESS )
+    {
+        *record = alloc_msihandle( &rec->hdr );
+        msiobj_release( &rec->hdr );
+    }
+    msiobj_release( &query->hdr );
+    return ret;
+}
+
+UINT MSI_ViewClose(MSIQUERY *query)
+{
+    MSIVIEW *view;
+
+    TRACE("%p\n", query );
+
+    view = query->view;
+    if( !view )
+        return ERROR_FUNCTION_FAILED;
+    if( !view->ops->close )
+        return ERROR_FUNCTION_FAILED;
+
+    return view->ops->close( view );
+}
+
+UINT WINAPI MsiViewClose(MSIHANDLE hView)
+{
+    MSIQUERY *query;
+    UINT ret;
+
+    TRACE("%ld\n", hView );
+
+    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+    if( !query )
+        return ERROR_INVALID_HANDLE;
+
+    ret = MSI_ViewClose( query );
+    msiobj_release( &query->hdr );
+    return ret;
+}
+
+UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec )
+{
+    MSIVIEW *view;
+
+    TRACE("%p %p\n", query, rec);
+
+    view = query->view;
+    if( !view )
+        return ERROR_FUNCTION_FAILED;
+    if( !view->ops->execute )
+        return ERROR_FUNCTION_FAILED;
+    query->row = 0;
+
+    return view->ops->execute( view, rec );
+}
+
+UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
+{
+    MSIQUERY *query;
+    MSIRECORD *rec = NULL;
+    UINT ret;
+    
+    TRACE("%ld %ld\n", hView, hRec);
+
+    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+    if( !query )
+        return ERROR_INVALID_HANDLE;
+
+    if( hRec )
+    {
+        rec = msihandle2msiinfo( hRec, MSIHANDLETYPE_RECORD );
+        if( !rec )
+        {
+            ret = ERROR_INVALID_HANDLE;
+            goto out;
+        }
+    }
+
+    ret = MSI_ViewExecute( query, rec );
+out:
+    if( query )
+        msiobj_release( &query->hdr );
+    if( rec )
+        msiobj_release( &rec->hdr );
+
+    return ret;
+}
+
+UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
+{
+    MSIVIEW *view;
+    MSIQUERY *query;
+    MSIHANDLE handle;
+    UINT ret, i, count = 0, type;
+    LPWSTR name;
+
+    TRACE("%ld %d %p\n", hView, info, hRec);
+
+    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+    if( !query )
+        return ERROR_INVALID_HANDLE;
+
+    view = query->view;
+    if( !view )
+        return ERROR_FUNCTION_FAILED;
+
+    if( !view->ops->get_dimensions )
+        return ERROR_FUNCTION_FAILED;
+
+    ret = view->ops->get_dimensions( view, NULL, &count );
+    if( ret )
+        return ret;
+    if( !count )
+        return ERROR_INVALID_PARAMETER;
+
+    handle = MsiCreateRecord( count );
+    if( !handle )
+        return ERROR_FUNCTION_FAILED;
+
+    for( i=0; i<count; i++ )
+    {
+        name = NULL;
+        ret = view->ops->get_column_info( view, i+1, &name, &type );
+        if( ret != ERROR_SUCCESS )
+            continue;
+        MsiRecordSetStringW( handle, i+1, name );
+        HeapFree( GetProcessHeap(), 0, name );
+    }
+
+    *hRec = handle;
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb, 
+                 LPCSTR szTransformFile, int iErrorCond)
+{
+    FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb, 
+                 LPCWSTR szTransformFile, int iErrorCond)
+{
+    FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
+                 LPCSTR szTransformFile, int iReserved1, int iReserved2 )
+{
+    FIXME("%ld %ld %s %d %d\n", hdb, hdbref, 
+           debugstr_a(szTransformFile), iReserved1, iReserved2);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
+                 LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
+{
+    FIXME("%ld %ld %s %d %d\n", hdb, hdbref, 
+           debugstr_w(szTransformFile), iReserved1, iReserved2);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
+{
+    MSIDATABASE *db;
+    UINT r;
+
+    TRACE("%ld\n", hdb);
+
+    db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
+    if( !db )
+        return ERROR_INVALID_HANDLE;
+
+    /* FIXME: lock the database */
+
+    r = MSI_CommitTables( db );
+
+    /* FIXME: unlock the database */
+
+    return r;
+}
+
+UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, 
+                    LPCSTR table, MSIHANDLE* rec)
+{
+    FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,
+                    LPCWSTR table, MSIHANDLE* rec)
+{
+    FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE
+hRecord)
+{
+    FIXME("%ld %x %ld\n",hView, eModifyMode, hRecord);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}

reactos/lib/msi
order.c added at 1.1.2.1
diff -N order.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ order.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,335 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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 <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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIORDERVIEW
+{
+    MSIVIEW        view;
+    MSIDATABASE   *db;
+    MSIVIEW       *table;
+    UINT          *reorder;
+    UINT           num_cols;
+    UINT           cols[1];
+} MSIORDERVIEW;
+
+static UINT ORDER_compare( MSIORDERVIEW *ov, UINT a, UINT b, UINT *swap )
+{
+    UINT r, i, a_val = 0, b_val = 0;
+
+    *swap = 0;
+    for( i=0; i<ov->num_cols; i++ )
+    {
+        r = ov->table->ops->fetch_int( ov->table, a, ov->cols[i], &a_val );
+        if( r != ERROR_SUCCESS )
+            return r;
+
+        r = ov->table->ops->fetch_int( ov->table, b, ov->cols[i], &b_val );
+        if( r != ERROR_SUCCESS )
+            return r;
+
+        if( a_val != b_val )
+        {
+            if( a_val > b_val )
+                *swap = 1;
+            break;
+        }
+    }
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ORDER_mergesort( MSIORDERVIEW *ov, UINT left, UINT right )
+{
+    UINT r, centre = (left + right)/2, temp, swap = 0, i, j;
+    UINT *array = ov->reorder;
+
+    if( left == right )
+        return ERROR_SUCCESS;
+
+    /* sort the left half */
+    r = ORDER_mergesort( ov, left, centre );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    /* sort the right half */
+    r = ORDER_mergesort( ov, centre+1, right );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    for( i=left, j=centre+1; (i<=centre) && (j<=right); i++ )
+    {
+        r = ORDER_compare( ov, array[i], array[j], &swap );
+        if( r != ERROR_SUCCESS )
+            return r;
+        if( swap )
+        { 
+            temp = array[j];
+            memmove( &array[i+1], &array[i], (j-i)*sizeof (UINT) );
+            array[i] = temp;
+            j++;
+            centre++;
+        }
+    }
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ORDER_verify( MSIORDERVIEW *ov, UINT num_rows )
+{
+    UINT i, swap, r;
+
+    for( i=1; i<num_rows; i++ )
+    {
+        r = ORDER_compare( ov, ov->reorder[i-1], ov->reorder[i], &swap );
+        if( r != ERROR_SUCCESS )
+            return r;
+        if( !swap )
+            continue;
+        ERR("Bad order! %d\n", i);
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p %d %d %p\n", ov, row, col, val );
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    row = ov->reorder[ row ];
+
+    return ov->table->ops->fetch_int( ov->table, row, col, val );
+}
+
+static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+    UINT r, num_rows = 0, i;
+
+    TRACE("%p %p\n", ov, record);
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    r = ov->table->ops->execute( ov->table, record );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    r = ov->table->ops->get_dimensions( ov->table, &num_rows, NULL );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    ov->reorder = HeapAlloc( GetProcessHeap(), 0, num_rows*sizeof(UINT) );
+    if( !ov->reorder )
+        return ERROR_FUNCTION_FAILED;
+
+    for( i=0; i<num_rows; i++ )
+        ov->reorder[i] = i;
+
+    r = ORDER_mergesort( ov, 0, num_rows - 1 );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    r = ORDER_verify( ov, num_rows );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ORDER_close( struct tagMSIVIEW *view )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p\n", ov );
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( ov->reorder )
+        HeapFree( GetProcessHeap(), 0, ov->reorder );
+    ov->reorder = NULL;
+
+    return ov->table->ops->close( ov->table );
+}
+
+static UINT ORDER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p %p %p\n", ov, rows, cols );
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return ov->table->ops->get_dimensions( ov->table, rows, cols );
+}
+
+static UINT ORDER_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p %d %p %p\n", ov, n, name, type );
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return ov->table->ops->get_column_info( ov->table, n, name, type );
+}
+
+static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p %d %ld\n", ov, eModifyMode, hrec );
+
+    if( !ov->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return ov->table->ops->modify( ov->table, eModifyMode, hrec );
+}
+
+static UINT ORDER_delete( struct tagMSIVIEW *view )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+    TRACE("%p\n", ov );
+
+    if( ov->table )
+        ov->table->ops->delete( ov->table );
+
+    if( ov->reorder )
+        HeapFree( GetProcessHeap(), 0, ov->reorder );
+    ov->reorder = NULL;
+
+    msiobj_release( &ov->db->hdr );
+    HeapFree( GetProcessHeap(), 0, ov );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS order_ops =
+{
+    ORDER_fetch_int,
+    NULL,
+    NULL,
+    NULL,
+    ORDER_execute,
+    ORDER_close,
+    ORDER_get_dimensions,
+    ORDER_get_column_info,
+    ORDER_modify,
+    ORDER_delete
+};
+
+UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+    MSIORDERVIEW *ov = NULL;
+    UINT count = 0, r;
+
+    TRACE("%p\n", ov );
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("can't get table dimensions\n");
+        return r;
+    }
+
+    ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                    sizeof *ov + sizeof (UINT) * count );
+    if( !ov )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    ov->view.ops = &order_ops;
+    msiobj_addref( &db->hdr );
+    ov->db = db;
+    ov->table = table;
+    ov->reorder = NULL;
+    ov->num_cols = 0;
+    *view = (MSIVIEW*) ov;
+
+    return ERROR_SUCCESS;
+}
+
+UINT ORDER_AddColumn( MSIVIEW *view, LPWSTR name )
+{
+    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+    UINT n, count, r;
+    MSIVIEW *table;
+
+    TRACE("%p adding %s\n", ov, debugstr_w( name ) );
+
+    if( ov->view.ops != &order_ops )
+        return ERROR_FUNCTION_FAILED;
+
+    table = ov->table;
+    if( !table )
+        return ERROR_FUNCTION_FAILED;
+    if( !table->ops->get_dimensions )
+        return ERROR_FUNCTION_FAILED;
+    if( !table->ops->get_column_info )
+        return ERROR_FUNCTION_FAILED;
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    if( ov->num_cols >= count )
+        return ERROR_FUNCTION_FAILED;
+
+    r = VIEW_find_column( table, name, &n );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    ov->cols[ov->num_cols] = n;
+    TRACE("Ordering by column %s (%d)\n", debugstr_w( name ), n);
+
+    ov->num_cols++;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
package.c added at 1.1.2.1
diff -N package.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ package.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,843 @@
+/*
+ * 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
+ */
+
+#define NONAMELESSUNION
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "wincrypt.h"
+#include "winuser.h"
+#include "shlobj.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
+ *  which is a problem because LPCTSTR isn't defined when compiling wine.
+ * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
+ *  and make sure to only use it in W functions.
+ */
+#define LPCTSTR LPCWSTR
+
+void MSI_FreePackage( MSIOBJECTHDR *arg)
+{
+    MSIPACKAGE *package= (MSIPACKAGE*) arg;
+
+    ACTION_remove_tracked_tempfiles(package);
+
+    if (package->features && package->loaded_features > 0)
+        HeapFree(GetProcessHeap(),0,package->features);
+
+    if (package->folders && package->loaded_folders > 0)
+        HeapFree(GetProcessHeap(),0,package->folders);
+    
+    if (package->components && package->loaded_components > 0)
+        HeapFree(GetProcessHeap(),0,package->components);
+
+    if (package->files && package->loaded_files > 0)
+        HeapFree(GetProcessHeap(),0,package->files);
+    msiobj_release( &package->db->hdr );
+}
+
+UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
+{
+    LPWSTR szwPack = NULL;
+    UINT len, ret;
+
+    TRACE("%s %p\n",debugstr_a(szPackage), phPackage);
+
+    if( szPackage )
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
+        szwPack = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        if( szwPack )
+            MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szwPack, len );
+    }
+
+    ret = MsiOpenPackageW( szwPack, phPackage );
+
+    if( szwPack )
+        HeapFree( GetProcessHeap(), 0, szwPack );
+
+    return ret;
+}
+
+
+static const UINT clone_properties(MSIDATABASE *db)
+{
+    MSIQUERY * view = NULL;
+    UINT rc;
+    static const WCHAR CreateSql[] = {
+       'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','_','P','r','o',
+       'p','e','r','t','y','`',' ','(',' ','`','_','P','r','o','p','e','r','t',
+       'y','`',' ','C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U',
+       'L','L',',',' ','`','V','a','l','u','e','`',' ','C','H','A','R','(','9',
+       '8',')',' ','N','O','T',' ','N','U','L','L',' ','P','R','I','M','A','R',
+       'Y',' ','K','E','Y',' ','`','_','P','r','o','p','e','r','t','y','`',')',0};
+    static const WCHAR Query[] = {
+       'S','E','L','E','C','T',' ','*',' ',
+       'f','r','o','m',' ','P','r','o','p','e','r','t','y',0};
+    static const WCHAR Insert[] = {
+       'I','N','S','E','R','T',' ','i','n','t','o',' ',
+       '`','_','P','r','o','p','e','r','t','y','`',' ',
+       '(','`','_','P','r','o','p','e','r','t','y','`',',',
+       '`','V','a','l','u','e','`',')',' ',
+       'V','A','L','U','E','S',' ','(','?',')',0};
+
+    /* create the temporary properties table */
+    rc = MSI_DatabaseOpenViewW(db, CreateSql, &view);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+    rc = MSI_ViewExecute(view,0);   
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr); 
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    /* clone the existing properties */
+    rc = MSI_DatabaseOpenViewW(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;
+    }
+    while (1)
+    {
+        MSIRECORD * row;
+        MSIQUERY * view2;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+            break;
+
+        rc = MSI_DatabaseOpenViewW(db,Insert,&view2);  
+        if (rc!= ERROR_SUCCESS)
+            continue;
+        rc = MSI_ViewExecute(view2,row);
+        MSI_ViewClose(view2);
+        msiobj_release(&view2->hdr);
+ 
+        if (rc == ERROR_SUCCESS) 
+            msiobj_release(&row->hdr); 
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    
+    return rc;
+}
+
+/*
+ * There are a whole slew of these we need to set
+ *
+ *
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
+ */
+static VOID set_installer_properties(MSIPACKAGE *package)
+{
+    WCHAR pth[MAX_PATH];
+    OSVERSIONINFOA OSVersion;
+    DWORD verval;
+    WCHAR verstr[10], msiver[10];
+
+    static const WCHAR cszbs[]={'\\',0};
+    static const WCHAR CFF[] = 
+{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
+    static const WCHAR PFF[] = 
+{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
+    static const WCHAR CADF[] = 
+{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+    static const WCHAR FaF[] = 
+{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
+    static const WCHAR FoF[] = 
+{'F','o','n','t','s','F','o','l','d','e','r',0};
+    static const WCHAR SendTF[] = 
+{'S','e','n','d','T','o','F','o','l','d','e','r',0};
+    static const WCHAR SMF[] = 
+{'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
+    static const WCHAR StF[] = 
+{'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
+    static const WCHAR TemplF[] = 
+{'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
+    static const WCHAR DF[] = 
+{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
+    static const WCHAR PMF[] = 
+{'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
+    static const WCHAR ATF[] = 
+{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
+    static const WCHAR ADF[] = 
+{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+    static const WCHAR SF[] = 
+{'S','y','s','t','e','m','F','o','l','d','e','r',0};
+    static const WCHAR LADF[] = 
+{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+    static const WCHAR MPF[] = 
+{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
+    static const WCHAR PF[] = 
+{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
+    static const WCHAR WF[] = 
+{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+    static const WCHAR TF[]=
+{'T','e','m','p','F','o','l','d','e','r',0};
+    static const WCHAR szAdminUser[] =
+{'A','d','m','i','n','U','s','e','r',0};
+    static const WCHAR szPriv[] =
+{'P','r','i','v','i','l','e','g','e','d',0};
+    static const WCHAR szOne[] =
+{'1',0};
+    static const WCHAR v9x[] = { 'V','e','r','s','i','o','n','9','X',0 };
+    static const WCHAR vNT[] = { 'V','e','r','s','i','o','n','N','T',0 };
+    static const WCHAR szFormat[] = {'%','l','i',0};
+    static const WCHAR szWinBuild[] =
+{'W','i','n','d','o','w','s','B','u','i','l','d', 0 };
+    static const WCHAR szSPL[] = 
+{'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0 };
+    static const WCHAR szSix[] = {'6',0 };
+
+    static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
+    static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
+
+/*
+ * Other things I notice set
+ *
+ScreenY
+ScreenX
+SystemLanguageID
+ComputerName
+UserLanguageID
+LogonUser
+VirtualMemory
+PhysicalMemory
+Intel
+ShellAdvSupport
+DefaultUIFont
+VersionDatabase
+PackagecodeChanging
+ProductState
+CaptionHeight
+BorderTop
+BorderSide
+TextHeight
+ColorBits
+RedirectedDllSupport
+Time
+Date
+Privileged
+*/
+
+    SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, CFF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, PFF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, CADF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, FaF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, FoF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, SendTF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, SMF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, StF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, TemplF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, DF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, PMF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, ATF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, ADF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, SF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, LADF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, MPF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, PF, pth);
+
+    SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
+    strcatW(pth,cszbs);
+    MSI_SetPropertyW(package, WF, pth);
+
+    GetTempPathW(MAX_PATH,pth);
+    MSI_SetPropertyW(package, TF, pth);
+
+
+    /* in a wine environment the user is always admin and privileged */
+    MSI_SetPropertyW(package,szAdminUser,szOne);
+    MSI_SetPropertyW(package,szPriv,szOne);
+
+    /* set the os things */
+    OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+    GetVersionExA(&OSVersion);
+    verval = OSVersion.dwMinorVersion+OSVersion.dwMajorVersion*100;
+    sprintfW(verstr,szFormat,verval);
+    switch (OSVersion.dwPlatformId)
+    {
+        case VER_PLATFORM_WIN32_WINDOWS:    
+            MSI_SetPropertyW(package,v9x,verstr);
+            break;
+        case VER_PLATFORM_WIN32_NT:
+            MSI_SetPropertyW(package,vNT,verstr);
+            break;
+    }
+    sprintfW(verstr,szFormat,OSVersion.dwBuildNumber);
+    MSI_SetPropertyW(package,szWinBuild,verstr);
+    /* just fudge this */
+    MSI_SetPropertyW(package,szSPL,szSix);
+
+    sprintfW( msiver, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
+    MSI_SetPropertyW( package, szVersionMsi, msiver );
+}
+
+UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
+{
+    UINT rc;
+    MSIDATABASE *db = NULL;
+    MSIPACKAGE *package = NULL;
+    WCHAR uilevel[10];
+    UINT ret = ERROR_FUNCTION_FAILED;
+
+    static const WCHAR OriginalDatabase[] =
+{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
+    static const WCHAR Database[] =
+{'D','A','T','A','B','A','S','E',0};
+    static const WCHAR szpi[] = {'%','i',0};
+    static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
+
+    TRACE("%s %p\n",debugstr_w(szPackage), pPackage);
+
+    if (szPackage[0] == '#')
+    {
+        INT handle = atoiW(&szPackage[1]);
+        db = msihandle2msiinfo( handle , MSIHANDLETYPE_DATABASE);
+    }
+    else
+    {
+        rc = MSI_OpenDatabaseW(szPackage, MSIDBOPEN_READONLY, &db);
+        if (rc != ERROR_SUCCESS)
+            return ERROR_FUNCTION_FAILED;
+    }
+
+    package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
+                               MSI_FreePackage );
+
+    if (package)
+    {
+        msiobj_addref( &db->hdr );
+
+        package->db = db;
+        package->features = NULL;
+        package->folders = NULL;
+        package->components = NULL;
+        package->files = NULL;
+        package->loaded_features = 0;
+        package->loaded_folders = 0;
+        package->loaded_components= 0;
+        package->loaded_files = 0;
+
+        /* OK, here is where we do a slew of things to the database to 
+         * prep for all that is to come as a package */
+
+        clone_properties(db);
+        set_installer_properties(package);
+        MSI_SetPropertyW(package, OriginalDatabase, szPackage);
+        MSI_SetPropertyW(package, Database, szPackage);
+        sprintfW(uilevel,szpi,gUILevel);
+        MSI_SetPropertyW(package, szLevel, uilevel);
+
+        msiobj_addref( &package->hdr );
+        *pPackage = package;
+        ret = ERROR_SUCCESS;
+    }
+
+    if( package )
+        msiobj_release( &package->hdr );
+    if( db )
+        msiobj_release( &db->hdr );
+
+    return ret;
+}
+
+UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
+{
+    MSIPACKAGE *package = NULL;
+    UINT ret;
+
+    ret = MSI_OpenPackageW( szPackage, &package);
+    if( ret == ERROR_SUCCESS )
+    {
+        *phPackage = alloc_msihandle( &package->hdr );
+        msiobj_release( &package->hdr );
+    }
+    return ret;
+}
+
+UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+    FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+    FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
+{
+    MSIPACKAGE *package;
+    MSIHANDLE handle = 0;
+
+    TRACE("(%ld)\n",hInstall);
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+    if( package)
+    {
+        handle = alloc_msihandle( &package->db->hdr );
+        msiobj_release( &package->hdr );
+    }
+
+    return handle;
+}
+
+INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
+                               MSIRECORD *record)
+{
+    DWORD log_type = 0;
+    LPWSTR message;
+    DWORD sz;
+    DWORD total_size = 0;
+    INT msg_field=1;
+    INT i;
+    INT rc;
+    char *msg;
+    int len;
+
+    TRACE("%x \n",eMessageType);
+    rc = 0;
+
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
+        log_type |= INSTALLLOGMODE_ERROR;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_WARNING)
+        log_type |= INSTALLLOGMODE_WARNING;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_USER)
+        log_type |= INSTALLLOGMODE_USER;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INFO)
+        log_type |= INSTALLLOGMODE_INFO;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA)
+        log_type |= INSTALLLOGMODE_COMMONDATA;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
+        log_type |= INSTALLLOGMODE_ACTIONSTART;
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA)
+        log_type |= INSTALLLOGMODE_ACTIONDATA;
+    /* just a guess */
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
+        log_type |= 0x800;
+
+    message = HeapAlloc(GetProcessHeap(),0,1*sizeof (WCHAR));
+    message[0]=0;
+    msg_field = MSI_RecordGetFieldCount(record);
+    for (i = 1; i <= msg_field; i++)
+    {
+        LPWSTR tmp;
+        WCHAR number[3];
+        const static WCHAR format[] = { '%','i',':',' ',0};
+        const static WCHAR space[] = { ' ',0};
+        sz = 0;
+        MSI_RecordGetStringW(record,i,NULL,&sz);
+        sz+=4;
+        total_size+=sz*sizeof(WCHAR);
+        tmp = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+        message = HeapReAlloc(GetProcessHeap(),0,message,total_size*sizeof (WCHAR));
+
+        MSI_RecordGetStringW(record,i,tmp,&sz);
+
+        if (msg_field > 1)
+        {
+            sprintfW(number,format,i);
+            strcatW(message,number);
+        }
+        strcatW(message,tmp);
+        if (msg_field > 1)
+            strcatW(message,space);
+
+        HeapFree(GetProcessHeap(),0,tmp);
+    }
+
+    TRACE("(%p %lx %lx %s)\n",gUIHandler, gUIFilter, log_type,
+                             debugstr_w(message));
+
+    /* convert it to ASCII */
+    len = WideCharToMultiByte( CP_ACP, 0, message, -1,
+                               NULL, 0, NULL, NULL );
+    msg = HeapAlloc( GetProcessHeap(), 0, len );
+    WideCharToMultiByte( CP_ACP, 0, message, -1,
+                         msg, len, NULL, NULL );
+
+    if (gUIHandler && (gUIFilter & log_type))
+    {
+        rc = gUIHandler(gUIContext,eMessageType,msg);
+    }
+
+    if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) ==
+                                      INSTALLMESSAGE_PROGRESS))
+    {
+        DWORD write;
+        HANDLE log_file = CreateFileW(gszLogFile,GENERIC_WRITE, 0, NULL,
+                                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+        if (log_file != INVALID_HANDLE_VALUE)
+        {
+            SetFilePointer(log_file,0, NULL, FILE_END);
+            WriteFile(log_file,msg,strlen(msg),&write,NULL);
+            WriteFile(log_file,"\n",1,&write,NULL);
+            CloseHandle(log_file);
+        }
+    }
+    HeapFree( GetProcessHeap(), 0, msg );
+    
+    HeapFree(GetProcessHeap(),0,message);
+    return ERROR_SUCCESS;
+}
+
+INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
+                              MSIHANDLE hRecord)
+{
+    UINT ret = ERROR_INVALID_HANDLE;
+    MSIPACKAGE *package = NULL;
+    MSIRECORD *record = NULL;
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
+    if( !package )
+        goto out;
+
+    record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
+    if( !record )
+        goto out;
+
+    ret = MSI_ProcessMessage( package, eMessageType, record );
+
+out:
+    if( package )
+        msiobj_release( &package->hdr );
+    if( record )
+        msiobj_release( &record->hdr );
+
+    return ret;
+}
+
+/* property code */
+UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
+{
+    LPWSTR szwName = NULL, szwValue = NULL;
+    UINT hr = ERROR_INSTALL_FAILURE;
+    UINT len;
+
+    if (0 == hInstall) {
+      return ERROR_INVALID_HANDLE;
+    }
+    if (NULL == szName) {
+      return ERROR_INVALID_PARAMETER;
+    }
+    if (NULL == szValue) {
+      return ERROR_INVALID_PARAMETER;
+    }
+
+    len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+    szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+    if( !szwName )
+        goto end;
+    MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+
+    len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
+    szwValue = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+    if( !szwValue)
+        goto end;
+    MultiByteToWideChar( CP_ACP, 0, szValue , -1, szwValue, len );
+
+    hr = MsiSetPropertyW( hInstall, szwName, szwValue);
+
+end:
+    if( szwName )
+        HeapFree( GetProcessHeap(), 0, szwName );
+    if( szwValue )
+        HeapFree( GetProcessHeap(), 0, szwValue );
+
+    return hr;
+}
+
+UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
+{
+    MSIQUERY *view;
+    MSIRECORD *row;
+    UINT rc;
+    DWORD sz = 0;
+    static const WCHAR Insert[]=
+     {'I','N','S','E','R','T',' ','i','n','t','o',' ','`','_','P','r','o','p'
+,'e','r','t','y','`',' ','(','`','_','P','r','o','p','e','r','t','y','`'
+,',','`','V','a','l','u','e','`',')',' ','V','A','L','U','E','S'
+,' ','(','?',')',0};
+    static const WCHAR Update[]=
+     {'U','P','D','A','T','E',' ','_','P','r','o','p','e'
+,'r','t','y',' ','s','e','t',' ','`','V','a','l','u','e','`',' ','='
+,' ','?',' ','w','h','e','r','e',' ','`','_','P','r','o','p'
+,'e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
+    WCHAR Query[1024];
+
+    TRACE("Setting property (%s %s)\n",debugstr_w(szName),
+          debugstr_w(szValue));
+
+    rc = MSI_GetPropertyW(package,szName,0,&sz);
+    if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS)
+    {
+        sprintfW(Query,Update,szName);
+
+        row = MSI_CreateRecord(1);
+        MSI_RecordSetStringW(row,1,szValue);
+
+    }
+    else
+    {
+       strcpyW(Query,Insert);
+
+        row = MSI_CreateRecord(2);
+        MSI_RecordSetStringW(row,1,szName);
+        MSI_RecordSetStringW(row,2,szValue);
+    }
+
+
+    rc = MSI_DatabaseOpenViewW(package->db,Query,&view);
+    if (rc!= ERROR_SUCCESS)
+    {
+        msiobj_release(&row->hdr);
+        return rc;
+    }
+
+    rc = MSI_ViewExecute(view,row);
+
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    return rc;
+}
+
+UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
+{
+    MSIPACKAGE *package;
+    UINT ret;
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+    if( !package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_SetPropertyW( package, szName, szValue);
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+static UINT MSI_GetPropertyRow(MSIPACKAGE *package, LPCWSTR szName, MSIRECORD **row)
+{
+    MSIQUERY *view;
+    UINT rc, sz;
+    static const WCHAR select[]=
+    {'s','e','l','e','c','t',' ','V','a','l','u','e',' ','f','r','o','m',' '
+     ,'_','P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' '
+     ,'_','P','r','o','p','e','r','t','y','=','`','%','s','`',0};
+    LPWSTR query;
+
+    if (!szName)
+        return ERROR_INVALID_PARAMETER;
+
+    sz = sizeof select + strlenW(szName)*sizeof(WCHAR);
+    query = HeapAlloc(GetProcessHeap(), 0, sz);
+    sprintfW(query,select,szName);
+
+    rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+    HeapFree(GetProcessHeap(), 0, query);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+        if (rc == ERROR_SUCCESS)
+            rc = MSI_ViewFetch(view,row);
+
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    return rc;
+}
+
+UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName, 
+                           LPWSTR szValueBuf, DWORD* pchValueBuf)
+{
+    MSIRECORD *row;
+    UINT rc;
+
+    rc = MSI_GetPropertyRow(package, szName, &row);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
+        msiobj_release(&row->hdr);
+    }
+
+    if (rc == ERROR_SUCCESS)
+        TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
+            debugstr_w(szName));
+    else
+    {
+        *pchValueBuf = 0;
+        TRACE("property not found\n");
+    }
+
+    return rc;
+}
+
+UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName, 
+                           LPSTR szValueBuf, DWORD* pchValueBuf)
+{
+    MSIRECORD *row;
+    UINT rc, len;
+    LPWSTR szwName;
+
+    len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+    szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+    if (!szwName)
+        return ERROR_NOT_ENOUGH_MEMORY;
+    MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+
+    rc = MSI_GetPropertyRow(package, szwName, &row);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_RecordGetStringA(row,1,szValueBuf,pchValueBuf);
+        msiobj_release(&row->hdr);
+    }
+
+    if (rc == ERROR_SUCCESS)
+        TRACE("returning %s for property %s\n", debugstr_a(szValueBuf),
+            debugstr_a(szName));
+    else
+    {
+        *pchValueBuf = 0;
+        TRACE("property not found\n");
+    }
+    HeapFree( GetProcessHeap(), 0, szwName );
+
+    return rc;
+}
+
+UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf) 
+{
+    MSIPACKAGE *package;
+    UINT ret;
+
+    TRACE("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
+
+    if (0 == hInstall)
+        return ERROR_INVALID_HANDLE;
+    if (NULL == szName)
+        return ERROR_INVALID_PARAMETER;
+    if (NULL != szValueBuf && NULL == pchValueBuf)
+        return ERROR_INVALID_PARAMETER;
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_GetPropertyA(package, szName, szValueBuf, pchValueBuf );
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+  
+UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, 
+                           LPWSTR szValueBuf, DWORD* pchValueBuf)
+{
+    MSIPACKAGE *package;
+    UINT ret;
+
+    if (0 == hInstall)
+        return ERROR_INVALID_HANDLE;
+    if (NULL == szName)
+        return ERROR_INVALID_PARAMETER;
+    if (NULL != szValueBuf && NULL == pchValueBuf)
+        return ERROR_INVALID_PARAMETER;
+
+    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_GetPropertyW(package, szName, szValueBuf, pchValueBuf );
+    msiobj_release( &package->hdr );
+    return ret;
+}

reactos/lib/msi
query.h added at 1.1.2.1
diff -N query.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ query.h	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,139 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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
+ */
+
+#ifndef __WINE_MSI_QUERY_H
+#define __WINE_MSI_QUERY_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+
+#define OP_EQ       1
+#define OP_AND      2
+#define OP_OR       3
+#define OP_GT       4
+#define OP_LT       5
+#define OP_LE       6
+#define OP_GE       7
+#define OP_NE       8
+#define OP_ISNULL   9
+#define OP_NOTNULL  10
+
+#define EXPR_COMPLEX  1
+#define EXPR_COLUMN   2
+#define EXPR_COL_NUMBER 3
+#define EXPR_IVAL     4
+#define EXPR_SVAL     5
+#define EXPR_UVAL     6
+#define EXPR_STRCMP   7
+#define EXPR_UTF8     8
+#define EXPR_WILDCARD 9
+
+struct sql_str {
+    LPCWSTR data;
+    INT len;
+};
+
+typedef struct _string_list
+{
+    LPWSTR string;
+    struct _string_list *next;
+} string_list;
+
+struct complex_expr
+{
+    UINT op;
+    struct expr *left;
+    struct expr *right;
+};
+
+struct expr
+{
+    int type;
+    union
+    {
+        struct complex_expr expr;
+        INT   ival;
+        UINT  uval;
+        LPWSTR sval;
+        LPWSTR column;
+        UINT col_number;
+        char *utf8;
+    } u;
+};
+
+typedef struct _create_col_info
+{
+    LPWSTR colname;
+    UINT   type;
+    struct _create_col_info *next;
+} create_col_info;
+
+typedef struct _value_list
+{
+    struct expr *val;
+    struct _value_list *next;
+} value_list;
+
+typedef struct _column_assignment
+{
+    string_list *col_list;
+    value_list *val_list;
+} column_assignment;
+
+
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phView);
+
+UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view );
+
+UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+                        string_list *columns );
+
+UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
+
+UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
+UINT ORDER_AddColumn( MSIVIEW *group, LPWSTR name );
+
+UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+                       struct expr *cond );
+
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+                        create_col_info *col_info, BOOL temp );
+
+UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+                        string_list *columns, value_list *values, BOOL temp );
+
+UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table,
+                        column_assignment *list, struct expr *expr );
+
+void delete_expr( struct expr *e );
+void delete_string_list( string_list *sl );
+void delete_value_list( value_list *vl );
+
+int sqliteGetToken(const WCHAR *z, int *tokenType);
+
+#endif /* __WINE_MSI_QUERY_H */

reactos/lib/msi
record.c added at 1.1.2.1
diff -N record.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ record.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,573 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+#define MSIFIELD_NULL   0
+#define MSIFIELD_INT    1
+#define MSIFIELD_STR    2
+#define MSIFIELD_WSTR   3
+#define MSIFIELD_STREAM 4
+
+void MSI_FreeField( MSIFIELD *field )
+{
+    switch( field->type )
+    {
+    case MSIFIELD_NULL:
+    case MSIFIELD_INT:
+        break;
+    case MSIFIELD_WSTR:
+        HeapFree( GetProcessHeap(), 0, field->u.szwVal);
+        break;
+    case MSIFIELD_STREAM:
+        IStream_Release( field->u.stream );
+        break;
+    default:
+        ERR("Invalid field type %d\n", field->type);
+    }
+}
+
+void MSI_CloseRecord( MSIOBJECTHDR *arg )
+{
+    MSIRECORD *rec = (MSIRECORD *) arg;
+    UINT i;
+
+    for( i=0; i<=rec->count; i++ )
+        MSI_FreeField( &rec->fields[i] );
+}
+
+MSIRECORD *MSI_CreateRecord( unsigned int cParams )
+{
+    MSIRECORD *rec;
+    UINT len;
+
+    TRACE("%d\n", cParams);
+
+    len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams;
+    rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord );
+    if( rec )
+    rec->count = cParams;
+    return rec;
+}
+
+MSIHANDLE WINAPI MsiCreateRecord( unsigned int cParams )
+{
+    MSIRECORD *rec;
+    MSIHANDLE ret = 0;
+
+    TRACE("%d\n", cParams);
+
+    rec = MSI_CreateRecord( cParams );
+    if( rec )
+        ret = alloc_msihandle( &rec->hdr );
+    return ret;
+}
+
+unsigned int MSI_RecordGetFieldCount( MSIRECORD *rec )
+{
+    return rec->count;
+}
+
+unsigned int WINAPI MsiRecordGetFieldCount( MSIHANDLE handle )
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld\n", handle );
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+    {
+        ERR("Record not found!\n");
+        return 0;
+    }
+
+    ret = MSI_RecordGetFieldCount( rec );
+    msiobj_release( &rec->hdr );
+
+    return ret;
+}
+
+static BOOL string2intW( LPCWSTR str, int *out )
+{
+    int x = 0;
+    LPCWSTR p = str;
+
+    if( *p == '-' ) /* skip the minus sign */
+        p++;
+    while ( *p )
+    {
+        if( (*p < '0') || (*p > '9') )
+            return FALSE;
+        x *= 10;
+        x += (*p - '0');
+        p++;
+    }
+
+    if( str[0] == '-' ) /* check if it's negative */
+        x = -x;
+    *out = x; 
+
+    return TRUE;
+}
+
+int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField)
+{
+    int ret = 0;
+
+    TRACE("%p %d\n", rec, iField );
+
+    if( iField > rec->count )
+        return MSI_NULL_INTEGER;
+
+    switch( rec->fields[iField].type )
+    {
+    case MSIFIELD_INT:
+        return rec->fields[iField].u.iVal;
+    case MSIFIELD_WSTR:
+        if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
+            return ret;
+        return MSI_NULL_INTEGER;
+    default:
+        break;
+    }
+
+    return MSI_NULL_INTEGER;
+}
+
+int WINAPI MsiRecordGetInteger( MSIHANDLE handle, unsigned int iField)
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d\n", handle, iField );
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return MSI_NULL_INTEGER;
+
+    ret = MSI_RecordGetInteger( rec, iField );
+    msiobj_release( &rec->hdr );
+
+    return ret;
+}
+
+UINT WINAPI MsiRecordClearData( MSIHANDLE handle )
+{
+    MSIRECORD *rec;
+    UINT i;
+
+    TRACE("%ld\n", handle );
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+
+    for( i=0; i<=rec->count; i++)
+    {
+        MSI_FreeField( &rec->fields[i] );
+        rec->fields[i].type = MSIFIELD_NULL;
+        rec->fields[i].u.iVal = 0;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+UINT MSI_RecordSetInteger( MSIRECORD *rec, unsigned int iField, int iVal )
+{
+    TRACE("%p %u %d\n", rec, iField, iVal);
+
+    if( iField <= rec->count )
+    {
+        MSI_FreeField( &rec->fields[iField] );
+        rec->fields[iField].type = MSIFIELD_INT;
+        rec->fields[iField].u.iVal = iVal;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal )
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %u %d\n", handle, iField, iVal);
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+
+    ret = MSI_RecordSetInteger( rec, iField, iVal );
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+BOOL MSI_RecordIsNull( MSIRECORD *rec, unsigned int iField )
+{
+    BOOL r = TRUE;
+
+    TRACE("%p %d\n", rec, iField );
+
+    r = ( iField > rec->count ) ||
+        ( rec->fields[iField].type == MSIFIELD_NULL );
+
+    return r;
+}
+
+BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d\n", handle, iField );
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_RecordIsNull( rec, iField );
+    msiobj_release( &rec->hdr );
+    return ret;
+
+}
+
+UINT MSI_RecordGetStringA(MSIRECORD *rec, unsigned int iField, 
+               LPSTR szValue, DWORD *pcchValue)
+{
+    UINT len=0, ret;
+    CHAR buffer[16];
+
+    TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
+
+    if( iField > rec->count )
+        return ERROR_INVALID_PARAMETER;
+
+    ret = ERROR_SUCCESS;
+    switch( rec->fields[iField].type )
+    {
+    case MSIFIELD_INT:
+        wsprintfA(buffer, "%d", rec->fields[iField].u.iVal);
+        len = lstrlenA( buffer );
+        lstrcpynA(szValue, buffer, *pcchValue);
+        break;
+    case MSIFIELD_WSTR:
+        len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
+                             NULL, 0 , NULL, NULL);
+        WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
+                             szValue, *pcchValue, NULL, NULL);
+        break;
+    case MSIFIELD_NULL:
+        len = 1;
+        if( *pcchValue > 0 )
+            szValue[0] = 0;
+        break;
+    default:
+        ret = ERROR_INVALID_PARAMETER;
+        break;
+    }
+
+    if( *pcchValue < len )
+        ret = ERROR_MORE_DATA;
+    *pcchValue = len;
+
+    return ret;
+}
+
+UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField, 
+               LPSTR szValue, DWORD *pcchValue)
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d %p %p\n", handle, iField, szValue, pcchValue);
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_RecordGetStringA( rec, iField, szValue, pcchValue);
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+const WCHAR *MSI_RecordGetString( MSIRECORD *rec, unsigned int iField )
+{
+    if( iField > rec->count )
+        return NULL;
+
+    if( rec->fields[iField].type != MSIFIELD_WSTR )
+        return NULL;
+
+    return rec->fields[iField].u.szwVal;
+}
+
+UINT MSI_RecordGetStringW(MSIRECORD *rec, unsigned int iField,
+               LPWSTR szValue, DWORD *pcchValue)
+{
+    UINT len=0, ret;
+    WCHAR buffer[16];
+    static const WCHAR szFormat[] = { '%','d',0 };
+
+    TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
+
+    if( iField > rec->count )
+        return ERROR_INVALID_PARAMETER;
+
+    ret = ERROR_SUCCESS;
+    switch( rec->fields[iField].type )
+    {
+    case MSIFIELD_INT:
+        wsprintfW(buffer, szFormat, rec->fields[iField].u.iVal);
+        len = lstrlenW( buffer );
+        lstrcpynW(szValue, buffer, *pcchValue);
+        break;
+    case MSIFIELD_WSTR:
+        len = lstrlenW( rec->fields[iField].u.szwVal );
+        lstrcpynW(szValue, rec->fields[iField].u.szwVal, *pcchValue);
+        break;
+    case MSIFIELD_NULL:
+        len = 1;
+        if( *pcchValue > 0 )
+            szValue[0] = 0;
+    default:
+        break;
+    }
+
+    if( *pcchValue < len )
+        ret = ERROR_MORE_DATA;
+    *pcchValue = len;
+
+    return ret;
+}
+
+UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, unsigned int iField,
+               LPWSTR szValue, DWORD *pcchValue)
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d %p %p\n", handle, iField, szValue, pcchValue);
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+
+    ret = MSI_RecordGetStringW( rec, iField, szValue, pcchValue );
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+UINT WINAPI MsiRecordDataSize(MSIHANDLE hRecord, unsigned int iField)
+{
+    FIXME("%ld %d\n", hRecord, iField);
+    return 0;
+}
+
+UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
+{
+    LPWSTR str;
+    UINT len;
+
+    TRACE("%p %d %s\n", rec, iField, debugstr_a(szValue));
+
+    if( iField > rec->count )
+        return ERROR_INVALID_FIELD;
+
+    len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
+    str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+    MultiByteToWideChar( CP_ACP, 0, szValue, -1, str, len );
+    MSI_FreeField( &rec->fields[iField] );
+    rec->fields[iField].type = MSIFIELD_WSTR;
+    rec->fields[iField].u.szwVal = str;
+
+    return 0;
+}
+
+UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, unsigned int iField, LPCSTR szValue )
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d %s\n", handle, iField, debugstr_a(szValue));
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_RecordSetStringA( rec, iField, szValue );
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+UINT MSI_RecordSetStringW( MSIRECORD *rec, unsigned int iField, LPCWSTR szValue )
+{
+    LPWSTR str;
+    UINT len;
+
+    TRACE("%p %d %s\n", rec, iField, debugstr_w(szValue));
+
+    if( iField > rec->count )
+        return ERROR_INVALID_FIELD;
+
+    len = lstrlenW(szValue) + 1;
+    str = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR));
+    lstrcpyW( str, szValue );
+
+    MSI_FreeField( &rec->fields[iField] );
+    rec->fields[iField].type = MSIFIELD_WSTR;
+    rec->fields[iField].u.szwVal = str;
+
+    return 0;
+}
+
+UINT WINAPI MsiRecordSetStringW( MSIHANDLE handle, unsigned int iField, LPCWSTR szValue )
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d %s\n", handle, iField, debugstr_w(szValue));
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+
+    ret = MSI_RecordSetStringW( rec, iField, szValue );
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+UINT WINAPI MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, LPSTR szResult, DWORD *sz)
+{
+    FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, LPWSTR szResult, DWORD *sz)
+{
+    FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR szFilename)
+{
+    FIXME("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiRecordSetStreamW(MSIHANDLE hRecord, unsigned int iField, LPCWSTR szFilename)
+{
+    FIXME("%ld %d %s\n", hRecord, iField, debugstr_w(szFilename));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD *sz)
+{
+    ULONG count;
+    HRESULT r;
+    IStream *stm;
+
+    TRACE("%p %d %p %p\n", rec, iField, buf, sz);
+
+    if( iField > rec->count )
+        return ERROR_INVALID_FIELD;
+
+    if( rec->fields[iField].type != MSIFIELD_STREAM )
+    {
+        *sz = 0;
+        return ERROR_INVALID_FIELD;
+    }
+
+    stm = rec->fields[iField].u.stream;
+    if( !stm )
+        return ERROR_INVALID_FIELD;
+
+    /* if there's no buffer pointer, calculate the length to the end */
+    if( !buf )
+    {
+        LARGE_INTEGER ofs;
+        ULARGE_INTEGER end, cur;
+
+        ofs.QuadPart = cur.QuadPart = 0;
+        end.QuadPart = 0;
+        r = IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
+        IStream_Seek( stm, ofs, STREAM_SEEK_END, &end );
+        ofs.QuadPart = cur.QuadPart;
+        IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
+        *sz = end.QuadPart - cur.QuadPart;
+
+        return ERROR_SUCCESS;
+    }
+
+    /* read the data */
+    count = 0;
+    r = IStream_Read( stm, buf, *sz, &count );
+    if( FAILED( r ) )
+        return ERROR_FUNCTION_FAILED;
+
+    *sz = count;
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, unsigned int iField, char *buf, DWORD *sz)
+{
+    MSIRECORD *rec;
+    UINT ret;
+
+    TRACE("%ld %d %p %p\n", handle, iField, buf, sz);
+
+    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+    if( !rec )
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_RecordReadStream( rec, iField, buf, sz );
+    msiobj_release( &rec->hdr );
+    return ret;
+}
+
+UINT MSI_RecordSetIStream( MSIRECORD *rec, unsigned int iField, IStream *stm )
+{
+    TRACE("%p %d %p\n", rec, iField, stm);
+
+    if( iField > rec->count )
+        return ERROR_INVALID_FIELD;
+
+    MSI_FreeField( &rec->fields[iField] );
+
+    rec->fields[iField].type = MSIFIELD_STREAM;
+    rec->fields[iField].u.stream = stm;
+    IStream_AddRef( stm );
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
regsvr.c added at 1.1.2.1
diff -N regsvr.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ regsvr.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,624 @@
+/*
+ *	self-registerable dll functions for msi.dll
+ *
+ * Copyright (C) 2004 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
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "ole2.h"
+#include "olectl.h"
+
+#include "wine/debug.h"
+
+#include "msi.h"
+#include "initguid.h"
+#include "msipriv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * 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);
+
+/**
+ * @todo: maybe adding typelibs support here
+ * [Software\\Classes\\CLSID\\{000C1090-0000-0000-C000-000000000046}\\TypeLib] 1080380217
+ * @="{000C1092-0000-0000-C000-000000000046}"
+ */
+struct regsvr_coclass {
+    CLSID const *clsid;		/* NULL for end of list */
+    LPCSTR name;		/* can be NULL to omit */
+    LPCSTR iph32;		/* 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, if apartment, iph32 must be set */
+    LPCSTR progid;		/* can be NULL to omit */
+    LPCSTR viprogid;		/* can be NULL to omit */
+    LPCSTR progid_extra;	/* 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 curver_keyname[7] = {
+    'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const iph32_keyname[] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'H', 'a', 'n', 'd', 'l', 'e', 'r',
+    '3', '2', 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 WCHAR const viprogid_keyname[25] = {
+    'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+    'e', 'n', 'd', 'e', 'n', 't', '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 register_progid(WCHAR const *clsid,
+			    char const *progid, char const *curver_progid,
+			    char const *name, char const *extra);
+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->iph32) {
+	    HKEY iph32_key;
+
+	    res = RegCreateKeyExW(clsid_key, iph32_keyname, 0, NULL, 0,
+				  KEY_READ | KEY_WRITE, NULL,
+				  &iph32_key, NULL);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = RegSetValueExA(iph32_key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)list->iph32,
+				 lstrlenA(list->iph32) + 1);
+	    RegCloseKey(iph32_key);
+	    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->progid) {
+	    res = register_key_defvalueA(clsid_key, progid_keyname,
+					 list->progid);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = register_progid(buf, list->progid, NULL,
+				  list->name, list->progid_extra);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->viprogid) {
+	    res = register_key_defvalueA(clsid_key, viprogid_keyname,
+					 list->viprogid);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = register_progid(buf, list->viprogid, list->progid,
+				  list->name, list->progid_extra);
+	    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;
+	}
+
+	if (list->viprogid) {
+	    res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
+	    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;
+}
+
+/***********************************************************************
+ *		regsvr_progid
+ */
+static LONG register_progid(
+    WCHAR const *clsid,
+    char const *progid,
+    char const *curver_progid,
+    char const *name,
+    char const *extra) {
+    LONG res;
+    HKEY progid_key;
+
+    res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+			  NULL, 0, KEY_READ | KEY_WRITE, NULL,
+			  &progid_key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+
+    if (name) {
+	res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+			     (CONST BYTE*)name, strlen(name) + 1);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (clsid) {
+	res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (curver_progid) {
+	res = register_key_defvalueA(progid_key, curver_keyname,
+				     curver_progid);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (extra) {
+	HKEY extra_key;
+
+	res = RegCreateKeyExA(progid_key, extra, 0,
+			      NULL, 0, KEY_READ | KEY_WRITE, NULL,
+			      &extra_key, NULL);
+	if (res == ERROR_SUCCESS)
+	    RegCloseKey(extra_key);
+    }
+
+error_close_progid_key:
+    RegCloseKey(progid_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_IMsiServer,
+	"Msi install server",
+	"ole32.dll",
+	NULL,
+	"msi.dll",
+	"Apartment",
+	"WindowsInstaller.Installer",
+	NULL
+    },    
+    {     
+        &CLSID_IMsiServerMessage,
+	"Wine Installer Message RPC",
+	NULL,
+	NULL,
+	"msi.dll",
+	NULL,
+	"WindowsInstaller.Message",
+	NULL
+    },
+    {     
+        &CLSID_IMsiServerX1,
+	"Msi install server",
+	"ole32.dll",
+	NULL,
+	"msi.dll",
+	"Apartment",
+	"WindowsInstaller.Installer",
+	NULL
+    },
+    {     
+        &CLSID_IMsiServerX2,
+	"Msi install server",
+	"ole32.dll",
+	NULL,
+	"msi.dll",
+	"Apartment",
+	"WindowsInstaller.Installer",
+	NULL
+    },
+    {     
+        &CLSID_IMsiServerX3,
+	"Msi install server",
+	"ole32.dll",
+	NULL,
+	"msi.dll",
+	"Apartment",
+	"WindowsInstaller.Installer",
+        NULL
+    },
+    { NULL }			/* list terminator */
+};
+
+/***********************************************************************
+ *		interface list
+ */
+/*
+ * we should declare: (@see ole32/regsvr.c for examples)
+ [-HKEY_CLASSES_ROOT\Interface\{000C101C-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C101D-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C1025-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C1033-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C1090-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C1093-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C1095-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109A-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109B-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109C-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109D-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109E-0000-0000-C000-000000000046}] 
+ [-HKEY_CLASSES_ROOT\Interface\{000C109F-0000-0000-C000-000000000046}]
+*/
+static struct regsvr_interface const interface_list[] = {
+    { NULL }			/* list terminator */
+};
+
+/***********************************************************************
+ *		DllRegisterServer
+ */
+HRESULT WINAPI MSI_DllRegisterServer(void) {
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = register_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+	hr = register_interfaces(interface_list);
+    return hr;
+}
+
+/***********************************************************************
+ *		DllUnregisterServer
+ */
+HRESULT WINAPI MSI_DllUnregisterServer(void) {
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = unregister_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+	hr = unregister_interfaces(interface_list);
+    return hr;
+}

reactos/lib/msi
select.c added at 1.1.2.1
diff -N select.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ select.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,290 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSISELECTVIEW
+{
+    MSIVIEW        view;
+    MSIDATABASE   *db;
+    MSIVIEW       *table;
+    UINT           num_cols;
+    UINT           max_cols;
+    UINT           cols[1];
+} MSISELECTVIEW;
+
+static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %d %d %p\n", sv, row, col, val );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( (col==0) || (col>sv->num_cols) )
+         return ERROR_FUNCTION_FAILED;
+
+    col = sv->cols[ col - 1 ];
+
+    return sv->table->ops->fetch_int( sv->table, row, col, val );
+}
+
+static UINT SELECT_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %d %d %p\n", sv, row, col, stm );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( (col==0) || (col>sv->num_cols) )
+         return ERROR_FUNCTION_FAILED;
+
+    col = sv->cols[ col - 1 ];
+
+    return sv->table->ops->fetch_stream( sv->table, row, col, stm );
+}
+
+static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %d %d %04x\n", sv, row, col, val );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( (col==0) || (col>sv->num_cols) )
+         return ERROR_FUNCTION_FAILED;
+
+    col = sv->cols[ col - 1 ];
+
+    return sv->table->ops->set_int( sv->table, row, col, val );
+}
+
+static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *num )  
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %p\n", sv, num );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return sv->table->ops->insert_row( sv->table, num );
+}
+
+static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %p\n", sv, record);
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return sv->table->ops->execute( sv->table, record );
+}
+
+static UINT SELECT_close( struct tagMSIVIEW *view )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p\n", sv );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return sv->table->ops->close( sv->table );
+}
+
+static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %p %p\n", sv, rows, cols );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( cols )
+        *cols = sv->num_cols;
+
+    return sv->table->ops->get_dimensions( sv->table, rows, NULL );
+}
+
+static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %d %p %p\n", sv, n, name, type );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( (n==0) || (n>sv->num_cols) )
+         return ERROR_FUNCTION_FAILED;
+
+    n = sv->cols[ n - 1 ];
+
+    return sv->table->ops->get_column_info( sv->table, n, name, type );
+}
+
+static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p %d %ld\n", sv, eModifyMode, hrec );
+
+    if( !sv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return sv->table->ops->modify( sv->table, eModifyMode, hrec );
+}
+
+static UINT SELECT_delete( struct tagMSIVIEW *view )
+{
+    MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+    TRACE("%p\n", sv );
+
+    if( sv->table )
+        sv->table->ops->delete( sv->table );
+
+    HeapFree( GetProcessHeap(), 0, sv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS select_ops =
+{
+    SELECT_fetch_int,
+    SELECT_fetch_stream,
+    SELECT_set_int,
+    SELECT_insert_row,
+    SELECT_execute,
+    SELECT_close,
+    SELECT_get_dimensions,
+    SELECT_get_column_info,
+    SELECT_modify,
+    SELECT_delete
+};
+
+static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPWSTR name )
+{
+    UINT r, n=0;
+    MSIVIEW *table;
+
+    TRACE("%p adding %s\n", sv, debugstr_w( name ) );
+
+    if( sv->view.ops != &select_ops )
+        return ERROR_FUNCTION_FAILED;
+
+    table = sv->table;
+    if( !table )
+        return ERROR_FUNCTION_FAILED;
+    if( !table->ops->get_dimensions )
+        return ERROR_FUNCTION_FAILED;
+    if( !table->ops->get_column_info )
+        return ERROR_FUNCTION_FAILED;
+
+    if( sv->num_cols >= sv->max_cols )
+        return ERROR_FUNCTION_FAILED;
+
+    r = VIEW_find_column( table, name, &n );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    sv->cols[sv->num_cols] = n;
+    TRACE("Translating column %s from %d -> %d\n", 
+          debugstr_w( name ), sv->num_cols, n);
+
+    sv->num_cols++;
+
+    return ERROR_SUCCESS;
+}
+
+UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+                        string_list *columns )
+{
+    MSISELECTVIEW *sv = NULL;
+    UINT count = 0, r;
+
+    TRACE("%p\n", sv );
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("can't get table dimensions\n");
+        return r;
+    }
+
+    sv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                    sizeof *sv + count*sizeof (UINT) );
+    if( !sv )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    sv->view.ops = &select_ops;
+    sv->db = db;
+    sv->table = table;
+    sv->num_cols = 0;
+    sv->max_cols = count;
+
+    while( columns )
+    {
+        r = SELECT_AddColumn( sv, columns->string );
+        if( r )
+            break;
+        columns = columns->next;
+    }
+
+    if( r != ERROR_SUCCESS )
+    {
+        sv->view.ops->delete( &sv->view );
+        sv = NULL;
+    }
+
+    *view = &sv->view;
+
+    return r;
+}

reactos/lib/msi
sql.tab.c added at 1.1.2.1
diff -N sql.tab.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sql.tab.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,2180 @@
+/* A Bison parser, made from ./sql.y
+   by GNU bison 1.35.  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define yyparse SQL_parse
+#define yylex SQL_lex
+#define yyerror SQL_error
+#define yylval SQL_lval
+#define yychar SQL_char
+#define yydebug SQL_debug
+#define yynerrs SQL_nerrs
+# define	TK_ABORT	257
+# define	TK_AFTER	258
+# define	TK_AGG_FUNCTION	259
+# define	TK_ALL	260
+# define	TK_AND	261
+# define	TK_AS	262
+# define	TK_ASC	263
+# define	TK_BEFORE	264
+# define	TK_BEGIN	265
+# define	TK_BETWEEN	266
+# define	TK_BITAND	267
+# define	TK_BITNOT	268
+# define	TK_BITOR	269
+# define	TK_BY	270
+# define	TK_CASCADE	271
+# define	TK_CASE	272
+# define	TK_CHAR	273
+# define	TK_CHECK	274
+# define	TK_CLUSTER	275
+# define	TK_COLLATE	276
+# define	TK_COLUMN	277
+# define	TK_COMMA	278
+# define	TK_COMMENT	279
+# define	TK_COMMIT	280
+# define	TK_CONCAT	281
+# define	TK_CONFLICT	282
+# define	TK_CONSTRAINT	283
+# define	TK_COPY	284
+# define	TK_CREATE	285
+# define	TK_DEFAULT	286
+# define	TK_DEFERRABLE	287
+# define	TK_DEFERRED	288
+# define	TK_DELETE	289
+# define	TK_DELIMITERS	290
+# define	TK_DESC	291
+# define	TK_DISTINCT	292
+# define	TK_DOT	293
+# define	TK_DROP	294
+# define	TK_EACH	295
+# define	TK_ELSE	296
+# define	TK_END	297
+# define	TK_END_OF_FILE	298
+# define	TK_EQ	299
+# define	TK_EXCEPT	300
+# define	TK_EXPLAIN	301
+# define	TK_FAIL	302
+# define	TK_FLOAT	303
+# define	TK_FOR	304
+# define	TK_FOREIGN	305
+# define	TK_FROM	306
+# define	TK_FUNCTION	307
+# define	TK_GE	308
+# define	TK_GLOB	309
+# define	TK_GROUP	310
+# define	TK_GT	311
+# define	TK_HAVING	312
+# define	TK_HOLD	313
+# define	TK_IGNORE	314
+# define	TK_ILLEGAL	315
+# define	TK_IMMEDIATE	316
+# define	TK_IN	317
+# define	TK_INDEX	318
+# define	TK_INITIALLY	319
+# define	TK_ID	320
+# define	TK_INSERT	321
+# define	TK_INSTEAD	322
+# define	TK_INT	323
+# define	TK_INTEGER	324
+# define	TK_INTERSECT	325
+# define	TK_INTO	326
+# define	TK_IS	327
+# define	TK_ISNULL	328
+# define	TK_JOIN	329
+# define	TK_JOIN_KW	330
+# define	TK_KEY	331
+# define	TK_LE	332
+# define	TK_LIKE	333
+# define	TK_LIMIT	334
+# define	TK_LONG	335
+# define	TK_LONGCHAR	336
+# define	TK_LP	337
+# define	TK_LSHIFT	338
+# define	TK_LT	339
+# define	TK_LOCALIZABLE	340
+# define	TK_MATCH	341
+# define	TK_MINUS	342
+# define	TK_NE	343
+# define	TK_NOT	344
+# define	TK_NOTNULL	345
+# define	TK_NULL	346
+# define	TK_OBJECT	347
+# define	TK_OF	348
+# define	TK_OFFSET	349
+# define	TK_ON	350
+# define	TK_OR	351
+# define	TK_ORACLE_OUTER_JOIN	352
+# define	TK_ORDER	353
+# define	TK_PLUS	354
+# define	TK_PRAGMA	355
+# define	TK_PRIMARY	356
+# define	TK_RAISE	357
+# define	TK_REFERENCES	358
+# define	TK_REM	359
+# define	TK_REPLACE	360
+# define	TK_RESTRICT	361
+# define	TK_ROLLBACK	362
+# define	TK_ROW	363
+# define	TK_RP	364
+# define	TK_RSHIFT	365
+# define	TK_SELECT	366
+# define	TK_SEMI	367
+# define	TK_SET	368
+# define	TK_SHORT	369
+# define	TK_SLASH	370
+# define	TK_SPACE	371
+# define	TK_STAR	372
+# define	TK_STATEMENT	373
+# define	TK_STRING	374
+# define	TK_TABLE	375
+# define	TK_TEMP	376
+# define	TK_THEN	377
+# define	TK_TRANSACTION	378
+# define	TK_TRIGGER	379
+# define	TK_UMINUS	380
+# define	TK_UNCLOSED_STRING	381
+# define	TK_UNION	382
+# define	TK_UNIQUE	383
+# define	TK_UPDATE	384
+# define	TK_UPLUS	385
+# define	TK_USING	386
+# define	TK_VACUUM	387
+# define	TK_VALUES	388
+# define	TK_VIEW	389
+# define	TK_WHEN	390
+# define	TK_WHERE	391
+# define	TK_WILDCARD	392
+# define	END_OF_FILE	393
+# define	ILLEGAL	394
+# define	SPACE	395
+# define	UNCLOSED_STRING	396
+# define	COMMENT	397
+# define	FUNCTION	398
+# define	COLUMN	399
+
+#line 1 "./sql.y"
+
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "query.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+extern int SQL_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_SQL_input
+{
+    MSIDATABASE *db;
+    LPCWSTR command;
+    DWORD n, len;
+    MSIVIEW **view;  /* view structure for the resulting query */
+} SQL_input;
+
+static LPWSTR SQL_getstring( struct sql_str *str );
+static INT SQL_getint( SQL_input *sql );
+static int SQL_lex( void *SQL_lval, SQL_input *info);
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, 
+                               string_list *columns );
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, 
+                             string_list *columns );
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+                                 string_list *keys);
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_column( LPWSTR );
+static struct expr * EXPR_ival( struct sql_str *);
+static struct expr * EXPR_sval( struct sql_str *);
+static struct expr * EXPR_wildcard();
+
+
+#line 73 "./sql.y"
+#ifndef YYSTYPE
+typedef union
+{
+    struct sql_str str;
+    LPWSTR string;
+    string_list *column_list;
+    value_list *val_list;
+    MSIVIEW *query;
+    struct expr *expr;
+    USHORT column_type;
+    create_col_info *column_info;
+    column_assignment update_col_info;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define	YYFINAL		121
+#define	YYFLAG		-32768
+#define	YYNTBASE	147
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 400 ? yytranslate[x] : 171)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const short yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     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,    53,    54,    55,
+      56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
+      66,    67,    68,    69,    70,    71,    72,    73,    74,    75,
+      76,    77,    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
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+       0,     0,     2,     4,     6,     8,    19,    31,    38,    46,
+      53,    58,    63,    66,    68,    71,    73,    77,    79,    84,
+      86,    88,    90,    92,    94,    96,   101,   103,   107,   112,
+     114,   118,   120,   123,   128,   132,   136,   140,   144,   148,
+     152,   156,   160,   164,   168,   172,   177,   179,   181,   183,
+     187,   189,   193,   197,   199,   201,   203,   205,   209,   211,
+     213,   215
+};
+static const short yyrhs[] =
+{
+     157,     0,   149,     0,   148,     0,   150,     0,    67,    72,
+     169,    83,   159,   110,   134,    83,   163,   110,     0,    67,
+      72,   169,    83,   159,   110,   134,    83,   163,   110,   122,
+       0,    31,   121,   169,    83,   151,   110,     0,    31,   121,
+     169,    83,   151,   110,    59,     0,   130,   169,   114,   164,
+     137,   161,     0,   152,   102,    77,   159,     0,   152,    24,
+     168,   153,     0,   168,   153,     0,   154,     0,   154,    86,
+       0,   155,     0,   155,    90,    92,     0,    19,     0,    19,
+      83,   156,   110,     0,    82,     0,   115,     0,    69,     0,
+      81,     0,    93,     0,    70,     0,   158,    99,    16,   159,
+       0,   158,     0,   112,   159,   160,     0,   112,    38,   159,
+     160,     0,   168,     0,   168,    24,   159,     0,   118,     0,
+      52,   169,     0,    52,   169,   137,   161,     0,    83,   161,
+     110,     0,   167,    45,   167,     0,   161,     7,   161,     0,
+     161,    97,   161,     0,   167,    45,   162,     0,   167,    57,
+     162,     0,   167,    85,   162,     0,   167,    78,   162,     0,
+     167,    54,   162,     0,   167,    89,   162,     0,   167,    73,
+      92,     0,   167,    73,    90,    92,     0,   167,     0,   166,
+       0,   166,     0,   163,    24,   166,     0,   165,     0,   165,
+      24,   164,     0,   168,    45,   166,     0,    70,     0,   120,
+       0,   138,     0,   168,     0,   169,    39,   170,     0,   170,
+       0,   170,     0,    66,     0,   120,     0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+       0,   141,   147,   152,   157,   164,   173,   183,   194,   206,
+     217,   227,   247,   258,   263,   270,   275,   281,   286,   290,
+     294,   298,   302,   306,   312,   323,   335,   338,   353,   370,
+     384,   397,   403,   415,   433,   438,   442,   446,   450,   454,
+     458,   462,   466,   470,   474,   478,   484,   486,   489,   502,
+     517,   519,   527,   543,   548,   552,   558,   565,   570,   576,
+     583,   588
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+  "$", "error", "$undefined.", "TK_ABORT", "TK_AFTER", "TK_AGG_FUNCTION", 
+  "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", "TK_BEGIN", 
+  "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY", 
+  "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER", 
+  "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT", 
+  "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE", 
+  "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE", 
+  "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP", 
+  "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT", 
+  "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM", 
+  "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING", 
+  "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN", 
+  "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", 
+  "TK_INT", "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", 
+  "TK_JOIN", "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", 
+  "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", 
+  "TK_LOCALIZABLE", "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", 
+  "TK_NOTNULL", "TK_NULL", "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", 
+  "TK_OR", "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", 
+  "TK_PRIMARY", "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", 
+  "TK_RESTRICT", "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", 
+  "TK_SELECT", "TK_SEMI", "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", 
+  "TK_STAR", "TK_STATEMENT", "TK_STRING", "TK_TABLE", "TK_TEMP", 
+  "TK_THEN", "TK_TRANSACTION", "TK_TRIGGER", "TK_UMINUS", 
+  "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", "TK_UPDATE", "TK_UPLUS", 
+  "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", "TK_WHEN", "TK_WHERE", 
+  "TK_WILDCARD", "END_OF_FILE", "ILLEGAL", "SPACE", "UNCLOSED_STRING", 
+  "COMMENT", "FUNCTION", "COLUMN", "AGG_FUNCTION.", "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
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+       0,   147,   147,   147,   147,   148,   148,   149,   149,   150,
+     151,   152,   152,   153,   153,   154,   154,   155,   155,   155,
+     155,   155,   155,   155,   156,   157,   157,   158,   158,   159,
+     159,   159,   160,   160,   161,   161,   161,   161,   161,   161,
+     161,   161,   161,   161,   161,   161,   162,   162,   163,   163,
+     164,   164,   165,   166,   166,   166,   167,   168,   168,   169,
+     170,   170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+       0,     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,     1,     1,     1,     3,     1,     1,
+       1,     1
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+   doesn't specify something else to do.  Zero means the default is an
+   error. */
+static const short yydefact[] =
+{
+       0,     0,     0,     0,     0,     3,     2,     4,     1,    26,
+       0,     0,     0,    60,    31,    61,     0,    29,     0,    58,
+       0,    59,     0,     0,     0,     0,     0,    27,     0,     0,
+       0,     0,     0,     0,    28,    32,    30,    57,     0,    50,
+       0,    25,     0,     0,     0,     0,     0,     0,     0,     0,
+       7,     0,     0,    17,    21,    22,    19,    23,    20,    12,
+      13,    15,     0,     0,    33,     0,    56,     9,    51,    53,
+      54,    55,    52,     8,     0,     0,     0,    14,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      11,    10,    24,     0,    16,     0,    34,    36,    37,    54,
+      38,    47,    35,    42,    46,    39,     0,    44,    41,    40,
+      43,    18,     0,    48,    45,     0,     5,    49,     6,     0,
+       0,     0
+};
+
+static const short yydefgoto[] =
+{
+     119,     5,     6,     7,    42,    43,    59,    60,    61,    93,
+       8,     9,    16,    27,    64,   100,   112,    38,    39,   101,
+      65,    66,    18,    19
+};
+
+static const short yypact[] =
+{
+     -30,  -113,   -49,   -34,   -50,-32768,-32768,-32768,-32768,   -79,
+     -50,   -50,   -52,-32768,-32768,-32768,   -25,     4,   -10,     0,
+     -72,-32768,    30,   -36,   -35,   -25,   -50,-32768,   -52,   -50,
+     -50,   -52,   -50,   -52,-32768,   -87,-32768,-32768,   -84,    33,
+      13,-32768,   -51,   -15,   -17,   -41,   -53,   -53,   -50,   -58,
+       1,   -50,    -5,    -8,-32768,-32768,-32768,-32768,-32768,-32768,
+     -13,    -9,   -57,   -53,    -4,    47,-32768,    -4,-32768,-32768,
+  -32768,-32768,-32768,-32768,   -17,   -52,    18,-32768,    -3,    11,
+      -7,   -53,   -53,   -59,   -59,   -59,   -71,   -59,   -59,   -59,
+  -32768,-32768,-32768,   -14,-32768,   -58,-32768,    -4,    -4,    56,
+  -32768,-32768,-32768,-32768,-32768,-32768,     5,-32768,-32768,-32768,
+  -32768,-32768,   -19,-32768,-32768,   -58,   -23,-32768,-32768,   102,
+     108,-32768
+};
+
+static const short yypgoto[] =
+{
+  -32768,-32768,-32768,-32768,-32768,-32768,    40,-32768,-32768,-32768,
+  -32768,-32768,    10,    93,   -37,    28,-32768,    71,-32768,   -32,
+      22,     3,    14,    45
+};
+
+
+#define	YYLAST		136
+
+
+static const short yytable[] =
+{
+      81,     1,    53,    81,    12,   115,    17,    13,    10,    51,
+      67,    69,    69,    13,    13,    17,    13,    72,    20,   106,
+      22,   107,    25,    11,    23,    24,    80,    26,    28,    29,
+      63,    17,    13,    40,    17,    44,    17,     2,    36,   -59,
+      35,    41,    30,    45,    97,    98,    31,    32,    33,    21,
+      46,    40,    54,    47,    74,    21,    21,    48,    49,    50,
+      73,    99,    70,   113,    55,    56,    14,    15,    15,    62,
+      15,    21,    75,    77,    37,    76,    57,    79,    17,    71,
+      71,    78,     3,   117,    14,    91,    15,    52,    92,    94,
+      82,   116,    83,    82,    95,   -61,   111,   114,    58,   118,
+       4,    84,   120,    96,    85,   102,   104,   104,   121,   104,
+     104,   104,   103,   105,    90,   108,   109,   110,    34,    68,
+      86,     0,     0,     0,     0,    87,     0,     0,     0,     0,
+       0,     0,    88,     0,     0,     0,    89
+};
+
+static const short yycheck[] =
+{
+       7,    31,    19,     7,    38,    24,     3,    66,   121,    24,
+      47,    70,    70,    66,    66,    12,    66,    49,     4,    90,
+      99,    92,    12,    72,    10,    11,    63,    52,    24,    39,
+      83,    28,    66,    30,    31,    32,    33,    67,    28,    39,
+      26,    31,   114,    33,    81,    82,    16,    83,    83,     4,
+     137,    48,    69,   137,    51,    10,    11,    24,    45,   110,
+      59,   120,   120,    95,    81,    82,   118,   120,   120,   110,
+     120,    26,    77,    86,    29,    83,    93,   134,    75,   138,
+     138,    90,   112,   115,   118,    75,   120,   102,    70,    92,
+      97,   110,    45,    97,    83,    39,   110,    92,   115,   122,
+     130,    54,     0,   110,    57,    83,    84,    85,     0,    87,
+      88,    89,    84,    85,    74,    87,    88,    89,    25,    48,
+      73,    -1,    -1,    -1,    -1,    78,    -1,    -1,    -1,    -1,
+      -1,    -1,    85,    -1,    -1,    -1,    89
+};
+#define YYPURE 1
+
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
+
+   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, 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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser when
+   the %semantic_parser declaration is not specified in the grammar.
+   It was written by Richard Stallman by simplifying the hairy parser
+   used when %semantic_parser is specified.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+# if YYLSP_NEEDED
+  YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# if YYLSP_NEEDED
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))	\
+      + 2 * YYSTACK_GAP_MAX)
+# else
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;	\
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");			\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).
+
+   When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+   first token.  By default, to implement support for ranges, extend
+   its range to the last symbol.  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)       	\
+   Current.last_line   = Rhs[N].last_line;	\
+   Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#if YYPURE
+# if YYLSP_NEEDED
+#  ifdef YYLEX_PARAM
+#   define YYLEX		yylex (&yylval, &yylloc, YYLEX_PARAM)
+#  else
+#   define YYLEX		yylex (&yylval, &yylloc)
+#  endif
+# else /* !YYLSP_NEEDED */
+#  ifdef YYLEX_PARAM
+#   define YYLEX		yylex (&yylval, YYLEX_PARAM)
+#  else
+#   define YYLEX		yylex (&yylval)
+#  endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX			yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+#endif
+
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL
+# else
+#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+   variables are global, or local to YYPARSE.  */
+
+#define YY_DECL_NON_LSP_VARIABLES			\
+/* The lookahead symbol.  */				\
+int yychar;						\
+							\
+/* The semantic value of the lookahead symbol. */	\
+YYSTYPE yylval;						\
+							\
+/* Number of parse errors so far.  */			\
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES			\
+YY_DECL_NON_LSP_VARIABLES			\
+						\
+/* Location data for the lookahead symbol.  */	\
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES			\
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  /* If reentrant, generate the variables here. */
+#if YYPURE
+  YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yychar1 = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack. */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+#if YYLSP_NEEDED
+  YYLTYPE yyloc;
+#endif
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule. */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+#if YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+	/* Each stack pointer address is followed by the size of the
[truncated at 1000 lines; 1184 more skipped]

reactos/lib/msi
sql.tab.h added at 1.1.2.1
diff -N sql.tab.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sql.tab.h	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,165 @@
+#ifndef BISON_SQL_TAB_H
+# define BISON_SQL_TAB_H
+
+#ifndef YYSTYPE
+typedef union
+{
+    struct sql_str str;
+    LPWSTR string;
+    string_list *column_list;
+    value_list *val_list;
+    MSIVIEW *query;
+    struct expr *expr;
+    USHORT column_type;
+    create_col_info *column_info;
+    column_assignment update_col_info;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define	TK_ABORT	257
+# define	TK_AFTER	258
+# define	TK_AGG_FUNCTION	259
+# define	TK_ALL	260
+# define	TK_AND	261
+# define	TK_AS	262
+# define	TK_ASC	263
+# define	TK_BEFORE	264
+# define	TK_BEGIN	265
+# define	TK_BETWEEN	266
+# define	TK_BITAND	267
+# define	TK_BITNOT	268
+# define	TK_BITOR	269
+# define	TK_BY	270
+# define	TK_CASCADE	271
+# define	TK_CASE	272
+# define	TK_CHAR	273
+# define	TK_CHECK	274
+# define	TK_CLUSTER	275
+# define	TK_COLLATE	276
+# define	TK_COLUMN	277
+# define	TK_COMMA	278
+# define	TK_COMMENT	279
+# define	TK_COMMIT	280
+# define	TK_CONCAT	281
+# define	TK_CONFLICT	282
+# define	TK_CONSTRAINT	283
+# define	TK_COPY	284
+# define	TK_CREATE	285
+# define	TK_DEFAULT	286
+# define	TK_DEFERRABLE	287
+# define	TK_DEFERRED	288
+# define	TK_DELETE	289
+# define	TK_DELIMITERS	290
+# define	TK_DESC	291
+# define	TK_DISTINCT	292
+# define	TK_DOT	293
+# define	TK_DROP	294
+# define	TK_EACH	295
+# define	TK_ELSE	296
+# define	TK_END	297
+# define	TK_END_OF_FILE	298
+# define	TK_EQ	299
+# define	TK_EXCEPT	300
+# define	TK_EXPLAIN	301
+# define	TK_FAIL	302
+# define	TK_FLOAT	303
+# define	TK_FOR	304
+# define	TK_FOREIGN	305
+# define	TK_FROM	306
+# define	TK_FUNCTION	307
+# define	TK_GE	308
+# define	TK_GLOB	309
+# define	TK_GROUP	310
+# define	TK_GT	311
+# define	TK_HAVING	312
+# define	TK_HOLD	313
+# define	TK_IGNORE	314
+# define	TK_ILLEGAL	315
+# define	TK_IMMEDIATE	316
+# define	TK_IN	317
+# define	TK_INDEX	318
+# define	TK_INITIALLY	319
+# define	TK_ID	320
+# define	TK_INSERT	321
+# define	TK_INSTEAD	322
+# define	TK_INT	323
+# define	TK_INTEGER	324
+# define	TK_INTERSECT	325
+# define	TK_INTO	326
+# define	TK_IS	327
+# define	TK_ISNULL	328
+# define	TK_JOIN	329
+# define	TK_JOIN_KW	330
+# define	TK_KEY	331
+# define	TK_LE	332
+# define	TK_LIKE	333
+# define	TK_LIMIT	334
+# define	TK_LONG	335
+# define	TK_LONGCHAR	336
+# define	TK_LP	337
+# define	TK_LSHIFT	338
+# define	TK_LT	339
+# define	TK_LOCALIZABLE	340
+# define	TK_MATCH	341
+# define	TK_MINUS	342
+# define	TK_NE	343
+# define	TK_NOT	344
+# define	TK_NOTNULL	345
+# define	TK_NULL	346
+# define	TK_OBJECT	347
+# define	TK_OF	348
+# define	TK_OFFSET	349
+# define	TK_ON	350
+# define	TK_OR	351
+# define	TK_ORACLE_OUTER_JOIN	352
+# define	TK_ORDER	353
+# define	TK_PLUS	354
+# define	TK_PRAGMA	355
+# define	TK_PRIMARY	356
+# define	TK_RAISE	357
+# define	TK_REFERENCES	358
+# define	TK_REM	359
+# define	TK_REPLACE	360
+# define	TK_RESTRICT	361
+# define	TK_ROLLBACK	362
+# define	TK_ROW	363
+# define	TK_RP	364
+# define	TK_RSHIFT	365
+# define	TK_SELECT	366
+# define	TK_SEMI	367
+# define	TK_SET	368
+# define	TK_SHORT	369
+# define	TK_SLASH	370
+# define	TK_SPACE	371
+# define	TK_STAR	372
+# define	TK_STATEMENT	373
+# define	TK_STRING	374
+# define	TK_TABLE	375
+# define	TK_TEMP	376
+# define	TK_THEN	377
+# define	TK_TRANSACTION	378
+# define	TK_TRIGGER	379
+# define	TK_UMINUS	380
+# define	TK_UNCLOSED_STRING	381
+# define	TK_UNION	382
+# define	TK_UNIQUE	383
+# define	TK_UPDATE	384
+# define	TK_UPLUS	385
+# define	TK_USING	386
+# define	TK_VACUUM	387
+# define	TK_VALUES	388
+# define	TK_VIEW	389
+# define	TK_WHEN	390
+# define	TK_WHERE	391
+# define	TK_WILDCARD	392
+# define	END_OF_FILE	393
+# define	ILLEGAL	394
+# define	SPACE	395
+# define	UNCLOSED_STRING	396
+# define	COMMENT	397
+# define	FUNCTION	398
+# define	COLUMN	399
+
+
+#endif /* not BISON_SQL_TAB_H */

reactos/lib/msi
sql.y added at 1.1.2.1
diff -N sql.y
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sql.y	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,828 @@
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "query.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+extern int SQL_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_SQL_input
+{
+    MSIDATABASE *db;
+    LPCWSTR command;
+    DWORD n, len;
+    MSIVIEW **view;  /* view structure for the resulting query */
+} SQL_input;
+
+static LPWSTR SQL_getstring( struct sql_str *str );
+static INT SQL_getint( SQL_input *sql );
+static int SQL_lex( void *SQL_lval, SQL_input *info);
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, 
+                               string_list *columns );
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, 
+                             string_list *columns );
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+                                 string_list *keys);
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_column( LPWSTR );
+static struct expr * EXPR_ival( struct sql_str *);
+static struct expr * EXPR_sval( struct sql_str *);
+static struct expr * EXPR_wildcard();
+
+%}
+
+%pure-parser
+
+%union
+{
+    struct sql_str str;
+    LPWSTR string;
+    string_list *column_list;
+    value_list *val_list;
+    MSIVIEW *query;
+    struct expr *expr;
+    USHORT column_type;
+    create_col_info *column_info;
+    column_assignment update_col_info;
+}
+
+%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC
+%token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY
+%token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
+%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT 
+%token TK_CONSTRAINT TK_COPY TK_CREATE
+%token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC
+%token TK_DISTINCT TK_DOT TK_DROP TK_EACH
+%token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN
+%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION
+%token TK_GE TK_GLOB TK_GROUP TK_GT
+%token TK_HAVING TK_HOLD
+%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
+%token <str> TK_ID 
+%token TK_INSERT TK_INSTEAD TK_INT 
+%token <str> TK_INTEGER
+%token TK_INTERSECT TK_INTO TK_IS
+%token TK_ISNULL
+%token TK_JOIN TK_JOIN_KW
+%token TK_KEY
+%token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT
+%token TK_LOCALIZABLE
+%token TK_MATCH TK_MINUS
+%token TK_NE TK_NOT TK_NOTNULL TK_NULL
+%token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
+%token TK_PLUS TK_PRAGMA TK_PRIMARY
+%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
+%token TK_ROW TK_RP TK_RSHIFT
+%token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT 
+%token <str> TK_STRING
+%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER
+%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
+%token TK_UPDATE TK_UPLUS TK_USING
+%token TK_VACUUM TK_VALUES TK_VIEW
+%token TK_WHEN TK_WHERE TK_WILDCARD
+
+/*
+ * These are extra tokens used by the lexer but never seen by the
+ * parser.  We put them in a rule so that the parser generator will
+ * add them to the parse.h output file.
+ *
+ */
+%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
+          COLUMN AGG_FUNCTION.
+
+%type <string> column table string_or_id
+%type <column_list> selcollist
+%type <query> from unorderedsel oneselect onequery onecreate oneinsert oneupdate
+%type <expr> expr val column_val const_val
+%type <column_type> column_type data_type data_type_l data_count
+%type <column_info> column_def table_def
+%type <val_list> constlist
+%type <update_col_info> column_assignment update_assign_list
+
+%%
+
+onequery:
+    oneselect
+    {
+        SQL_input* sql = (SQL_input*) info;
+        *sql->view = $1;
+    }
+  | onecreate
+    {
+        SQL_input* sql = (SQL_input*) info;
+        *sql->view = $1;
+    }
+  | oneinsert
+    {
+        SQL_input* sql = (SQL_input*) info;
+        *sql->view = $1;
+    }
+  | oneupdate
+    {
+        SQL_input* sql = (SQL_input*) info;
+        *sql->view = $1;
+    }
+    ;
+
+oneinsert:
+    TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
+    {
+        SQL_input *sql = (SQL_input*) info;
+        MSIVIEW *insert = NULL; 
+
+        INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); 
+        $$ = insert;
+    }
+  | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP
+    {
+        SQL_input *sql = (SQL_input*) info;
+        MSIVIEW *insert = NULL; 
+
+        INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); 
+        $$ = insert;
+    }
+    ;
+
+onecreate:
+    TK_CREATE TK_TABLE table TK_LP table_def TK_RP
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *create = NULL; 
+
+            if( !$5 )
+                YYABORT;
+            CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
+            $$ = create;
+        }
+  | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *create = NULL; 
+
+            if( !$5 )
+                YYABORT;
+            CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
+            $$ = create;
+        }
+    ;
+
+oneupdate:
+    TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *update = NULL; 
+
+            UPDATE_CreateView( sql->db, &update, $2, &$4, $6 );
+            $$ = update;
+        }
+    ;
+
+table_def:
+    column_def TK_PRIMARY TK_KEY selcollist
+        {
+            if( SQL_MarkPrimaryKeys( $1, $4 ) )
+                $$ = $1;
+            else
+                $$ = NULL;
+        }
+    ;
+
+column_def:
+    column_def TK_COMMA column column_type
+        {
+            create_col_info *ci;
+
+            for( ci = $1; ci->next; ci = ci->next )
+                ;
+
+            ci->next = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
+            if( !ci->next )
+            {
+                /* FIXME: free $1 */
+                YYABORT;
+            }
+            ci->next->colname = $3;
+            ci->next->type = $4;
+            ci->next->next = NULL;
+
+            $$ = $1;
+        }
+  | column column_type
+        {
+            $$ = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
+            if( ! $$ )
+                YYABORT;
+            $$->colname = $1;
+            $$->type = $2;
+            $$->next = NULL;
+        }
+    ;
+
+column_type:
+    data_type_l
+        {
+            $$ = $1 | MSITYPE_VALID;
+        }
+  | data_type_l TK_LOCALIZABLE
+        {
+            FIXME("LOCALIZABLE ignored\n");
+            $$ = $1 | MSITYPE_VALID;
+        }
+    ;
+
+data_type_l:
+    data_type
+        {
+            $$ |= MSITYPE_NULLABLE;
+        }
+  | data_type TK_NOT TK_NULL
+        {
+            $$ = $1;
+        }
+    ;
+
+data_type:
+    TK_CHAR
+        {
+            $$ = MSITYPE_STRING | 1;
+        }
+  | TK_CHAR TK_LP data_count TK_RP
+        {
+            $$ = MSITYPE_STRING | 0x400 | $3;
+        }
+  | TK_LONGCHAR
+        {
+            $$ = 2;
+        }
+  | TK_SHORT
+        {
+            $$ = 2;
+        }
+  | TK_INT
+        {
+            $$ = 2;
+        }
+  | TK_LONG
+        {
+            $$ = 4;
+        }
+  | TK_OBJECT
+        {
+            $$ = 0;
+        }
+    ;
+
+data_count:
+    TK_INTEGER
+        {
+            SQL_input* sql = (SQL_input*) info;
+            int val = SQL_getint(sql);
+            if( ( val > 255 ) || ( val < 0 ) )
+                YYABORT;
+            $$ = val;
+        }
+    ;
+
+oneselect:
+    unorderedsel TK_ORDER TK_BY selcollist
+        {
+            SQL_input* sql = (SQL_input*) info;
+
+            if( !$1 )
+                YYABORT;
+            if( $4 )
+                $$ = do_order_by( sql->db, $1, $4 );
+            else
+                $$ = $1;
+        }
+  | unorderedsel
+    ;
+
+unorderedsel:
+    TK_SELECT selcollist from 
+        {
+            SQL_input* sql = (SQL_input*) info;
+            if( !$3 )
+                YYABORT;
+            if( $2 )
+            {
+                $$ = do_one_select( sql->db, $3, $2 );
+                if( !$$ )
+                    YYABORT;
+            }
+            else
+                $$ = $3;
+        }
+  | TK_SELECT TK_DISTINCT selcollist from 
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *view = $4;
+
+            if( !view )
+                YYABORT;
+            if( $3 )
+            {
+                view = do_one_select( sql->db, view, $3 );
+                if( !view )
+                    YYABORT;
+            }
+            DISTINCT_CreateView( sql->db, & $$, view );
+        }
+    ;
+
+selcollist:
+    column 
+        { 
+            string_list *list;
+
+            list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );
+            if( !list )
+                YYABORT;
+            list->string = $1;
+            list->next = NULL;
+
+            $$ = list;
+            TRACE("Collist %s\n",debugstr_w($$->string));
+        }
+  | column TK_COMMA selcollist
+        { 
+            string_list *list;
+
+            list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );
+            if( !list )
+                YYABORT;
+            list->string = $1;
+            list->next = $3;
+
+            $$ = list;
+            TRACE("From table: %s\n",debugstr_w($$->string));
+        }
+  | TK_STAR
+        {
+            $$ = NULL;
+        }
+    ;
+
+from:
+    TK_FROM table
+        { 
+            SQL_input* sql = (SQL_input*) info;
+            UINT r;
+
+            $$ = NULL;
+            TRACE("From table: %s\n",debugstr_w($2));
+            r = TABLE_CreateView( sql->db, $2, & $$ );
+            if( r != ERROR_SUCCESS )
+                YYABORT;
+        }
+  | TK_FROM table TK_WHERE expr
+        { 
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *view = NULL;
+            UINT r;
+
+            $$ = NULL;
+            TRACE("From table: %s\n",debugstr_w($2));
+            r = TABLE_CreateView( sql->db, $2, &view );
+            if( r != ERROR_SUCCESS )
+                YYABORT;
+            r = WHERE_CreateView( sql->db, &view, view, $4 );
+            if( r != ERROR_SUCCESS )
+                YYABORT;
+            $$ = view;
+        }
+    ;
+
+expr:
+    TK_LP expr TK_RP
+        {
+            $$ = $2;
+        }
+  | column_val TK_EQ column_val
+        {
+            $$ = EXPR_complex( $1, OP_EQ, $3 );
+        }
+  | expr TK_AND expr
+        {
+            $$ = EXPR_complex( $1, OP_AND, $3 );
+        }
+  | expr TK_OR expr
+        {
+            $$ = EXPR_complex( $1, OP_OR, $3 );
+        }
+  | column_val TK_EQ val
+        {
+            $$ = EXPR_complex( $1, OP_EQ, $3 );
+        }
+  | column_val TK_GT val
+        {
+            $$ = EXPR_complex( $1, OP_GT, $3 );
+        }
+  | column_val TK_LT val
+        {
+            $$ = EXPR_complex( $1, OP_LT, $3 );
+        }
+  | column_val TK_LE val
+        {
+            $$ = EXPR_complex( $1, OP_LE, $3 );
+        }
+  | column_val TK_GE val
+        {
+            $$ = EXPR_complex( $1, OP_GE, $3 );
+        }
+  | column_val TK_NE val
+        {
+            $$ = EXPR_complex( $1, OP_NE, $3 );
+        }
+  | column_val TK_IS TK_NULL
+        {
+            $$ = EXPR_complex( $1, OP_ISNULL, NULL );
+        }
+  | column_val TK_IS TK_NOT TK_NULL
+        {
+            $$ = EXPR_complex( $1, OP_NOTNULL, NULL );
+        }
+    ;
+
+val:
+    column_val
+  | const_val
+    ;
+
+constlist:
+    const_val
+        {
+            value_list *vals;
+
+            vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );
+            if( vals )
+            {
+                vals->val = $1;
+                vals->next = NULL;
+            }
+            $$ = vals;
+        }
+  | constlist TK_COMMA const_val
+        {
+            value_list *vals;
+
+            vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );
+            if( vals )
+            {
+                vals->val = $3;
+                vals->next = NULL;
+            }
+            $1->next = vals;
+            $$ = $1;
+        }
+    ;
+
+update_assign_list:
+    column_assignment
+  | column_assignment TK_COMMA update_assign_list
+        {
+            $1.col_list->next = $3.col_list;
+            $1.val_list->next = $3.val_list;
+            $$ = $1;
+        }
+    ;
+
+column_assignment:
+    column TK_EQ const_val
+        {
+            $$.col_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.col_list );
+            if( !$$.col_list )
+                YYABORT;
+            $$.col_list->string = $1;
+            $$.col_list->next = NULL;
+            $$.val_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.val_list );
+            if( !$$.val_list )
+                YYABORT;
+            $$.val_list->val = $3;
+            $$.val_list->next = 0;
+        }
+    ;
+
+const_val:
+    TK_INTEGER
+        {
+            $$ = EXPR_ival( &$1 );
+        }
+  | TK_STRING
+        {
+            $$ = EXPR_sval( &$1 );
+        }
+  | TK_WILDCARD
+        {
+            $$ = EXPR_wildcard();
+        }
+    ;
+
+column_val:
+    column 
+        {
+            $$ = EXPR_column( $1 );
+        }
+    ;
+
+column:
+    table TK_DOT string_or_id
+        {
+            $$ = $3;  /* FIXME */
+        }
+  | string_or_id
+        {
+            $$ = $1;
+        }
+    ;
+
+table:
+    string_or_id
+        {
+            $$ = $1;
+        }
+    ;
+
+string_or_id:
+    TK_ID
+        {
+            $$ = SQL_getstring( &$1 );
+        }
+  | TK_STRING
+        {
+            $$ = SQL_getstring( &$1 );
+        }
+    ;
+
+%%
+
+int SQL_lex( void *SQL_lval, SQL_input *sql)
+{
+    int token;
+    struct sql_str * str = SQL_lval;
+
+    do
+    {
+        sql->n += sql->len;
+        if( ! sql->command[sql->n] )
+            return 0;  /* end of input */
+
+        TRACE("string : %s\n", debugstr_w(&sql->command[sql->n]));
+        sql->len = sqliteGetToken( &sql->command[sql->n], &token );
+        if( sql->len==0 )
+            break;
+        str->data = &sql->command[sql->n];
+        str->len = sql->len;
+    }
+    while( token == TK_SPACE );
+
+    TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len));
+    
+    return token;
+}
+
+LPWSTR SQL_getstring( struct sql_str *strdata)
+{
+    LPCWSTR p = strdata->data;
+    UINT len = strdata->len;
+    LPWSTR str;
+
+    /* if there's quotes, remove them */
+    if( ( (p[0]=='`') && (p[len-1]=='`') ) || 
+        ( (p[0]=='\'') && (p[len-1]=='\'') ) )
+    {
+        p++;
+        len -= 2;
+    }
+    str = HeapAlloc( GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
+    if(!str )
+        return str;
+    memcpy(str, p, len*sizeof(WCHAR) );
+    str[len]=0;
+
+    return str;
+}
+
+INT SQL_getint( SQL_input *sql )
+{
+    LPCWSTR p = &sql->command[sql->n];
+
+    return atoiW( p );
+}
+
+int SQL_error(const char *str)
+{
+    return 0;
+}
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, 
+                               string_list *columns )
+{
+    MSIVIEW *view = NULL;
+
+    SELECT_CreateView( db, &view, in, columns );
+    delete_string_list( columns );
+    if( !view )
+        ERR("Error creating select query\n");
+    return view;
+}
+
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, 
+                             string_list *columns )
+{
+    MSIVIEW *view = NULL;
+
+    ORDER_CreateView( db, &view, in );
+    if( view )
+    {
+        string_list *x = columns;
+
+        for( x = columns; x ; x = x->next )
+            ORDER_AddColumn( view, x->string );
+    }
+    else
+        ERR("Error creating select query\n");
+    delete_string_list( columns );
+    return view;
+}
+
+static struct expr * EXPR_wildcard()
+{
+    struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+    if( e )
+    {
+        e->type = EXPR_WILDCARD;
+    }
+    return e;
+}
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r )
+{
+    struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+    if( e )
+    {
+        e->type = EXPR_COMPLEX;
+        e->u.expr.left = l;
+        e->u.expr.op = op;
+        e->u.expr.right = r;
+    }
+    return e;
+}
+
+static struct expr * EXPR_column( LPWSTR str )
+{
+    struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+    if( e )
+    {
+        e->type = EXPR_COLUMN;
+        e->u.sval = str;
+    }
+    return e;
+}
+
+static struct expr * EXPR_ival( struct sql_str *str )
+{
+    struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+    if( e )
+    {
+        e->type = EXPR_IVAL;
+        e->u.ival = atoiW( str->data );
+    }
+    return e;
+}
+
+static struct expr * EXPR_sval( struct sql_str *str )
+{
+    struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+    if( e )
+    {
+        e->type = EXPR_SVAL;
+        e->u.sval = SQL_getstring( str );
+    }
+    return e;
+}
+
+void delete_expr( struct expr *e )
+{
+    if( !e )
+        return;
+    if( e->type == EXPR_COMPLEX )
+    {
+        delete_expr( e->u.expr.left );
+        delete_expr( e->u.expr.right );
+    }
+    else if( e->type == EXPR_UTF8 )
+        HeapFree( GetProcessHeap(), 0, e->u.utf8 );
+    else if( e->type == EXPR_SVAL )
+        HeapFree( GetProcessHeap(), 0, e->u.sval );
+    HeapFree( GetProcessHeap(), 0, e );
+}
+
+void delete_string_list( string_list *sl )
+{
+    while( sl )
+    {
+        string_list *t = sl->next;
+        HeapFree( GetProcessHeap(), 0, sl->string );
+        HeapFree( GetProcessHeap(), 0, sl );
+        sl = t;
+    }
+}
+
+void delete_value_list( value_list *vl )
+{
+    while( vl )
+    {
+        value_list *t = vl->next;
+        delete_expr( vl->val );
+        HeapFree( GetProcessHeap(), 0, vl );
+        vl = t;
+    }
+}
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+                                 string_list *keys )
+{
+    string_list *k;
+    BOOL found = TRUE;
+
+    for( k = keys; k && found; k = k->next )
+    {
+        create_col_info *c;
+
+        found = FALSE;
+        for( c = cols; c && !found; c = c->next )
+        {
+             if( lstrcmpW( k->string, c->colname ) )
+                 continue;
+             c->type |= MSITYPE_KEY;
+             found = TRUE;
+        }
+    }
+
+    return found;
+}
+
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
+{
+    SQL_input sql;
+    int r;
+
+    *phview = NULL;
+
+    sql.db = db;
+    sql.command = command;
+    sql.n = 0;
+    sql.len = 0;
+    sql.view = phview;
+
+    r = SQL_parse(&sql);
+
+    TRACE("Parse returned %d\n", r);
+    if( r )
+    {
+        if( *sql.view )
+            (*sql.view)->ops->delete( *sql.view );
+        *sql.view = NULL;
+        return ERROR_BAD_QUERY_SYNTAX;
+    }
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
string.c added at 1.1.2.1
diff -N string.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ string.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,459 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#include <stdarg.h>
+#include <assert.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.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);
+
+typedef struct _msistring
+{
+    UINT hash;
+    UINT refcount;
+    LPWSTR str;
+} msistring;
+
+struct string_table
+{
+    UINT maxcount;         /* the number of strings */
+    UINT freeslot;
+    UINT codepage;
+    msistring *strings; /* an array of strings (in the tree) */
+};
+
+static UINT msistring_makehash( const WCHAR *str )
+{
+    UINT hash = 0;
+
+    if (str==NULL)
+        return hash;
+
+    while( *str )
+    {
+        hash ^= *str++;
+        hash *= 53;
+        hash = (hash<<5) | (hash>>27);
+    }
+    return hash;
+}
+
+string_table *msi_init_stringtable( int entries, UINT codepage )
+{
+    string_table *st;
+
+    st = HeapAlloc( GetProcessHeap(), 0, sizeof (string_table) );
+    if( !st )
+        return NULL;    
+    st->strings = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                              sizeof (msistring) * entries );
+    if( !st )
+    {
+        HeapFree( GetProcessHeap(), 0, st );
+        return NULL;    
+    }
+    if( entries < 1 )
+        entries = 1;
+    st->maxcount = entries;
+    st->freeslot = 1;
+    st->codepage = codepage;
+
+    return st;
+}
+
+VOID msi_destroy_stringtable( string_table *st )
+{
+    UINT i;
+
+    for( i=0; i<st->maxcount; i++ )
+    {
+        if( st->strings[i].refcount )
+            HeapFree( GetProcessHeap(), 0, st->strings[i].str );
+    }
+    HeapFree( GetProcessHeap(), 0, st->strings );
+    HeapFree( GetProcessHeap(), 0, st );
+}
+
+static int st_find_free_entry( string_table *st )
+{
+    UINT i, sz;
+    msistring *p;
+
+    TRACE("%p\n", st);
+
+    if( st->freeslot )
+    {
+        for( i = st->freeslot; i < st->maxcount; i++ )
+            if( !st->strings[i].refcount )
+                return i;
+    }
+    for( i = 1; i < st->maxcount; i++ )
+        if( !st->strings[i].refcount )
+            return i;
+
+    /* dynamically resize */
+    sz = st->maxcount + 1 + st->maxcount/2;
+    p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                     st->strings, sz*sizeof(msistring) );
+    if( !p )
+        return -1;
+    st->strings = p;
+    st->freeslot = st->maxcount;
+    st->maxcount = sz;
+    if( st->strings[st->freeslot].refcount )
+        ERR("oops. expected freeslot to be free...\n");
+    return st->freeslot;
+}
+
+static void st_mark_entry_used( string_table *st, UINT n )
+{
+    if( n >= st->maxcount )
+        return;
+    st->freeslot = n + 1;
+}
+
+int msi_addstring( string_table *st, int n, const CHAR *data, int len, UINT refcount )
+{
+    int sz;
+
+    if( !data )
+        return 0;
+    if( !data[0] )
+        return 0;
+    if( n > 0 )
+    {
+        if( st->strings[n].refcount )
+            return -1;
+    }
+    else
+    {
+        if( ERROR_SUCCESS == msi_string2idA( st, data, &n ) )
+        {
+            st->strings[n].refcount++;
+            return n;
+        }
+        n = st_find_free_entry( st );
+        if( n < 0 )
+            return -1;
+    }
+
+    if( n < 1 )
+    {
+        ERR("invalid index adding %s (%d)\n", debugstr_a( data ), n );
+        return -1;
+    }
+
+    /* allocate a new string */
+    if( len < 0 )
+        len = strlen(data);
+    sz = MultiByteToWideChar( st->codepage, 0, data, len, NULL, 0 );
+    st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (sz+1)*sizeof(WCHAR) );
+    if( !st->strings[n].str )
+        return -1;
+    MultiByteToWideChar( st->codepage, 0, data, len, st->strings[n].str, sz );
+    st->strings[n].str[sz] = 0;
+    st->strings[n].refcount = 1;
+    st->strings[n].hash = msistring_makehash( st->strings[n].str );
+
+    st_mark_entry_used( st, n );
+
+    return n;
+}
+
+int msi_addstringW( string_table *st, int n, const WCHAR *data, int len, UINT refcount )
+{
+    /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
+
+    if( !data )
+        return 0;
+    if( !data[0] )
+        return 0;
+    if( n > 0 )
+    {
+        if( st->strings[n].refcount )
+            return -1;
+    }
+    else
+    {
+        if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) )
+        {
+            st->strings[n].refcount++;
+            return n;
+        }
+        n = st_find_free_entry( st );
+        if( n < 0 )
+            return -1;
+    }
+
+    if( n < 1 )
+    {
+        ERR("invalid index adding %s (%d)\n", debugstr_w( data ), n );
+        return -1;
+    }
+
+    /* allocate a new string */
+    if(len<0)
+        len = strlenW(data);
+    TRACE("%s, n = %d len = %d\n", debugstr_w(data), n, len );
+
+    st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
+    if( !st->strings[n].str )
+        return -1;
+    TRACE("%d\n",__LINE__);
+    memcpy( st->strings[n].str, data, len*sizeof(WCHAR) );
+    st->strings[n].str[len] = 0;
+    st->strings[n].refcount = 1;
+    st->strings[n].hash = msistring_makehash( st->strings[n].str );
+
+    st_mark_entry_used( st, n );
+
+    return n;
+}
+
+/* find the string identified by an id - return null if there's none */
+const WCHAR *msi_string_lookup_id( string_table *st, UINT id )
+{
+    static const WCHAR zero[] = { 0 };
+    if( id == 0 )
+        return zero;
+
+    if( id >= st->maxcount )
+        return NULL;
+
+    if( id && !st->strings[id].refcount )
+        return NULL;
+
+    return st->strings[id].str;
+}
+
+/*
+ *  msi_id2stringW
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] id  - id of the string to retrieve
+ *  [out] buffer    - destination of the string
+ *  [in/out] sz     - number of bytes available in the buffer on input
+ *                    number of bytes used on output
+ *
+ *   The size includes the terminating nul character.  Short buffers
+ *  will be filled, but not nul terminated.
+ */
+UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
+{
+    UINT len;
+    const WCHAR *str;
+
+    TRACE("Finding string %d of %d\n", id, st->maxcount);
+
+    str = msi_string_lookup_id( st, id );
+    if( !str )
+        return ERROR_FUNCTION_FAILED;
+
+    len = strlenW( str ) + 1;
+
+    if( !buffer )
+    {
+        *sz = len;
+        return ERROR_SUCCESS;
+    }
+
+    if( *sz < len )
+        *sz = len;
+    memcpy( buffer, str, (*sz)*sizeof(WCHAR) ); 
+    *sz = len;
+
+    return ERROR_SUCCESS;
+}
+
+/*
+ *  msi_id2stringA
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] id         - id of the string to retrieve
+ *  [out] buffer    - destination of the UTF8 string
+ *  [in/out] sz     - number of bytes available in the buffer on input
+ *                    number of bytes used on output
+ *
+ *   The size includes the terminating nul character.  Short buffers
+ *  will be filled, but not nul terminated.
+ */
+UINT msi_id2stringA( string_table *st, UINT id, LPSTR buffer, UINT *sz )
+{
+    UINT len;
+    const WCHAR *str;
+    int n;
+
+    TRACE("Finding string %d of %d\n", id, st->maxcount);
+
+    str = msi_string_lookup_id( st, id );
+    if( !str )
+        return ERROR_FUNCTION_FAILED;
+
+    len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL );
+
+    if( !buffer )
+    {
+        *sz = len;
+        return ERROR_SUCCESS;
+    }
+
+    if( len > *sz )
+    {
+        n = strlenW( str ) + 1;
+        while( n && (len > *sz) )
+            len = WideCharToMultiByte( st->codepage, 0, 
+                           str, --n, NULL, 0, NULL, NULL );
+    }
+    else
+        n = -1;
+
+    *sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL );
+
+    return ERROR_SUCCESS;
+}
+
+/*
+ *  msi_string2idW
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] str        - string to find in the string table
+ *  [out] id        - id of the string, if found
+ */
+UINT msi_string2idW( string_table *st, LPCWSTR str, UINT *id )
+{
+    UINT hash;
+    UINT i, r = ERROR_INVALID_PARAMETER;
+
+    hash = msistring_makehash( str );
+    for( i=0; i<st->maxcount; i++ )
+    {
+        if ( (str == NULL && st->strings[i].str == NULL) || 
+            ( ( st->strings[i].hash == hash ) &&
+            !strcmpW( st->strings[i].str, str ) ))
+        {
+            r = ERROR_SUCCESS;
+            *id = i;
+            break;
+        }
+    }
+
+    return r;
+}
+
+UINT msi_string2idA( string_table *st, LPCSTR buffer, UINT *id )
+{
+    DWORD sz;
+    UINT r = ERROR_INVALID_PARAMETER;
+    LPWSTR str;
+
+    TRACE("Finding string %s in string table\n", debugstr_a(buffer) );
+
+    if( buffer[0] == 0 )
+    {
+        *id = 0;
+        return ERROR_SUCCESS;
+    }
+
+    sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
+    if( sz <= 0 )
+        return r;
+    str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
+    if( !str )
+        return ERROR_NOT_ENOUGH_MEMORY;
+    MultiByteToWideChar( st->codepage, 0, buffer, -1, str, sz );
+
+    r = msi_string2idW( st, str, id );
+    if( str )
+        HeapFree( GetProcessHeap(), 0, str );
+
+    return r;
+}
+
+UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res )
+{
+    const WCHAR *l_str, *r_str;
+
+    l_str = msi_string_lookup_id( st, lval );
+    if( !l_str )
+        return ERROR_INVALID_PARAMETER;
+    
+    r_str = msi_string_lookup_id( st, rval );
+    if( !r_str )
+        return ERROR_INVALID_PARAMETER;
+
+    /* does this do the right thing for all UTF-8 strings? */
+    *res = strcmpW( l_str, r_str );
+
+    return ERROR_SUCCESS;
+}
+
+UINT msi_string_count( string_table *st )
+{
+    return st->maxcount;
+}
+
+UINT msi_id_refcount( string_table *st, UINT i )
+{
+    if( i >= st->maxcount )
+        return 0;
+    return st->strings[i].refcount;
+}
+
+UINT msi_string_totalsize( string_table *st, UINT *total )
+{
+    UINT size = 0, i, len;
+
+    if( st->strings[0].str || st->strings[0].refcount )
+        ERR("oops. element 0 has a string\n");
+    *total = 0;
+    for( i=1; i<st->maxcount; i++ )
+    {
+        if( st->strings[i].str )
+        {
+            TRACE("[%u] = %s\n", i, debugstr_w(st->strings[i].str));
+            len = WideCharToMultiByte( st->codepage, 0,
+                     st->strings[i].str, -1, NULL, 0, NULL, NULL);
+            if( len )
+                len--;
+            size += len;
+            *total = (i+1);
+        }
+    }
+    TRACE("%u/%u strings %u bytes codepage %x\n", *total, st->maxcount, size, st->codepage );
+    return size;
+}
+
+UINT msi_string_get_codepage( string_table *st )
+{
+    return st->codepage;
+}

reactos/lib/msi
suminfo.c added at 1.2.2.1
diff -N suminfo.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ suminfo.c	13 Dec 2004 16:18:26 -0000	1.2.2.1
@@ -0,0 +1,234 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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 <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#define PRSPEC_PROPID (1)
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
+                       'I','n','f','o','r','m','a','t','i','o','n',0 };
+
+static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
+{
+    MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg;
+    IPropertyStorage_Release( suminfo->propstg );
+}
+
+UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, 
+              LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
+{
+    LPWSTR szwDatabase = NULL;
+    UINT ret;
+
+    TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase), 
+          uiUpdateCount, phSummaryInfo);
+
+    if( szDatabase )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, NULL, 0 );
+        szwDatabase = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+        if( !szwDatabase )
+            return ERROR_FUNCTION_FAILED;
+        MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, szwDatabase, len );
+    }
+
+    ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, phSummaryInfo);
+
+    if( szwDatabase )
+        HeapFree( GetProcessHeap(), 0, szwDatabase );
+
+    return ret;
+}
+
+UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, 
+              LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
+{
+    HRESULT r;
+    MSIHANDLE handle;
+    MSISUMMARYINFO *suminfo;
+    MSIDATABASE *db;
+    UINT ret = ERROR_SUCCESS;
+    IPropertySetStorage *psstg = NULL;
+    IPropertyStorage *ps = NULL;
+    DWORD grfMode;
+
+    TRACE("%ld %s %d %p\n", hDatabase, debugstr_w(szDatabase),
+           uiUpdateCount, phSummaryInfo);
+
+    if( !phSummaryInfo )
+        return ERROR_INVALID_PARAMETER;
+
+    if( szDatabase )
+    {
+        UINT res;
+
+        res = MSI_OpenDatabaseW(szDatabase, NULL, &db);
+        if( res != ERROR_SUCCESS )
+            return res;
+    }
+    else
+    {
+        db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
+        if( !db )
+            return ERROR_INVALID_PARAMETER;
+    }
+
+    r = IStorage_QueryInterface( db->storage, 
+             &IID_IPropertySetStorage, (LPVOID)&psstg);
+    if( FAILED( r ) )
+    {
+        ERR("IStorage -> IPropertySetStorage failed\n");
+        if (db)
+            msiobj_release(&db->hdr);
+        return ERROR_FUNCTION_FAILED;
+    }
+    ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
+
+    grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
+
+    r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
+    if( FAILED( r ) )
+    {
+        ERR("failed to get IPropertyStorage r=%08lx\n",r);
+        ret = ERROR_FUNCTION_FAILED;
+        goto end;
+    }
+
+    suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO, 
+                  sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
+    if( !suminfo )
+    {
+        ret = ERROR_FUNCTION_FAILED;
+        goto end;
+    }
+
+    IPropertyStorage_AddRef(ps);
+    suminfo->propstg = ps;
+    handle = alloc_msihandle( &suminfo->hdr );
+    if( handle )
+    *phSummaryInfo = handle;
+    else
+        ret = ERROR_FUNCTION_FAILED;
+    msiobj_release( &suminfo->hdr );
+
+end:
+    if( ps )
+        IPropertyStorage_Release(ps);
+    if( psstg )
+        IPropertySetStorage_Release(psstg);
+    if (db)
+        msiobj_release(&db->hdr);
+
+    return ret;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
+{
+    MSISUMMARYINFO *suminfo;
+
+    FIXME("%ld %p\n",hSummaryInfo, pCount);
+
+    suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
+    if( !suminfo )
+        return ERROR_INVALID_HANDLE;
+
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyA(
+      MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
+      FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf)
+{
+    MSISUMMARYINFO *suminfo;
+    HRESULT r;
+    PROPSPEC spec;
+    PROPVARIANT var;
+
+    TRACE("%ld %d %p %p %p %p %p\n",
+        hSummaryInfo, uiProperty, puiDataType, piValue,
+        pftValue, szValueBuf, pcchValueBuf);
+
+    suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
+    if( !suminfo )
+        return ERROR_INVALID_HANDLE;
+
+    spec.ulKind = PRSPEC_PROPID;
+    spec.u.propid = uiProperty;
+
+    r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
+    if( FAILED(r) )
+        return ERROR_FUNCTION_FAILED;
+
+    if( puiDataType )
+        *puiDataType = var.vt;
+
+    switch( var.vt )
+    {
+    case VT_I4:
+        if( piValue )
+            *piValue = var.u.lVal;
+        break;
+    case VT_LPSTR:
+        if( pcchValueBuf && szValueBuf )
+        {
+            lstrcpynA(szValueBuf, var.u.pszVal, *pcchValueBuf );
+            *pcchValueBuf = lstrlenA( var.u.pszVal );
+        }
+        break;
+    case VT_FILETIME:
+        if( pftValue )
+            memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
+        break;
+    case VT_EMPTY:
+        break;
+    default:
+        FIXME("Unknown property variant type\n");
+        break;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyW(
+      MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
+      FILETIME *pftValue, LPWSTR szValueBuf, DWORD *pcchValueBuf)
+{
+    FIXME("%ld %d %p %p %p %p %p\n",
+        hSummaryInfo, uiProperty, puiDataType, piValue,
+        pftValue, szValueBuf, pcchValueBuf);
+    
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}

reactos/lib/msi
table.c added at 1.3.2.1
diff -N table.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ table.c	13 Dec 2004 16:18:26 -0000	1.3.2.1
@@ -0,0 +1,1425 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-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
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#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 "wine/unicode.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tagMSICOLUMNINFO
+{
+    LPWSTR tablename;
+    UINT   number;
+    LPWSTR colname;
+    UINT   type;
+    UINT   offset;
+} MSICOLUMNINFO;
+
+struct tagMSITABLE
+{
+    USHORT **data;
+    UINT ref_count;
+    UINT row_count;
+    struct tagMSITABLE *next;
+    struct tagMSITABLE *prev;
+    WCHAR name[1];
+};
+
+#define MAX_STREAM_NAME 0x1f
+
+static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name,
+       MSICOLUMNINFO **pcols, UINT *pcount );
+static UINT get_tablecolumns( MSIDATABASE *db, 
+       LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz);
+
+static inline UINT bytes_per_column( MSICOLUMNINFO *col )
+{
+    if( col->type & MSITYPE_STRING )
+        return 2;
+    if( (col->type & 0xff) > 4 )
+        ERR("Invalid column size!\n");
+    return col->type & 0xff;
+}
+
+static int utf2mime(int x)
+{
+    if( (x>='0') && (x<='9') )
+        return x-'0';
+    if( (x>='A') && (x<='Z') )
+        return x-'A'+10;
+    if( (x>='a') && (x<='z') )
+        return x-'a'+10+26;
+    if( x=='.' )
+        return 10+26+26;
+    if( x=='_' )
+        return 10+26+26+1;
+    return -1;
+}
+
+static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
+{
+    DWORD count = MAX_STREAM_NAME;
+    DWORD ch, next;
+    LPWSTR out, p;
+
+    if( !bTable )
+        count = strlenW( in )+2;
+    out = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) );
+    p = out;
+
+    if( bTable )
+    {
+         *p++ = 0x4840;
+         count --;
+    }
+    while( count -- ) 
+    {
+        ch = *in++;
+        if( !ch )
+        {
+            *p = ch;
+            return out;
+        }
+        if( ( ch < 0x80 ) && ( utf2mime(ch) >= 0 ) )
+        {
+            ch = utf2mime(ch) + 0x4800;
+            next = *in;
+            if( next && (next<0x80) )
+            {
+                next = utf2mime(next);
+                if( next >= 0  )
+                {
+                     next += 0x3ffffc0;
+                     ch += (next<<6);
+                     in++;
+                }
+            }
+        }
+        *p++ = ch;
+    }
+    ERR("Failed to encode stream name (%s)\n",debugstr_w(in));
+    HeapFree( GetProcessHeap(), 0, out );
+    return NULL;
+}
+
+static int mime2utf(int x)
+{
+    if( x<10 )
+        return x + '0';
+    if( x<(10+26))
+        return x - 10 + 'A';
+    if( x<(10+26+26))
+        return x - 10 - 26 + 'a';
+    if( x == (10+26+26) )
+        return '.';
+    return '_';
+}
+
+static BOOL decode_streamname(LPWSTR in, LPWSTR out)
+{
+    WCHAR ch;
+    DWORD count = 0;
+
+    while ( (ch = *in++) )
+    {
+        if( (ch >= 0x3800 ) && (ch < 0x4840 ) )
+        {
+            if( ch >= 0x4800 )
+                ch = mime2utf(ch-0x4800);
+            else
+            {
+                ch -= 0x3800;
+                *out++ = mime2utf(ch&0x3f);
+                count++;
+                ch = mime2utf((ch>>6)&0x3f);
+            }
+        }
+        *out++ = ch;
+        count++;
+    }
+    *out = 0;
+    return count;
+}
+
+void enum_stream_names( IStorage *stg )
+{
+    IEnumSTATSTG *stgenum = NULL;
+    HRESULT r;
+    STATSTG stat;
+    ULONG n, count;
+    WCHAR name[0x40];
+
+    r = IStorage_EnumElements( stg, 0, NULL, 0, &stgenum );
+    if( FAILED( r ) )
+        return;
+
+    n = 0;
+    while( 1 )
+    {
+        count = 0;
+        r = IEnumSTATSTG_Next( stgenum, 1, &stat, &count );
+        if( FAILED( r ) || !count )
+            break;
+        decode_streamname( stat.pwcsName, name );
+        ERR("stream %2ld -> %s %s\n", n, 
+            debugstr_w(stat.pwcsName), debugstr_w(name) );
+        n++;
+    }
+
+    IEnumSTATSTG_Release( stgenum );
+}
+
+static UINT read_stream_data( IStorage *stg, LPCWSTR stname,
+                              USHORT **pdata, UINT *psz )
+{
+    HRESULT r;
+    UINT ret = ERROR_FUNCTION_FAILED;
+    VOID *data;
+    ULONG sz, count;
+    IStream *stm = NULL;
+    STATSTG stat;
+    LPWSTR encname;
+
+    encname = encode_streamname(TRUE, stname);
+
+    TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
+
+    r = IStorage_OpenStream(stg, encname, NULL, 
+            STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
+    HeapFree( GetProcessHeap(), 0, encname );
+    if( FAILED( r ) )
+    {
+        WARN("open stream failed r = %08lx - empty table?\n",r);
+        return ret;
+    }
+
+    r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
+    if( FAILED( r ) )
+    {
+        ERR("open stream failed r = %08lx!\n",r);
+        goto end;
+    }
+
+    if( stat.cbSize.QuadPart >> 32 )
+    {
+        ERR("Too big!\n");
+        goto end;
+    }
+        
+    sz = stat.cbSize.QuadPart;
+    data = HeapAlloc( GetProcessHeap(), 0, sz );
+    if( !data )
+    {
+        ERR("couldn't allocate memory r=%08lx!\n",r);
+        ret = ERROR_NOT_ENOUGH_MEMORY;
+        goto end;
+    }
+        
+    r = IStream_Read(stm, data, sz, &count );
+    if( FAILED( r ) || ( count != sz ) )
+    {
+        HeapFree( GetProcessHeap(), 0, data );
+        ERR("read stream failed r = %08lx!\n",r);
+        goto end;
+    }
+
+    *pdata = data;
+    *psz = sz;
+    ret = ERROR_SUCCESS;
+
+end:
+    IStream_Release( stm );
+
+    return ret;
+}
+
+UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
+{
+    LPWSTR encname;
+    HRESULT r;
+
+    encname = encode_streamname(FALSE, stname);
+
+    TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
+
+    r = IStorage_OpenStream(db->storage, encname, NULL, 
+            STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm);
+    HeapFree( GetProcessHeap(), 0, encname );
+    if( FAILED( r ) )
+    {
+        WARN("open stream failed r = %08lx - empty table?\n",r);
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
+                              USHORT **pdata, UINT *psz )
+{
+    HRESULT r;
+    UINT ret = ERROR_FUNCTION_FAILED;
+    VOID *data;
+    ULONG sz, count;
+    IStream *stm = NULL;
+    STATSTG stat;
+
+    r = db_get_raw_stream( db, stname, &stm );
+    if( r != ERROR_SUCCESS)
+        return ret;
+    r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
+    if( FAILED( r ) )
+    {
+        ERR("open stream failed r = %08lx!\n",r);
+        goto end;
+    }
+
+    if( stat.cbSize.QuadPart >> 32 )
+    {
+        ERR("Too big!\n");
+        goto end;
+    }
+        
+    sz = stat.cbSize.QuadPart;
+    data = HeapAlloc( GetProcessHeap(), 0, sz );
+    if( !data )
+    {
+        ERR("couldn't allocate memory r=%08lx!\n",r);
+        ret = ERROR_NOT_ENOUGH_MEMORY;
+        goto end;
+    }
+        
+    r = IStream_Read(stm, data, sz, &count );
+    if( FAILED( r ) || ( count != sz ) )
+    {
+        HeapFree( GetProcessHeap(), 0, data );
+        ERR("read stream failed r = %08lx!\n",r);
+        goto end;
+    }
+
+    *pdata = data;
+    *psz = sz;
+    ret = ERROR_SUCCESS;
+
+end:
+    IStream_Release( stm );
+
+    return ret;
+}
+
+static UINT write_stream_data( IStorage *stg, LPCWSTR stname,
+                               LPVOID data, UINT sz )
+{
+    HRESULT r;
+    UINT ret = ERROR_FUNCTION_FAILED;
+    ULONG count;
+    IStream *stm = NULL;
+    ULARGE_INTEGER size;
+    LARGE_INTEGER pos;
+    LPWSTR encname;
+
+    encname = encode_streamname(TRUE, stname );
+    r = IStorage_OpenStream( stg, encname, NULL, 
+            STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
+    HeapFree( GetProcessHeap(), 0, encname );
+    if( FAILED(r) )
+    {
+        r = IStorage_CreateStream( stg, encname,
+                STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+    }
+    if( FAILED( r ) )
+    {
+        ERR("open stream failed r = %08lx\n",r);
+        return ret;
+    }
+
+    size.QuadPart = sz;
+    r = IStream_SetSize( stm, size );
+    if( FAILED( r ) )
+    {
+        ERR("Failed to SetSize\n");
+        goto end;
+    }
+
+    pos.QuadPart = 0;
+    r = IStream_Seek( stm, pos, STREAM_SEEK_SET, NULL );
+    if( FAILED( r ) )
+    {
+        ERR("Failed to Seek\n");
+        goto end;
+    }
+
+    r = IStream_Write(stm, data, sz, &count );
+    if( FAILED( r ) || ( count != sz ) )
+    {
+        ERR("Failed to Write\n");
+        goto end;
+    }
+
+    ret = ERROR_SUCCESS;
+
+end:
+    IStream_Release( stm );
+
+    return ret;
+}
+
+UINT read_table_from_storage( MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+    MSITABLE *t;
+    USHORT *rawdata = NULL;
+    UINT rawsize = 0, r, i, j, row_size = 0, num_cols = 0;
+    MSICOLUMNINFO *cols, *last_col;
+
+    TRACE("%s\n",debugstr_w(name));
+
+    /* non-existing tables should be interpretted as empty tables */
+    t = HeapAlloc( GetProcessHeap(), 0, 
+                   sizeof (MSITABLE) + lstrlenW(name)*sizeof (WCHAR) );
+    if( !t )
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    r = table_get_column_info( db, name, &cols, &num_cols );
+    if( r != ERROR_SUCCESS )
+    {
+        HeapFree( GetProcessHeap(), 0, t );
+        return r;
+    }
+    last_col = &cols[num_cols-1];
+    row_size = last_col->offset + bytes_per_column( last_col );
+
+    t->row_count = 0;
+    t->data = NULL;
+    lstrcpyW( t->name, name );
+    t->ref_count = 1;
+    *ptable = t;
+
+    /* if we can't read the table, just assume that it's empty */
+    read_stream_data( db->storage, name, &rawdata, &rawsize );
+    if( !rawdata )
+        return ERROR_SUCCESS;
+
+    TRACE("Read %d bytes\n", rawsize );
+
+    if( rawsize % row_size )
+    {
+        ERR("Table size is invalid %d/%d\n", rawsize, row_size );
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    t->row_count = rawsize / row_size;
+    t->data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                         t->row_count * sizeof (USHORT*) );
+    if( !t->data )
+        return ERROR_NOT_ENOUGH_MEMORY;  /* FIXME: memory leak */
+
+    /* transpose all the data */
+    TRACE("Transposing data from %d columns\n", t->row_count );
+    for( i=0; i<t->row_count; i++ )
+    {
+        t->data[i] = HeapAlloc( GetProcessHeap(), 0, row_size );
+        if( !t->data[i] )
+            return ERROR_NOT_ENOUGH_MEMORY;  /* FIXME: memory leak */
+        for( j=0; j<num_cols; j++ )
+        {
+            UINT ofs = cols[j].offset/2;
+            UINT n = bytes_per_column( &cols[j] );
+
+            switch( n )
+            {
+            case 2:
+                t->data[i][ofs] = rawdata[ofs*t->row_count + i ];
+                break;
+            case 4:
+                t->data[i][ofs] = rawdata[ofs*t->row_count + i ];
+                t->data[i][ofs+1] = rawdata[ofs*t->row_count + i + 1];
+                break;
+            default:
+                ERR("oops - unknown column width %d\n", n);
+                return ERROR_FUNCTION_FAILED;
+            }
+        }
+    }
+
+    HeapFree( GetProcessHeap(), 0, cols );
+    HeapFree( GetProcessHeap(), 0, rawdata );
+
+    return ERROR_SUCCESS;
+}
+
+/* add this table to the list of cached tables in the database */
+void add_table(MSIDATABASE *db, MSITABLE *table)
+{
+    table->next = db->first_table;
+    table->prev = NULL;
+    if( db->first_table )
+        db->first_table->prev = table;
+    else
+        db->last_table = table;
+    db->first_table = table;
+}
+ 
+/* remove from the list of cached tables */
+void remove_table( MSIDATABASE *db, MSITABLE *table )
+{
+    if( table->next )
+        table->next->prev = table->prev;
+    else
+        db->last_table = table->prev;
+    if( table->prev )
+        table->prev->next = table->next;
+    else
+        db->first_table = table->next;
+    table->next = NULL;
+    table->prev = NULL;
+}
+
+void release_table( MSIDATABASE *db, MSITABLE *table )
+{
+    if( !table->ref_count )
+        ERR("Trying to destroy table with refcount 0\n");
+    table->ref_count --;
+    if( !table->ref_count )
+    {
+        remove_table( db, table );
+        HeapFree( GetProcessHeap(), 0, table->data );
+        HeapFree( GetProcessHeap(), 0, table );
+        TRACE("Destroyed table %s\n", debugstr_w(table->name));
+    }
+}
+
+void free_cached_tables( MSIDATABASE *db )
+{
+    while( db->first_table )
+    {
+        MSITABLE *t = db->first_table;
+
+        if ( --t->ref_count )
+            ERR("table ref count not zero for %s\n", debugstr_w(t->name));
+        remove_table( db, t );
+        HeapFree( GetProcessHeap(), 0, t->data );
+        HeapFree( GetProcessHeap(), 0, t );
+    }
+}
+
+UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+    MSITABLE *t;
+
+    for( t = db->first_table; t; t=t->next )
+    {
+        if( !lstrcmpW( name, t->name ) )
+        {
+            *ptable = t;
+            return ERROR_SUCCESS;
+        }
+    }
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO **pcols, UINT *pcount )
+{
+    UINT r, column_count;
+    MSICOLUMNINFO *columns;
+
+    /* get the number of columns in this table */
+    column_count = 0;
+    r = get_tablecolumns( db, name, NULL, &column_count );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    /* if there's no columns, there's no table */
+    if( column_count == 0 )
+        return ERROR_INVALID_PARAMETER;
+
+    TRACE("Table %s found\n", debugstr_w(name) );
+
+    columns = HeapAlloc( GetProcessHeap(), 0, column_count*sizeof (MSICOLUMNINFO));
+    if( !columns )
+        return ERROR_FUNCTION_FAILED;
+
+    r = get_tablecolumns( db, name, columns, &column_count );
+    if( r != ERROR_SUCCESS )
+    {
+        HeapFree( GetProcessHeap(), 0, columns );
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    *pcols = columns;
+    *pcount = column_count;
+
+    return r;
+}
+
+UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+    UINT r;
+
+    *ptable = NULL;
+
+    /* first, see if the table is cached */
+    r = find_cached_table( db, name, ptable );
+    if( r == ERROR_SUCCESS )
+    {
+        (*ptable)->ref_count++;
+        return r;
+    }
+
+    r = read_table_from_storage( db, name, ptable );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    /* add the table to the list */
+    add_table( db, *ptable );
+    (*ptable)->ref_count++;
+
+    return ERROR_SUCCESS;
+}
+
+UINT save_table( MSIDATABASE *db, MSITABLE *t )
+{
+    USHORT *rawdata = NULL, *p;
+    UINT rawsize, r, i, j, row_size, num_cols = 0;
+    MSICOLUMNINFO *cols, *last_col;
+
+    TRACE("Saving %s\n", debugstr_w( t->name ) );
+
+    r = table_get_column_info( db, t->name, &cols, &num_cols );
+    if( r != ERROR_SUCCESS )
+        return r;
+    
+    last_col = &cols[num_cols-1];
+    row_size = last_col->offset + bytes_per_column( last_col );
+
+    rawsize = t->row_count * row_size;
+    rawdata = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, rawsize );
+    if( !rawdata )
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    p = rawdata;
+    for( i=0; i<num_cols; i++ )
+    {
+        for( j=0; j<t->row_count; j++ )
+        {
+            UINT offset = cols[i].offset;
+
+            *p++ = t->data[j][offset/2];
+            if( 4 == bytes_per_column( &cols[i] ) )
+                *p++ = t->data[j][offset/2+1];
+        }
+    }
+
+    TRACE("writing %d bytes\n", rawsize);
+    r = write_stream_data( db->storage, t->name, rawdata, rawsize );
+
+    HeapFree( GetProcessHeap(), 0, rawdata );
+
+    return r;
+}
+
+HRESULT init_string_table( IStorage *stg )
+{
+    HRESULT r;
+    static const WCHAR szStringData[] = {
+        '_','S','t','r','i','n','g','D','a','t','a',0 };
+    static const WCHAR szStringPool[] = {
+        '_','S','t','r','i','n','g','P','o','o','l',0 };
+    USHORT zero[2] = { 0, 0 };
+    ULONG count = 0;
+    IStream *stm = NULL;
+    LPWSTR encname;
+
+    encname = encode_streamname(TRUE, szStringPool );
+
+    /* create the StringPool stream... add the zero string to it*/
+    r = IStorage_CreateStream( stg, encname,
+            STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+    HeapFree( GetProcessHeap(), 0, encname );
+    if( r ) 
+    {
+        TRACE("Failed\n");
+        return r;
+    }
+
+    r = IStream_Write(stm, zero, sizeof zero, &count );
+    IStream_Release( stm );
+
+    if( FAILED( r ) || ( count != sizeof zero ) )
+    {
+        TRACE("Failed\n");
+        return E_FAIL;
+    }
+
+    /* create the StringData stream... make it zero length */
+    encname = encode_streamname(TRUE, szStringData );
+    r = IStorage_CreateStream( stg, encname,
+            STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+    HeapFree( GetProcessHeap(), 0, encname );
+    if( r ) 
+    {
+        TRACE("Failed\n");
+        return E_FAIL;
+    }
+    IStream_Release( stm );
+
+    return r;
+}
+
+UINT load_string_table( MSIDATABASE *db )
+{
+    CHAR *data;
+    USHORT *pool;
+    UINT r, ret = ERROR_FUNCTION_FAILED, datasize = 0, poolsize = 0, codepage;
+    DWORD i, count, offset, len, n;
+    static const WCHAR szStringData[] = {
+        '_','S','t','r','i','n','g','D','a','t','a',0 };
+    static const WCHAR szStringPool[] = {
+        '_','S','t','r','i','n','g','P','o','o','l',0 };
+
+    if( db->strings )
+    {
+        msi_destroy_stringtable( db->strings );
+        db->strings = NULL;
+    }
+
+    r = read_stream_data( db->storage, szStringPool, &pool, &poolsize );
+    if( r != ERROR_SUCCESS)
+        goto end;
+    r = read_stream_data( db->storage, szStringData, (USHORT**)&data, &datasize );
+    if( r != ERROR_SUCCESS)
+        goto end;
+
+    count = poolsize/4;
+    if( poolsize > 4 )
+        codepage = pool[0] | ( pool[1] << 16 );
+    else
+        codepage = CP_ACP;
+    db->strings = msi_init_stringtable( count, codepage );
+
+    offset = 0;
+    for( i=1; i<count; i++ )
+    {
+        len = pool[i*2];
+        n = msi_addstring( db->strings, i, data+offset, len, pool[i*2+1] );
+        if( n != i )
+            ERR("Failed to add string %ld\n", i );
+        offset += len;
+    }
+
+    TRACE("Loaded %ld strings\n", count);
+
+    ret = ERROR_SUCCESS;
+
+end:
+    if( pool )
+        HeapFree( GetProcessHeap(), 0, pool );
+    if( data )
+        HeapFree( GetProcessHeap(), 0, data );
+
+    return ret;
+}
+
+UINT save_string_table( MSIDATABASE *db )
+{
+    UINT i, count, datasize, poolsize, sz, used, r, codepage;
+    UINT ret = ERROR_FUNCTION_FAILED;
+    static const WCHAR szStringData[] = {
+        '_','S','t','r','i','n','g','D','a','t','a',0 };
+    static const WCHAR szStringPool[] = {
+        '_','S','t','r','i','n','g','P','o','o','l',0 };
+    CHAR *data = NULL;
+    USHORT *pool = NULL;
+
+    TRACE("\n");
+
+    /* construct the new table in memory first */
+    datasize = msi_string_totalsize( db->strings, &count );
+    poolsize = count*2*sizeof(USHORT);
+
+    pool = HeapAlloc( GetProcessHeap(), 0, poolsize );
+    if( ! pool )
+    {
+        ERR("Failed to alloc pool %d bytes\n", poolsize );
+        goto err;
+    }
+    data = HeapAlloc( GetProcessHeap(), 0, datasize );
+    if( ! data )
+    {
+        ERR("Failed to alloc data %d bytes\n", poolsize );
+        goto err;
+    }
+
+    used = 0;
+    codepage = msi_string_get_codepage( db->strings );
+    pool[0]=codepage&0xffff;
+    pool[1]=(codepage>>16);
+    for( i=1; i<count; i++ )
+    {
+        sz = datasize - used;
+        r = msi_id2stringA( db->strings, i, data+used, &sz );
+        if( r != ERROR_SUCCESS )
+        {
+            ERR("failed to fetch string\n");
+            sz = 0;
+        }
+        if( sz && (sz < (datasize - used ) ) )
+            sz--;
+        TRACE("adding %u bytes %s\n", sz, data+used );
+        pool[ i*2 ] = sz;
+        pool[ i*2 + 1 ] = msi_id_refcount( db->strings, i );
+        used += sz;
+        if( used > datasize  )
+        {
+            ERR("oops overran %d >= %d\n", used, datasize);
+            goto err;
+        }
+    }
+
+    if( used != datasize )
+    {
+        ERR("oops used %d != datasize %d\n", used, datasize);
+        goto err;
+    }
+
+    /* write the streams */
+    r = write_stream_data( db->storage, szStringData, data, datasize );
+    TRACE("Wrote StringData r=%08x\n", r);
+    if( r )
+        goto err;
+    r = write_stream_data( db->storage, szStringPool, pool, poolsize );
+    TRACE("Wrote StringPool r=%08x\n", r);
+    if( r )
+        goto err;
+
+    ret = ERROR_SUCCESS;
+
+err:
+    if( data )
+        HeapFree( GetProcessHeap(), 0, data );
+    if( pool )
+        HeapFree( GetProcessHeap(), 0, pool );
+
+    return ret;
+}
+
+static LPWSTR strdupW( LPCWSTR str )
+{
+    UINT len = lstrlenW( str ) + 1;
+    LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+    if( ret )
+        lstrcpyW( ret, str );
+    return ret;
+}
+
+/* information for default tables */
+static const WCHAR szTables[]  = { '_','T','a','b','l','e','s',0 };
+static const WCHAR szTable[]  = { 'T','a','b','l','e',0 };
+static const WCHAR szName[]    = { 'N','a','m','e',0 };
+static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+static const WCHAR szColumn[]  = { 'C','o','l','u','m','n',0 };
+static const WCHAR szNumber[]  = { 'N','u','m','b','e','r',0 };
+static const WCHAR szType[]    = { 'T','y','p','e',0 };
+
+struct standard_table {
+    LPCWSTR tablename;
+    LPCWSTR columnname;
+    UINT number;
+    UINT type;
+} MSI_standard_tables[] =
+{
+  { szTables,  szName,   1, MSITYPE_VALID | MSITYPE_STRING | 32},
+  { szColumns, szTable,  1, MSITYPE_VALID | MSITYPE_STRING | 32},
+  { szColumns, szNumber, 2, MSITYPE_VALID | 2},
+  { szColumns, szName,   3, MSITYPE_VALID | MSITYPE_STRING | 32},
+  { szColumns, szType,   4, MSITYPE_VALID | 2},
+};
+
+#define STANDARD_TABLE_COUNT \
+     (sizeof(MSI_standard_tables)/sizeof(struct standard_table))
+
+UINT get_defaulttablecolumns( LPCWSTR szTable, MSICOLUMNINFO *colinfo, UINT *sz)
+{
+    DWORD i, n=0;
+
+    for(i=0; i<STANDARD_TABLE_COUNT; i++)
+    {
+        if( lstrcmpW( szTable, MSI_standard_tables[i].tablename ) )
+            continue;
+        if(colinfo && (n < *sz) )
+        {
+            colinfo[n].tablename = strdupW(MSI_standard_tables[i].tablename);
+            colinfo[n].colname = strdupW(MSI_standard_tables[i].columnname);
+            colinfo[n].number = MSI_standard_tables[i].number;
+            colinfo[n].type = MSI_standard_tables[i].type;
+            /* ERR("Table %s has column %s\n",debugstr_w(colinfo[n].tablename),
+                    debugstr_w(colinfo[n].colname)); */
+            if( n )
+                colinfo[n].offset = colinfo[n-1].offset
+                                  + bytes_per_column( &colinfo[n-1] );
+            else
+                colinfo[n].offset = 0;
+        }
+        n++;
+        if( colinfo && (n >= *sz) )
+            break;
+    }
+    *sz = n;
+    return ERROR_SUCCESS;
+}
+
+LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid)
+{
+    UINT sz=0, r;
+    LPWSTR str;
+
+    r = msi_id2stringW( db->strings, stringid, NULL, &sz );
+    if( r != ERROR_SUCCESS )
+        return NULL;
+    str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR));
+    if( !str )
+        return str;
+    r = msi_id2stringW( db->strings, stringid, str, &sz );
+    if( r == ERROR_SUCCESS )
+        return str;
+    HeapFree(  GetProcessHeap(), 0, str );
+    return NULL;
+}
+
+static UINT get_tablecolumns( MSIDATABASE *db, 
+       LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz)
+{
+    UINT r, i, n=0, table_id, count, maxcount = *sz;
+    MSITABLE *table = NULL;
+    static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+
+    /* first check if there is a default table with that name */
+    r = get_defaulttablecolumns( szTableName, colinfo, sz );
+    if( ( r == ERROR_SUCCESS ) && *sz )
+        return r;
+
+    r = get_table( db, szColumns, &table);
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("table %s not available\n", debugstr_w(szColumns));
+        return r;
+    }
+
+    /* convert table and column names to IDs from the string table */
+    r = msi_string2idW( db->strings, szTableName, &table_id );
+    if( r != ERROR_SUCCESS )
+    {
+        release_table( db, table );
+        ERR("Couldn't find id for %s\n", debugstr_w(szTableName));
+        return r;
+    }
+
+    TRACE("Table id is %d\n", table_id);
+
+    count = table->row_count;
+    for( i=0; i<count; i++ )
+    {
+        if( table->data[ i ][ 0 ] != table_id )
+            continue;
+        if( colinfo )
+        {
+            UINT id = table->data[ i ] [ 2 ];
+            colinfo[n].tablename = MSI_makestring( db, table_id );
+            colinfo[n].number = table->data[ i ][ 1 ] - (1<<15);
+            colinfo[n].colname = MSI_makestring( db, id );
+            colinfo[n].type = table->data[ i ] [ 3 ];
+            /* this assumes that columns are in order in the table */
+            if( n )
+                colinfo[n].offset = colinfo[n-1].offset
+                                  + bytes_per_column( &colinfo[n-1] );
+            else
+                colinfo[n].offset = 0;
+            TRACE("table %s column %d is [%s] (%d) with type %08x "
+                  "offset %d at row %d\n", debugstr_w(szTableName),
+                   colinfo[n].number, debugstr_w(colinfo[n].colname),
+                   id, colinfo[n].type, colinfo[n].offset, i);
+            if( n != (colinfo[n].number-1) )
+            {
+                ERR("oops. data in the _Columns table isn't in the right "
+                    "order for table %s\n", debugstr_w(szTableName));
+                return ERROR_FUNCTION_FAILED;
+            }
+        }
+        n++;
+        if( colinfo && ( n >= maxcount ) )
+            break;
+    }
+    *sz = n;
+
+    release_table( db, table );
+
+    return ERROR_SUCCESS;
+}
+
+/* try to find the table name in the _Tables table */
+BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name )
+{
[truncated at 1000 lines; 429 more skipped]

reactos/lib/msi
tokenize.c added at 1.1.2.1
diff -N tokenize.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tokenize.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,397 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** An tokenizer for SQL
+**
+** This file contains C code that splits an SQL input string up into
+** individual tokens and sends those tokens one-by-one over to the
+** parser for analysis.
+*/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "winnls.h"
+#include "query.h"
+#include "sql.tab.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+** All the keywords of the SQL language are stored as in a hash
+** table composed of instances of the following structure.
+*/
+typedef struct Keyword Keyword;
+struct Keyword {
+  const char *zName;             /* The keyword name */
+  int tokenType;           /* The token value for this keyword */
+};
+
+/*
+** These are the keywords
+*/
+static const Keyword aKeywordTable[] = {
+  { "ABORT", TK_ABORT },
+  { "AFTER", TK_AFTER },
+  { "ALL", TK_ALL },
+  { "AND", TK_AND },
+  { "AS", TK_AS },
+  { "ASC", TK_ASC },
+  { "BEFORE", TK_BEFORE },
+  { "BEGIN", TK_BEGIN },
+  { "BETWEEN", TK_BETWEEN },
+  { "BY", TK_BY },
+  { "CASCADE", TK_CASCADE },
+  { "CASE", TK_CASE },
+  { "CHAR", TK_CHAR },
+  { "CHARACTER", TK_CHAR },
+  { "CHECK", TK_CHECK },
+  { "CLUSTER", TK_CLUSTER },
+  { "COLLATE", TK_COLLATE },
+  { "COMMIT", TK_COMMIT },
+  { "CONFLICT", TK_CONFLICT },
+  { "CONSTRAINT", TK_CONSTRAINT },
+  { "COPY", TK_COPY },
+  { "CREATE", TK_CREATE },
+  { "CROSS", TK_JOIN_KW },
+  { "DEFAULT", TK_DEFAULT },
+  { "DEFERRED", TK_DEFERRED },
+  { "DEFERRABLE", TK_DEFERRABLE },
+  { "DELETE", TK_DELETE },
+  { "DELIMITERS", TK_DELIMITERS },
+  { "DESC", TK_DESC },
+  { "DISTINCT", TK_DISTINCT },
+  { "DROP", TK_DROP },
+  { "END", TK_END },
+  { "EACH", TK_EACH },
+  { "ELSE", TK_ELSE },
+  { "EXCEPT", TK_EXCEPT },
+  { "EXPLAIN", TK_EXPLAIN },
+  { "FAIL", TK_FAIL },
+  { "FOR", TK_FOR },
+  { "FOREIGN", TK_FOREIGN },
+  { "FROM", TK_FROM },
+  { "FULL", TK_JOIN_KW },
+  { "GLOB", TK_GLOB },
+  { "GROUP", TK_GROUP },
+  { "HAVING", TK_HAVING },
+  { "HOLD", TK_HOLD },
+  { "IGNORE", TK_IGNORE },
+  { "IMMEDIATE", TK_IMMEDIATE },
+  { "IN", TK_IN },
+  { "INDEX", TK_INDEX },
+  { "INITIALLY", TK_INITIALLY },
+  { "INNER", TK_JOIN_KW },
+  { "INSERT", TK_INSERT },
+  { "INSTEAD", TK_INSTEAD },
+  { "INT", TK_INT },
+  { "INTERSECT", TK_INTERSECT },
+  { "INTO", TK_INTO },
+  { "IS", TK_IS },
+  { "ISNULL", TK_ISNULL },
+  { "JOIN", TK_JOIN },
+  { "KEY", TK_KEY },
+  { "LEFT", TK_JOIN_KW },
+  { "LIKE", TK_LIKE },
+  { "LIMIT", TK_LIMIT },
+  { "LOCALIZABLE", TK_LOCALIZABLE },
+  { "LONG", TK_LONG },
+  { "LONGCHAR", TK_LONGCHAR },
+  { "MATCH", TK_MATCH },
+  { "NATURAL", TK_JOIN_KW },
+  { "NOT", TK_NOT },
+  { "NOTNULL", TK_NOTNULL },
+  { "NULL", TK_NULL },
+  { "OBJECT", TK_OBJECT },
+  { "OF", TK_OF },
+  { "OFFSET", TK_OFFSET },
+  { "ON", TK_ON },
+  { "OR", TK_OR },
+  { "ORDER", TK_ORDER },
+  { "OUTER", TK_JOIN_KW },
+  { "PRAGMA", TK_PRAGMA },
+  { "PRIMARY", TK_PRIMARY },
+  { "RAISE", TK_RAISE },
+  { "REFERENCES", TK_REFERENCES },
+  { "REPLACE", TK_REPLACE },
+  { "RESTRICT", TK_RESTRICT },
+  { "RIGHT", TK_JOIN_KW },
+  { "ROLLBACK", TK_ROLLBACK },
+  { "ROW", TK_ROW },
+  { "SELECT", TK_SELECT },
+  { "SET", TK_SET },
+  { "SHORT", TK_SHORT },
+  { "STATEMENT", TK_STATEMENT },
+  { "TABLE", TK_TABLE },
+  { "TEMP", TK_TEMP },
+  { "TEMPORARY", TK_TEMP },
+  { "THEN", TK_THEN },
+  { "TRANSACTION", TK_TRANSACTION },
+  { "TRIGGER", TK_TRIGGER },
+  { "UNION", TK_UNION },
+  { "UNIQUE", TK_UNIQUE },
+  { "UPDATE", TK_UPDATE },
+  { "USING", TK_USING },
+  { "VACUUM", TK_VACUUM },
+  { "VALUES", TK_VALUES },
+  { "VIEW", TK_VIEW },
+  { "WHEN", TK_WHEN },
+  { "WHERE", TK_WHERE },
+};
+
+#define KEYWORD_COUNT ( sizeof aKeywordTable/sizeof (Keyword) )
+
+/*
+** This function looks up an identifier to determine if it is a
+** keyword.  If it is a keyword, the token code of that keyword is 
+** returned.  If the input is not a keyword, TK_ID is returned.
+*/
+int sqliteKeywordCode(const WCHAR *z, int n){
+  UINT i, len;
+  char buffer[0x10];
+
+  len = WideCharToMultiByte( CP_ACP, 0, z, n, buffer, sizeof buffer, NULL, NULL );
+  for(i=0; i<len; i++)
+      buffer[i] = toupper(buffer[i]);
+  for(i=0; i<KEYWORD_COUNT; i++)
+  {
+      if(memcmp(buffer, aKeywordTable[i].zName, len))
+          continue;
+      if(strlen(aKeywordTable[i].zName) == len )
+          return aKeywordTable[i].tokenType;
+  }
+  return TK_ID;
+}
+
+
+/*
+** If X is a character that can be used in an identifier then
+** isIdChar[X] will be 1.  Otherwise isIdChar[X] will be 0.
+**
+** In this implementation, an identifier can be a string of
+** alphabetic characters, digits, and "_" plus any character
+** with the high-order bit set.  The latter rule means that
+** any sequence of UTF-8 characters or characters taken from
+** an extended ISO8859 character set can form an identifier.
+*/
+static const char isIdChar[] = {
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 1x */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 8x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 9x */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Ax */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Bx */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Cx */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Dx */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Ex */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* Fx */
+};
+
+
+/*
+** Return the length of the token that begins at z[0].  Return
+** -1 if the token is (or might be) incomplete.  Store the token
+** type in *tokenType before returning.
+*/
+int sqliteGetToken(const WCHAR *z, int *tokenType){
+  int i;
+  switch( *z ){
+    case ' ': case '\t': case '\n': case '\f': case '\r': {
+      for(i=1; isspace(z[i]); i++){}
+      *tokenType = TK_SPACE;
+      return i;
+    }
+    case '-': {
+      if( z[1]==0 ) return -1;
+      if( z[1]=='-' ){
+        for(i=2; z[i] && z[i]!='\n'; i++){}
+        *tokenType = TK_COMMENT;
+        return i;
+      }
+      *tokenType = TK_MINUS;
+      return 1;
+    }
+    case '(': {
+      if( z[1]=='+' && z[2]==')' ){
+        *tokenType = TK_ORACLE_OUTER_JOIN;
+        return 3;
+      }else{
+        *tokenType = TK_LP;
+        return 1;
+      }
+    }
+    case ')': {
+      *tokenType = TK_RP;
+      return 1;
+    }
+    case ';': {
+      *tokenType = TK_SEMI;
+      return 1;
+    }
+    case '+': {
+      *tokenType = TK_PLUS;
+      return 1;
+    }
+    case '*': {
+      *tokenType = TK_STAR;
+      return 1;
+    }
+    case '/': {
+      if( z[1]!='*' || z[2]==0 ){
+        *tokenType = TK_SLASH;
+        return 1;
+      }
+      for(i=3; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
+      if( z[i] ) i++;
+      *tokenType = TK_COMMENT;
+      return i;
+    }
+    case '%': {
+      *tokenType = TK_REM;
+      return 1;
+    }
+    case '=': {
+      *tokenType = TK_EQ;
+      return 1 + (z[1]=='=');
+    }
+    case '<': {
+      if( z[1]=='=' ){
+        *tokenType = TK_LE;
+        return 2;
+      }else if( z[1]=='>' ){
+        *tokenType = TK_NE;
+        return 2;
+      }else if( z[1]=='<' ){
+        *tokenType = TK_LSHIFT;
+        return 2;
+      }else{
+        *tokenType = TK_LT;
+        return 1;
+      }
+    }
+    case '>': {
+      if( z[1]=='=' ){
+        *tokenType = TK_GE;
+        return 2;
+      }else if( z[1]=='>' ){
+        *tokenType = TK_RSHIFT;
+        return 2;
+      }else{
+        *tokenType = TK_GT;
+        return 1;
+      }
+    }
+    case '!': {
+      if( z[1]!='=' ){
+        *tokenType = TK_ILLEGAL;
+        return 2;
+      }else{
+        *tokenType = TK_NE;
+        return 2;
+      }
+    }
+    case '|': {
+      if( z[1]!='|' ){
+        *tokenType = TK_BITOR;
+        return 1;
+      }else{
+        *tokenType = TK_CONCAT;
+        return 2;
+      }
+    }
+    case '?': {
+      *tokenType = TK_WILDCARD;
+      return 1;
+    }
+    case ',': {
+      *tokenType = TK_COMMA;
+      return 1;
+    }
+    case '&': {
+      *tokenType = TK_BITAND;
+      return 1;
+    }
+    case '~': {
+      *tokenType = TK_BITNOT;
+      return 1;
+    }
+    case '`': case '\'': case '"': {
+      int delim = z[0];
+      for(i=1; z[i]; i++){
+        if( z[i]==delim ){
+          if( z[i+1]==delim ){
+            i++;
+          }else{
+            break;
+          }
+        }
+      }
+      if( z[i] ) i++;
+      *tokenType = TK_STRING;
+      return i;
+    }
+    case '.': {
+      if( !isdigit(z[1]) ){
+        *tokenType = TK_DOT;
+        return 1;
+      }
+      /* Fall thru into the next case */
+    }
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9': {
+      *tokenType = TK_INTEGER;
+      for(i=1; isdigit(z[i]); i++){}
+      if( z[i]=='.' ){
+        i++;
+        while( isdigit(z[i]) ){ i++; }
+        *tokenType = TK_FLOAT;
+      }
+      if( (z[i]=='e' || z[i]=='E') &&
+           ( isdigit(z[i+1]) 
+            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
+           )
+      ){
+        i += 2;
+        while( isdigit(z[i]) ){ i++; }
+        *tokenType = TK_FLOAT;
+      }else if( z[0]=='.' ){
+        *tokenType = TK_FLOAT;
+      }
+      return i;
+    }
+    case '[': {
+      for(i=1; z[i] && z[i-1]!=']'; i++){}
+      *tokenType = TK_ID;
+      return i;
+    }
+    default: {
+      if( !isIdChar[*z] ){
+        break;
+      }
+      for(i=1; isIdChar[z[i]]; i++){}
+      *tokenType = sqliteKeywordCode(z, i);
+      return i;
+    }
+  }
+  *tokenType = TK_ILLEGAL;
+  return 1;
+}

reactos/lib/msi
update.c added at 1.1.2.1
diff -N update.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ update.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,239 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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 receuved 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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIUPDATEVIEW
+{
+    MSIVIEW          view;
+    MSIDATABASE     *db;
+    MSIVIEW         *wv;
+    value_list      *vals;
+} MSIUPDATEVIEW;
+
+static UINT UPDATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+
+    TRACE("%p %d %d %p\n", uv, row, col, val );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+    UINT n, type, val, r, row, col_count = 0, row_count = 0;
+    MSIVIEW *wv;
+
+    TRACE("%p %p\n", uv, record );
+
+    if( !record )
+        return ERROR_FUNCTION_FAILED;
+
+    wv = uv->wv;
+    if( !wv )
+        return ERROR_FUNCTION_FAILED;
+
+    r = wv->ops->execute( wv, 0 );
+    TRACE("tv execute returned %x\n", r);
+    if( r )
+        return r;
+
+    r = wv->ops->get_dimensions( wv, &row_count, &col_count );
+    if( r )
+        goto err;
+
+    for( row = 0; row < row_count; row++ )
+    {
+        for( n = 1; n <= col_count; n++ )
+        {
+            r = wv->ops->get_column_info( wv, n, NULL, &type );
+            if( r )
+                break;
+
+            if( type & MSITYPE_STRING )
+            {
+                const WCHAR *str = MSI_RecordGetString( record, n );
+                val = msi_addstringW( uv->db->strings, 0, str, -1, 1 );
+            }
+            else
+            {
+                val = MSI_RecordGetInteger( record, n );
+                val |= 0x8000;
+            }
+            r = wv->ops->set_int( wv, row, n, val );
+            if( r )
+                break;
+        }
+    }
+
+err:
+    return ERROR_SUCCESS;
+}
+
+
+static UINT UPDATE_close( struct tagMSIVIEW *view )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+    MSIVIEW *wv;
+
+    TRACE("%p\n", uv);
+
+    wv = uv->wv;
+    if( !wv )
+        return ERROR_FUNCTION_FAILED;
+
+    return wv->ops->close( wv );
+}
+
+static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+    MSIVIEW *wv;
+
+    TRACE("%p %p %p\n", uv, rows, cols );
+
+    wv = uv->wv;
+    if( !wv )
+        return ERROR_FUNCTION_FAILED;
+
+    return wv->ops->get_dimensions( wv, rows, cols );
+}
+
+static UINT UPDATE_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+    MSIVIEW *wv;
+
+    TRACE("%p %d %p %p\n", uv, n, name, type );
+
+    wv = uv->wv;
+    if( !wv )
+        return ERROR_FUNCTION_FAILED;
+
+    return wv->ops->get_column_info( wv, n, name, type );
+}
+
+static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+
+    TRACE("%p %d %ld\n", uv, eModifyMode, hrec );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT UPDATE_delete( struct tagMSIVIEW *view )
+{
+    MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+    MSIVIEW *wv;
+
+    TRACE("%p\n", uv );
+
+    wv = uv->wv;
+    if( wv )
+        wv->ops->delete( wv );
+    delete_value_list( uv->vals );
+    msiobj_release( &uv->db->hdr );
+    HeapFree( GetProcessHeap(), 0, uv );
+
+    return ERROR_SUCCESS;
+}
+
+
+static MSIVIEWOPS update_ops =
+{
+    UPDATE_fetch_int,
+    NULL,
+    NULL,
+    NULL,
+    UPDATE_execute,
+    UPDATE_close,
+    UPDATE_get_dimensions,
+    UPDATE_get_column_info,
+    UPDATE_modify,
+    UPDATE_delete
+};
+
+UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+                        column_assignment *list, struct expr *expr )
+{
+    MSIUPDATEVIEW *uv = NULL;
+    UINT r;
+    MSIVIEW *tv = NULL, *sv = NULL, *wv = NULL;
+
+    TRACE("%p\n", uv );
+
+    r = TABLE_CreateView( db, table, &tv );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    /* add conditions first */
+    r = WHERE_CreateView( db, &wv, tv, expr );
+    if( r != ERROR_SUCCESS )
+    {
+        if( sv )
+            sv->ops->delete( tv );
+        return r;
+    }
+    
+    /* then select the columns we want */
+    r = SELECT_CreateView( db, &sv, wv, list->col_list );
+    if( r != ERROR_SUCCESS )
+    {
+        if( tv )
+            tv->ops->delete( sv );
+        return r;
+    }
+
+    uv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *uv );
+    if( !uv )
+        return ERROR_FUNCTION_FAILED;
+
+    /* fill the structure */
+    uv->view.ops = &update_ops;
+    msiobj_addref( &db->hdr );
+    uv->db = db;
+    uv->vals = list->val_list;
+    uv->wv = sv;
+    *view = (MSIVIEW*) uv;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
version.rc added at 1.1.2.1
diff -N version.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ version.rc	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2004 Christian Costa
+ *
+ * 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
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"
+#define WINE_FILENAME_STR "msi.dll"
+#define WINE_FILEVERSION 2,0,2600,0
+#define WINE_FILEVERSION_STR "2.0.2600.0"
+#define WINE_PRODUCTVERSION 2,0,2600,0
+#define WINE_PRODUCTVERSION_STR "2.0.2600.0"
+
+#include "wine/wine_common_ver.rc"

reactos/lib/msi
where.c added at 1.1.2.1
diff -N where.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ where.c	13 Dec 2004 16:18:26 -0000	1.1.2.1
@@ -0,0 +1,471 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * 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 <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.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);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIWHEREVIEW
+{
+    MSIVIEW        view;
+    MSIDATABASE   *db;
+    MSIVIEW       *table;
+    UINT           row_count;
+    UINT          *reorder;
+    struct expr   *cond;
+} MSIWHEREVIEW;
+
+static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %d %d %p\n", wv, row, col, val );
+
+    if( !wv->table )
+        return ERROR_FUNCTION_FAILED;
+
+    if( row > wv->row_count )
+        return ERROR_NO_MORE_ITEMS;
+
+    row = wv->reorder[ row ];
+
+    return wv->table->ops->fetch_int( wv->table, row, col, val );
+}
+
+static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %d %d %p\n", wv, row, col, stm );
+
+    if( !wv->table )
+        return ERROR_FUNCTION_FAILED;
+
+    if( row > wv->row_count )
+        return ERROR_NO_MORE_ITEMS;
+
+    row = wv->reorder[ row ];
+
+    return wv->table->ops->fetch_stream( wv->table, row, col, stm );
+}
+
+static UINT WHERE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %d %d %04x\n", wv, row, col, val );
+
+    if( !wv->table )
+         return ERROR_FUNCTION_FAILED;
+    
+    if( row > wv->row_count )
+        return ERROR_NO_MORE_ITEMS;
+    
+    row = wv->reorder[ row ];
+    
+    return wv->table->ops->set_int( wv->table, row, col, val );
+}
+
+static UINT INT_evaluate( UINT lval, UINT op, UINT rval )
+{
+    switch( op )
+    {
+    case OP_EQ:
+        return ( lval == rval );
+    case OP_AND:
+        return ( lval && rval );
+    case OP_OR:
+        return ( lval || rval );
+    case OP_GT:
+        return ( lval > rval );
+    case OP_LT:
+        return ( lval < rval );
+    case OP_LE:
+        return ( lval <= rval );
+    case OP_GE:
+        return ( lval >= rval );
+    case OP_NE:
+        return ( lval != rval );
+    case OP_ISNULL:
+        return ( !lval );
+    case OP_NOTNULL:
+        return ( lval );
+    default:
+        ERR("Unknown operator %d\n", op );
+    }
+    return 0;
+}
+
+static const WCHAR *STRING_evaluate( string_table *st,
+              MSIVIEW *table, UINT row, struct expr *expr, MSIRECORD *record )
+{
+    UINT val = 0, r;
+
+    switch( expr->type )
+    {
+    case EXPR_COL_NUMBER:
+        r = table->ops->fetch_int( table, row, expr->u.col_number, &val );
+        if( r != ERROR_SUCCESS )
+            return NULL;
+        return msi_string_lookup_id( st, val );
+
+    case EXPR_SVAL:
+        return expr->u.sval;
+
+    case EXPR_WILDCARD:
+        return MSI_RecordGetString( record, 1 );
+
+    default:
+        ERR("Invalid expression type\n");
+        break;
+    }
+    return NULL;
+}
+
+static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row, 
+                             struct expr *cond, UINT *val, MSIRECORD *record )
+{
+    int sr;
+    const WCHAR *l_str, *r_str;
+
+    l_str = STRING_evaluate( st, table, row, cond->u.expr.left, record );
+    r_str = STRING_evaluate( st, table, row, cond->u.expr.right, record );
+    if( l_str == r_str )
+        sr = 0;
+    else if( l_str && ! r_str )
+        sr = 1;
+    else if( r_str && ! l_str )
+        sr = -1;
+    else
+        sr = strcmpW( l_str, r_str );
+
+    *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) ||
+           ( cond->u.expr.op == OP_LT && ( sr < 0 ) ) ||
+           ( cond->u.expr.op == OP_GT && ( sr > 0 ) );
+
+    return ERROR_SUCCESS;
+}
+
+static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row, 
+                             struct expr *cond, UINT *val, MSIRECORD *record )
+{
+    UINT r, lval, rval;
+
+    if( !cond )
+        return ERROR_SUCCESS;
+
+    switch( cond->type )
+    {
+    case EXPR_COL_NUMBER:
+        return table->ops->fetch_int( table, row, cond->u.col_number, val );
+
+    case EXPR_UVAL:
+        *val = cond->u.uval;
+        return ERROR_SUCCESS;
+
+    case EXPR_COMPLEX:
+        r = WHERE_evaluate( db, table, row, cond->u.expr.left, &lval, record );
+        if( r != ERROR_SUCCESS )
+            return r;
+        r = WHERE_evaluate( db, table, row, cond->u.expr.right, &rval, record );
+        if( r != ERROR_SUCCESS )
+            return r;
+        *val = INT_evaluate( lval, cond->u.expr.op, rval );
+        return ERROR_SUCCESS;
+
+    case EXPR_STRCMP:
+        return STRCMP_Evaluate( db->strings, table, row, cond, val, record );
+
+    case EXPR_WILDCARD:
+        *val = MSI_RecordGetInteger( record, 1 );
+        return ERROR_SUCCESS;
+
+    default:
+        ERR("Invalid expression type\n");
+        break;
+    } 
+
+    return ERROR_SUCCESS;
+
+}
+
+static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+    UINT count = 0, r, val, i;
+    MSIVIEW *table = wv->table;
+
+    TRACE("%p %p\n", wv, record);
+
+    if( !table )
+         return ERROR_FUNCTION_FAILED;
+
+    r = table->ops->execute( table, record );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    r = table->ops->get_dimensions( table, &count, NULL );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    wv->reorder = HeapAlloc( GetProcessHeap(), 0, count*sizeof(UINT) );
+    if( !wv->reorder )
+        return ERROR_FUNCTION_FAILED;
+
+    for( i=0; i<count; i++ )
+    {
+        val = 0;
+        r = WHERE_evaluate( wv->db, table, i, wv->cond, &val, record );
+        if( r != ERROR_SUCCESS )
+            return r;
+        if( val )
+            wv->reorder[ wv->row_count ++ ] = i;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+static UINT WHERE_close( struct tagMSIVIEW *view )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p\n", wv );
+
+    if( !wv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( wv->reorder )
+        HeapFree( GetProcessHeap(), 0, wv->reorder );
+    wv->reorder = NULL;
+
+    return wv->table->ops->close( wv->table );
+}
+
+static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %p %p\n", wv, rows, cols );
+
+    if( !wv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    if( rows )
+    {
+        if( !wv->reorder )
+            return ERROR_FUNCTION_FAILED;
+        *rows = wv->row_count;
+    }
+
+    return wv->table->ops->get_dimensions( wv->table, NULL, cols );
+}
+
+static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %d %p %p\n", wv, n, name, type );
+
+    if( !wv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return wv->table->ops->get_column_info( wv->table, n, name, type );
+}
+
+static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p %d %ld\n", wv, eModifyMode, hrec );
+
+    if( !wv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return wv->table->ops->modify( wv->table, eModifyMode, hrec );
+}
+
+static UINT WHERE_delete( struct tagMSIVIEW *view )
+{
+    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+    TRACE("%p\n", wv );
+
+    if( wv->table )
+        wv->table->ops->delete( wv->table );
+
+    if( wv->reorder )
+        HeapFree( GetProcessHeap(), 0, wv->reorder );
+    wv->reorder = NULL;
+    wv->row_count = 0;
+
+    if( wv->cond )
+        delete_expr( wv->cond );
+
+    msiobj_release( &wv->db->hdr );
+    HeapFree( GetProcessHeap(), 0, wv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS where_ops =
+{
+    WHERE_fetch_int,
+    WHERE_fetch_stream,
+    WHERE_set_int,
+    NULL,
+    WHERE_execute,
+    WHERE_close,
+    WHERE_get_dimensions,
+    WHERE_get_column_info,
+    WHERE_modify,
+    WHERE_delete
+};
+
+static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr *cond,
+                                   UINT *valid )
+{
+    UINT r, val = 0;
+
+    switch( cond->type )
+    {
+    case EXPR_COLUMN:
+        r = VIEW_find_column( table, cond->u.column, &val );
+        if( r == ERROR_SUCCESS )
+        {
+            *valid = 1;
+            cond->type = EXPR_COL_NUMBER;
+            cond->u.col_number = val;
+        }
+        else
+        {
+            *valid = 0;
+            ERR("Couldn't find column %s\n", debugstr_w( cond->u.column ) );
+        }
+        break;
+    case EXPR_COMPLEX:
+        r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
+        if( r != ERROR_SUCCESS )
+            return r;
+        if( !*valid )
+            return ERROR_SUCCESS;
+        r = WHERE_VerifyCondition( db, table, cond->u.expr.right, valid );
+        if( r != ERROR_SUCCESS )
+            return r;
+
+        /* check the type of the comparison */
+        if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
+            ( cond->u.expr.right->type == EXPR_SVAL ) )
+        {
+            switch( cond->u.expr.op )
+            {
+            case OP_EQ:
+            case OP_GT:
+            case OP_LT:
+                break;
+            default:
+                *valid = FALSE;
+                return ERROR_INVALID_PARAMETER;
+            }
+
+            /* FIXME: check we're comparing a string to a column */
+
+            cond->type = EXPR_STRCMP;
+        }
+
+        break;
+    case EXPR_IVAL:
+        *valid = 1;
+        cond->type = EXPR_UVAL;
+        cond->u.uval = cond->u.ival + (1<<15);
+        break;
+    case EXPR_WILDCARD:
+        *valid = 1;
+        break;
+    case EXPR_SVAL:
+        *valid = 1;
+        break;
+    default:
+        ERR("Invalid expression type\n");
+        *valid = 0;
+        break;
+    } 
+
+    return ERROR_SUCCESS;
+}
+
+UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+                       struct expr *cond )
+{
+    MSIWHEREVIEW *wv = NULL;
+    UINT count = 0, r, valid = 0;
+
+    TRACE("%p\n", wv );
+
+    r = table->ops->get_dimensions( table, NULL, &count );
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("can't get table dimensions\n");
+        return r;
+    }
+
+    if( cond )
+    {
+        r = WHERE_VerifyCondition( db, table, cond, &valid );
+        if( r != ERROR_SUCCESS )
+            return r;
+        if( !valid )
+            return ERROR_FUNCTION_FAILED;
+    }
+
+    wv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *wv );
+    if( !wv )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    wv->view.ops = &where_ops;
+    msiobj_addref( &db->hdr );
+    wv->db = db;
+    wv->table = table;
+    wv->row_count = 0;
+    wv->reorder = NULL;
+    wv->cond = cond;
+    *view = (MSIVIEW*) wv;
+
+    return ERROR_SUCCESS;
+}

reactos/lib/msi
winehq2ros.patch added at 1.3.2.1
diff -N winehq2ros.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch	13 Dec 2004 16:18:26 -0000	1.3.2.1
@@ -0,0 +1,99 @@
+Index: action.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/action.c,v
+retrieving revision 1.40
+diff -u -r1.40 action.c
+--- action.c	3 Nov 2004 22:16:53 -0000	1.40
++++ action.c	7 Dec 2004 22:53:54 -0000
+@@ -28,7 +28,7 @@
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+-
++#include <fcntl.h>
+ #define COBJMACROS
+ 
+ #include "windef.h"
+@@ -39,7 +39,7 @@
+ #include "fdi.h"
+ #include "msi.h"
+ #include "msiquery.h"
+-#include "msvcrt/fcntl.h"
++//#include "msvcrt/fcntl.h"
+ #include "objbase.h"
+ #include "objidl.h"
+ #include "msipriv.h"
+@@ -2263,7 +2263,7 @@
+                     version = HeapAlloc(GetProcessHeap(),0,versize);
+                     GetFileVersionInfoW(file->TargetPath, 0, versize, version);
+ 
+-                    VerQueryValueW(version, name, (LPVOID*)&lpVer, &sz);
++                    VerQueryValueW(version, (LPWSTR) name, (LPVOID*)&lpVer, &sz);
+ 
+                     sprintfW(filever,name_fmt,
+                         HIWORD(lpVer->dwFileVersionMS),
+Index: msi.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/msi.c,v
+retrieving revision 1.42
+diff -u -r1.42 msi.c
+--- msi.c	7 Oct 2004 03:06:50 -0000	1.42
++++ msi.c	7 Dec 2004 22:53:55 -0000
+@@ -40,6 +40,9 @@
+ 
+ #include "initguid.h"
+ 
++UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf);
++
++
+ WINE_DEFAULT_DEBUG_CHANNEL(msi);
+ 
+ /*
+@@ -1392,7 +1395,7 @@
+           lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
+           lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
+ 
+-    dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
++    dwVerLen = GetFileVersionInfoSizeW( (LPWSTR) szFilePath, NULL);
+     if(!dwVerLen)
+         return GetLastError();
+ 
+@@ -1402,12 +1405,12 @@
+         goto end;
+     }
+ 
+-    if(!GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer)) {
++    if(!GetFileVersionInfoW((LPWSTR) szFilePath, 0, dwVerLen, lpVer)) {
+         ret = GetLastError();
+         goto end;
+     }
+     if(lpVersionBuf && pcchVersionBuf && *pcchVersionBuf) {
+-        if(VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) && puLen > 0) {
++        if(VerQueryValueW(lpVer, (LPWSTR) szVersionResource, (LPVOID*)&ffi, &puLen) && puLen > 0) {
+             wsprintfW(tmp, szVersionFormat, HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
+             lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
+             *pcchVersionBuf = strlenW(lpVersionBuf);
+Index: suminfo.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/suminfo.c,v
+retrieving revision 1.9
+diff -u -r1.9 suminfo.c
+--- suminfo.c	7 Oct 2004 03:06:50 -0000	1.9
++++ suminfo.c	7 Dec 2004 22:53:55 -0000
+@@ -23,6 +23,8 @@
+ #define COBJMACROS
+ #define NONAMELESSUNION
+ 
++#define PRSPEC_PROPID (1)
++
+ #include "windef.h"
+ #include "winbase.h"
+ #include "winreg.h"
+@@ -116,6 +118,7 @@
+     ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
+ 
+     grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
++
+     r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
+     if( FAILED( r ) )
+     {

reactos/lib/msvcrt/tests
.cvsignore added at 1.1.2.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,6 @@
+*.d
+*.o
+*.exe
+*.a
+*.map
+*.sym
\ No newline at end of file

reactos/lib/msvcrt/tests
Makefile added at 1.2.2.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	13 Dec 2004 16:18:27 -0000	1.2.2.1
@@ -0,0 +1,34 @@
+# $Id: Makefile,v 1.2.2.1 2004/12/13 16:18:27 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+TARGET_NORC = yes
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = console
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \
+	-D_WIN32_WINNT=0x0501 -D__REACTOS__
+
+TARGET_NAME = msvcrt_test
+
+TARGET_SDKLIBS = ntdll.a wine.a
+
+TARGET_OBJECTS = \
+	testlist.o \
+	cpp.o \
+	environ.o \
+	file.o \
+	heap.o \
+	printf.o \
+	scanf.o \
+	string.o \
+	time.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# EOF
\ No newline at end of file

reactos/lib/msvcrt/tests
Makefile.in added at 1.1.2.1
diff -N Makefile.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile.in	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,21 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+TESTDLL   = msvcrt.dll
+IMPORTS   = msvcrt
+EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt -I$(SRCDIR)/..
+
+CTESTS = \
+	cpp.c \
+	environ.c \
+	file.c \
+	heap.c \
+	printf.c \
+	scanf.c \
+	string.c \
+	time.c
+
+@MAKE_TEST_RULES@
+
+### Dependencies:

reactos/lib/msvcrt/tests
cpp.c added at 1.2.2.1
diff -N cpp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cpp.c	13 Dec 2004 16:18:27 -0000	1.2.2.1
@@ -0,0 +1,831 @@
+/* Unit test suite for msvcrt C++ objects
+ *
+ * Copyright 2003 Jon Griffiths
+ *
+ * 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
+ *
+ * NOTES
+ * This tests is only valid for ix86 platforms, on others it's a no-op.
+ * Some tests cannot be checked with ok(), for example the dtors. We simply
+ * call them to ensure we don't crash ;-)
+ *
+ * If we build this test with VC++ in debug mode, we will fail in _chkstk()
+ * or at program exit malloc() checking if these methods haven't been
+ * implemented correctly (they have).
+ *
+ * Tested with a range of native msvcrt's from v4 -> v7.
+ */
+#include "wine/test.h"
+#include "winbase.h"
+#include "winnt.h"
+
+#ifndef __i386__
+/* Skip these tests for non x86 platforms */
+START_TEST(cpp)
+{
+}
+#else
+
+typedef struct __exception
+{
+  void *vtable;
+  char *name;
+  int   do_free;
+} exception;
+
+typedef struct __type_info
+{
+  void *vtable;
+  char *name;
+  char  mangled[16];
+} type_info;
+
+/* Function pointers. We need to use these to call these funcs as __thiscall */
+static HMODULE hMsvcrt;
+
+static void* (*poperator_new)(unsigned int);
+static void  (*poperator_delete)(void*);
+static void* (*pmalloc)(unsigned int);
+static void  (*pfree)(void*);
+
+/* exception */
+static void (WINAPI *pexception_ctor)(exception*,LPCSTR*);
+static void (WINAPI *pexception_copy_ctor)(exception*,exception*);
+static void (WINAPI *pexception_default_ctor)(exception*);
+static void (WINAPI *pexception_dtor)(exception*);
+static exception* (WINAPI *pexception_opequals)(exception*,exception*);
+static char* (WINAPI *pexception_what)(exception*);
+static void* (WINAPI *pexception_vtable)(exception*);
+static void (WINAPI *pexception_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pexception_scalar_dtor)(exception*,unsigned int);
+
+/* bad_typeid */
+static void (WINAPI *pbad_typeid_ctor)(exception*,LPCSTR);
+static void (WINAPI *pbad_typeid_ctor_closure)(exception*);
+static void (WINAPI *pbad_typeid_copy_ctor)(exception*,exception*);
+static void (WINAPI *pbad_typeid_dtor)(exception*);
+static exception* (WINAPI *pbad_typeid_opequals)(exception*,exception*);
+static char* (WINAPI *pbad_typeid_what)(exception*);
+static void* (WINAPI *pbad_typeid_vtable)(exception*);
+static void (WINAPI *pbad_typeid_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pbad_typeid_scalar_dtor)(exception*,unsigned int);
+
+/* bad_cast */
+static void (WINAPI *pbad_cast_ctor)(exception*,LPCSTR*);
+static void (WINAPI *pbad_cast_ctor2)(exception*,LPCSTR);
+static void (WINAPI *pbad_cast_ctor_closure)(exception*);
+static void (WINAPI *pbad_cast_copy_ctor)(exception*,exception*);
+static void (WINAPI *pbad_cast_dtor)(exception*);
+static exception* (WINAPI *pbad_cast_opequals)(exception*,exception*);
+static char* (WINAPI *pbad_cast_what)(exception*);
+static void* (WINAPI *pbad_cast_vtable)(exception*);
+static void (WINAPI *pbad_cast_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pbad_cast_scalar_dtor)(exception*,unsigned int);
+
+/* __non_rtti_object */
+static void (WINAPI *p__non_rtti_object_ctor)(exception*,LPCSTR);
+static void (WINAPI *p__non_rtti_object_copy_ctor)(exception*,exception*);
+static void (WINAPI *p__non_rtti_object_dtor)(exception*);
+static exception* (WINAPI *p__non_rtti_object_opequals)(exception*,exception*);
+static char* (WINAPI *p__non_rtti_object_what)(exception*);
+static void* (WINAPI *p__non_rtti_object_vtable)(exception*);
+static void (WINAPI *p__non_rtti_object_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *p__non_rtti_object_scalar_dtor)(exception*,unsigned int);
+
+/* type_info */
+static void  (WINAPI *ptype_info_dtor)(type_info*);
+static char* (WINAPI *ptype_info_raw_name)(type_info*);
+static char* (WINAPI *ptype_info_name)(type_info*);
+static int   (WINAPI *ptype_info_before)(type_info*,type_info*);
+static int   (WINAPI *ptype_info_opequals_equals)(type_info*,type_info*);
+static int   (WINAPI *ptype_info_opnot_equals)(type_info*,type_info*);
+
+/* RTTI */
+static type_info* (*p__RTtypeid)(void*);
+static void* (*p__RTCastToVoid)(void*);
+static void* (*p__RTDynamicCast)(void*,int,void*,void*,int);
+
+/* _very_ early native versions have serious RTTI bugs, so we check */
+static void* bAncientVersion;
+
+/* Emulate a __thiscall */
+#ifdef _MSC_VER
+inline static void* do_call_func1(void *func, void *_this)
+{
+  volatile void* retval = 0;
+  __asm
+  {
+    push ecx
+    mov ecx, _this
+    call func
+    mov retval, eax
+    pop ecx
+  }
+  return (void*)retval;
+}
+
+inline static void* do_call_func2(void *func, void *_this, void* arg)
+{
+  volatile void* retval = 0;
+  __asm
+  {
+    push ecx
+    push arg
+    mov ecx, _this
+    call func
+    mov retval, eax
+    pop ecx
+  }
+  return (void*)retval;
+}
+#else
+static void* do_call_func1(void *func, void *_this)
+{
+  void* ret;
+  __asm__ __volatile__ ("call *%1"
+                        : "=a" (ret)
+                        : "g" (func), "c" (_this)
+                        : "memory" );
+  return ret;
+}
+static void* do_call_func2(void *func, void *_this, void* arg)
+{
+  void* ret;
+  __asm__ __volatile__ ("pushl %2\n\tcall *%1"
+                        : "=a" (ret)
+                        : "r" (func), "g" (arg), "c" (_this)
+                        : "memory" );
+  return ret;
+}
+#endif
+
+#define call_func1(x,y)   do_call_func1((void*)x,(void*)y)
+#define call_func2(x,y,z) do_call_func2((void*)x,(void*)y,(void*)z)
+
+/* Some exports are only available in later versions */
+#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
+#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
+
+static void InitFunctionPtrs()
+{
+  hMsvcrt = LoadLibraryA("msvcrt.dll");
+  ok(hMsvcrt != 0, "LoadLibraryA failed\n");
+  if (hMsvcrt)
+  {
+    SETNOFAIL(poperator_new, "??_U@YAPAXI@Z");
+    SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z");
+    SET(pmalloc, "malloc");
+    SET(pfree, "free");
+
+    if (!poperator_new)
+      poperator_new = pmalloc;
+    if (!poperator_delete)
+      poperator_delete = pfree;
+
+    SET(pexception_ctor, "??0exception@@QAE@ABQBD@Z");
+    SET(pexception_copy_ctor, "??0exception@@QAE@ABV0@@Z");
+    SET(pexception_default_ctor, "??0exception@@QAE@XZ");
+    SET(pexception_dtor, "??1exception@@UAE@XZ");
+    SET(pexception_opequals, "??4exception@@QAEAAV0@ABV0@@Z");
+    SET(pexception_what, "?what@exception@@UBEPBDXZ");
+    SET(pexception_vtable, "??_7exception@@6B@");
+    SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");
+    SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");
+
+    SET(pbad_typeid_ctor, "??0bad_typeid@@QAE@PBD@Z");
+    SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAEXXZ");
+    SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAE@ABV0@@Z");
+    SET(pbad_typeid_dtor, "??1bad_typeid@@UAE@XZ");
+    SET(pbad_typeid_opequals, "??4bad_typeid@@QAEAAV0@ABV0@@Z");
+    SET(pbad_typeid_what, "?what@exception@@UBEPBDXZ");
+    SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@");
+    SET(pbad_typeid_vector_dtor, "??_Ebad_typeid@@UAEPAXI@Z");
+    SET(pbad_typeid_scalar_dtor, "??_Gbad_typeid@@UAEPAXI@Z");
+
+    SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z");
+    if (!pbad_cast_ctor)
+      SET(pbad_cast_ctor, "??0bad_cast@@AAE@PBQBD@Z");
+    SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAE@PBD@Z");
+    SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAEXXZ");
+    SET(pbad_cast_copy_ctor, "??0bad_cast@@QAE@ABV0@@Z");
+    SET(pbad_cast_dtor, "??1bad_cast@@UAE@XZ");
+    SET(pbad_cast_opequals, "??4bad_cast@@QAEAAV0@ABV0@@Z");
+    SET(pbad_cast_what, "?what@exception@@UBEPBDXZ");
+    SET(pbad_cast_vtable, "??_7bad_cast@@6B@");
+    SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z");
+    SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z");
+
+    SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAE@PBD@Z");
+    SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@@QAE@ABV0@@Z");
+    SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAE@XZ");
+    SET(p__non_rtti_object_opequals, "??4__non_rtti_object@@QAEAAV0@ABV0@@Z");
+    SET(p__non_rtti_object_what, "?what@exception@@UBEPBDXZ");
+    SET(p__non_rtti_object_vtable, "??_7__non_rtti_object@@6B@");
+    SET(p__non_rtti_object_vector_dtor, "??_E__non_rtti_object@@UAEPAXI@Z");
+    SET(p__non_rtti_object_scalar_dtor, "??_G__non_rtti_object@@UAEPAXI@Z");
+
+    SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
+    SET(ptype_info_raw_name, "?raw_name@type_info@@QBEPBDXZ");
+#ifndef __REACTOS__
+    SET(ptype_info_name, "?name@type_info@@QBEPBDXZ");
+#endif
+    SET(ptype_info_before, "?before@type_info@@QBEHABV1@@Z");
+    SET(ptype_info_opequals_equals, "??8type_info@@QBEHABV0@@Z");
+    SET(ptype_info_opnot_equals, "??9type_info@@QBEHABV0@@Z");
+
+    SET(p__RTtypeid, "__RTtypeid");
+    SET(p__RTCastToVoid, "__RTCastToVoid");
+    SET(p__RTDynamicCast, "__RTDynamicCast");
+
+    /* Extremely early versions export logic_error, and crash in RTTI */
+    SETNOFAIL(bAncientVersion, "??0logic_error@@QAE@ABQBD@Z");
+  }
+}
+
+static void test_exception(void)
+{
+  static const char* e_name = "An exception name";
+  char* name;
+  exception e, e2, e3, *pe;
+
+  if (!poperator_new || !poperator_delete ||
+      !pexception_ctor || !pexception_copy_ctor || !pexception_default_ctor ||
+      !pexception_dtor || !pexception_opequals || !pexception_what ||
+      !pexception_vtable || !pexception_vector_dtor || !pexception_scalar_dtor)
+    return;
+
+  /* 'const char*&' ctor */
+  memset(&e, 0, sizeof(e));
+  call_func2(pexception_ctor, &e, &e_name);
+  ok(e.vtable != NULL, "Null exception vtable for e\n");
+  ok(e.name && e.name != e_name && !strcmp(e.name, "An exception name"), "Bad name '%s' for e\n", e.name);
+  ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+  /* Copy ctor */
+  memset(&e2, 0, sizeof(e2));
+  call_func2(pexception_copy_ctor, &e2, &e);
+  ok(e2.vtable != NULL, "Null exception vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "An exception name"), "Bad exception name for e2\n");
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+  /* Default ctor */
+  memset(&e3, 1, sizeof(e3));
+  call_func1(pexception_default_ctor, &e3);
+  ok(e3.vtable != NULL, "Null exception vtable for e3\n");
+  ok(e3.name == NULL, "Bad exception name for e3\n");
+  ok(e3.do_free == 0, "do_free set to %d for e3\n", e3.do_free);
+
+  ok(e.vtable == e2.vtable && e.vtable == e3.vtable, "exception vtables differ!\n");
+
+  /* Test calling the dtors */
+  call_func1(pexception_dtor, &e2);
+  call_func1(pexception_dtor, &e3);
+
+  /* Operator equals */
+  memset(&e2, 0, sizeof(e2));
+  pe = call_func2(pexception_opequals, &e2, &e);
+  ok(e2.vtable != NULL, "Null exception vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "An exception name"), "Bad exception name for e2\n");
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+  ok(pe == &e2, "opequals didn't return e2\n");
+
+  /* what() */
+  name = call_func1(pexception_what, &e2);
+  ok(e2.name == name, "Bad exception name from e2::what()\n");
+
+  /* vtable ptr */
+  ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+  call_func1(pexception_dtor, &e2);
+
+  /* new() */
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    call_func2(pexception_ctor, pe, &e_name);
+    /* scalar dtor */
+    call_func2(pexception_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+    pe->name = NULL;
+    pe->do_free = 0;
+    call_func2(pexception_scalar_dtor, pe, 1); /* Should delete pe */
+  }
+
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, single element */
+    call_func2(pexception_ctor, pe, &e_name);
+    call_func2(pexception_vector_dtor, pe, 1); /* Should delete pe as single element*/
+  }
+
+  pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, multiple elements */
+    char name[] = "a constant";
+    *((int*)pe) = 3;
+    pe = (exception*)((int*)pe + 1);
+    call_func2(pexception_ctor, &pe[0], &e_name);
+    call_func2(pexception_ctor, &pe[1], &e_name);
+    call_func2(pexception_ctor, &pe[2], &e_name);
+    pe[3].name = name;
+    pe[3].do_free = 1; /* Crash if we try to free this */
+    call_func2(pexception_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+  }
+
+  /* test our exported vtable is kosher */
+  pe = (void*)pexception_vtable; /* Use the exception struct to get vtable ptrs */
+  pexception_vector_dtor = (void*)pe->vtable;
+  pexception_what = (void*)pe->name;
+
+  name = call_func1(pexception_what, &e);
+  ok(e.name == name, "Bad exception name from vtable e::what()\n");
+
+  if (p__RTtypeid && !bAncientVersion)
+  {
+    /* Check the rtti */
+    type_info *ti = p__RTtypeid(&e);
+    ok (ti && ti->mangled &&
+        !strcmp(ti->mangled, ".?AVexception@@"), "bad rtti for e\n");
+
+    if (ti)
+    {
+      /* Check the returned type_info has rtti too */
+      type_info *ti2 = p__RTtypeid(ti);
+      ok (ti2 != NULL && !strcmp(ti2->mangled, ".?AVtype_info@@"), "bad rtti for e's type_info\n");
+    }
+  }
+
+  call_func2(pexception_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+/* This test is basically a cut 'n' paste of the exception test. but it verifies that
+ * bad_typeid works the exact same way... */
+static void test_bad_typeid(void)
+{
+  static const char* e_name = "A bad_typeid name";
+  char* name;
+  exception e, e2, e3, *pe;
+
+  if (!poperator_new || !poperator_delete ||
+      !pbad_typeid_ctor || !pbad_typeid_copy_ctor ||
+      !pbad_typeid_dtor || !pbad_typeid_opequals || !pbad_typeid_what ||
+      !pbad_typeid_vtable || !pbad_typeid_vector_dtor || !pbad_typeid_scalar_dtor)
+    return;
+
+  /* 'const char*' ctor */
+  memset(&e, 0, sizeof(e));
+  call_func2(pbad_typeid_ctor, &e, e_name);
+  ok(e.vtable != NULL, "Null bad_typeid vtable for e\n");
+  ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_typeid name"), "Bad name '%s' for e\n", e.name);
+  ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+  /* Copy ctor */
+  memset(&e2, 0, sizeof(e2));
+  call_func2(pbad_typeid_copy_ctor, &e2, &e);
+  ok(e2.vtable != NULL, "Null bad_typeid vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_typeid name"), "Bad name '%s' for e2\n", e2.name);
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+  /* Ctor closure */
+  if (pbad_typeid_ctor_closure)
+  {
+    memset(&e3, 1, sizeof(e3));
+    call_func1(pbad_typeid_ctor_closure, &e3);
+    ok(e3.vtable != NULL, "Null bad_typeid vtable for e3\n");
+    ok(e3.name && !strcmp(e3.name, "bad typeid"), "Bad bad_typeid name for e3\n");
+    ok(e3.do_free == 1, "do_free set to %d for e3\n", e3.do_free);
+    ok(e.vtable == e3.vtable, "bad_typeid closure vtables differ!\n");
+    call_func1(pbad_typeid_dtor, &e3);
+  }
+  ok(e.vtable == e2.vtable, "bad_typeid vtables differ!\n");
+
+  /* Test calling the dtors */
+  call_func1(pbad_typeid_dtor, &e2);
+
+  /* Operator equals */
+  memset(&e2, 1, sizeof(e2));
+  pe = call_func2(pbad_typeid_opequals, &e2, &e);
+  ok(e2.vtable != NULL, "Null bad_typeid vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_typeid name"), "Bad bad_typeid name for e2\n");
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+  ok(pe == &e2, "opequals didn't return e2\n");
+
+  /* what() */
+  name = call_func1(pbad_typeid_what, &e2);
+  ok(e2.name == name, "Bad bad_typeid name from e2::what()\n");
+
+  /* vtable ptr */
+  ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+  call_func1(pbad_typeid_dtor, &e2);
+
+  /* new() */
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    call_func2(pbad_typeid_ctor, pe, e_name);
+    /* scalar dtor */
+    call_func2(pbad_typeid_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+    pe->name = NULL;
+    pe->do_free = 0;
+    call_func2(pbad_typeid_scalar_dtor, pe, 1); /* Should delete pe */
+  }
+
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, single element */
+    call_func2(pbad_typeid_ctor, pe, e_name);
+    call_func2(pbad_typeid_vector_dtor, pe, 1); /* Should delete pe as single element*/
+  }
+
+  pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, multiple elements */
+    *((int*)pe) = 3;
+    pe = (exception*)((int*)pe + 1);
+    call_func2(pbad_typeid_ctor, &pe[0], e_name);
+    call_func2(pbad_typeid_ctor, &pe[1], e_name);
+    call_func2(pbad_typeid_ctor, &pe[2], e_name);
+    pe[3].name = 0;
+    pe[3].do_free = 1; /* Crash if we try to free this element */
+    call_func2(pbad_typeid_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+  }
+
+  /* test our exported vtable is kosher */
+  pe = (void*)pbad_typeid_vtable; /* Use the exception struct to get vtable ptrs */
+  pbad_typeid_vector_dtor = (void*)pe->vtable;
+  pbad_typeid_what = (void*)pe->name;
+
+  name = call_func1(pbad_typeid_what, &e);
+  ok(e.name == name, "Bad bad_typeid name from vtable e::what()\n");
+
+  if (p__RTtypeid && !bAncientVersion)
+  {
+    /* Check the rtti */
+    type_info *ti = p__RTtypeid(&e);
+    ok (ti != NULL && !strcmp(ti->mangled, ".?AVbad_typeid@@"), "bad rtti for e (%s)\n",
+        !ti ? "null" : ti->mangled);
+  }
+
+  call_func2(pbad_typeid_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+
+/* Ditto for this test... */
+static void test_bad_cast(void)
+{
+  static const char* e_name = "A bad_cast name";
+  char* name;
+  exception e, e2, e3, *pe;
+
+  if (!poperator_new || !poperator_delete ||
+      !pbad_cast_ctor || !pbad_cast_copy_ctor ||
+      !pbad_cast_dtor || !pbad_cast_opequals || !pbad_cast_what ||
+      !pbad_cast_vtable || !pbad_cast_vector_dtor || !pbad_cast_scalar_dtor)
+    return;
+
+  if (pbad_cast_ctor2)
+  {
+    /* 'const char*' ctor */
+    memset(&e, 0, sizeof(e));
+    call_func2(pbad_cast_ctor2, &e, e_name);
+    ok(e.vtable != NULL, "Null bad_cast vtable for e\n");
+    ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_cast name"), "Bad name '%s' for e\n", e.name);
+    ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+    call_func1(pbad_cast_dtor, &e);
+  }
+
+  /* 'const char*&' ctor */
+  memset(&e, 0, sizeof(e));
+  call_func2(pbad_cast_ctor, &e, &e_name);
+  ok(e.vtable != NULL, "Null bad_cast vtable for e\n");
+  ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_cast name"), "Bad name '%s' for e\n", e.name);
+  ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+  /* Copy ctor */
+  memset(&e2, 0, sizeof(e2));
+  call_func2(pbad_cast_copy_ctor, &e2, &e);
+  ok(e2.vtable != NULL, "Null bad_cast vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_cast name"), "Bad name '%s' for e2\n", e2.name);
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+  /* Ctor closure */
+  if (pbad_cast_ctor_closure)
+  {
+    memset(&e3, 1, sizeof(e3));
+    call_func1(pbad_cast_ctor_closure, &e3);
+    ok(e3.vtable != NULL, "Null bad_cast vtable for e3\n");
+    ok(e3.name && !strcmp(e3.name, "bad cast"), "Bad bad_cast name for e3\n");
+    ok(e3.do_free == 1, "do_free set to %d for e3\n", e3.do_free);
+    ok(e.vtable == e3.vtable, "bad_cast closure vtables differ!\n");
+    call_func1(pbad_cast_dtor, &e3);
+  }
+  ok(e.vtable == e2.vtable, "bad_cast vtables differ!\n");
+
+  /* Test calling the dtors */
+  call_func1(pbad_cast_dtor, &e2);
+
+  /* Operator equals */
+  memset(&e2, 1, sizeof(e2));
+  pe = call_func2(pbad_cast_opequals, &e2, &e);
+  ok(e2.vtable != NULL, "Null bad_cast vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_cast name"), "Bad bad_cast name for e2\n");
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+  ok(pe == &e2, "opequals didn't return e2\n");
+
+  /* what() */
+  name = call_func1(pbad_cast_what, &e2);
+  ok(e2.name == name, "Bad bad_cast name from e2::what()\n");
+
+  /* vtable ptr */
+  ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+  call_func1(pbad_cast_dtor, &e2);
+
+  /* new() */
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    call_func2(pbad_cast_ctor, pe, &e_name);
+    /* scalar dtor */
+    call_func2(pbad_cast_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+    pe->name = NULL;
+    pe->do_free = 0;
+    call_func2(pbad_cast_scalar_dtor, pe, 1); /* Should delete pe */
+  }
+
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, single element */
+    call_func2(pbad_cast_ctor, pe, &e_name);
+    call_func2(pbad_cast_vector_dtor, pe, 1); /* Should delete pe as single element*/
+  }
+
+  pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, multiple elements */
+    *((int*)pe) = 3;
+    pe = (exception*)((int*)pe + 1);
+    call_func2(pbad_cast_ctor, &pe[0], &e_name);
+    call_func2(pbad_cast_ctor, &pe[1], &e_name);
+    call_func2(pbad_cast_ctor, &pe[2], &e_name);
+    pe[3].name = 0;
+    pe[3].do_free = 1; /* Crash if we try to free this element */
+    call_func2(pbad_cast_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+  }
+
+  /* test our exported vtable is kosher */
+  pe = (void*)pbad_cast_vtable; /* Use the exception struct to get vtable ptrs */
+  pbad_cast_vector_dtor = (void*)pe->vtable;
+  pbad_cast_what = (void*)pe->name;
+
+  name = call_func1(pbad_cast_what, &e);
+  ok(e.name == name, "Bad bad_cast name from vtable e::what()\n");
+
+  if (p__RTtypeid && !bAncientVersion)
+  {
+    /* Check the rtti */
+    type_info *ti = p__RTtypeid(&e);
+    ok (ti != NULL && !strcmp(ti->mangled, ".?AVbad_cast@@"), "bad rtti for e\n");
+  }
+  call_func2(pbad_cast_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+/* ... and this one */
+static void test___non_rtti_object(void)
+{
+  static const char* e_name = "A __non_rtti_object name";
+  char* name;
+  exception e, e2, *pe;
+
+  if (!poperator_new || !poperator_delete ||
+      !p__non_rtti_object_ctor || !p__non_rtti_object_copy_ctor ||
+      !p__non_rtti_object_dtor || !p__non_rtti_object_opequals || !p__non_rtti_object_what ||
+      !p__non_rtti_object_vtable || !p__non_rtti_object_vector_dtor || !p__non_rtti_object_scalar_dtor)
+    return;
+
+  /* 'const char*' ctor */
+  memset(&e, 0, sizeof(e));
+  call_func2(p__non_rtti_object_ctor, &e, e_name);
+  ok(e.vtable != NULL, "Null __non_rtti_object vtable for e\n");
+  ok(e.name && e.name != e_name && !strcmp(e.name, "A __non_rtti_object name"), "Bad name '%s' for e\n", e.name);
+  ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+  /* Copy ctor */
+  memset(&e2, 0, sizeof(e2));
+  call_func2(p__non_rtti_object_copy_ctor, &e2, &e);
+  ok(e2.vtable != NULL, "Null __non_rtti_object vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A __non_rtti_object name"), "Bad name '%s' for e2\n", e2.name);
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+  ok(e.vtable == e2.vtable, "__non_rtti_object vtables differ!\n");
+
+  /* Test calling the dtors */
+  call_func1(p__non_rtti_object_dtor, &e2);
+
+  /* Operator equals */
+  memset(&e2, 1, sizeof(e2));
+  pe = call_func2(p__non_rtti_object_opequals, &e2, &e);
+  ok(e2.vtable != NULL, "Null __non_rtti_object vtable for e2\n");
+  ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A __non_rtti_object name"), "Bad __non_rtti_object name for e2\n");
+  ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+  ok(pe == &e2, "opequals didn't return e2\n");
+
+  /* what() */
+  name = call_func1(p__non_rtti_object_what, &e2);
+  ok(e2.name == name, "Bad __non_rtti_object name from e2::what()\n");
+
+  /* vtable ptr */
+  ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+  call_func1(p__non_rtti_object_dtor, &e2);
+
+  /* new() */
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    call_func2(p__non_rtti_object_ctor, pe, e_name);
+    /* scalar dtor */
+    call_func2(p__non_rtti_object_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+    pe->name = NULL;
+    pe->do_free = 0;
+    call_func2(p__non_rtti_object_scalar_dtor, pe, 1); /* Should delete pe */
+  }
+
+  pe = poperator_new(sizeof(exception));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, single element */
+    call_func2(p__non_rtti_object_ctor, pe, e_name);
+    call_func2(p__non_rtti_object_vector_dtor, pe, 1); /* Should delete pe as single element*/
+  }
+
+  pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+  ok(pe != NULL, "new() failed\n");
+  if (pe)
+  {
+    /* vector dtor, multiple elements */
+    *((int*)pe) = 3;
+    pe = (exception*)((int*)pe + 1);
+    call_func2(p__non_rtti_object_ctor, &pe[0], e_name);
+    call_func2(p__non_rtti_object_ctor, &pe[1], e_name);
+    call_func2(p__non_rtti_object_ctor, &pe[2], e_name);
+    pe[3].name = 0;
+    pe[3].do_free = 1; /* Crash if we try to free this element */
+    call_func2(p__non_rtti_object_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+  }
+
+  /* test our exported vtable is kosher */
+  pe = (void*)p__non_rtti_object_vtable; /* Use the exception struct to get vtable ptrs */
+  p__non_rtti_object_vector_dtor = (void*)pe->vtable;
+  p__non_rtti_object_what = (void*)pe->name;
+
+  name = call_func1(p__non_rtti_object_what, &e);
+  ok(e.name == name, "Bad __non_rtti_object name from vtable e::what()\n");
+
+  if (p__RTtypeid && !bAncientVersion)
+  {
+    /* Check the rtti */
+    type_info *ti = p__RTtypeid(&e);
+    ok (ti != NULL && !strcmp(ti->mangled, ".?AV__non_rtti_object@@"), "bad rtti for e\n");
+  }
+  call_func2(p__non_rtti_object_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+
+static void test_type_info(void)
+{
+  static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
+  static type_info t1_1 = { NULL, NULL,{'?','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
+  static type_info t2 = { NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0,0,0,0,0 } };
+  char* name;
+  int res;
+
+  if (!pmalloc || !pfree || !ptype_info_dtor || !ptype_info_raw_name ||
+      !ptype_info_name || !ptype_info_before ||
+      !ptype_info_opequals_equals || !ptype_info_opnot_equals)
+    return;
+
+  /* Test calling the dtors */
+  call_func1(ptype_info_dtor, &t1); /* No effect, since name is NULL */
+  t1.name = pmalloc(64);
+  strcpy(t1.name, "foo");
+  call_func1(ptype_info_dtor, &t1); /* Frees t1.name using 'free' */
+
+  /* raw_name */
+  t1.name = NULL;
+  name = call_func1(ptype_info_raw_name, &t1);
+
+  /* FIXME: This fails on native; it shouldn't though - native bug?
+   * ok(name && !strcmp(name, t1.mangled), "bad raw_name '%s' for t1 (expected '%s')\n", name, t1.mangled);
+   */
+  ok(t1.name == NULL, "raw_name() set name for t1\n");
+
+  /* name */
+  t1.name = NULL;
+  name = call_func1(ptype_info_name, &t1);
+  ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
+
+  ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
+  call_func1(ptype_info_dtor, &t1);
+
+  /* before */
+  t1.name = NULL;
+  res = (int)call_func2(ptype_info_before, &t1, &t1);
+  ok(res == 0, "expected 0, got %d\n", res);
+  res = (int)call_func2(ptype_info_before, &t2, &t1);
+  ok(res == 0, "expected 0, got %d\n", res);
+  res = (int)call_func2(ptype_info_before, &t1, &t2);
+  ok(res == 1, "expected 1, got %d\n", res);
+  /* Doesn't check first char */
+  res = (int)call_func2(ptype_info_before, &t1, &t1_1);
+  ok(res == 0, "expected 0, got %d\n", res);
+
+  /* opequals_equals */
+  t1.name = NULL;
+  res = (int)call_func2(ptype_info_opequals_equals, &t1, &t1);
+  ok(res == 1, "expected 1, got %d\n", res);
+  res = (int)call_func2(ptype_info_opequals_equals, &t1, &t2);
+  ok(res == 0, "expected 0, got %d\n", res);
+  res = (int)call_func2(ptype_info_opequals_equals, &t2, &t1);
+  ok(res == 0, "expected 0, got %d\n", res);
+
+  /* opnot_equals */
+  t1.name = NULL;
+  res = (int)call_func2(ptype_info_opnot_equals, &t1, &t1);
+  ok(res == 0, "expected 0, got %d\n", res);
+  res = (int)call_func2(ptype_info_opnot_equals, &t1, &t2);
+  ok(res == 1, "expected 1, got %d\n", res);
+  res = (int)call_func2(ptype_info_opnot_equals, &t2, &t1);
+  ok(res == 1, "expected 1, got %d\n", res);
+}
+
+/* Test RTTI functions */
+static void test_rtti(void)
+{
+  static const char* e_name = "name";
+  type_info *ti,*bti;
+  exception e,b;
+  void *casted;
+
+  if (bAncientVersion ||
+      !p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor || !p__RTDynamicCast)
+    return;
+
+  call_func2(pexception_ctor, &e, &e_name);
+  call_func2(pbad_typeid_ctor, &b, e_name);
+
+  /* dynamic_cast to void* */
+  casted = p__RTCastToVoid(&e);
+  ok (casted == (void*)&e, "failed cast to void\n");
+
+  /* dynamic_cast up */
+  ti = p__RTtypeid(&e);
+  bti = p__RTtypeid(&b);
+
+  casted = p__RTDynamicCast(&b, 0, NULL, ti, 0);
+  ok (casted == (void*)&b, "failed cast from bad_cast to exception\n");
+
+  /* dynamic_cast down */
+  casted = p__RTDynamicCast(&e, 0, NULL, bti, 0);
+  ok (casted == NULL, "Cast succeeded\n");
+}
+
+START_TEST(cpp)
+{
+  InitFunctionPtrs();
+
+  test_exception();
+  test_bad_typeid();
+  test_bad_cast();
+  test___non_rtti_object();
+  test_type_info();
+  test_rtti();
+
+  if (hMsvcrt)
+    FreeLibrary(hMsvcrt);
+}
+#endif /* __i386__ */

reactos/lib/msvcrt/tests
environ.c added at 1.2.2.1
diff -N environ.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ environ.c	13 Dec 2004 16:18:27 -0000	1.2.2.1
@@ -0,0 +1,38 @@
+/*
+ * Unit tests for C library environment routines
+ *
+ * Copyright 2004 Mike Hearn <mh@codeweavers.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 "wine/test.h"
+#include <stdlib.h>
+
+START_TEST(environ)
+{
+#ifndef __REACTOS__
+    ok( _putenv("cat=") == 0, "_putenv failed on deletion of non-existent environment variable\n" );
+#endif
+    ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" );
+    ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" );
+    ok( _putenv("cat=") == 0, "failed deleting cat\n" );
+
+    ok( _putenv("=") == -1, "should not accept '=' as input\n" );
+#ifndef __REACTOS__
+    ok( _putenv("=dog") == -1, "should not accept '=dog' as input\n" );
+#endif
+    ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" );
+}

reactos/lib/msvcrt/tests
file.c added at 1.1.2.1
diff -N file.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ file.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,331 @@
+/*
+ * Unit test suite for file functions
+ *
+ * Copyright 2002 Bill Currie
+ *
+ * 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 "wine/test.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <process.h>
+#include <errno.h>
+
+static void test_fdopen( void )
+{
+    static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
+    char ibuf[10];
+    int fd;
+    FILE *file;
+
+    fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
+    write (fd, buffer, sizeof (buffer));
+    close (fd);
+
+    fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
+    lseek (fd, 5, SEEK_SET);
+    file = fdopen (fd, "rb");
+    ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
+    ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
+    fclose (file);
+    unlink ("fdopen.tst");
+}
+
+static void test_fileops( void )
+{
+    static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
+    char buffer[256];
+    WCHAR wbuffer[256];
+    int fd;
+    FILE *file;
+
+    fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
+    write (fd, outbuffer, sizeof (outbuffer));
+    close (fd);
+
+    fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
+    file = fdopen (fd, "rb");
+    ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
+    ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
+    ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
+    ok(feof(file) !=0,"feof doesn't signal EOF\n");
+    rewind(file);
+    ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
+    ok(lstrlenA(buffer) == strlen(outbuffer) -1,"fgets didn't read right size\n");
+    ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
+    ok(strlen(buffer) == 1,"fgets dropped chars\n");
+    ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
+    fclose (file);
+    fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
+    file = fdopen (fd, "rt"); /* open in TEXT mode */
+    ok(fgetws(wbuffer,sizeof(wbuffer),file) !=0,"fgetws failed unexpected\n");
+    ok(fgetws(wbuffer,sizeof(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
+    ok(feof(file) !=0,"feof doesn't signal EOF\n");
+    rewind(file);
+    ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
+    ok(lstrlenW(wbuffer) == (strlen(outbuffer) -1),"fgetws didn't read right size\n");
+    ok(fgetws(wbuffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
+    ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
+    fclose (file);
+    unlink ("fdopen.tst");
+}
+
+static WCHAR* AtoW( char* p )
+{
+    WCHAR* buffer;
+    DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
+    buffer = malloc( len * sizeof(WCHAR) );
+    MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
+    return buffer;
+}
+
+static void test_fgetwc( void )
+{
+#define LLEN 512
+
+  char* tempf;
+  FILE *tempfh;
+  static const char mytext[]= "This is test_fgetwc\n";
+  WCHAR wtextW[LLEN+1];
+  WCHAR *mytextW = NULL, *aptr, *wptr;
+  BOOL diff_found = FALSE;
+  unsigned int i;
+
+  tempf=_tempnam(".","wne");
+  tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
+  fputs(mytext,tempfh);
+  fclose(tempfh);
+  tempfh = fopen(tempf,"rt");
+  fgetws(wtextW,LLEN,tempfh);
+  mytextW = AtoW ((char*)mytext);
+  aptr = mytextW;
+  wptr = wtextW;
+
+  for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
+    {
+      diff_found |= (*aptr != *wptr);
+    }
+  ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
+  if(mytextW) free (mytextW);
+  fclose(tempfh);
+  unlink(tempf);
+}
+
+static void test_file_put_get( void )
+{
+  char* tempf;
+  FILE *tempfh;
+  static const char mytext[]=  "This is a test_file_put_get\n";
+  static const char dostext[]= "This is a test_file_put_get\r\n";
+  char btext[LLEN];
+  WCHAR wtextW[LLEN+1];
+  WCHAR *mytextW = NULL, *aptr, *wptr;
+  BOOL diff_found = FALSE;
+  unsigned int i;
+
+  tempf=_tempnam(".","wne");
+  tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
+  fputs(mytext,tempfh);
+  fclose(tempfh);
+  tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
+  fgets(btext,LLEN,tempfh);
+  ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
+  ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
+  fclose(tempfh);
+  tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
+  fputs(dostext,tempfh);
+  fclose(tempfh);
+  tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
+  fgets(btext,LLEN,tempfh);
+  ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
+  fclose(tempfh);
+  tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
+  fgets(btext,LLEN,tempfh);
+  ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
+
+  fclose(tempfh);
+  tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
+  fgetws(wtextW,LLEN,tempfh);
+  mytextW = AtoW ((char*)mytext);
+  aptr = mytextW;
+  wptr = wtextW;
+
+  for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
+    {
+      diff_found |= (*aptr != *wptr);
+    }
+  ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
+  if(mytextW) free (mytextW);
+  fclose(tempfh);
+  unlink(tempf);
+}
+
+static void test_file_write_read( void )
+{
+  char* tempf;
+  int tempfd;
+  static const char mytext[]=  "This is test_file_write_read\nsecond line\n";
+  static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
+  char btext[LLEN];
+
+  tempf=_tempnam(".","wne");
+  ok((tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
+                     _S_IREAD | _S_IWRITE)) != -1,
+     "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
+  ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
+     "_write _O_TEXT bad return value\n");
+  _close(tempfd);
+  tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
+  ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
+     "_read _O_BINARY got bad length\n");
+  ok( memcmp(dostext,btext,strlen(dostext)) == 0,
+      "problems with _O_TEXT _write / _O_BINARY _read\n");
+  ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
+  _close(tempfd);
+  tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
+  ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
+     "_read _O_TEXT got bad length\n");
+  ok( memcmp(mytext,btext,strlen(mytext)) == 0,
+      "problems with _O_TEXT _write / _read\n");
+  _close(tempfd);
+  ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
+
+  tempf=_tempnam(".","wne");
+  ok((tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0)) != -1,
+     "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
+  ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
+     "_write _O_BINARY bad return value\n");
+  _close(tempfd);
+  tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
+  ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
+     "_read _O_BINARY got bad length\n");
+  ok( memcmp(dostext,btext,strlen(dostext)) == 0,
+      "problems with _O_BINARY _write / _read\n");
+  ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
+  _close(tempfd);
+  tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
+  ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
+     "_read _O_TEXT got bad length\n");
+  ok( memcmp(mytext,btext,strlen(mytext)) == 0,
+      "problems with _O_BINARY _write / _O_TEXT _read\n");
+  _close(tempfd);
+
+  ok(_chmod (tempf, _S_IREAD | _S_IWRITE) == 0,
+     "Can't chmod '%s' to read-write: %d\n", tempf, errno);
+  ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
+}
+
+static void test_file_inherit_child(const char* fd_s)
+{
+    int fd = atoi(fd_s);
+    char buffer[32];
+
+    ok(write(fd, "Success", 8) == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
+    lseek(fd, 0, SEEK_SET);
+    ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
+    ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
+}
+
+static void test_file_inherit_child_no(const char* fd_s)
+{
+    int fd = atoi(fd_s);
+
+    ok(write(fd, "Success", 8) == -1 && errno == EBADF, 
+       "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
+}
+ 
+static void test_file_inherit( const char* selfname )
+{
+    int			fd;
+    const char*		arg_v[5];
+    char 		buffer[16];
+
+    fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
+    ok(fd != -1, "Couldn't create test file\n ");
+    arg_v[0] = selfname;
+    arg_v[1] = "tests/file.c";
+    arg_v[2] = buffer; sprintf(buffer, "%d", fd);
+    arg_v[3] = 0;
+    _spawnvp(_P_WAIT, selfname, arg_v);
+    ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
+    lseek(fd, 0, SEEK_SET);
+    ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
+    close (fd);
+    ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
+    
+    fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
+    ok(fd != -1, "Couldn't create test file\n ");
+    arg_v[0] = selfname;
+    arg_v[1] = "tests/file.c";
+    arg_v[2] = buffer; sprintf(buffer, "%d", fd);
+    arg_v[3] = buffer;
+    arg_v[4] = 0;
+    _spawnvp(_P_WAIT, selfname, arg_v);
+    ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
+    ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
+    close (fd);
+    ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
+}
+
+static void test_tmpnam( void )
+{
+  char name[MAX_PATH] = "abc";
+  char *res;
+
+  res = tmpnam(NULL);
+  ok(res != NULL, "tmpnam returned NULL\n");
+  ok(res[0] == '\\', "first character is not a backslash\n");
+  ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
+  ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
+
+  res = tmpnam(name);
+  ok(res != NULL, "tmpnam returned NULL\n");
+  ok(res == name, "supplied buffer was not used\n");
+  ok(res[0] == '\\', "first character is not a backslash\n");
+  ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
+  ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
+}
+
+
+
+START_TEST(file)
+{
+    int arg_c;
+    char** arg_v;
+
+    arg_c = winetest_get_mainargs( &arg_v );
+
+    if (arg_c >= 3)
+    {
+	if (arg_c == 3) test_file_inherit_child(arg_v[2]); else test_file_inherit_child_no(arg_v[2]);
+        return;
+    }
+
+    test_fdopen();
+    test_fileops();
+    test_fgetwc();
+    test_file_put_get();
+    test_file_write_read();
+    test_file_inherit(arg_v[0]);
+    test_tmpnam();
+}

reactos/lib/msvcrt/tests
heap.c added at 1.1.2.1
diff -N heap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ heap.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,42 @@
+/*
+ * Unit test suite for memory functions
+ *
+ * Copyright 2003 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
+ */
+
+#include <stdlib.h>
+#include "wine/test.h"
+
+START_TEST(heap)
+{
+    void *mem;
+
+    mem = malloc(0);
+    ok(mem != NULL, "memory not allocated for size 0\n");
+
+    mem = realloc(NULL, 10);
+    ok(mem != NULL, "memory not allocated\n");
+    
+    mem = realloc(mem, 20);
+    ok(mem != NULL, "memory not reallocated\n");
+ 
+    mem = realloc(mem, 0);
+    ok(mem == NULL, "memory not freed\n");
+    
+    mem = realloc(NULL, 0);
+    ok(mem != NULL, "memory not (re)allocated for size 0\n");
+}

reactos/lib/msvcrt/tests
msvcrt_test.dsp added at 1.1.2.1
diff -N msvcrt_test.dsp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msvcrt_test.dsp	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="msvcrt_test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=msvcrt_test - Win32 Wine Headers
+!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 "msvcrt_test.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 "msvcrt_test.mak" CFG="msvcrt_test - Win32 Wine Headers"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "msvcrt_test - Win32 MSVC Headers" (based on "Win32 (x86) Console Application")
+!MESSAGE "msvcrt_test - Win32 Wine Headers" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+!IF  "$(CFG)" == "msvcrt_test - Win32 MSVC Headers"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Output\Win32_MSVC_Headers"
+# PROP BASE Intermediate_Dir "Output\Win32_MSVC_Headers"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output\Win32_MSVC_Headers"
+# PROP Intermediate_Dir "Output\Win32_MSVC_Headers"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ  /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ..\..\..\Output\\Win32_MSVC_Headers /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_MSVCRT_TEST_" /D "__WINE_USE_NATIVE_HEADERS" /D __WINETEST_OUTPUT_DIR=\"Output\\Win32_MSVC_Headers\" /D "__i386__" /D "_X86_" /D inline=__inline /FR /FD /GZ /c
+# ADD BASE RSC /l 0x41d /d "_DEBUG"
+# ADD RSC /l 0x41d /i "..\..\..\Output\\Win32_MSVC_Headers" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF  "$(CFG)" == "msvcrt_test - Win32 Wine Headers"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Output\Win32_Wine_Headers"
+# PROP BASE Intermediate_Dir "Output\Win32_Wine_Headers"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output\Win32_Wine_Headers"
+# PROP Intermediate_Dir "Output\Win32_Wine_Headers"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ  /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ..\..\..\Output\\Win32_Wine_Headers /I ..\..\..\include /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_MSVCRT_TEST_" /D __WINETEST_OUTPUT_DIR=\"Output\\Win32_Wine_Headers\" /D "__i386__" /D "_X86_" /D inline=__inline /FR /FD /GZ /c
+# ADD BASE RSC /l 0x41d /d "_DEBUG"
+# ADD RSC /l 0x41d /i "..\..\..\Output\\Win32_Wine_Headers" /i "..\..\..\include" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "msvcrt_test - Win32 MSVC Headers"
+# Name "msvcrt_test - Win32 Wine Headers"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\cpp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\\
+# End Source File
+# Begin Source File
+
+SOURCE=.\testlist.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project

reactos/lib/msvcrt/tests
printf.c added at 1.1.2.1
diff -N printf.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ printf.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,151 @@
+/*
+ * Conformance tests for *printf functions.
+ *
+ * Copyright 2002 Uwe Bonnes
+ * Copyright 2004 Aneurin Price
+ *
+ * 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 <stdio.h>
+
+#include "wine/test.h"
+
+static void test_sprintf( void )
+{
+    char buffer[100];
+    const char *I64d = "%I64d";
+    const char *O4c = "%04c";
+    const char *O4s = "%04s";
+    const char *hash012p = "%#012p";
+    double pnumber=789456123;
+/**    WCHAR widestring[]={'w','i','d','e','s','t','r','i','n','g',0};**/
+    sprintf(buffer,"%+#23.15e",pnumber);
+    todo_wine
+      {
+        ok(strstr(buffer,"e+008") != 0,"Sprintf different \"%s\"\n",buffer);
+      }
+    sprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff);
+    todo_wine
+      {
+        ok(strlen(buffer) == 11,"Problem with long long \"%s\"\n",buffer);
+      }
+    sprintf(buffer,"%lld",((ULONGLONG)0xffffffff)*0xffffffff);
+    todo_wine
+      {
+        ok(strlen(buffer) == 1,"Problem with \"ll\" interpretation \"%s\"\n",buffer);
+      }
+/** This one actually crashes WINE at the moment, when using builtin msvcrt.dll.
+    sprintf(buffer,"%S",widestring);
+    todo_wine
+      {
+        ok(strlen(buffer) == 10,"Problem with \"%%S\" interpretation \"%s\"\n",buffer);
+      }
+ **/
+    sprintf(buffer,O4c,'1');
+    todo_wine
+      {
+        ok(!strcmp(buffer,"0001"),"Character not zero-prefixed \"%s\"\n",buffer);
+      }
+    sprintf(buffer,"%p",(void *)57);
+    todo_wine
+      {
+        ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
+      }
+    sprintf(buffer,hash012p,(void *)57);
+    todo_wine
+      {
+        ok(!strcmp(buffer,"  0X00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
+      }
+    sprintf(buffer,O4s,"foo");/**Warning again**/
+    todo_wine
+      {
+        ok(!strcmp(buffer,"0foo"),"String not zero-prefixed \"%s\"\n",buffer);
+      }
+}
+
+static void test_swprintf( void )
+{
+    wchar_t buffer[100];
+    const wchar_t I64d[] = {'%','I','6','4','d',0};
+    double pnumber=789456123;
+    const wchar_t TwentyThreePoint15e[]= {'%','+','#','2','3','.','1','5','e',0};
+    const wchar_t e008[] = {'e','+','0','0','8',0};
+    const char string[]={'s','t','r','i','n','g',0};
+    const wchar_t S[]={'%','S',0};
+    swprintf(buffer,TwentyThreePoint15e,pnumber);
+    todo_wine
+      {
+        ok(wcsstr(buffer,e008) != 0,"Sprintf different\n");
+      }
+    swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff);
+    todo_wine
+      {
+        ok(wcslen(buffer) == 11,"Problem with long long\n");
+      }
+    swprintf(buffer,S,string);
+      ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n");
+}
+
+static void test_fwprintf( void )
+{
+    const char *string="not a wide string";
+    todo_wine
+      {
+        ok(fwprintf(fopen("nul","r+"),(wchar_t *)string) == -1,"Non-wide string should not be printed by fwprintf\n");
+      }
+}
+
+static void test_snprintf (void)
+{
+    struct snprintf_test {
+        const char *format;
+        int expected;
+        struct {
+            int retval;
+            int render;
+        } todo;
+    };
+    /* Pre-2.1 libc behaviour, not C99 compliant. */
+    const struct snprintf_test tests[] = {{"short", 5, {0, 0}},
+                                          {"justfit", 7, {0, 0}},
+                                          {"justfits", 8, {0, 1}},
+                                          {"muchlonger", -1, {1, 1}}};
+    char buffer[8];
+    const int bufsiz = sizeof buffer;
+    unsigned int i;
+
+    for (i = 0; i < sizeof tests / sizeof tests[0]; i++) {
+        const char *fmt  = tests[i].format;
+        const int expect = tests[i].expected;
+        const int n      = _snprintf (buffer, bufsiz, fmt);
+        const int valid  = n < 0 ? bufsiz : (n == bufsiz ? n : n+1);
+
+        todo (tests[i].todo.retval ? "wine" : "none")
+            ok (n == expect, "\"%s\": expected %d, returned %d\n",
+                fmt, expect, n);
+        todo (tests[i].todo.render ? "wine" : "none")
+            ok (!memcmp (fmt, buffer, valid),
+                "\"%s\": rendered \"%.*s\"\n", fmt, valid, buffer);
+    };
+}
+
+START_TEST(printf)
+{
+    test_sprintf();
+    test_swprintf();
+    test_fwprintf();
+    test_snprintf();
+}

reactos/lib/msvcrt/tests
scanf.c added at 1.1.2.1
diff -N scanf.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scanf.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,103 @@
+/*
+ * Unit test suite for *scanf functions.
+ *
+ * Copyright 2002 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 <stdio.h>
+
+#include "wine/test.h"
+
+static void test_sscanf( void )
+{
+    char buffer[100], buffer1[100];
+    char format[20];
+    int result, ret;
+    float res1= -82.6267f, res2= 27.76f, res11, res12;
+    static const char pname[]=" St. Petersburg, Florida\n";
+    int hour=21,min=59,sec=20;
+    int  number,number_so_far;
+
+
+    /* check EOF */
+    strcpy(buffer,"");
+    ret = sscanf(buffer, "%d", &result);
+    ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF );
+
+    /* check %x */
+    strcpy(buffer,"0x519");
+    ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n"  );
+    ok( result == 0x519,"sscanf reads %x instead of %x\n", result, 0x519 );
+
+    strcpy(buffer,"0x51a");
+    ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
+    ok( result == 0x51a ,"sscanf reads %x instead of %x\n", result, 0x51a );
+
+    strcpy(buffer,"0x51g");
+    ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
+    ok( result == 0x51, "sscanf reads %x instead of %x\n", result, 0x51 );
+
+    /* check % followed by any char */
+    strcpy(buffer,"\"%12@");
+    strcpy(format,"%\"%%%d%@");  /* work around gcc format check */
+    ok( sscanf(buffer, format, &result) == 1, "sscanf failed\n" );
+    ok( result == 12, "sscanf reads %x instead of %x\n", result, 12 );
+
+    /* Check float */
+    ret = sprintf(buffer,"%f %f",res1, res2);
+    ret = sscanf(buffer,"%f%f",&res11, &res12);
+    ok( (res11 == res1) && (res12 == res2), "Error reading floats\n");
+
+    /* check strings */
+    ret = sprintf(buffer," %s", pname);
+    ret = sscanf(buffer,"%*c%[^\n]",buffer1);
+    ok( ret == 1, "Error with format \"%s\"\n","%*c%[^\n]");
+    ok( strncmp(pname,buffer1,strlen(buffer1)) == 0, "Error with \"%s\" \"%s\"\n",pname, buffer1);
+
+    ret = sscanf("abcefgdh","%*[a-cg-e]%c",&buffer[0]);
+    ok( ret == 1, "Error with format \"%s\"\n","%*[a-cg-e]%c");
+    ok( buffer[0] == 'd', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]);
+
+    ret = sscanf("abcefgdh","%*[a-cd-dg-e]%c",&buffer[0]);
+    ok( ret == 1, "Error with format \"%s\"\n","%*[a-cd-dg-e]%c");
+    ok( buffer[0] == 'h', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]);
+
+    /* check digits */
+    ret = sprintf(buffer,"%d:%d:%d",hour,min,sec);
+    ret = sscanf(buffer,"%d%n",&number,&number_so_far);
+    ok(ret == 1 , "problem with format arg \"%%d%%n\"\n");
+    ok(number == hour,"Read wrong arg %d instead of %d\n",number, hour);
+    ok(number_so_far == 2,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far);
+
+    ret = sscanf(buffer+2,"%*c%n",&number_so_far);
+    ok(ret == 0 , "problem with format arg \"%%*c%%n\"\n");
+    ok(number_so_far == 1,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far);
+
+    /* Check %i according to bug 1878 */
+    strcpy(buffer,"123");
+    ret = sscanf(buffer, "%i", &result);
+    ok( ret == 1 , "Wrong number of arguments read\n");
+    ok(result == 123, "Wrong number read\n");
+    ret = sscanf(buffer, "%d", &result);
+    ok( ret == 1 , "Wrong number of arguments read\n");
+    ok(result == 123, "Wrong number read\n");
+}
+
+START_TEST(scanf)
+{
+    test_sscanf();
+}

reactos/lib/msvcrt/tests
string.c added at 1.1.2.1
diff -N string.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ string.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,51 @@
+/*
+ * Unit test suite for string functions.
+ *
+ * Copyright 2004 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 "wine/test.h"
+#include "winbase.h"
+#include <string.h>
+#include <stdlib.h>
+
+static void* (*pmemcpy)(void *, const void *, size_t n);
+static int* (*pmemcmp)(void *, const void *, size_t n);
+
+#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
+#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
+
+
+START_TEST(string)
+{
+    void *mem;
+    static const char xilstring[]="c:/xilinx";
+    int nLen=strlen(xilstring);
+    HMODULE hMsvcrt = LoadLibraryA("msvcrt.dll");
+    ok(hMsvcrt != 0, "LoadLibraryA failed\n");
+    SET(pmemcpy,"memcpy");
+    SET(pmemcmp,"memcmp");
+
+    /* MSVCRT memcpy behaves like memmove for overlapping moves,
+       MFC42 CString::Insert seems to rely on that behaviour */
+    mem = malloc(100);
+    ok(mem != NULL, "memory not allocated for size 0\n");
+    strcpy((char*)mem,xilstring);
+    pmemcpy((char*)mem+5, mem,nLen+1);
+    ok(pmemcmp((char*)mem+5,xilstring, nLen) == 0, 
+       "Got result %s\n",(char*)mem+5);
+}

reactos/lib/msvcrt/tests
testlist.c added at 1.1.2.1
diff -N testlist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testlist.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,39 @@
+/* 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_cpp(void);
+extern void func_environ(void);
+extern void func_file(void);
+extern void func_heap(void);
+extern void func_printf(void);
+extern void func_scanf(void);
+extern void func_string(void);
+extern void func_time(void);
+
+struct test
+{
+    const char *name;
+    void (*func)(void);
+};
+
+static const struct test winetest_testlist[] =
+{
+    { "cpp", func_cpp },
+    { "environ", func_environ },
+    { "file", func_file },
+    { "heap", func_heap },
+    { "printf", func_printf },
+    { "scanf", func_scanf },
+    { "string", func_string },
+    { "time", func_time },
+    { 0, 0 }
+};
+
+#define WINETEST_WANT_MAIN
+#include "wine/test.h"

reactos/lib/msvcrt/tests
time.c added at 1.1.2.1
diff -N time.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ time.c	13 Dec 2004 16:18:27 -0000	1.1.2.1
@@ -0,0 +1,189 @@
+/*
+ * Unit test suite for time functions.
+ *
+ * Copyright 2004 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 "wine/test.h"
+#include "winbase.h"
+#include "time.h"
+
+#include <stdlib.h> /*setenv*/
+#include <stdio.h> /*printf*/
+
+#define SECSPERDAY         86400
+#define SECSPERHOUR        3600
+#define SECSPERMIN         60
+#define MINSPERHOUR        60
+#define HOURSPERDAY        24
+
+static void test_gmtime()
+{
+    time_t gmt = (time_t)NULL;
+    struct tm* gmt_tm = gmtime(&gmt);
+    if(gmt_tm == 0)
+	{
+	    ok(0,"gmtime() error\n");
+	    return;
+	}
+    ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon  == 0) && (gmt_tm->tm_yday  == 0) &&
+	(gmt_tm->tm_mday ==  1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour  == 0) &&
+	(gmt_tm->tm_min  ==  0) && (gmt_tm->tm_sec  == 0) && (gmt_tm->tm_isdst == 0)),
+       "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+       gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, 
+       gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); 
+  
+}
+static void test_mktime()
+{
+    TIME_ZONE_INFORMATION tzinfo;
+    DWORD res =  GetTimeZoneInformation(&tzinfo);
+    struct tm my_tm, sav_tm;
+    time_t nulltime, local_time;
+    char TZ_env[256];
+    int secs;
+
+    ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
+    /* Bias may be positive or negative, to use offset of one day */
+    secs= SECSPERDAY - (tzinfo.Bias +
+      ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
+      ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN;
+    my_tm.tm_mday = 1 + secs/SECSPERDAY;
+    secs = secs % SECSPERDAY;
+    my_tm.tm_hour = secs / SECSPERHOUR;
+    secs = secs % SECSPERHOUR;
+    my_tm.tm_min = secs / SECSPERMIN;
+    secs = secs % SECSPERMIN;
+    my_tm.tm_sec = secs;
+
+    my_tm.tm_year = 70;
+    my_tm.tm_mon  =  0;
+    my_tm.tm_isdst=  0;
+
+    sav_tm = my_tm;
+  
+    local_time = mktime(&my_tm);
+    ok(((DWORD)local_time == SECSPERDAY), "mktime returned 0x%08lx\n",(DWORD)local_time);
+    /* now test some unnormalized struct tm's */
+    my_tm = sav_tm;
+    my_tm.tm_sec += 60;
+    my_tm.tm_min -= 1;
+    local_time = mktime(&my_tm);
+    ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+    ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+        my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+        my_tm.tm_sec == sav_tm.tm_sec
+            , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
+            my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+            my_tm.tm_hour,my_tm.tm_sec,
+            sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+            sav_tm.tm_hour,sav_tm.tm_sec);
+    my_tm = sav_tm;
+    my_tm.tm_min -= 60;
+    my_tm.tm_hour += 1;
+    local_time = mktime(&my_tm);
+    ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+    ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+        my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+        my_tm.tm_sec == sav_tm.tm_sec
+            , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
+            my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+            my_tm.tm_hour,my_tm.tm_sec,
+            sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+            sav_tm.tm_hour,sav_tm.tm_sec);
+    my_tm = sav_tm;
+    my_tm.tm_mon -= 12;
+    my_tm.tm_year += 1;
+    local_time = mktime(&my_tm);
+    ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+    ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+        my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+        my_tm.tm_sec == sav_tm.tm_sec
+            , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
+            my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+            my_tm.tm_hour,my_tm.tm_sec,
+            sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+            sav_tm.tm_hour,sav_tm.tm_sec);
+    my_tm = sav_tm;
+    my_tm.tm_mon += 12;
+    my_tm.tm_year -= 1;
+    local_time = mktime(&my_tm);
+    ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+    ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+        my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+        my_tm.tm_sec == sav_tm.tm_sec
+            , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
+            my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+            my_tm.tm_hour,my_tm.tm_sec,
+            sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+            sav_tm.tm_hour,sav_tm.tm_sec);
+    /* now a bad time example */
+    my_tm = sav_tm;
+    my_tm.tm_year -= 1;
+    local_time = mktime(&my_tm);
+    ok((local_time == -1), "(bad time) mktime returned 0x%08lx\n",(DWORD)local_time);
+
+    my_tm = sav_tm;
+    /* TEST that we are independent from the TZ variable */
+    /*Argh, msvcrt doesn't have setenv() */
+    _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
+    putenv("TZ=GMT");
+    nulltime = mktime(&my_tm);
+    ok(((DWORD)nulltime == SECSPERDAY),"mktime returned 0x%08lx\n",(DWORD)nulltime);
+    putenv(TZ_env);
+}
+static void test_localtime()
+{
+    TIME_ZONE_INFORMATION tzinfo;
+    DWORD res =  GetTimeZoneInformation(&tzinfo);
+    time_t gmt = (time_t)(SECSPERDAY + (tzinfo.Bias +
+      ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
+      ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN);
+
+    char TZ_env[256];
+    struct tm* lt;
+    
+    ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
+    lt = localtime(&gmt);
+    ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
+	(lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
+	(lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst ==
+                                                      (res == TIME_ZONE_ID_DAYLIGHT))),
+       "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+       lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
+       lt->tm_min, lt->tm_sec, lt->tm_isdst); 
+
+    _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
+    putenv("TZ=GMT");
+    lt = localtime(&gmt);
+    ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
+	(lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
+	(lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst ==
+                                                      (res == TIME_ZONE_ID_DAYLIGHT))),
+       "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+       lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
+       lt->tm_min, lt->tm_sec, lt->tm_isdst); 
+    putenv(TZ_env);
+}
+
+
+START_TEST(time)
+{
+    test_gmtime();
+    test_mktime();
+    test_localtime();
+}
CVSspam 0.2.8