From e3ed2d773259cc445c7ff8181ebd934931365328 Mon Sep 17 00:00:00 2001 From: short <> Date: Wed, 12 Feb 2003 22:32:54 +0000 Subject: [PATCH] update for HEAD-2003021201 --- .cvsignore | 1 + ChangeLog | 2509 +++++---- Makefile | 239 +- apps/tests/Makefile | 86 + apps/tests/alive/.cvsignore | 5 + apps/tests/apc/.cvsignore | 5 + apps/tests/args/.cvsignore | 5 + apps/tests/atomtest/.cvsignore | 5 + apps/tests/bench/.cvsignore | 5 + apps/tests/bitblt/.cvsignore | 5 + apps/tests/consume/.cvsignore | 5 + apps/tests/copymove/.cvsignore | 3 + apps/tests/copymove/Makefile | 19 + apps/tests/copymove/copymove.c | 302 ++ apps/tests/count/.cvsignore | 5 + apps/tests/dibtest/.cvsignore | 5 + apps/tests/dump_shared_data/.cvsignore | 5 + apps/tests/event/.cvsignore | 5 + apps/tests/file/.cvsignore | 5 + apps/tests/gditest/.cvsignore | 5 + apps/tests/hello/.cvsignore | 5 + apps/tests/hivetest/.cvsignore | 5 + apps/tests/hivetest/hivetest.c | 1205 +++++ apps/tests/hivetest/makefile | 22 + apps/tests/isotest/.cvsignore | 5 + apps/tests/lock/Makefile | 21 + apps/tests/lock/lock.c | 112 + apps/tests/lpc/.cvsignore | 5 + apps/tests/mstest/.cvsignore | 5 + apps/tests/mutex/.cvsignore | 5 + apps/tests/nptest/.cvsignore | 5 + apps/tests/pteb/.cvsignore | 5 + apps/tests/regdump/main.c | 45 + apps/tests/regdump/makefile | 5 +- apps/tests/regdump/regcmds.c | 224 + apps/tests/regdump/regdump.c | 347 +- apps/tests/regdump/regdump.h | 44 + apps/tests/regdump/regproc.c | 1491 ++++++ apps/tests/regdump/regproc.h | 110 + apps/tests/regtest/.cvsignore | 5 + apps/tests/regtest/regtest.c | 142 +- apps/tests/sectest/.cvsignore | 5 + apps/tests/sertest/.cvsignore | 5 + apps/tests/sertest/sertest.c | 33 +- apps/tests/shm/.cvsignore | 5 + apps/tests/simple/.cvsignore | 5 + apps/tests/stretchblt/stretchblt.cpp | 6 +- apps/tests/tests/GetSysMetrics/.cvsignore | 5 + apps/tests/tests/GetSystemInfo/.cvsignore | 3 + apps/tests/tests/Mutex/.cvsignore | 2 + apps/tests/tests/Parent_Child/.cvsignore | 3 + apps/tests/tests/guitest/.cvsignore | 3 + apps/tests/tests/hello/.cvsignore | 3 + apps/tests/tests/hello2/.cvsignore | 3 + apps/tests/tests/new/.cvsignore | 3 + apps/tests/tests/rolex/.cvsignore | 3 + apps/tests/tests/volinfo/.cvsignore | 3 + apps/tests/thread/.cvsignore | 5 + apps/tests/tokentest/.cvsignore | 5 + apps/tests/vmtest/.cvsignore | 5 + apps/tests/winhello/.cvsignore | 6 + apps/tests/winhello/winhello.c | 14 +- apps/tests/wm_paint/Listing1_1.cpp | 129 + apps/tests/wm_paint/makefile | 66 + apps/testsets/Makefile | 188 + apps/testsets/loadlib/.cvsignore | 9 + apps/testsets/loadlib/loadlib.c | 222 + apps/testsets/loadlib/loadlib.h | 45 + apps/testsets/loadlib/makefile | 24 + apps/testsets/msvcrt/fileio/.cvsignore | 5 + apps/testsets/msvcrt/fileio/_tfileio.c | 421 ++ apps/testsets/msvcrt/fileio/fileio.c | 31 + apps/testsets/msvcrt/fileio/main.c | 124 + apps/testsets/msvcrt/fileio/main.h | 42 + apps/testsets/msvcrt/fileio/makefile | 27 + apps/testsets/msvcrt/fileio/wfileio.c | 31 + apps/utils/Makefile | 82 + apps/utils/cabman/.cvsignore | 5 + apps/utils/cabman/makefile | 10 +- apps/utils/cat/.cvsignore | 5 + apps/utils/net/ping/.cvsignore | 6 +- apps/utils/net/roshttpd/.cvsignore | 5 + apps/utils/net/roshttpd/include/socket.h | 2 +- apps/utils/net/telnet/.cvsignore | 5 + apps/utils/objdir/.cvsignore | 5 + apps/utils/partinfo/.cvsignore | 5 + apps/utils/pice/.cvsignore | 5 + apps/utils/ps/.cvsignore | 5 + apps/utils/ps/ps.c | 70 + apps/utils/ps/ps.cpp | 42 - apps/utils/sc/.cvsignore | 7 + apps/utils/sc/command.c | 109 + apps/utils/sc/config.c | 75 + apps/utils/sc/main.c | 248 + apps/utils/sc/main.h | 72 + apps/utils/sc/makefile | 24 + apps/utils/sc/query.c | 111 + apps/utils/sc/setup.c | 62 + apps/utils/stats/.cvsignore | 5 + apps/utils/tickcount/makefile | 19 + apps/utils/tickcount/tickcount.c | 142 + boot.bat | 2 +- bootcd.bat | 99 + dk/w32/Makefile | 115 +- drivers/bus/acpi/.cvsignore | 1 + drivers/bus/acpi/include/acpi.h | 4 + drivers/bus/acpi/include/actypes.h | 14 +- drivers/bus/acpi/include/platform/types.h | 780 +-- drivers/bus/acpi/ospm/.cvsignore | 3 - drivers/bus/acpi/ospm/busmgr/.cvsignore | 2 + drivers/bus/acpi/ospm/include/acpisys.h | 3 - drivers/bus/acpi/ospm/osl.c | 22 +- drivers/bus/acpi/resource/.cvsignore | 1 + drivers/bus/isapnp/.cvsignore | 1 + drivers/bus/isapnp/isapnp.c | 35 +- drivers/bus/isapnp/isapnp.rc | 1 - drivers/bus/pci/.cvsignore | 1 + drivers/bus/pci/pci.rc | 1 - drivers/dd/beep/.cvsignore | 3 + drivers/dd/beep/beep.rc | 1 - drivers/dd/blue/.cvsignore | 4 +- drivers/dd/blue/blue.rc | 1 - drivers/dd/floppy/.cvsignore | 4 +- drivers/dd/floppy/floppy.c | 25 +- drivers/dd/floppy/floppy.h | 3 - drivers/dd/floppy/floppy.rc | 1 - drivers/dd/ide/.cvsignore | 4 +- drivers/dd/ide/ide.c | 29 +- drivers/dd/null/.cvsignore | 8 +- drivers/dd/vga/display/.cvsignore | 5 +- drivers/dd/vga/display/main/.cvsignore | 1 + drivers/dd/vga/display/objects/.cvsignore | 1 + drivers/dd/vga/display/objects/bitblt.c | 44 +- drivers/dd/vga/display/objects/offscreen.c | 10 +- drivers/dd/vga/display/objects/pointer.c | 35 +- drivers/dd/vga/display/vgaddi.rc | 4 +- drivers/dd/vga/display/vgavideo/.cvsignore | 1 + drivers/dd/vga/miniport/.cvsignore | 5 +- drivers/dd/vga/miniport/vgamp.rc | 4 +- drivers/dd/vidport/.cvsignore | 4 +- drivers/fs/cdfs/.cvsignore | 6 +- drivers/fs/cdfs/cleanup.c | 7 +- drivers/fs/cdfs/finfo.c | 2 +- drivers/fs/cdfs/rw.c | 76 +- drivers/fs/fs_rec/.cvsignore | 6 +- drivers/fs/fs_rec/cdfs.c | 1 + drivers/fs/fs_rec/fat.c | 5 +- drivers/fs/fs_rec/fs_rec.c | 24 +- drivers/fs/fs_rec/fs_rec.h | 12 +- drivers/fs/fs_rec/makefile | 3 +- drivers/fs/fs_rec/ntfs.c | 5 +- drivers/fs/fs_rec/udfs.c | 296 ++ drivers/fs/ms/.cvsignore | 4 +- drivers/fs/mup/.cvsignore | 5 +- drivers/fs/np/.cvsignore | 5 +- drivers/fs/np/create.c | 6 +- drivers/fs/ntfs/.cvsignore | 5 +- drivers/fs/ntfs/attrib.c | 65 +- drivers/fs/ntfs/dirctl.c | 7 +- drivers/fs/ntfs/ntfs.h | 8 + drivers/fs/vfat/.cvsignore | 6 +- drivers/fs/vfat/cleanup.c | 30 +- drivers/fs/vfat/close.c | 19 +- drivers/fs/vfat/create.c | 491 +- drivers/fs/vfat/dir.c | 82 +- drivers/fs/vfat/direntry.c | 232 +- drivers/fs/vfat/dirwr.c | 125 +- drivers/fs/vfat/fat.c | 45 +- drivers/fs/vfat/fcb.c | 302 +- drivers/fs/vfat/finfo.c | 223 +- drivers/fs/vfat/flush.c | 119 + drivers/fs/vfat/fsctl.c | 12 +- drivers/fs/vfat/iface.c | 11 + drivers/fs/vfat/makefile | 3 +- drivers/fs/vfat/misc.c | 49 +- drivers/fs/vfat/rw.c | 41 +- drivers/fs/vfat/shutdown.c | 50 +- drivers/fs/vfat/string.c | 96 - drivers/fs/vfat/vfat.h | 112 +- drivers/input/keyboard/.cvsignore | 4 +- drivers/input/mouclass/.cvsignore | 4 +- drivers/input/mouclass/mouclass.c | 12 +- drivers/input/psaux/.cvsignore | 4 +- drivers/input/psaux/psaux.c | 8 +- drivers/lib/bzip2/.cvsignore | 5 + drivers/lib/bzip2/Makefile | 21 +- drivers/lib/zlib/.cvsignore | 4 + drivers/lib/zlib/Makefile | 2 + drivers/net/afd/.cvsignore | 5 +- .../assert => drivers/net/afd/afd}/.cvsignore | 2 +- drivers/net/afd/afd/afd.c | 2 +- drivers/net/dd/ne2000/.cvsignore | 5 +- drivers/net/dd/ne2000/ne2000/.cvsignore | 1 + drivers/net/ndis/.cvsignore | 1 + drivers/net/ndis/ndis/.cvsignore | 1 + drivers/net/npf/.cvsignore | 5 + drivers/net/npf/Makefile | 38 + drivers/net/npf/bucket_lookup.c | 251 + drivers/net/npf/bucket_lookup.h | 43 + drivers/net/npf/count_packets.c | 51 + drivers/net/npf/count_packets.h | 51 + drivers/net/npf/debug.h | 52 + drivers/net/npf/dump.c | 590 +++ drivers/net/npf/functions.c | 82 + drivers/net/npf/functions.h | 67 + drivers/net/npf/jitter.c | 681 +++ drivers/net/npf/jitter.h | 391 ++ drivers/net/npf/memory_t.c | 68 + drivers/net/npf/memory_t.h | 124 + drivers/net/npf/normal_lookup.c | 191 + drivers/net/npf/normal_lookup.h | 45 + drivers/net/npf/npf.def | 8 + drivers/net/npf/npf.edf | 8 + drivers/net/npf/npf.rc | 47 + drivers/net/npf/ntddpack.h | 30 + drivers/net/npf/openclos.c | 683 +++ drivers/net/npf/packet.c | 1388 +++++ drivers/net/npf/packet.h | 959 ++++ drivers/net/npf/read.c | 680 +++ drivers/net/npf/resource.h | 15 + drivers/net/npf/tcp_session.c | 283 ++ drivers/net/npf/tcp_session.h | 85 + drivers/net/npf/time_calls.c | 277 + drivers/net/npf/time_calls.h | 262 + drivers/net/npf/tme.c | 378 ++ drivers/net/npf/tme.h | 182 + drivers/net/npf/valid_insns.h | 73 + drivers/net/npf/win_bpf.h | 325 ++ drivers/net/npf/win_bpf_filter.c | 961 ++++ drivers/net/npf/win_bpf_filter_init.c | 689 +++ drivers/net/npf/win_bpf_filter_init.h | 31 + drivers/net/npf/write.c | 366 ++ drivers/net/packet/Makefile | 4 +- drivers/net/packet/bucket_lookup.h | 6 +- drivers/net/packet/count_packets.h | 12 +- drivers/net/packet/debug.h | 2 +- drivers/net/packet/dump.c | 789 +-- drivers/net/packet/functions.h | 2 +- drivers/net/packet/jitter.c | 948 ++-- drivers/net/packet/jitter.h | 16 +- drivers/net/packet/memory_t.c | 3 + drivers/net/packet/memory_t.h | 89 +- drivers/net/packet/normal_lookup.h | 8 +- drivers/net/packet/ntddpack.h | 2 +- drivers/net/packet/openclos.c | 70 +- drivers/net/packet/packet.c | 234 +- drivers/net/packet/packet.h | 346 +- drivers/net/packet/read.c | 94 +- drivers/net/packet/tcp_session.h | 74 +- drivers/net/packet/time_calls.c | 65 +- drivers/net/packet/time_calls.h | 302 +- drivers/net/packet/tme.h | 144 +- drivers/net/packet/win_bpf.h | 208 +- drivers/net/packet/win_bpf_filter_init.c | 120 + drivers/net/packet/win_bpf_filter_init.h | 6 +- drivers/net/packet/write.c | 56 +- drivers/net/tcpip/.cvsignore | 1 + drivers/net/tcpip/datalink/.cvsignore | 1 + drivers/net/tcpip/include/linux.h | 1876 +++++++ drivers/net/tcpip/include/tcpcore.h | 3856 ++++++++++++++ drivers/net/tcpip/include/tcpdef.h | 187 + drivers/net/tcpip/makefile | 4 +- drivers/net/tcpip/network/.cvsignore | 1 + drivers/net/tcpip/network/receive.c | 7 +- drivers/net/tcpip/tcpip/.cvsignore | 1 + drivers/net/tcpip/transport/datagram/.cvsignore | 1 + drivers/net/tcpip/transport/rawip/.cvsignore | 1 + drivers/net/tcpip/transport/tcp/.cvsignore | 1 + drivers/net/tcpip/transport/tcp/tcp.c | 2 + drivers/net/tcpip/transport/tcp/tcp_input.c | 4184 +++++++++++++++ drivers/net/tcpip/transport/tcp/tcp_ipv4.c | 2523 +++++++++ drivers/net/tcpip/transport/tcp/tcp_output.c | 1549 ++++++ drivers/net/tcpip/transport/tcp/tcp_timer.c | 702 +++ drivers/net/tcpip/transport/tcp/tcpcore.c | 2783 ++++++++++ drivers/net/tcpip/transport/udp/.cvsignore | 1 + drivers/net/tdi/.cvsignore | 3 + drivers/net/tdi/cte/.cvsignore | 1 + drivers/net/tdi/misc/.cvsignore | 3 +- drivers/net/tdi/tdi/.cvsignore | 1 + drivers/storage/atapi/.cvsignore | 4 +- drivers/storage/atapi/atapi.c | 1007 ++-- drivers/storage/atapi/atapi.h | 21 +- drivers/storage/atapi/atapi.rc | 1 - drivers/storage/cdrom/.cvsignore | 4 +- drivers/storage/cdrom/cdrom.c | 107 +- drivers/storage/cdrom/cdrom.rc | 1 - drivers/storage/class2/.cvsignore | 4 +- drivers/storage/class2/class2.c | 146 +- drivers/storage/class2/class2.rc | 1 - drivers/storage/disk/.cvsignore | 4 +- drivers/storage/disk/disk.c | 80 +- drivers/storage/disk/disk.rc | 1 - drivers/storage/scsiport/.cvsignore | 4 +- drivers/storage/scsiport/scsiport.c | 625 ++- drivers/storage/scsiport/scsiport.rc | 1 - hal/halx86/bus.c | 2 + hal/halx86/include/bus.h | 8 + hal/halx86/irql.c | 128 +- hal/halx86/isa.c | 12 + hal/halx86/mp.c | 7 +- hal/halx86/mpsirql.c | 7 +- hal/halx86/pci.c | 154 +- hal/halx86/sysbus.c | 2 +- hal/halx86/time.c | 46 +- iface/native/genntdll.c | 2 +- include/ascii.h | 25 +- include/base.h | 50 +- include/basetsd.h | 119 + include/crtdll/alloc.h | 77 - include/crtdll/assert.h | 69 - include/crtdll/conio.h | 67 - include/crtdll/crtdll.h | 1 - include/crtdll/ctype.h | 142 - include/crtdll/dir.h | 103 - include/crtdll/direct.h | 27 - include/crtdll/dirent.h | 61 - include/crtdll/dos.h | 158 - include/crtdll/errno.h | 134 - include/crtdll/excpt.h | 121 - include/crtdll/fcntl.h | 125 - include/crtdll/float.h | 199 - include/crtdll/internal/atexit.h | 33 - include/crtdll/internal/file.h | 93 - include/crtdll/internal/ieee.h | 25 - include/crtdll/internal/quad.h | 131 - include/crtdll/io.h | 140 - include/crtdll/locale.h | 84 - include/crtdll/malloc.h | 53 - include/crtdll/math.h | 161 - include/crtdll/mbctype.h | 47 - include/crtdll/mbstring.h | 108 - include/crtdll/process.h | 160 - include/crtdll/search.h | 35 - include/crtdll/setjmp.h | 46 - include/crtdll/share.h | 17 - include/crtdll/signal.h | 111 - include/crtdll/stdarg.h | 107 - include/crtdll/stddef.h | 173 - include/crtdll/stdio.h | 357 -- include/crtdll/stdlib.h | 210 - include/crtdll/string.h | 192 - include/crtdll/sys/fcntl.h | 8 - include/crtdll/sys/file.h | 9 - include/crtdll/sys/locking.h | 38 - include/crtdll/sys/stat.h | 113 - include/crtdll/sys/time.h | 3 - include/crtdll/sys/timeb.h | 60 - include/crtdll/sys/types.h | 77 - include/crtdll/sys/unistd.h | 9 - include/crtdll/sys/utime.h | 75 - include/crtdll/tchar.h | 231 - include/crtdll/time.h | 119 - include/crtdll/wchar.h | 32 - include/csrss/csrss.h | 32 +- include/ddk/af_irda.h | 221 + include/ddk/cctypes.h | 12 +- include/ddk/cmfuncs.h | 47 - include/ddk/cmtypes.h | 4 +- include/ddk/defines.h | 141 +- include/ddk/extypes.h | 12 +- include/ddk/fstypes.h | 23 +- include/ddk/haltypes.h | 46 +- include/ddk/iofuncs.h | 11 +- include/ddk/iotypes.h | 30 +- include/ddk/ketypes.h | 18 +- include/ddk/ntddbeep.h | 3 + include/ddk/ntddk.h | 11 +- include/ddk/ntddkbd.h | 46 +- include/ddk/ntdef.h | 13 +- include/ddk/ntifs.h | 26 +- include/ddk/obtypes.h | 20 +- include/ddk/pnptypes.h | 4 +- include/ddk/potypes.h | 6 +- include/ddk/pstypes.h | 8 +- include/ddk/setypes.h | 2 +- include/ddk/status.h | 1354 ++--- include/ddk/winddi.h | 6 +- include/debug.h | 2 + include/defines.h | 88 +- include/errors.h | 5 + include/excpt.h | 4 +- include/freetype/internal/ftdebug.h | 9 +- include/funcs.h | 25 +- include/kernel32/winnls.h | 8 +- include/libc/atexit.h | 4 +- include/msvcrt/alloc.h | 51 +- include/msvcrt/assert.h | 34 +- include/msvcrt/conio.h | 52 +- include/msvcrt/crttypes.h | 63 + include/msvcrt/ctype.h | 155 +- include/msvcrt/dir.h | 135 +- include/msvcrt/direct.h | 77 +- include/msvcrt/errno.h | 112 +- include/msvcrt/fcntl.h | 98 +- include/msvcrt/float.h | 207 +- include/msvcrt/internal/atexit.h | 6 +- include/msvcrt/internal/file.h | 56 +- include/msvcrt/internal/ieee.h | 24 +- include/msvcrt/internal/rterror.h | 42 +- include/msvcrt/internal/stdio.h | 6 +- include/msvcrt/internal/tls.h | 21 +- include/msvcrt/io.h | 159 +- include/msvcrt/locale.h | 71 +- include/msvcrt/malloc.h | 16 +- include/msvcrt/math.h | 173 +- include/msvcrt/mbctype.h | 67 +- include/msvcrt/mbstring.h | 184 +- include/msvcrt/msvcrtdbg.h | 21 + include/msvcrt/process.h | 174 +- include/msvcrt/share.h | 53 +- include/msvcrt/signal.h | 94 +- include/msvcrt/stdarg.h | 33 +- include/msvcrt/stddef.h | 50 +- include/msvcrt/stdio.h | 295 +- include/msvcrt/stdlib.h | 277 +- include/msvcrt/string.h | 212 +- include/msvcrt/sys/locking.h | 29 +- include/msvcrt/sys/stat.h | 139 +- include/msvcrt/sys/timeb.h | 37 +- include/msvcrt/sys/types.h | 64 +- include/msvcrt/sys/utime.h | 49 +- include/msvcrt/time.h | 107 +- include/msvcrt/wchar.h | 9 +- include/napi/lpc.h | 8 + include/napi/npipe.h | 2 + include/napi/shared_data.h | 8 +- include/napi/teb.h | 479 +- include/napi/types.h | 47 +- include/net/ndis.h | 23 +- include/net/ntddndis.h | 2 + include/ntdll/ldr.h | 1 + include/ntdll/rtl.h | 15 +- include/ntos.h | 10 + include/ntos/cdrom.h | 14 +- include/ntos/console.h | 43 +- include/ntos/disk.h | 18 +- include/ntos/except.h | 35 +- include/ntos/file.h | 47 +- include/ntos/gditypes.h | 4 + include/ntos/heap.h | 10 +- include/ntos/kdbgsyms.h | 3 +- include/ntos/keyboard.h | 155 +- include/{ddk => ntos}/ldrtypes.h | 3 +- include/ntos/minmax.h | 4 +- include/ntos/mm.h | 13 +- include/ntos/ntdef.h | 10 +- include/ntos/port.h | 7 + include/ntos/ps.h | 26 +- include/ntos/registry.h | 3 + include/{ddk => ntos}/rtl.h | 727 +-- include/{ddk => ntos}/rtltypes.h | 135 +- include/ntos/security.h | 134 +- include/ntos/synch.h | 7 +- include/ntos/time.h | 11 + include/ntos/types.h | 541 +- include/{ddk => ntos}/zw.h | 2514 ++++----- include/{ddk => ntos}/zwtypes.h | 1777 ++++--- include/pe.h | 611 +-- include/reactos/.cvsignore | 3 +- include/reactos/resource.h | 2 +- include/reactos/version.h | 6 +- include/structs.h | 77 +- include/tchar.h | 32 +- include/unicode.h | 25 +- include/win32k/gdiobj.h | 27 +- include/win32k/math.h | 2 +- include/win32k/ntuser.h | 10 +- include/windows.h | 3 + include/wine/commctrl.h | 4492 ++++++++++++++++ install.bat | 65 +- installwine.bat | 63 +- lib/advapi32/.cvsignore | 3 +- lib/advapi32/advapi32.def | 24 +- lib/advapi32/advapi32.edf | 110 +- lib/advapi32/makefile | 9 +- lib/advapi32/misc/.cvsignore | 1 + lib/advapi32/misc/dllmain.c | 2 + lib/advapi32/misc/shutdown.c | 242 +- lib/advapi32/reg/.cvsignore | 1 + lib/advapi32/reg/reg.c | 2856 +++++------ lib/advapi32/sec/.cvsignore | 1 + lib/advapi32/sec/ac.c | 4 +- lib/advapi32/sec/lsa.c | 681 +-- lib/advapi32/sec/misc.c | 11 +- lib/advapi32/sec/sec.c | 4 +- lib/advapi32/sec/sid.c | 4 +- lib/advapi32/service/.cvsignore | 1 + lib/advapi32/service/scm.c | 873 ++-- lib/advapi32/service/sctrl.c | 12 +- lib/advapi32/token/.cvsignore | 1 + lib/advapi32/token/token.c | 3 +- lib/crtdll/assert/assert.c | 12 - lib/crtdll/conio/cgets.c | 8 +- lib/crtdll/conio/cprintf.c | 4 +- lib/crtdll/conio/cputs.c | 8 +- lib/crtdll/conio/cscanf.c | 27 +- lib/crtdll/conio/getch.c | 56 +- lib/crtdll/conio/getche.c | 8 +- lib/crtdll/conio/kbhit.c | 10 +- lib/crtdll/conio/putch.c | 4 +- lib/crtdll/conio/ungetch.c | 9 +- lib/crtdll/ctype/ctype.c | 264 + lib/crtdll/ctype/isalnum.c | 6 +- lib/crtdll/ctype/isalpha.c | 10 +- lib/crtdll/ctype/isascii.c | 18 +- lib/crtdll/ctype/iscntrl.c | 7 +- lib/crtdll/ctype/iscsym.c | 2 +- lib/crtdll/ctype/isctype.c | 266 +- lib/crtdll/ctype/isdigit.c | 7 +- lib/crtdll/ctype/isgraph.c | 2 +- lib/crtdll/ctype/islower.c | 7 +- lib/crtdll/ctype/isprint.c | 2 +- lib/crtdll/ctype/ispunct.c | 7 +- lib/crtdll/ctype/isspace.c | 4 +- lib/crtdll/ctype/isupper.c | 7 +- lib/crtdll/ctype/isxdigit.c | 7 +- lib/crtdll/ctype/toascii.c | 4 +- lib/crtdll/ctype/tolower.c | 5 +- lib/crtdll/ctype/toupper.c | 7 +- lib/crtdll/direct/chdir.c | 21 +- lib/crtdll/direct/chdrive.c | 34 +- lib/crtdll/direct/getcwd.c | 35 +- lib/crtdll/direct/getdcwd.c | 34 +- lib/crtdll/direct/getdfree.c | 28 +- lib/crtdll/direct/getdrive.c | 24 +- lib/crtdll/direct/mkdir.c | 10 +- lib/crtdll/direct/rmdir.c | 11 +- lib/crtdll/dirent/dirent.c | 18 +- lib/crtdll/except/abnorter.c | 6 + lib/crtdll/except/exhand2.c | 27 +- lib/crtdll/except/matherr.c | 38 +- lib/crtdll/float/chgsign.c | 12 +- lib/crtdll/float/clearfp.c | 7 +- lib/crtdll/float/cntrlfp.c | 9 +- lib/crtdll/float/copysign.c | 4 +- lib/crtdll/float/fpclass.c | 30 +- lib/crtdll/float/fpreset.c | 5 +- lib/crtdll/float/isnan.c | 33 +- lib/crtdll/float/logb.c | 9 +- lib/crtdll/float/nafter.c | 9 +- lib/crtdll/float/scalb.c | 5 +- lib/crtdll/float/statfp.c | 6 +- lib/crtdll/io/access.c | 54 +- lib/crtdll/io/chmod.c | 54 +- lib/crtdll/io/chsize.c | 6 +- lib/crtdll/io/close.c | 20 +- lib/crtdll/io/commit.c | 7 +- lib/crtdll/io/create.c | 4 +- lib/crtdll/io/dup.c | 12 +- lib/crtdll/io/dup2.c | 5 +- lib/crtdll/io/eof.c | 6 +- lib/crtdll/io/filelen.c | 6 +- lib/crtdll/io/find.c | 124 +- lib/crtdll/io/fmode.c | 4 +- lib/crtdll/io/isatty.c | 8 +- lib/crtdll/io/locking.c | 7 +- lib/crtdll/io/lseek.c | 6 +- lib/crtdll/io/mktemp.c | 12 +- lib/crtdll/io/open.c | 339 +- lib/crtdll/io/pipe.c | 7 +- lib/crtdll/io/read.c | 11 +- lib/crtdll/io/setmode.c | 13 +- lib/crtdll/io/sopen.c | 2 +- lib/crtdll/io/tell.c | 7 +- lib/crtdll/io/umask.c | 2 +- lib/crtdll/io/unlink.c | 2 +- lib/crtdll/io/utime.c | 12 +- lib/crtdll/io/write.c | 2 +- lib/crtdll/locale/locale.c | 8 +- lib/crtdll/makefile | 627 ++- lib/crtdll/malloc/expand.c | 34 +- lib/crtdll/malloc/heap.c | 17 +- lib/crtdll/math/acos.c | 7 +- lib/crtdll/math/acosh.c | 8 +- lib/crtdll/math/asin.c | 7 +- lib/crtdll/math/asinh.c | 9 +- lib/crtdll/math/atan.c | 7 +- lib/crtdll/math/atan2.c | 8 +- lib/crtdll/math/atanh.c | 6 +- lib/crtdll/math/cabs.c | 2 +- lib/crtdll/math/ceil.c | 9 +- lib/crtdll/math/cos.c | 7 +- lib/crtdll/math/cosh.c | 7 +- lib/crtdll/math/exp.c | 5 + lib/crtdll/math/fabs.c | 6 +- lib/crtdll/math/floor.c | 6 +- lib/crtdll/math/fmod.c | 6 +- lib/crtdll/math/frexp.c | 6 +- lib/crtdll/math/ftol.c | 5 +- lib/crtdll/math/huge_val.c | 2 +- lib/crtdll/math/hypot.c | 8 +- lib/crtdll/math/j0_y0.c | 3 +- lib/crtdll/math/j1_y1.c | 3 +- lib/crtdll/math/jn_yn.c | 3 +- lib/crtdll/math/ldexp.c | 7 +- lib/crtdll/math/log.c | 7 +- lib/crtdll/math/log10.c | 6 +- lib/crtdll/math/modf.c | 99 +- lib/crtdll/math/pow.c | 17 +- lib/crtdll/math/sin.c | 6 +- lib/crtdll/math/sinh.c | 2 +- lib/crtdll/math/sqrt.c | 7 +- lib/crtdll/math/stubs.c | 73 +- lib/crtdll/math/tan.c | 6 +- lib/crtdll/math/tanh.c | 4 +- lib/crtdll/mbstring/hanzen.c | 2 +- lib/crtdll/mbstring/ischira.c | 13 +- lib/crtdll/mbstring/iskana.c | 4 +- lib/crtdll/mbstring/iskmoji.c | 2 +- lib/crtdll/mbstring/iskpun.c | 2 +- lib/crtdll/mbstring/islead.c | 2 +- lib/crtdll/mbstring/islwr.c | 4 +- lib/crtdll/mbstring/ismbal.c | 6 +- lib/crtdll/mbstring/ismbaln.c | 5 +- lib/crtdll/mbstring/ismbc.c | 3 +- lib/crtdll/mbstring/ismbgra.c | 6 +- lib/crtdll/mbstring/ismbkaln.c | 4 +- lib/crtdll/mbstring/ismblead.c | 6 +- lib/crtdll/mbstring/ismbpri.c | 6 +- lib/crtdll/mbstring/ismbpun.c | 13 +- lib/crtdll/mbstring/ismbtrl.c | 4 +- lib/crtdll/mbstring/isuppr.c | 4 +- lib/crtdll/mbstring/jistojms.c | 2 +- lib/crtdll/mbstring/jmstojis.c | 2 +- lib/crtdll/mbstring/mbbtype.c | 4 +- lib/crtdll/mbstring/mbccpy.c | 4 +- lib/crtdll/mbstring/mbclen.c | 5 +- lib/crtdll/mbstring/mbscat.c | 2 +- lib/crtdll/mbstring/mbschr.c | 2 +- lib/crtdll/mbstring/mbscmp.c | 4 +- lib/crtdll/mbstring/mbscoll.c | 4 +- lib/crtdll/mbstring/mbscpy.c | 4 +- lib/crtdll/mbstring/mbscspn.c | 3 +- lib/crtdll/mbstring/mbsdec.c | 2 +- lib/crtdll/mbstring/mbsdup.c | 4 +- lib/crtdll/mbstring/mbsicmp.c | 6 +- lib/crtdll/mbstring/mbsicoll.c | 7 +- lib/crtdll/mbstring/mbsinc.c | 2 +- lib/crtdll/mbstring/mbslen.c | 2 +- lib/crtdll/mbstring/mbslwr.c | 41 +- lib/crtdll/mbstring/mbsncat.c | 4 +- lib/crtdll/mbstring/mbsnccnt.c | 2 +- lib/crtdll/mbstring/mbsncmp.c | 2 +- lib/crtdll/mbstring/mbsncoll.c | 2 +- lib/crtdll/mbstring/mbsncpy.c | 14 +- lib/crtdll/mbstring/mbsnextc.c | 4 +- lib/crtdll/mbstring/mbsnicmp.c | 12 +- lib/crtdll/mbstring/mbsnicoll.c | 3 +- lib/crtdll/mbstring/mbsninc.c | 2 +- lib/crtdll/mbstring/mbsnset.c | 2 +- lib/crtdll/mbstring/mbspbrk.c | 2 +- lib/crtdll/mbstring/mbsrchr.c | 2 +- lib/crtdll/mbstring/mbsrev.c | 2 +- lib/crtdll/mbstring/mbsset.c | 2 +- lib/crtdll/mbstring/mbsspn.c | 3 +- lib/crtdll/mbstring/mbsspnp.c | 3 +- lib/crtdll/mbstring/mbsstr.c | 4 +- lib/crtdll/mbstring/mbstok.c | 2 +- lib/crtdll/mbstring/mbstrlen.c | 4 +- lib/crtdll/mbstring/mbsupr.c | 4 +- lib/crtdll/misc/GetArgs.c | 4 +- lib/crtdll/misc/amsg.c | 16 +- lib/crtdll/misc/assert.c | 13 + lib/crtdll/misc/crt1.c | 12 +- lib/crtdll/misc/debug.c | 19 + lib/crtdll/misc/dllcrt1.c | 17 +- lib/crtdll/misc/dllmain.c | 36 +- lib/crtdll/misc/gccmain.c | 27 +- lib/crtdll/misc/init.c | 30 +- lib/crtdll/misc/initterm.c | 16 +- lib/crtdll/misc/main.c | 16 +- lib/crtdll/misc/setnew.c | 23 +- lib/crtdll/process/_cwait.c | 17 +- lib/crtdll/process/_system.c | 9 +- lib/crtdll/process/dll.c | 13 +- lib/crtdll/process/execl.c | 4 +- lib/crtdll/process/execle.c | 6 +- lib/crtdll/process/execlp.c | 6 +- lib/crtdll/process/execlpe.c | 6 +- lib/crtdll/process/execv.c | 4 +- lib/crtdll/process/execve.c | 5 +- lib/crtdll/process/execvp.c | 8 +- lib/crtdll/process/execvpe.c | 2 +- lib/crtdll/process/procid.c | 6 +- lib/crtdll/process/spawnl.c | 15 +- lib/crtdll/process/spawnle.c | 6 +- lib/crtdll/process/spawnlp.c | 4 +- lib/crtdll/process/spawnlpe.c | 6 +- lib/crtdll/process/spawnv.c | 4 +- lib/crtdll/process/spawnve.c | 451 +- lib/crtdll/process/spawnvp.c | 4 +- lib/crtdll/process/spawnvpe.c | 4 +- lib/crtdll/process/thread.c | 17 +- lib/crtdll/process/threadid.c | 2 +- lib/crtdll/quad/divdi3.c | 2 +- lib/crtdll/quad/moddi3.c | 2 +- lib/crtdll/quad/qdivrem.c | 2 +- lib/crtdll/quad/udivdi3.c | 2 +- lib/crtdll/quad/umoddi3.c | 2 +- lib/crtdll/search/lfind.c | 11 +- lib/crtdll/search/lsearch.c | 23 +- lib/crtdll/setjmp/setjmp.c | 15 +- lib/crtdll/signal/signal.c | 10 +- lib/crtdll/signal/xcptinfo.c | 2 +- lib/crtdll/stdio/allocfil.c | 8 +- lib/crtdll/stdio/clearerr.c | 6 +- lib/crtdll/stdio/doscan.c | 10 +- lib/crtdll/stdio/fclose.c | 14 +- lib/crtdll/stdio/fdopen.c | 16 +- lib/crtdll/stdio/feof.c | 6 +- lib/crtdll/stdio/ferror.c | 4 +- lib/crtdll/stdio/fflush.c | 18 +- lib/crtdll/stdio/fgetc.c | 10 +- lib/crtdll/stdio/fgetchar.c | 28 +- lib/crtdll/stdio/fgetpos.c | 7 +- lib/crtdll/stdio/fgets.c | 37 +- lib/crtdll/stdio/fgetws.c | 63 + lib/crtdll/stdio/filbuf.c | 16 +- lib/crtdll/stdio/fileno.c | 2 +- lib/crtdll/stdio/flsbuf.c | 105 +- lib/crtdll/stdio/fopen.c | 10 +- lib/crtdll/stdio/fprintf.c | 6 +- lib/crtdll/stdio/fputc.c | 8 +- lib/crtdll/stdio/fputchar.c | 6 +- lib/crtdll/stdio/fputs.c | 6 +- lib/crtdll/stdio/fputws.c | 38 + lib/crtdll/stdio/fread.c | 10 +- lib/crtdll/stdio/freopen.c | 14 +- lib/crtdll/stdio/frlist.c | 6 +- lib/crtdll/stdio/fscanf.c | 11 +- lib/crtdll/stdio/fseek.c | 12 +- lib/crtdll/stdio/fsetpos.c | 9 +- lib/crtdll/stdio/fsopen.c | 32 +- lib/crtdll/stdio/ftell.c | 18 +- lib/crtdll/stdio/fwalk.c | 26 +- lib/crtdll/stdio/fwrite.c | 10 +- lib/crtdll/stdio/getc.c | 10 +- lib/crtdll/stdio/getchar.c | 4 +- lib/crtdll/stdio/getenv.c | 2 +- lib/crtdll/stdio/gets.c | 5 +- lib/crtdll/stdio/getw.c | 10 +- lib/crtdll/stdio/perror.c | 9 +- lib/crtdll/stdio/popen.c | 18 +- lib/crtdll/stdio/printf.c | 6 +- lib/crtdll/stdio/putc.c | 19 +- lib/crtdll/stdio/putchar.c | 2 +- lib/crtdll/stdio/puts.c | 21 +- lib/crtdll/stdio/putw.c | 37 +- lib/crtdll/stdio/remove.c | 2 +- lib/crtdll/stdio/rename.c | 7 +- lib/crtdll/stdio/rewind.c | 7 +- lib/crtdll/stdio/rmtmp.c | 6 +- lib/crtdll/stdio/scanf.c | 11 +- lib/crtdll/stdio/setbuf.c | 9 +- lib/crtdll/stdio/setbuffe.c | 6 +- lib/crtdll/stdio/setlineb.c | 2 +- lib/crtdll/stdio/setvbuf.c | 10 +- lib/crtdll/stdio/sprintf.c | 8 +- lib/crtdll/stdio/sscanf.c | 28 +- lib/crtdll/stdio/stdhnd.c | 7 +- lib/crtdll/stdio/stdiohk.c | 4 +- lib/crtdll/stdio/tempnam.c | 34 +- lib/crtdll/stdio/tmpfile.c | 25 +- lib/crtdll/stdio/tmpnam.c | 11 +- lib/crtdll/stdio/ungetc.c | 17 +- lib/crtdll/stdio/vfprintf.c | 20 +- lib/crtdll/stdio/vfscanf.c | 22 +- lib/crtdll/stdio/vfwprint.c | 21 +- lib/crtdll/stdio/vprintf.c | 6 +- lib/crtdll/stdio/vscanf.c | 14 +- lib/crtdll/stdio/vsprintf.c | 6 +- lib/crtdll/stdio/vsscanf.c | 22 +- lib/crtdll/stdlib/_exit.c | 8 +- lib/crtdll/stdlib/abort.c | 8 +- lib/crtdll/stdlib/abs.c | 3 +- lib/crtdll/stdlib/alloca.c | 68 + lib/crtdll/stdlib/atexit.c | 4 +- lib/crtdll/stdlib/atof.c | 2 +- lib/crtdll/stdlib/atoi.c | 2 +- lib/crtdll/stdlib/atol.c | 2 +- lib/crtdll/stdlib/atold.c | 2 +- lib/crtdll/stdlib/bsearch.c | 2 +- lib/crtdll/stdlib/calloc.c | 4 +- lib/crtdll/stdlib/div.c | 2 +- lib/crtdll/stdlib/ecvt.c | 4 +- lib/crtdll/stdlib/ecvtbuf.c | 12 +- lib/crtdll/stdlib/errno.c | 2 +- lib/crtdll/stdlib/fcvt.c | 4 +- lib/crtdll/stdlib/fcvtbuf.c | 12 +- lib/crtdll/stdlib/fullpath.c | 15 +- lib/crtdll/stdlib/gcvt.c | 6 +- lib/crtdll/stdlib/itoa.c | 20 +- lib/crtdll/stdlib/itow.c | 280 +- lib/crtdll/stdlib/labs.c | 3 +- lib/crtdll/stdlib/ldiv.c | 2 +- lib/crtdll/stdlib/llabs.c | 2 +- lib/crtdll/stdlib/lldiv.c | 2 +- lib/crtdll/stdlib/makepath.c | 20 +- lib/crtdll/stdlib/malloc.c | 66 +- lib/crtdll/stdlib/mbstow.c | 17 - lib/crtdll/stdlib/mbstowcs.c | 1 - lib/crtdll/stdlib/obsol.c | 6 +- lib/crtdll/stdlib/putenv.c | 13 +- lib/crtdll/stdlib/qsort.c | 2 +- lib/crtdll/stdlib/rand.c | 2 +- lib/crtdll/stdlib/rot.c | 3 +- lib/crtdll/stdlib/senv.c | 13 +- lib/crtdll/stdlib/splitp.c | 6 +- lib/crtdll/stdlib/strtod.c | 4 +- lib/crtdll/stdlib/strtol.c | 8 +- lib/crtdll/stdlib/strtold.c | 12 +- lib/crtdll/stdlib/strtoll.c | 8 +- lib/crtdll/stdlib/strtoul.c | 8 +- lib/crtdll/stdlib/strtoull.c | 8 +- lib/crtdll/stdlib/swab.c | 2 +- lib/crtdll/stdlib/wcstom.c | 2 +- lib/crtdll/stdlib/wcstomb.c | 10 +- lib/crtdll/stdlib/wcstombs.c | 18 +- lib/crtdll/string/memccpy.c | 2 +- lib/crtdll/string/memchr.c | 3 +- lib/crtdll/string/memcmp.c | 24 +- lib/crtdll/string/memcpy.c | 10 +- lib/crtdll/string/memicmp.c | 4 +- lib/crtdll/string/memmove.c | 2 +- lib/crtdll/string/memset.c | 9 +- lib/crtdll/string/str_old.c | 4 +- lib/crtdll/string/strcat.c | 14 +- lib/crtdll/string/strchr.c | 4 +- lib/crtdll/string/strcmp.c | 8 +- lib/crtdll/string/strcoll.c | 28 +- lib/crtdll/string/strcpy.c | 4 +- lib/crtdll/string/strcspn.c | 5 +- lib/crtdll/string/strdup.c | 6 +- lib/crtdll/string/strerror.c | 8 +- lib/crtdll/string/stricmp.c | 4 +- lib/crtdll/string/strlen.c | 8 +- lib/crtdll/string/strlwr.c | 4 +- lib/crtdll/string/strncat.c | 2 +- lib/crtdll/string/strncmp.c | 2 +- lib/crtdll/string/strncpy.c | 2 +- lib/crtdll/string/strnicmp.c | 4 +- lib/crtdll/string/strnlen.c | 2 +- lib/crtdll/string/strpbrk.c | 2 +- lib/crtdll/string/strrchr.c | 3 +- lib/crtdll/string/strrev.c | 4 +- lib/crtdll/string/strset.c | 5 +- lib/crtdll/string/strspn.c | 2 +- lib/crtdll/string/strspnp.c | 2 +- lib/crtdll/string/strstr.c | 7 +- lib/crtdll/string/strtok.c | 5 +- lib/crtdll/string/strtoul.c | 4 +- lib/crtdll/string/strupr.c | 4 +- lib/crtdll/string/strxfrm.c | 11 +- lib/crtdll/sys_stat/fstat.c | 74 +- lib/crtdll/sys_stat/ftime.c | 49 +- lib/crtdll/sys_stat/futime.c | 71 +- lib/crtdll/sys_stat/stat.c | 88 +- lib/crtdll/sys_stat/systime.c | 95 +- lib/crtdll/tchar/strdec.c | 2 +- lib/crtdll/tchar/strinc.c | 2 +- lib/crtdll/tchar/strncnt.c | 5 +- lib/crtdll/tchar/strnextc.c | 2 +- lib/crtdll/tchar/strninc.c | 4 +- lib/crtdll/tchar/strspnp.c | 4 +- lib/crtdll/time/clock.c | 22 +- lib/crtdll/time/ctime.c | 140 +- lib/crtdll/time/difftime.c | 2 +- lib/crtdll/time/strdate.c | 10 +- lib/crtdll/time/strftime.c | 68 +- lib/crtdll/time/strtime.c | 9 +- lib/crtdll/time/time.c | 16 +- lib/crtdll/time/tz_vars.c | 21 + lib/crtdll/wchar/.cvsignore | 2 - lib/crtdll/wchar/wcscat.c | 19 - lib/crtdll/wchar/wcschr.c | 16 - lib/crtdll/wchar/wcscmp.c | 16 - lib/crtdll/wchar/wcscoll.c | 3 +- lib/crtdll/wchar/wcscpy.c | 11 - lib/crtdll/wchar/wcscspn.c | 20 - lib/crtdll/wchar/wcsdup.c | 19 - lib/crtdll/wchar/wcsftime.c | 6 - lib/crtdll/wchar/wcsicmp.c | 16 - lib/crtdll/wchar/wcslen.c | 6 +- lib/crtdll/wchar/wcslwr.c | 22 - lib/crtdll/wchar/wcsncat.c | 21 - lib/crtdll/wchar/wcsncmp.c | 16 - lib/crtdll/wchar/wcsncpy.c | 21 - lib/crtdll/wchar/wcsnicmp.c | 14 - lib/crtdll/wchar/wcsnlen.c | 12 - lib/crtdll/wchar/wcspbrk.c | 16 - lib/crtdll/wchar/wcsrchr.c | 16 - lib/crtdll/wchar/wcsrev.c | 18 - lib/crtdll/wchar/wcsset.c | 27 - lib/crtdll/wchar/wcsspn.c | 20 - lib/crtdll/wchar/wcsstr.c | 23 - lib/crtdll/wchar/wcstod.c | 4 +- lib/crtdll/wchar/wcstok.c | 9 +- lib/crtdll/wchar/wcstol.c | 18 +- lib/crtdll/wchar/wcstombs.c | 4 +- lib/crtdll/wchar/wcsupr.c | 12 - lib/crtdll/wchar/wcsxfrm.c | 23 - lib/crtdll/wchar/wtoi.c | 7 +- lib/fmifs/.cvsignore | 6 +- lib/fmifs/makefile | 4 + lib/gdi32/.cvsignore | 4 +- lib/gdi32/main/.cvsignore | 1 + lib/gdi32/makefile | 8 + lib/gdi32/misc/.cvsignore | 3 +- lib/gdi32/misc/stubs.c | 415 +- lib/gdi32/objects/.cvsignore | 1 + lib/gdi32/objects/dc.c | 23 + lib/gdi32/objects/region.c | 2 +- lib/gdi32/objects/text.c | 2 +- lib/kernel32/.cvsignore | 4 +- lib/kernel32/MSG00409.bin | Bin 0 -> 292 bytes lib/kernel32/errcodes.rc | 7 + lib/kernel32/errormsg.mak | 18 + lib/kernel32/except/except.c | 4 +- lib/kernel32/file/backup.c | 9 +- lib/kernel32/file/cnotify.c | 2 +- lib/kernel32/file/copy.c | 385 +- lib/kernel32/file/create.c | 8 +- lib/kernel32/file/curdir.c | 5 +- lib/kernel32/file/delete.c | 5 +- lib/kernel32/file/deviceio.c | 4 +- lib/kernel32/file/dir.c | 14 +- lib/kernel32/file/dosdev.c | 3 +- lib/kernel32/file/file.c | 23 +- lib/kernel32/file/find.c | 5 +- lib/kernel32/file/iocompl.c | 21 +- lib/kernel32/file/lfile.c | 5 +- lib/kernel32/file/lock.c | 8 +- lib/kernel32/file/mailslot.c | 6 +- lib/kernel32/file/move.c | 236 +- lib/kernel32/file/npipe.c | 14 +- lib/kernel32/file/pipe.c | 4 +- lib/kernel32/file/rw.c | 6 +- lib/kernel32/file/tape.c | 6 +- lib/kernel32/file/volume.c | 59 +- lib/kernel32/k32.h | 26 + lib/kernel32/kernel32.def | 24 + lib/kernel32/kernel32.edf | 25 + lib/kernel32/kernel32.mc | 5358 ++++++++++++++++++++ lib/kernel32/kernel32.rc | 3 + lib/kernel32/makefile | 79 +- lib/kernel32/mem/global.c | 4 +- lib/kernel32/mem/heap.c | 11 +- lib/kernel32/mem/isbad.c | 2 +- lib/kernel32/mem/local.c | 4 +- lib/kernel32/mem/procmem.c | 5 +- lib/kernel32/mem/section.c | 20 +- lib/kernel32/mem/virtual.c | 4 +- lib/kernel32/misc/atom.c | 4 +- lib/kernel32/misc/comm.c | 740 ++- lib/kernel32/misc/console.c | 135 +- lib/kernel32/misc/debug.c | 7 +- lib/kernel32/misc/dllmain.c | 8 +- lib/kernel32/misc/env.c | 193 +- lib/kernel32/misc/error.c | 7 +- lib/kernel32/misc/errormsg.c | 796 +++ lib/kernel32/misc/getname.c | 49 + lib/kernel32/misc/handle.c | 8 +- lib/kernel32/misc/ldr.c | 9 +- lib/kernel32/misc/mbchars.c | 302 ++ lib/kernel32/misc/muldiv.c | 61 + lib/kernel32/misc/perfcnt.c | 84 + lib/kernel32/misc/profile.c | 6 +- lib/kernel32/misc/res.c | 7 +- lib/kernel32/misc/stubs.c | 1434 ++---- lib/kernel32/misc/sysinfo.c | 15 +- lib/kernel32/misc/time.c | 13 +- lib/kernel32/misc/toolhelp.c | 317 ++ lib/kernel32/nls/codepage.c | 4 +- lib/kernel32/nls/locale.c | 12 +- lib/kernel32/nls/mbtowc.c | 6 +- lib/kernel32/nls/ole2nls.c | 33 +- lib/kernel32/nls/wctomb.c | 4 +- lib/kernel32/process/cmdline.c | 9 +- lib/kernel32/process/create.c | 130 +- lib/kernel32/process/proc.c | 87 +- lib/kernel32/process/session.c | 2 +- lib/kernel32/string/lstring.c | 4 +- lib/kernel32/synch/critical.c | 3 +- lib/kernel32/synch/event.c | 4 +- lib/kernel32/synch/intrlck.c | 2 +- lib/kernel32/synch/mutex.c | 6 +- lib/kernel32/synch/sem.c | 4 +- lib/kernel32/synch/timer.c | 4 +- lib/kernel32/synch/wait.c | 5 +- lib/kernel32/thread/fiber.c | 3 +- lib/kernel32/thread/thread.c | 659 ++- lib/kernel32/thread/tls.c | 6 +- lib/msafd/.cvsignore | 2 + lib/msafd/makefile | 10 +- lib/msafd/misc/.cvsignore | 1 + lib/msafd/misc/dllmain.c | 1 + lib/msafd/misc/helpers.c | 97 +- lib/msafd/misc/sndrcv.c | 1 + lib/msvcrt/.cvsignore | 5 + lib/msvcrt/Makefile | 171 +- lib/msvcrt/conio/cputs.c | 2 +- lib/msvcrt/conio/cscanf.c | 18 +- lib/msvcrt/conio/getch.c | 47 +- lib/msvcrt/conio/getche.c | 2 +- lib/msvcrt/conio/kbhit.c | 7 +- lib/msvcrt/conio/putch.c | 6 +- lib/msvcrt/conio/ungetch.c | 2 +- lib/msvcrt/ctype/ctype.c | 264 + lib/msvcrt/ctype/isalnum.c | 6 +- lib/msvcrt/ctype/isalpha.c | 6 +- lib/msvcrt/ctype/isascii.c | 12 +- lib/msvcrt/ctype/iscntrl.c | 5 +- lib/msvcrt/ctype/iscsym.c | 6 +- lib/msvcrt/ctype/isctype.c | 262 +- lib/msvcrt/ctype/isdigit.c | 5 +- lib/msvcrt/ctype/islower.c | 5 +- lib/msvcrt/ctype/ispunct.c | 5 +- lib/msvcrt/ctype/isspace.c | 4 +- lib/msvcrt/ctype/isupper.c | 5 +- lib/msvcrt/ctype/isxdigit.c | 5 +- lib/msvcrt/ctype/toascii.c | 2 +- lib/msvcrt/ctype/tolower.c | 14 +- lib/msvcrt/ctype/toupper.c | 8 +- lib/msvcrt/direct/chdir.c | 23 +- lib/msvcrt/direct/chdrive.c | 27 +- lib/msvcrt/direct/getcwd.c | 48 +- lib/msvcrt/direct/getdcwd.c | 51 +- lib/msvcrt/direct/getdfree.c | 24 +- lib/msvcrt/direct/getdrive.c | 17 +- lib/msvcrt/direct/mkdir.c | 15 +- lib/msvcrt/direct/rmdir.c | 14 +- lib/msvcrt/direct/wchdir.c | 13 + lib/msvcrt/direct/wgetcwd.c | 20 + lib/msvcrt/direct/wgetdcwd.c | 24 + lib/msvcrt/direct/wmkdir.c | 10 + lib/msvcrt/direct/wrmdir.c | 9 + lib/msvcrt/except/abnorter.c | 6 + lib/msvcrt/except/exhand2.c | 13 +- lib/msvcrt/except/matherr.c | 34 +- lib/msvcrt/except/unwind.c | 3 + lib/msvcrt/float/chgsign.c | 2 + lib/msvcrt/float/clearfp.c | 5 +- lib/msvcrt/float/cntrlfp.c | 5 +- lib/msvcrt/float/fpclass.c | 4 +- lib/msvcrt/float/fpreset.c | 1 + lib/msvcrt/float/isnan.c | 7 +- lib/msvcrt/float/logb.c | 7 +- lib/msvcrt/float/nafter.c | 1 + lib/msvcrt/float/statfp.c | 4 +- lib/msvcrt/io/access.c | 82 +- lib/msvcrt/io/chmod.c | 58 +- lib/msvcrt/io/commit.c | 10 +- lib/msvcrt/io/create.c | 11 +- lib/msvcrt/io/filelen.c | 12 +- lib/msvcrt/io/fileleni.c | 11 + lib/msvcrt/io/find.c | 304 +- lib/msvcrt/io/locking.c | 2 + lib/msvcrt/io/lseek.c | 10 +- lib/msvcrt/io/lseeki64.c | 39 + lib/msvcrt/io/mktemp.c | 65 +- lib/msvcrt/io/open.c | 556 +- lib/msvcrt/io/pipe.c | 2 +- lib/msvcrt/io/read.c | 34 +- lib/msvcrt/io/setmode.c | 6 +- lib/msvcrt/io/sopen.c | 5 - lib/msvcrt/io/tell.c | 7 +- lib/msvcrt/io/telli64.c | 8 + lib/msvcrt/io/umask.c | 2 +- lib/msvcrt/io/unlink.c | 22 +- lib/msvcrt/io/utime.c | 39 +- lib/msvcrt/io/waccess.c | 29 + lib/msvcrt/io/wchmod.c | 33 + lib/msvcrt/io/wcreate.c | 12 + lib/msvcrt/io/wfind.c | 203 + lib/msvcrt/io/wmktemp.c | 75 + lib/msvcrt/io/wopen.c | 140 + lib/msvcrt/io/write.c | 117 +- lib/msvcrt/io/wunlink.c | 23 + lib/msvcrt/io/wutime.c | 22 + lib/msvcrt/math/acos.c | 5 +- lib/msvcrt/math/asin.c | 5 +- lib/msvcrt/math/atan.c | 5 +- lib/msvcrt/math/atan2.c | 5 +- lib/msvcrt/math/ceil.c | 5 +- lib/msvcrt/math/cos.c | 5 +- lib/msvcrt/math/cosh.c | 5 +- lib/msvcrt/math/exp.c | 4 + lib/msvcrt/math/fabs.c | 5 +- lib/msvcrt/math/floor.c | 5 +- lib/msvcrt/math/fmod.c | 5 +- lib/msvcrt/math/frexp.c | 17 +- lib/msvcrt/math/ftol.c | 2 +- lib/msvcrt/math/hypot.c | 2 +- lib/msvcrt/math/j0_y0.c | 10 +- lib/msvcrt/math/j1_y1.c | 9 +- lib/msvcrt/math/jn_yn.c | 3 +- lib/msvcrt/math/ldexp.c | 5 +- lib/msvcrt/math/log.c | 5 +- lib/msvcrt/math/log10.c | 5 +- lib/msvcrt/math/math.c | 120 + lib/msvcrt/math/pow.c | 14 +- lib/msvcrt/math/sin.c | 5 +- lib/msvcrt/math/sqrt.c | 5 +- lib/msvcrt/math/stubs.c | 71 +- lib/msvcrt/math/tan.c | 5 +- lib/msvcrt/mbstring/hanzen.c | 2 +- lib/msvcrt/mbstring/ischira.c | 3 +- lib/msvcrt/mbstring/iskana.c | 2 +- lib/msvcrt/mbstring/iskmoji.c | 2 +- lib/msvcrt/mbstring/iskpun.c | 2 +- lib/msvcrt/mbstring/islwr.c | 2 +- lib/msvcrt/mbstring/ismbal.c | 6 +- lib/msvcrt/mbstring/ismbkaln.c | 2 +- lib/msvcrt/mbstring/ismblead.c | 2 +- lib/msvcrt/mbstring/ismbpun.c | 7 +- lib/msvcrt/mbstring/ismbtrl.c | 2 +- lib/msvcrt/mbstring/isuppr.c | 2 +- lib/msvcrt/mbstring/mbbtype.c | 58 +- lib/msvcrt/mbstring/mbclen.c | 4 - lib/msvcrt/mbstring/mbscoll.c | 2 +- lib/msvcrt/mbstring/mbsdup.c | 2 +- lib/msvcrt/mbstring/mbsicmp.c | 2 +- lib/msvcrt/mbstring/mbsicoll.c | 2 +- lib/msvcrt/mbstring/mbslwr.c | 38 +- lib/msvcrt/mbstring/mbsncat.c | 3 +- lib/msvcrt/mbstring/mbsncmp.c | 2 +- lib/msvcrt/mbstring/mbsncoll.c | 2 +- lib/msvcrt/mbstring/mbsncpy.c | 16 +- lib/msvcrt/mbstring/mbsnicmp.c | 3 +- lib/msvcrt/mbstring/mbsnset.c | 2 +- lib/msvcrt/mbstring/mbspbrk.c | 1 - lib/msvcrt/mbstring/mbsrchr.c | 2 +- lib/msvcrt/mbstring/mbsset.c | 2 +- lib/msvcrt/mbstring/mbsupr.c | 1 - lib/msvcrt/misc/amsg.c | 11 +- lib/msvcrt/misc/assert.c | 1 + lib/msvcrt/misc/crtmain.c | 99 + lib/msvcrt/misc/dllmain.c | 298 +- lib/msvcrt/misc/environ.c | 123 + lib/msvcrt/misc/getargs.c | 216 +- lib/msvcrt/misc/initterm.c | 14 +- lib/msvcrt/misc/purecall.c | 2 +- lib/msvcrt/misc/tls.c | 1 + lib/msvcrt/msvcrt.def | 16 +- lib/msvcrt/process/_cwait.c | 28 +- lib/msvcrt/process/_system.c | 4 +- lib/msvcrt/process/dll.c | 11 +- lib/msvcrt/process/process.c | 4 +- lib/msvcrt/process/thread.c | 37 +- lib/msvcrt/process/threadx.c | 26 + lib/msvcrt/search/lfind.c | 17 +- lib/msvcrt/search/lsearch.c | 4 + lib/msvcrt/setjmp/setjmp.c | 9 +- lib/msvcrt/stdio/fdopen.c | 56 +- lib/msvcrt/stdio/ferror.c | 2 + lib/msvcrt/stdio/fflush.c | 4 +- lib/msvcrt/stdio/fgetc.c | 2 +- lib/msvcrt/stdio/fgetchar.c | 29 +- lib/msvcrt/stdio/fgets.c | 37 +- lib/msvcrt/stdio/fgetws.c | 58 + lib/msvcrt/stdio/filbuf.c | 31 +- lib/msvcrt/stdio/flsbuf.c | 271 +- lib/msvcrt/stdio/fopen.c | 109 +- lib/msvcrt/stdio/fputchar.c | 29 +- lib/msvcrt/stdio/fputs.c | 56 + lib/msvcrt/stdio/fsopen.c | 6 +- lib/msvcrt/stdio/ftell.c | 1 - lib/msvcrt/stdio/fwalk.c | 6 +- lib/msvcrt/stdio/getc.c | 128 +- lib/msvcrt/stdio/getchar.c | 35 +- lib/msvcrt/stdio/gets.c | 72 +- lib/msvcrt/stdio/getw.c | 7 +- lib/msvcrt/stdio/printf.c | 40 +- lib/msvcrt/stdio/putc.c | 173 +- lib/msvcrt/stdio/putchar.c | 4 +- lib/msvcrt/stdio/puts.c | 31 +- lib/msvcrt/stdio/rename.c | 24 +- lib/msvcrt/stdio/rmtmp.c | 2 +- lib/msvcrt/stdio/tempnam.c | 51 +- lib/msvcrt/stdio/tmpfile.c | 4 +- lib/msvcrt/stdio/tmpnam.c | 26 +- lib/msvcrt/stdio/ungetc.c | 7 +- lib/msvcrt/stdio/vfprintf.c | 56 +- lib/msvcrt/stdio/vfscanf.c | 44 +- lib/msvcrt/stdio/vfwprint.c | 20 +- lib/msvcrt/stdio/vprintf.c | 62 +- lib/msvcrt/stdio/wfdopen.c | 54 + lib/msvcrt/stdio/wrename.c | 15 + lib/msvcrt/stdio/wtempnam.c | 22 + lib/msvcrt/stdio/wtmpnam.c | 16 + lib/msvcrt/stdlib/abs.c | 1 + lib/msvcrt/stdlib/fullpath.c | 21 +- lib/msvcrt/stdlib/itoa.c | 108 +- lib/msvcrt/stdlib/itow.c | 319 +- lib/msvcrt/stdlib/labs.c | 1 + lib/msvcrt/stdlib/makepath.c | 75 +- lib/msvcrt/stdlib/mbstow.c | 17 - lib/msvcrt/stdlib/mbstowcs.c | 117 +- lib/msvcrt/stdlib/mbtowc.c | 52 + lib/msvcrt/stdlib/obsol.c | 4 + lib/msvcrt/stdlib/putenv.c | 56 +- lib/msvcrt/stdlib/rand.c | 6 +- lib/msvcrt/stdlib/rot.c | 3 +- lib/msvcrt/stdlib/senv.c | 67 +- lib/msvcrt/stdlib/splitp.c | 126 +- lib/msvcrt/stdlib/strtold.c | 6 +- lib/msvcrt/stdlib/wcstombs.c | 10 +- lib/msvcrt/stdlib/wctomb.c | 146 + lib/msvcrt/stdlib/wfulpath.c | 22 + lib/msvcrt/stdlib/witoa.c | 92 + lib/msvcrt/stdlib/witow.c | 90 + lib/msvcrt/stdlib/wmakpath.c | 33 + lib/msvcrt/stdlib/wputenv.c | 31 + lib/msvcrt/stdlib/wsenv.c | 32 + lib/msvcrt/stdlib/wsplitp.c | 48 + lib/msvcrt/stdlib/wtoi64.c | 39 +- lib/msvcrt/string/memccpy.c | 16 +- lib/msvcrt/string/memcmp.c | 23 +- lib/msvcrt/string/memcpy.c | 9 +- lib/msvcrt/string/memset.c | 8 +- lib/msvcrt/string/strcat.c | 13 +- lib/msvcrt/string/strcmp.c | 6 +- lib/msvcrt/string/strcoll.c | 33 +- lib/msvcrt/string/strcpy.c | 1 + lib/msvcrt/string/strlen.c | 7 +- lib/msvcrt/string/strncoll.c | 17 + lib/msvcrt/string/strrev.c | 17 +- lib/msvcrt/string/strset.c | 1 + lib/msvcrt/string/strtok.c | 2 +- lib/msvcrt/string/strxfrm.c | 3 +- lib/msvcrt/sys_stat/fstat.c | 75 +- lib/msvcrt/sys_stat/fstati64.c | 82 + lib/msvcrt/sys_stat/futime.c | 21 +- lib/msvcrt/sys_stat/stat.c | 146 +- lib/msvcrt/sys_stat/wstat.c | 146 + lib/msvcrt/time/ctime.c | 498 +- lib/msvcrt/time/strdate.c | 39 +- lib/msvcrt/time/strftime.c | 36 +- lib/msvcrt/time/strtime.c | 39 +- lib/msvcrt/time/time.c | 10 +- lib/msvcrt/time/tz_vars.c | 21 + lib/msvcrt/time/wctime.c | 69 + lib/msvcrt/time/wstrdate.c | 30 + lib/msvcrt/time/wstrtime.c | 30 + lib/msvcrt/wstring/wcsdup.c | 20 +- lib/msvcrt/wstring/wcsncmp.c | 25 +- lib/msvcrt/wstring/wcsncpy.c | 1 - lib/msvcrt/wstring/wcspbrk.c | 2 +- lib/msvcrt/wstring/wcsupr.c | 5 +- lib/ntdll/.cvsignore | 2 + lib/ntdll/def/ntdll.def | 12 +- lib/ntdll/def/ntdll.edf | 12 +- lib/ntdll/ldr/res.c | 268 + lib/ntdll/ldr/startup.c | 129 +- lib/ntdll/ldr/utils.c | 1897 ++++--- lib/ntdll/makefile | 3 +- lib/ntdll/rtl/error.c | 10 +- lib/ntdll/rtl/heap.c | 4 +- lib/ntdll/rtl/i386/.cvsignore | 1 + lib/ntdll/rtl/largeint.c | 6 +- lib/ntdll/rtl/mem.c | 36 +- lib/ntdll/rtl/ppb.c | 40 +- lib/ntdll/rtl/time.c | 135 +- lib/ntdll/rtl/unicode.c | 229 +- lib/ntdll/stdlib/abs.c | 2 +- lib/ntdll/string/stricmp.c | 4 +- lib/ntdll/string/wstring.c | 1 - lib/ole32/ole32.def | 604 +-- lib/packet/Packet32.c | 5 +- lib/packet/include/devioctl.h | 90 - lib/packet/include/ntddndis.h | 1400 ----- lib/packet/include/packet32.h | 1 - lib/packet/makefile | 2 - lib/psapi/misc/win32.c | 9 + lib/secur32/.cvsignore | 2 + lib/secur32/Makefile | 9 +- lib/secur32/dllmain.c | 2 +- lib/shell32/control/.cvsignore | 6 + lib/shell32/control/makefile | 64 + lib/shell32/misc/stubs.c | 3 + lib/user32/Makefile | 11 +- lib/user32/controls/scrollbar.c | 391 +- lib/user32/misc/resources.c | 234 +- lib/user32/misc/stubs.c | 37 +- lib/user32/user32.def | 4 +- lib/user32/user32.edf | 4 +- lib/user32/windows/bitmap.c | 2 +- lib/user32/windows/defwnd.c | 137 +- lib/user32/windows/draw.c | 1337 ++++- lib/user32/windows/text.c | 439 +- lib/user32/windows/window.c | 24 +- lib/version/.cvsignore | 3 +- lib/version/makefile | 6 +- lib/version/misc/.cvsignore | 1 + lib/version/misc/libmain.c | 33 +- lib/winedbgc/.cvsignore | 4 + lib/winedbgc/Makefile | 35 + lib/winedbgc/debug.c | 436 ++ lib/winedbgc/libmain.c | 97 + lib/winedbgc/porting.c | 38 + lib/winedbgc/porting.h | 40 + lib/winedbgc/winedbgc.c | 258 + lib/winedbgc/winedbgc.def | 37 + lib/winedbgc/winedbgc.dll.dbg.c | 42 + lib/winedbgc/winedbgc.edf | 81 + lib/winedbgc/winedbgc.rc | 38 + lib/winmm/dllmain.c | 2 +- lib/winmm/misc/.cvsignore | 1 + lib/winmm/misc/stubs.c | 114 +- lib/winmm/winmm.def | 16 +- lib/winmm/winmm.edf | 16 +- lib/ws2_32/.cvsignore | 1 + lib/ws2_32/makefile | 11 +- lib/ws2_32/misc/.cvsignore | 1 + lib/ws2_32/misc/catalog.c | 9 +- lib/ws2_32/misc/dllmain.c | 1 - lib/ws2_32/misc/event.c | 1 - lib/ws2_32/misc/sndrcv.c | 1 + lib/ws2_32/misc/upcall.c | 3 +- lib/ws2help/makefile | 9 +- loaders/boot/boot.asm | 4 +- loaders/boot/boot.mak | 4 +- loaders/boot/bootbk.asm | 4 +- loaders/dos/.cvsignore | 1 + loaders/dos/loadros.asm | 51 +- ntoskrnl/.cvsignore | 7 +- ntoskrnl/Makefile | 8 +- ntoskrnl/cc/misc.c | 2 + ntoskrnl/cc/pin.c | 21 +- ntoskrnl/cc/view.c | 408 +- ntoskrnl/cm/cm.h | 95 +- ntoskrnl/cm/import.c | 4 + ntoskrnl/cm/ntfunc.c | 923 ++-- ntoskrnl/cm/regfile.c | 1203 +++-- ntoskrnl/cm/registry.c | 523 +- ntoskrnl/cm/regobj.c | 125 +- ntoskrnl/cm/rtlfunc.c | 27 +- ntoskrnl/dbg/errinfo.c | 6 +- ntoskrnl/dbg/kdb.h | 20 + ntoskrnl/dbg/kdb_stabs.c | 22 +- ntoskrnl/dbg/profile.c | 500 ++ ntoskrnl/ex/hashtab.c | 2 +- ntoskrnl/ex/i386/interlck.c | 4 +- ntoskrnl/ex/napi.c | 3 +- ntoskrnl/ex/power.c | 2 + ntoskrnl/ex/time.c | 4 +- ntoskrnl/fs/filelock.c | 1345 ++++- ntoskrnl/include/internal/cc.h | 74 +- ntoskrnl/include/internal/i386/ke.h | 4 + ntoskrnl/include/internal/ifs.h | 68 + ntoskrnl/include/internal/kd.h | 2 +- ntoskrnl/include/internal/ldr.h | 7 +- ntoskrnl/include/internal/mm.h | 11 +- ntoskrnl/io/arcname.c | 4 +- ntoskrnl/io/cancel.c | 12 +- ntoskrnl/io/irp.c | 82 +- ntoskrnl/io/lock.c | 257 +- ntoskrnl/io/pnpmgr.c | 1 + ntoskrnl/io/pnproot.c | 1 + ntoskrnl/io/rw.c | 2 +- ntoskrnl/kd/gdbstub.c | 2 +- ntoskrnl/kd/kdebug.c | 6 + ntoskrnl/ke/catch.c | 3 +- ntoskrnl/ke/i386/exp.c | 48 +- ntoskrnl/ke/i386/irq.c | 87 +- ntoskrnl/ke/main.c | 69 +- ntoskrnl/ke/queue.c | 2 +- ntoskrnl/ke/sem.c | 2 +- ntoskrnl/ke/timer.c | 82 +- ntoskrnl/ke/wait.c | 69 +- ntoskrnl/ldr/init.c | 706 +-- ntoskrnl/ldr/loader.c | 62 +- ntoskrnl/ldr/resource.c | 2 +- ntoskrnl/lpc/connect.c | 1 - ntoskrnl/mm/anonmem.c | 23 +- ntoskrnl/mm/balance.c | 2 +- ntoskrnl/mm/freelist.c | 2 +- ntoskrnl/mm/marea.c | 27 +- ntoskrnl/mm/mdl.c | 2 +- ntoskrnl/mm/mminit.c | 13 +- ntoskrnl/mm/mpw.c | 9 + ntoskrnl/mm/npool.c | 8 +- ntoskrnl/mm/pagefile.c | 4 +- ntoskrnl/mm/pageop.c | 26 +- ntoskrnl/mm/pool.c | 1 + ntoskrnl/mm/region.c | 8 +- ntoskrnl/mm/rmap.c | 19 +- ntoskrnl/mm/section.c | 106 +- ntoskrnl/ntoskrnl.def | 16 +- ntoskrnl/ntoskrnl.edf | 16 +- ntoskrnl/ob/handle.c | 16 +- ntoskrnl/ob/namespc.c | 18 +- ntoskrnl/ps/debug.c | 2 +- ntoskrnl/ps/kill.c | 43 +- ntoskrnl/ps/process.c | 4 +- ntoskrnl/rtl/bitmap.c | 114 +- ntoskrnl/rtl/error.c | 9 +- ntoskrnl/rtl/i386/exception.c | 12 +- ntoskrnl/rtl/largeint.c | 3 +- ntoskrnl/rtl/math.c | 332 ++ ntoskrnl/rtl/mem.c | 10 +- ntoskrnl/rtl/nls.c | 6 + ntoskrnl/rtl/string.c | 2 +- ntoskrnl/rtl/time.c | 36 +- ntoskrnl/rtl/unicode.c | 145 +- ntoskrnl/rtl/wstring.c | 10 +- rules.mak | 27 + services/eventlog/.cvsignore | 1 + services/eventlog/eventlog.rc | 4 +- services/rpcss/.cvsignore | 1 + services/rpcss/rpcss.rc | 4 +- subsys/csrss/api.h | 5 +- subsys/csrss/api/conio.c | 173 +- subsys/csrss/api/process.c | 136 +- subsys/csrss/api/wapi.c | 2 + subsys/csrss/csrss.def | 8 + subsys/csrss/csrss.edf | 9 + subsys/csrss/csrss.rc | 4 +- subsys/csrss/makefile | 3 +- subsys/ntvdm/ntvdm.c | 267 +- subsys/system/gstart/gstart.rc | 4 +- subsys/system/services/services.c | 321 +- subsys/system/services/services.rc | 4 +- subsys/system/shell/shell.rc | 4 +- subsys/system/usetup/bootsup.c | 1492 ++++++ subsys/system/usetup/bootsup.h | 72 + subsys/system/usetup/console.c | 106 +- subsys/system/usetup/console.h | 7 +- subsys/system/usetup/drivesup.h | 2 +- subsys/system/usetup/filequeue.c | 381 ++ subsys/system/usetup/filequeue.h | 87 + subsys/system/usetup/filesup.c | 331 ++ subsys/system/usetup/filesup.h | 44 + subsys/system/usetup/inicache.c | 1202 +++++ subsys/system/usetup/inicache.h | 132 + subsys/system/usetup/makefile | 3 +- subsys/system/usetup/partlist.c | 444 +- subsys/system/usetup/partlist.h | 18 +- subsys/system/usetup/progress.c | 246 + subsys/system/usetup/progress.h | 67 + subsys/system/usetup/usetup.c | 1746 +++++-- subsys/system/winlogon/winlogon.c | 323 +- subsys/win32k/.cvsignore | 5 +- subsys/win32k/eng/mouse.c | 221 +- subsys/win32k/eng/xlate.c | 19 +- subsys/win32k/freetype/src/base/ftinit.c | 1 + subsys/win32k/freetype/src/cff/.cvsignore | 1 + subsys/win32k/include/window.h | 4 + subsys/win32k/makefile | 2 +- subsys/win32k/ntuser/painting.c | 17 +- subsys/win32k/ntuser/scrollbar.c | 309 ++ subsys/win32k/ntuser/stubs.c | 66 - subsys/win32k/ntuser/window.c | 26 +- subsys/win32k/objects/brush.c | 11 +- subsys/win32k/objects/cliprgn.c | 14 +- subsys/win32k/objects/color.c | 48 +- subsys/win32k/objects/dc.c | 45 +- subsys/win32k/objects/fillshap.c | 6 +- subsys/win32k/objects/gdiobj.c | 260 +- subsys/win32k/objects/line.c | 4 +- subsys/win32k/objects/region.c | 149 +- subsys/win32k/win32k.rc | 5 +- system.hiv | 107 +- tools/.cvsignore | 1 + tools/Makefile | 13 +- tools/helper.mk | 61 +- tools/rsym.c | 2 - tools/rtouch.c | 81 + tools/wmc/.cvsignore | 4 + tools/wmc/lang.c | 13 + tools/wmc/lang.h | 13 + tools/wmc/mcl.c | 13 + tools/wmc/mcy.y | 16 + tools/wmc/utils.c | 13 + tools/wmc/utils.h | 13 + tools/wmc/wmc.c | 13 + tools/wmc/wmc.h | 22 + tools/wmc/wmctypes.h | 13 + tools/wmc/write.c | 22 +- tools/wmc/write.h | 13 + txtsetup.sif | 98 + 1481 files changed, 94668 insertions(+), 35360 deletions(-) create mode 100644 apps/tests/Makefile create mode 100644 apps/tests/alive/.cvsignore create mode 100644 apps/tests/apc/.cvsignore create mode 100644 apps/tests/args/.cvsignore create mode 100644 apps/tests/atomtest/.cvsignore create mode 100644 apps/tests/bench/.cvsignore create mode 100644 apps/tests/bitblt/.cvsignore create mode 100644 apps/tests/consume/.cvsignore create mode 100644 apps/tests/copymove/.cvsignore create mode 100644 apps/tests/copymove/Makefile create mode 100644 apps/tests/copymove/copymove.c create mode 100644 apps/tests/count/.cvsignore create mode 100644 apps/tests/dibtest/.cvsignore create mode 100644 apps/tests/dump_shared_data/.cvsignore create mode 100644 apps/tests/event/.cvsignore create mode 100644 apps/tests/file/.cvsignore create mode 100644 apps/tests/gditest/.cvsignore create mode 100644 apps/tests/hello/.cvsignore create mode 100644 apps/tests/hivetest/.cvsignore create mode 100644 apps/tests/hivetest/hivetest.c create mode 100644 apps/tests/hivetest/makefile create mode 100644 apps/tests/isotest/.cvsignore create mode 100644 apps/tests/lock/Makefile create mode 100644 apps/tests/lock/lock.c create mode 100644 apps/tests/lpc/.cvsignore create mode 100644 apps/tests/mstest/.cvsignore create mode 100644 apps/tests/mutex/.cvsignore create mode 100644 apps/tests/nptest/.cvsignore create mode 100644 apps/tests/pteb/.cvsignore create mode 100644 apps/tests/regdump/main.c create mode 100644 apps/tests/regdump/regcmds.c create mode 100644 apps/tests/regdump/regdump.h create mode 100644 apps/tests/regdump/regproc.c create mode 100644 apps/tests/regdump/regproc.h create mode 100644 apps/tests/regtest/.cvsignore create mode 100644 apps/tests/sectest/.cvsignore create mode 100644 apps/tests/sertest/.cvsignore create mode 100644 apps/tests/shm/.cvsignore create mode 100644 apps/tests/simple/.cvsignore create mode 100644 apps/tests/tests/GetSysMetrics/.cvsignore create mode 100644 apps/tests/tests/GetSystemInfo/.cvsignore create mode 100644 apps/tests/tests/Mutex/.cvsignore create mode 100644 apps/tests/tests/Parent_Child/.cvsignore create mode 100644 apps/tests/tests/guitest/.cvsignore create mode 100644 apps/tests/tests/hello/.cvsignore create mode 100644 apps/tests/tests/hello2/.cvsignore create mode 100644 apps/tests/tests/new/.cvsignore create mode 100644 apps/tests/tests/rolex/.cvsignore create mode 100644 apps/tests/tests/volinfo/.cvsignore create mode 100644 apps/tests/thread/.cvsignore create mode 100644 apps/tests/tokentest/.cvsignore create mode 100644 apps/tests/vmtest/.cvsignore create mode 100644 apps/tests/winhello/.cvsignore create mode 100644 apps/tests/wm_paint/Listing1_1.cpp create mode 100644 apps/tests/wm_paint/makefile create mode 100644 apps/testsets/Makefile create mode 100644 apps/testsets/loadlib/.cvsignore create mode 100644 apps/testsets/loadlib/loadlib.c create mode 100644 apps/testsets/loadlib/loadlib.h create mode 100644 apps/testsets/loadlib/makefile create mode 100644 apps/testsets/msvcrt/fileio/.cvsignore create mode 100644 apps/testsets/msvcrt/fileio/_tfileio.c create mode 100644 apps/testsets/msvcrt/fileio/fileio.c create mode 100644 apps/testsets/msvcrt/fileio/main.c create mode 100644 apps/testsets/msvcrt/fileio/main.h create mode 100644 apps/testsets/msvcrt/fileio/makefile create mode 100644 apps/testsets/msvcrt/fileio/wfileio.c create mode 100644 apps/utils/Makefile create mode 100644 apps/utils/cabman/.cvsignore create mode 100644 apps/utils/cat/.cvsignore create mode 100644 apps/utils/net/roshttpd/.cvsignore create mode 100644 apps/utils/net/telnet/.cvsignore create mode 100644 apps/utils/objdir/.cvsignore create mode 100644 apps/utils/partinfo/.cvsignore create mode 100644 apps/utils/pice/.cvsignore create mode 100644 apps/utils/ps/.cvsignore create mode 100644 apps/utils/ps/ps.c delete mode 100644 apps/utils/ps/ps.cpp create mode 100644 apps/utils/sc/.cvsignore create mode 100644 apps/utils/sc/command.c create mode 100644 apps/utils/sc/config.c create mode 100644 apps/utils/sc/main.c create mode 100644 apps/utils/sc/main.h create mode 100644 apps/utils/sc/makefile create mode 100644 apps/utils/sc/query.c create mode 100644 apps/utils/sc/setup.c create mode 100644 apps/utils/stats/.cvsignore create mode 100644 apps/utils/tickcount/makefile create mode 100644 apps/utils/tickcount/tickcount.c create mode 100644 drivers/bus/acpi/ospm/busmgr/.cvsignore create mode 100644 drivers/bus/acpi/resource/.cvsignore create mode 100644 drivers/dd/vga/display/main/.cvsignore create mode 100644 drivers/dd/vga/display/objects/.cvsignore create mode 100644 drivers/dd/vga/display/vgavideo/.cvsignore create mode 100644 drivers/fs/fs_rec/udfs.c create mode 100644 drivers/fs/vfat/flush.c create mode 100644 drivers/lib/bzip2/.cvsignore rename {lib/crtdll/assert => drivers/net/afd/afd}/.cvsignore (100%) create mode 100644 drivers/net/dd/ne2000/ne2000/.cvsignore create mode 100644 drivers/net/ndis/ndis/.cvsignore create mode 100644 drivers/net/npf/.cvsignore create mode 100644 drivers/net/npf/Makefile create mode 100644 drivers/net/npf/bucket_lookup.c create mode 100644 drivers/net/npf/bucket_lookup.h create mode 100644 drivers/net/npf/count_packets.c create mode 100644 drivers/net/npf/count_packets.h create mode 100644 drivers/net/npf/debug.h create mode 100644 drivers/net/npf/dump.c create mode 100644 drivers/net/npf/functions.c create mode 100644 drivers/net/npf/functions.h create mode 100644 drivers/net/npf/jitter.c create mode 100644 drivers/net/npf/jitter.h create mode 100644 drivers/net/npf/memory_t.c create mode 100644 drivers/net/npf/memory_t.h create mode 100644 drivers/net/npf/normal_lookup.c create mode 100644 drivers/net/npf/normal_lookup.h create mode 100644 drivers/net/npf/npf.def create mode 100644 drivers/net/npf/npf.edf create mode 100644 drivers/net/npf/npf.rc create mode 100644 drivers/net/npf/ntddpack.h create mode 100644 drivers/net/npf/openclos.c create mode 100644 drivers/net/npf/packet.c create mode 100644 drivers/net/npf/packet.h create mode 100644 drivers/net/npf/read.c create mode 100644 drivers/net/npf/resource.h create mode 100644 drivers/net/npf/tcp_session.c create mode 100644 drivers/net/npf/tcp_session.h create mode 100644 drivers/net/npf/time_calls.c create mode 100644 drivers/net/npf/time_calls.h create mode 100644 drivers/net/npf/tme.c create mode 100644 drivers/net/npf/tme.h create mode 100644 drivers/net/npf/valid_insns.h create mode 100644 drivers/net/npf/win_bpf.h create mode 100644 drivers/net/npf/win_bpf_filter.c create mode 100644 drivers/net/npf/win_bpf_filter_init.c create mode 100644 drivers/net/npf/win_bpf_filter_init.h create mode 100644 drivers/net/npf/write.c create mode 100644 drivers/net/tcpip/datalink/.cvsignore create mode 100755 drivers/net/tcpip/include/linux.h create mode 100755 drivers/net/tcpip/include/tcpcore.h create mode 100755 drivers/net/tcpip/include/tcpdef.h create mode 100644 drivers/net/tcpip/network/.cvsignore create mode 100644 drivers/net/tcpip/tcpip/.cvsignore create mode 100644 drivers/net/tcpip/transport/datagram/.cvsignore create mode 100644 drivers/net/tcpip/transport/rawip/.cvsignore create mode 100644 drivers/net/tcpip/transport/tcp/.cvsignore create mode 100755 drivers/net/tcpip/transport/tcp/tcp_input.c create mode 100755 drivers/net/tcpip/transport/tcp/tcp_ipv4.c create mode 100755 drivers/net/tcpip/transport/tcp/tcp_output.c create mode 100755 drivers/net/tcpip/transport/tcp/tcp_timer.c create mode 100755 drivers/net/tcpip/transport/tcp/tcpcore.c create mode 100644 drivers/net/tcpip/transport/udp/.cvsignore create mode 100644 drivers/net/tdi/.cvsignore create mode 100644 drivers/net/tdi/cte/.cvsignore create mode 100644 drivers/net/tdi/tdi/.cvsignore create mode 100644 include/basetsd.h delete mode 100644 include/crtdll/alloc.h delete mode 100644 include/crtdll/assert.h delete mode 100644 include/crtdll/conio.h delete mode 100644 include/crtdll/crtdll.h delete mode 100644 include/crtdll/ctype.h delete mode 100644 include/crtdll/dir.h delete mode 100644 include/crtdll/direct.h delete mode 100644 include/crtdll/dirent.h delete mode 100644 include/crtdll/dos.h delete mode 100644 include/crtdll/errno.h delete mode 100644 include/crtdll/excpt.h delete mode 100644 include/crtdll/fcntl.h delete mode 100644 include/crtdll/float.h delete mode 100644 include/crtdll/internal/atexit.h delete mode 100644 include/crtdll/internal/file.h delete mode 100644 include/crtdll/internal/ieee.h delete mode 100644 include/crtdll/internal/quad.h delete mode 100644 include/crtdll/io.h delete mode 100644 include/crtdll/locale.h delete mode 100644 include/crtdll/malloc.h delete mode 100644 include/crtdll/math.h delete mode 100644 include/crtdll/mbctype.h delete mode 100644 include/crtdll/mbstring.h delete mode 100644 include/crtdll/process.h delete mode 100644 include/crtdll/search.h delete mode 100644 include/crtdll/setjmp.h delete mode 100644 include/crtdll/share.h delete mode 100644 include/crtdll/signal.h delete mode 100644 include/crtdll/stdarg.h delete mode 100644 include/crtdll/stddef.h delete mode 100644 include/crtdll/stdio.h delete mode 100644 include/crtdll/stdlib.h delete mode 100644 include/crtdll/string.h delete mode 100644 include/crtdll/sys/fcntl.h delete mode 100644 include/crtdll/sys/file.h delete mode 100644 include/crtdll/sys/locking.h delete mode 100644 include/crtdll/sys/stat.h delete mode 100644 include/crtdll/sys/time.h delete mode 100644 include/crtdll/sys/timeb.h delete mode 100644 include/crtdll/sys/types.h delete mode 100644 include/crtdll/sys/unistd.h delete mode 100644 include/crtdll/sys/utime.h delete mode 100644 include/crtdll/tchar.h delete mode 100644 include/crtdll/time.h delete mode 100644 include/crtdll/wchar.h create mode 100644 include/ddk/af_irda.h delete mode 100644 include/ddk/cmfuncs.h create mode 100644 include/msvcrt/crttypes.h rename include/{ddk => ntos}/ldrtypes.h (99%) mode change 100644 => 100755 rename include/{ddk => ntos}/rtl.h (95%) mode change 100644 => 100755 rename include/{ddk => ntos}/rtltypes.h (93%) mode change 100644 => 100755 rename include/{ddk => ntos}/zw.h (97%) mode change 100644 => 100755 rename include/{ddk => ntos}/zwtypes.h (97%) mode change 100644 => 100755 create mode 100644 include/wine/commctrl.h create mode 100644 lib/advapi32/misc/.cvsignore create mode 100644 lib/advapi32/reg/.cvsignore create mode 100644 lib/advapi32/sec/.cvsignore create mode 100644 lib/advapi32/service/.cvsignore create mode 100644 lib/advapi32/token/.cvsignore delete mode 100644 lib/crtdll/assert/assert.c create mode 100644 lib/crtdll/ctype/ctype.c create mode 100644 lib/crtdll/misc/assert.c create mode 100644 lib/crtdll/misc/debug.c create mode 100644 lib/crtdll/stdio/fgetws.c create mode 100644 lib/crtdll/stdio/fputws.c create mode 100644 lib/crtdll/stdlib/alloca.c delete mode 100644 lib/crtdll/stdlib/mbstow.c create mode 100644 lib/crtdll/time/tz_vars.c delete mode 100644 lib/crtdll/wchar/wcscat.c delete mode 100644 lib/crtdll/wchar/wcschr.c delete mode 100644 lib/crtdll/wchar/wcscmp.c delete mode 100644 lib/crtdll/wchar/wcscpy.c delete mode 100644 lib/crtdll/wchar/wcscspn.c delete mode 100644 lib/crtdll/wchar/wcsdup.c delete mode 100644 lib/crtdll/wchar/wcsftime.c delete mode 100644 lib/crtdll/wchar/wcsicmp.c delete mode 100644 lib/crtdll/wchar/wcslwr.c delete mode 100644 lib/crtdll/wchar/wcsncat.c delete mode 100644 lib/crtdll/wchar/wcsncmp.c delete mode 100644 lib/crtdll/wchar/wcsncpy.c delete mode 100644 lib/crtdll/wchar/wcsnicmp.c delete mode 100644 lib/crtdll/wchar/wcsnlen.c delete mode 100644 lib/crtdll/wchar/wcspbrk.c delete mode 100644 lib/crtdll/wchar/wcsrchr.c delete mode 100644 lib/crtdll/wchar/wcsrev.c delete mode 100644 lib/crtdll/wchar/wcsset.c delete mode 100644 lib/crtdll/wchar/wcsspn.c delete mode 100644 lib/crtdll/wchar/wcsstr.c delete mode 100644 lib/crtdll/wchar/wcsupr.c delete mode 100644 lib/crtdll/wchar/wcsxfrm.c create mode 100644 lib/gdi32/main/.cvsignore create mode 100644 lib/gdi32/objects/.cvsignore create mode 100644 lib/kernel32/MSG00409.bin create mode 100644 lib/kernel32/errcodes.rc create mode 100644 lib/kernel32/errormsg.mak create mode 100755 lib/kernel32/k32.h create mode 100644 lib/kernel32/kernel32.mc create mode 100644 lib/kernel32/misc/errormsg.c create mode 100644 lib/kernel32/misc/getname.c create mode 100644 lib/kernel32/misc/mbchars.c create mode 100644 lib/kernel32/misc/muldiv.c create mode 100644 lib/kernel32/misc/perfcnt.c create mode 100644 lib/kernel32/misc/toolhelp.c create mode 100644 lib/msafd/misc/.cvsignore create mode 100644 lib/msvcrt/ctype/ctype.c create mode 100644 lib/msvcrt/direct/wchdir.c create mode 100644 lib/msvcrt/direct/wgetcwd.c create mode 100644 lib/msvcrt/direct/wgetdcwd.c create mode 100644 lib/msvcrt/direct/wmkdir.c create mode 100644 lib/msvcrt/direct/wrmdir.c create mode 100644 lib/msvcrt/io/fileleni.c create mode 100644 lib/msvcrt/io/lseeki64.c create mode 100644 lib/msvcrt/io/telli64.c create mode 100644 lib/msvcrt/io/waccess.c create mode 100644 lib/msvcrt/io/wchmod.c create mode 100644 lib/msvcrt/io/wcreate.c create mode 100644 lib/msvcrt/io/wfind.c create mode 100644 lib/msvcrt/io/wmktemp.c create mode 100644 lib/msvcrt/io/wopen.c create mode 100644 lib/msvcrt/io/wunlink.c create mode 100644 lib/msvcrt/io/wutime.c create mode 100644 lib/msvcrt/math/math.c create mode 100644 lib/msvcrt/misc/crtmain.c create mode 100644 lib/msvcrt/misc/environ.c create mode 100644 lib/msvcrt/process/threadx.c create mode 100644 lib/msvcrt/stdio/fgetws.c create mode 100644 lib/msvcrt/stdio/wfdopen.c create mode 100644 lib/msvcrt/stdio/wrename.c create mode 100644 lib/msvcrt/stdio/wtempnam.c create mode 100644 lib/msvcrt/stdio/wtmpnam.c delete mode 100644 lib/msvcrt/stdlib/mbstow.c create mode 100644 lib/msvcrt/stdlib/mbtowc.c create mode 100644 lib/msvcrt/stdlib/wctomb.c create mode 100644 lib/msvcrt/stdlib/wfulpath.c create mode 100644 lib/msvcrt/stdlib/witoa.c create mode 100644 lib/msvcrt/stdlib/witow.c create mode 100644 lib/msvcrt/stdlib/wmakpath.c create mode 100644 lib/msvcrt/stdlib/wputenv.c create mode 100644 lib/msvcrt/stdlib/wsenv.c create mode 100644 lib/msvcrt/stdlib/wsplitp.c create mode 100644 lib/msvcrt/string/strncoll.c create mode 100644 lib/msvcrt/sys_stat/fstati64.c create mode 100644 lib/msvcrt/sys_stat/wstat.c create mode 100644 lib/msvcrt/time/tz_vars.c create mode 100644 lib/msvcrt/time/wctime.c create mode 100644 lib/msvcrt/time/wstrdate.c create mode 100644 lib/msvcrt/time/wstrtime.c create mode 100644 lib/ntdll/ldr/res.c create mode 100644 lib/ntdll/rtl/i386/.cvsignore delete mode 100644 lib/packet/include/devioctl.h delete mode 100644 lib/packet/include/ntddndis.h create mode 100644 lib/shell32/control/.cvsignore create mode 100644 lib/shell32/control/makefile create mode 100644 lib/version/misc/.cvsignore create mode 100644 lib/winedbgc/.cvsignore create mode 100644 lib/winedbgc/Makefile create mode 100644 lib/winedbgc/debug.c create mode 100644 lib/winedbgc/libmain.c create mode 100644 lib/winedbgc/porting.c create mode 100644 lib/winedbgc/porting.h create mode 100644 lib/winedbgc/winedbgc.c create mode 100644 lib/winedbgc/winedbgc.def create mode 100644 lib/winedbgc/winedbgc.dll.dbg.c create mode 100644 lib/winedbgc/winedbgc.edf create mode 100644 lib/winedbgc/winedbgc.rc create mode 100644 lib/winmm/misc/.cvsignore create mode 100644 lib/ws2_32/misc/.cvsignore create mode 100644 loaders/dos/.cvsignore create mode 100755 ntoskrnl/dbg/profile.c create mode 100644 ntoskrnl/rtl/math.c create mode 100644 subsys/csrss/csrss.def create mode 100644 subsys/csrss/csrss.edf create mode 100644 subsys/system/usetup/bootsup.c create mode 100644 subsys/system/usetup/bootsup.h create mode 100644 subsys/system/usetup/filequeue.c create mode 100644 subsys/system/usetup/filequeue.h create mode 100644 subsys/system/usetup/filesup.c create mode 100644 subsys/system/usetup/filesup.h create mode 100644 subsys/system/usetup/inicache.c create mode 100644 subsys/system/usetup/inicache.h create mode 100644 subsys/system/usetup/progress.c create mode 100644 subsys/system/usetup/progress.h create mode 100644 subsys/win32k/ntuser/scrollbar.c create mode 100755 tools/rtouch.c create mode 100644 txtsetup.sif diff --git a/.cvsignore b/.cvsignore index 80ccb71..b4fa551 100644 --- a/.cvsignore +++ b/.cvsignore @@ -16,3 +16,4 @@ reactos *.sym *.plg *.bak +*.zip diff --git a/ChangeLog b/ChangeLog index b6b7015..ccae3af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,1113 +1,1396 @@ -2002-11-03 Casper S. Hornstrup - - * apps/tests/lpc/lpcclt.c: Change LPC_MESSAGE_HEADER to LPC_MESSAGE. - * include/csrss/csrss.h: Ditto. - * include/lsass/lsass.h: Ditto. - * include/napi/dbg.h: Ditto. - * include/napi/lpc.h: Ditto. - * lib/kernel32/misc/console.c: Ditto. - * lib/ntdll/csr/lpc.c: Ditto. - * lib/ntdll/dbg/debug.c: Ditto. - * lib/secur32/lsa.c: Ditto. - * ntoskrnl/dbg/user.c: Ditto. - * ntoskrnl/include/internal/port.h: Ditto. - * ntoskrnl/lpc/connect.c: Ditto. - * ntoskrnl/lpc/reply.c: Ditto. - * ntoskrnl/ps/process.c: Ditto. - * subsys/csrss/api/conio.c: Ditto. - * subsys/csrss/api/process.c: Ditto. - * subsys/csrss/api/user.c: Ditto. - -2002-10-26 Casper S. Hornstrup - - * lib/msvcrt/except/seh.s: Fix end-of-line formatting. - * lib/ntdll/rtl/i386/exception.c: Ditto. - * lib/ntdll/rtl/i386/except.s: Ditto. - * ntoskrnl/rtl/i386/except.s: Ditto. - * ntoskrnl/rtl/i386/seh.s: Ditto. - -2002-10-26 Casper S. Hornstrup - - * lib/msvcrt/Makefile (OBJECTS_EXCEPT): Add except/seh.o; Remove - except/exhand3.o. - * lib/msvcrt/except/exhand2.c (MsvcrtDebug): New function. - * lib/msvcrt/except/unwind.c (PEXCEPTION_FRAME): Remove. - (_global_unwind2): Correct prototype. - * lib/ntdll/makefile (RTL_I386_OBJECTS, ARCH_OBJECTS): New groups. - (TARGET_OBJECTS): Add ARCH_OBJECTS group. - * lib/ntdll/rtl/exception.c (KiUserExceptionDispatcher): Set - NumberParameters in exception record. - (RtlRaiseStatus): Remove. - * ntoskrnl/Makefile (OBJECTS_RTL): Remove rtl/seh.o. - (OBJECTS_RTL_I386): Add rtl/i386/except.o, rtl/i386/exception.o, and - rtl/i386/seh.o. - * ntoskrnl/ke/catch.c (RtlpExecuteHandlerForException, - RtlpDumpExceptionRegistrations, RtlpDispatchException, - RtlpExecuteHandler, RtlpExceptionHandler, RtlpUnwindHandler, - RtlpExecuteHandlerForException, RtlpExecuteHandlerForUnwind, - RtlUnwind): Remove. - (RtlpDispatchException): Add prototype. - * ntoskrnl/ke/i386/usertrap.c (ExceptionTypeStrings): Remove. - * ntoskrnl/ps/create.c (PsCreateTeb): Mark end of exception - registration list. - * tools/helper.mk (TARGET_ASFLAGS): Add -g if DBG = 1. - * lib/msvcrt/except/exhand3.c: Remove. - * ntoskrnl/rtl/seh.c: Ditto. - * lib/msvcrt/except/seh.s: New file. - * lib/ntdll/rtl/i386/except.s: Ditto. - * lib/ntdll/rtl/i386/exception.c: Ditto. - * ntoskrnl/rtl/i386/except.s: Ditto. - * ntoskrnl/rtl/i386/exception.c: Ditto. - * ntoskrnl/rtl/i386/seh.s: Ditto. - -2002-10-26 Casper S. Hornstrup - - * lib/kernel32/process/create.c (_except_handler): New function. - (BaseProcessStart): Ditto. - (KlCreateFirstThread): Return INVALID_HANDLE_VALUE on error; Call - BaseProcessStart() before process entry point. - * lib/kernel32/thread/thread.c (_except_handler): New function. - (ThreadStartup): Protect thread using SEH constructs. - -2002-10-26 Casper S. Hornstrup - - * include/ddk/zw.h (NtProcessStartup): Use standard calling convention. - * subsys/csrss/csrss.c (NtProcessStartup): Ditto. - * subsys/smss/smss.c (NtProcessStartup): Ditto. - * subsys/system/autochk/autochk.c (NtProcessStartup): Ditto. - * subsys/system/usetup/usetup.c (NtProcessStartup): Ditto. - -2002-10-25 Casper S. Hornstrup - - * apps/tests/tokentest/tokentest.c (ROS_ACE_HEADER): Move field - AccessMask ... - (ROS_ACE): ... here. - (DisplayDacl): Make pAce an ROS_ACE*; Use new path for AceType; Use - sizeof(ACE) instead of sizeof(ACE_HEADER). - * include/ntos/security.h (ACE_HEADER): Move field AccessMask ... - (ACE): ... here. - * lib/ntdll/rtl/acl.c: Use new path for AccessMask. - * ntoskrnl/se/semgr.c: Ditto. - * ntoskrnl/se/acl.c (SepInitDACLs): Use new path for AccessMask; Use - sizeof(ACE) instead of sizeof(ACE_HEADER). - * ntoskrnl/se/token.c (SepCreateSystemProcessToken): Use sizeof(ACE) - instead of sizeof(ACE_HEADER). - -2002-10-20 Casper S. Hornstrup - - * include/napi/teb.h (RTL_USER_PROCESS_PARAMETERS): Use field names - as described in Windows NT/2000 Native API Reference. - * lib/kernel32/file/file.c: Use new field names. - * lib/kernel32/misc/console.c: Ditto. - * lib/kernel32/process/create.c: Ditto. - * lib/kernel32/process/proc.c: Ditto. - * lib/ntdll/rtl/path.c: Ditto. - * lib/ntdll/rtl/ppb.c: Ditto. - * lib/ntdll/rtl/process.c: Ditto. - -2002-10-19 Casper S. Hornstrup - - * include/ntos.h: Include relevant files. - * include/internal/ke.h: Include files relative to - ntoskrnl/include. - * include/internal/arch/ke.h: Ditto. - -2002-10-01 Casper S. Hornstrup - - * drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. - * drivers/fs/cdfs/fcb.c: Ditto. - * drivers/fs/cdfs/fsctl.c: Ditto. - * drivers/fs/cdfs/rw.c: Ditto. - * drivers/fs/ext2/dir.c: Ditto. - * drivers/fs/ext2/inode.c: Ditto. - * drivers/fs/ext2/rw.c: Ditto. - * drivers/fs/ext2/super.c: Ditto. - * drivers/fs/minix/blockdev.c: Ditto. - * drivers/fs/minix/cache.c: Ditto. - * drivers/fs/minix/inode.c: Ditto. - * drivers/fs/minix/rw.c: Ditto. - * drivers/fs/ntfs/fcb.c: Ditto. - * drivers/fs/ntfs/ntfs.h: Ditto. - * drivers/fs/vfat/create.c: Ditto. - * drivers/fs/vfat/direntry.c: Ditto. - * drivers/fs/vfat/dirwr.c: Ditto. - * drivers/fs/vfat/fat.c: Ditto. - * drivers/fs/vfat/fcb.c: Ditto. - * drivers/fs/vfat/fsctl.c: Ditto. - * drivers/fs/vfat/rw.c: Ditto. - * drivers/storage/class2/class2.c: Ditto. - * drivers/storage/scsiport/scsiport.c: Ditto. - * hal/halx86/adapter.c: Ditto. - * hal/halx86/mp.c: Ditto. - * include/ddk/mmfuncs.h: Ditto. - * include/ddk/mmtypes.h: Ditto. - * include/ddk/i386/pagesize.h: Ditto. - * include/ntdll/pagesize.h: Ditto. - * lib/kernel32/process/create.c: Ditto. - * lib/kernel32/thread/thread.c: Ditto. - * lib/ntdll/ldr/utils.c: Ditto. - * lib/ntdll/rtl/env.c: Ditto. - * lib/ntdll/rtl/heap.c: Ditto. - * lib/ntdll/rtl/ppb.c: Ditto. - * lib/ntdll/rtl/process.c: Ditto. - * lib/ntdll/rtl/thread.c: Ditto. - * ntoskrnl/cc/copy.c: Ditto. - * ntoskrnl/cc/view.c: Ditto. - * ntoskrnl/ex/sysinfo.c: Ditto. - * ntoskrnl/include/internal/i386/mm.h: Ditto. - * ntoskrnl/io/mdl.c: Ditto. - * ntoskrnl/ke/kthread.c: Ditto. - * ntoskrnl/ke/i386/kernel.c: Ditto. - * ntoskrnl/ldr/init.c: Ditto. - * ntoskrnl/ldr/loader.c: Ditto. - * ntoskrnl/mm/anonmem.c: Ditto. - * ntoskrnl/mm/cont.c: Ditto. - * ntoskrnl/mm/freelist.c: Ditto. - * ntoskrnl/mm/iospace.c: Ditto. - * ntoskrnl/mm/kmap.c: Ditto. - * ntoskrnl/mm/marea.c: Ditto. - * ntoskrnl/mm/mdl.c: Ditto. - * ntoskrnl/mm/mminit.c: Ditto. - * ntoskrnl/mm/ncache.c: Ditto. - * ntoskrnl/mm/npool.c: Ditto. - * ntoskrnl/mm/pagefile.c: Ditto. - * ntoskrnl/mm/pageop.c: Ditto. - * ntoskrnl/mm/section.c: Ditto. - * ntoskrnl/mm/slab.c: Ditto. - * ntoskrnl/mm/i386/page.c: Ditto. - * ntoskrnl/ob/handle.c: Ditto. - * ntoskrnl/ps/create.c: Ditto. - * ntoskrnl/ps/process.c: Ditto. - * ntoskrnl/ps/w32call.c: Ditto. - * subsys/win32k/include/object.h: Ditto. - -2002-10-01 Casper S. Hornstrup - - * lib/ntdll/string/ctype.c: Undefine __MSVCRT__ to not have mingw - runtime import _pctype. - -2002-09-30 Casper S. Hornstrup - - * lib/user32/misc/desktop.c (string.h): Include. - * lib/user32/misc/resources.c: Ditto. - * lib/user32/misc/winhelp.c: Ditto. - * lib/user32/windows/accel.c: Ditto. - * lib/user32/windows/bitmap.c: Ditto. - * subsys/win32k/freetype/ctype.c: Undefine __MSVCRT__ and _pctype to not - have mingw runtime import _pctype. - -2002-09-30 Casper S. Hornstrup - - * ntoskrnl/cc/view.c (alloca): Prototype. - * ntoskrnl/rtl/ctype.c: Undefine __MSVCRT__ to not have mingw runtime - import _pctype. - -2002-08-26 David Welch - - * lib/gdi32/misc/dllmain.c (GdiDllInitialize): Don't initialize - win32k.sys for each process. - * subsys/csrss/init.c (CsrServerInitialization): Initialize - win32k.sys as well. - -2002-08-26 David Welch - - * ntoskrnl/ps/process.c (NtCreateProcess): Reference the - parent process's handle using ExGetPreviousMode. - -2002-08-26 David Welch - - * lib/user32/misc/dllmain.c (Init): Initialize gdi32 as well. - -2002-08-26 David Welch - - * iface/addsys/genw32k.c (main, process): Generate a set of - stubs for csrss as well. - -2002-08-26 David Welch - - * lib/kernel32/process/create.c (CreateProcessW): Initialize - all the members of the new process's PPB. - -2002-08-17 David Welch - - * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): Ensure the - process isn't freed in the middle of our operations. - -2002-08-17 David Welch - - * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): Fixed. - -2002-08-17 David Welch - - * ntoskrnl/ps/create.c (PiDeleteThread): Don't dereference - the thread's process while holding the thread list lock. - -2002-08-17 David Welch - - * ntoskrnl/mm/section.c (MmMapViewOfSection): Check there is - enough space for all parts of an image before mapping it; if - there isn't enough space free at the preferred base address - then try to choose a different one. - -2002-08-17 David Welch - - * ntoskrnl/mm/mpw.c (MmInitMpwThread): Run the MPW thread at - idle priority. - -2002-08-17 David Welch - - * ntoskrnl/mm/kmap.c (ExUnmapPage, ExAllocatePageWithPhysPage, - MiFreeNonPagedPoolRegion, MiAllocNonPagedPoolRegion): Maintain - a hint of the next free page; makes running with whole page - allocation more bearable. - -2002-08-17 David Welch - - * ntoskrnl/mm/anonmem.c (MmPageOutVirtualMemory): Show an - out of swap space message if we are out of swap space. - * ntoskrnl/mm/section.c (MmPageOutSectionView): Show an - out of swap space message if we are out of swap space. - * ntoskrnl/mm/pagefile.c (MmAllocSwapPage): Don't automatically - show an out of swap space message on failure. - * ntoskrnl/mm/pagefile.c (MmShowOutOfSpaceMessagePagingFile): New - function to notify the user that the pagefile is full. - -2002-08-17 David Welch - - * drivers/lib/zlib/Makefile: Create a dummy zlib.sym - -2002-08-16 David Welch - - * ntoskrnl/mm/npool.c (ExAllocateWholePageBlock): Converted - to use PHYSICAL_ADDRESS type for page address. - -2002-08-16 David Welch - - * subsys/win32k/ntuser/class.c (W32kCreateClass): Corrected - typo when calculating the offset into the class object to - put the class name string. - -2002-08-16 David Welch - - * ntoskrnl/ps/thread.c (PsDispatchThreadNoLock): Don't call - the reaper function directly; set an event to wake up a seperate - reaper thread. - * ntoskrnl/ps/thread.c (PsReaperThreadMain): New function that - waits for a notification and then calls PsReapThreads. - * ntoskrnl/ps/thread.c (PsInitThreadManagement): Create the - reaper thread. - -2002-08-15 David Welch - - * lib/advapi32/misc/dllmain.c (DllMain): Removed debug message. - -2002-08-14 David Welch - - * subsys/smss/init.c (SmPagingFilesQueryRoutine): If possible - take the size of the paging file from the registry. - -2002-08-14 David Welch - - * ntoskrnl/mm/section.c (MmCreateDataFileSection): Extend the - section if necessary. - -2002-08-14 David Welch - - * ntoskrnl/mm/pagefile.c (NtCreatePagingFile): Set the file - size using the FileAllocationInformation class. - -2002-08-14 David Welch - - * ntoskrnl/mm/anonmem.c (MmWritePageVirtualMemory): Implemented - function to write anonymous memory pages to the swap file. - * ntoskrnl/mm/anonmem.c (MmFreeVirtualMemoryPage): Free any - swap page associated with the page. - * ntoskrnl/mm/mpw.c (MmWriteDirtyPages): New function to find - pages to write to disk. - * ntoskrnl/mm/mpw.c (MmMpwThreadMain): Implemented MPW functionality. - * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): New function - to write a single page back to disk. - * ntoskrnl/mm/rmap.c (MmSetCleanAllRmaps, MmSetDirtyAllRmaps, - MmIsDirtyPageRmap): New rmap function to support the MPW thread. - * ntoskrnl/mm/section.c (MmWritePageSectionView): Implemented - function to write back section pages. - * ntoskrnl/mm/section.c (MmFreeSectionPage): Free any swap - entry associated with the page; mark pages shared with - the cache as dirty if necessary. - -2002-08-14 David Welch - - * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set name of - the module into the module text structure. - -2002-08-14 David Welch - - * ntoskrnl/io/rw.c (NtReadFile, NtWriteFile): Use the correct - test for whether to wait for the completion of i/o. - -2002-08-14 David Welch - - * ntoskrnl/cm/ntfunc.c (NtFlushKey): Request synchronous i/o - from NtOpenFile. - * ntoskrnl/cm/regfile (CmiInitPermanentRegistryHive): Request - synchronous i/o from NtCreateFile. - * ntoskrnl/dbg/kdb_stabs.c (LdrpLoadModuleSymbols): Request - synchronous i/o from NtOpenFile. - * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Request synchronous i/o - from NtOpenFile. - -2002-08-14 David Welch - - * ntoskrnl/cc/view.c (CcRosSuggestFreeCacheSegment): Maintain the - correct reference count. - -2002-08-14 David Welch - - * ntoskrnl/cc/view.c (CcRosFlushCacheSegment): New function to - write back a modified cache segment. - * ntoskrnl/cc/view.c (CcRosFlushDirtyPages): New function to - flush some dirty pages from the cache. - * ntoskrnl/cc/view.c (CcRosMarkDirtyCacheSegment): New function to - mark a cache segment modified while mapped into memory as dirty. - -2002-08-14 David Welch - - * ntoskrnl/cc/pin.c (CcMapData, CcUnpinData, CcSetDirtyPinnedData): - Store the dirty status in the BCB; don't write back dirty data - immediately. - -2002-08-14 David Welch - - * include/ntos/mm.h: Added SEC_XXXX defines from 'Windows NT/2000 - Native API Reference' - -2002-08-14 David Welch - - * drivers/fs/vfat/ea.c (VfatSetExtendedAttributes): Empty - placeholder for extended attribute functions. - -2002-08-14 David Welch - - * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): - Added function to set allocation size. - -2002-08-14 David Welch - - * drivers/fs/vfat/fcb.c (vfatFCBInitializeCache): Renamed - to vfatFCBInitializeCacheFromVolume. - * drivers/fs/vfat/fcb.c (vfatMakeFCBFromDirEntry): Don't - initialise the cache with a file object representing the - volume unless the FCB is for a directory. - -2002-08-14 David Welch - - * drivers/fs/vfat/create.c (VfatPagingFileCreate): Added a - new function for handling paging file only code. - * drivers/fs/vfat/create.c (VfatSupersedeFile): Added a - new function for doing a file supersede. - * drivers/fs/vfat/create.c (VfatCreateFile): Reformatted and - adjusted control flow. Set allocation size and extended attributes - on create. - * drivers/fs/vfat/create.c (VfatCreate): Removed goto. - -2002-08-14 David Welch - - * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Renamed - updEntry to VfatUpdateEntry. - * drivers/fs/vfat/close.c (VfatCloseFile): Renamed - updEntry to VfatUpdateEntry. - * drivers/fs/vfat/dirwr.c (updEntry): Renamed to - VfatUpdateEntry. - * drivers/fs/vfat/dirwr.c (addEntry): Renamed to - VfatAddEntry. - -2002-08-14 David Welch - - * apps/tests/sectest/sectest.c (main): Fixed formatting. - -2002-08-10 David Welch - - * ntoskrnl/mm/i386/page.c (MmSetPageProtect): Fixed - behaviour when called on the system address space. - -2002-08-10 David Welch - - * ntoskrnl/mm/virtual.c (MmQueryAnonMem, MmProtectAnonMem, - NtAllocateVirtualMemory, NtFreeVirtualMemory): Renamed - segments to regions; moved region code to seperate file. - Implemented NtQueryVirtualMemory and NtProtectVirtualMemory - for anonymous memory areas. - -2002-08-10 David Welch - - * ntoskrnl/mm/anonmem.c: Moved functions relating to - areas created with NtAllocateVirtualMemory to a - seperate file. - -2002-08-10 David Welch - - * ntoskrnl/mm/section.c (MmQuerySectionView): Implemented - NtQueryVirtualMemory for section views. - -2002-08-10 David Welch - - * ntoskrnl/mm/section.c (MmAccessFaultSectionView, - MmNotPresentFaultSectionView, MmProtectSectionView, - MmMapViewOfSegment, MmAlterViewAttributes): Implemented - NtProtectVirtualMemory for section views. - -2002-08-10 David Welch - - * ntoskrnl/ke/main.c: Removed SEH test code. - -2002-08-10 David Welch - - * lib/ntdll/ldr/utils.c (LdrFixupImports): Remove the readonly - protection from the IAT before writing to it. - -2002-08-10 David Welch - - * lib/ntdll/ldr/utils.c (LdrAdjustDllName): Properly null terminate - the base name of the DLL. - -2002-08-10 David Welch - - * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set the text segment - of modules to readonly after loading. - -2002-08-09 David Welch - - * ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread - if NtCreateThread has CreateSuspended as TRUE. - * ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread, - PiSuspendThreadKernelRoutine): Fixed suspend functionality. - -2002-08-09 David Welch - - * ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy - the LDR variable from the right address. - -2002-08-09 David Welch - - * ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for - kernel APCs pending on exit from the kernel. - * ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc, - KiDeliverApc): Set the APC's inserted flag to FALSE after - removing it from the thread's queue. - -2002-08-09 David Welch - - * lib/kernel32/thread/thread.c (ThreadStartup): Don't - call DLL entrypoints; this is done by LdrInitializeThunk. - * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call - DLLs in initialization order; take the loader lock before - calling. - -2002-08-09 David Welch - - * apps/tests/thread/thread.c (main): Test suspend and - resume functionality. - -2002-08-08 David Welch - - * ntoskrnl/mm/section (NtQuerySection): Return the - right result length. - -2002-08-08 David Welch - - * ntoskrnl/ke/usertrap.c (print_user_address): Check for - a NULL LDR structure in the PEB; copy the LDR pointer in - safely. - -2002-08-08 David Welch - - * ntoskrnl/ke/apc.c (KiDeliverUserApc): Deliver all present - APCs; release the APC spinlock while acccessing user memory. - -2002-08-08 David Welch - - * include/internal/ps.h: Adjusted offsets into the ETHREAD - structure. - * include/internal/ps.h: Removed redundant members from the - KTHREAD structure. - * ntoskrnl/ke/kthread.c (KeInitializeThread): Removed - redundant members from the KTHREAD structure. - -2002-08-08 David Welch - - * ntoskrnl/dbg/kdb.c (KdbEnterDebuggerException): New - function to enter the debugger on an exception. - * ntoskrnl/kd/kdebug.c (KdInitSystem): Initialize the - local kernel debugger if enabled. - * ntoskrnl/ke/catch.c (KiDispatchException): Enter the - local kernel debugger on an exception. - -2002-08-08 David Welch - - * include/ntdll/ldr.h: Added definition for a DLL entrypoint. - * lib/kernel32/process/create.c (KlCreateFirstThread): Put - the argument to the NtProcessStartup function on the stack. - * lib/kernel32/process/create.c (KlInitPeb): Read the - base address of the new image from the PEB. - * lib/kernel32/process/create.c (CreateProcessW): Start the - first thread at the entrypoint of the new image. - * lib/ntdll/ldr/startup.c (LdrInitializeThunk): If the - function is called after the initial startup then just call the - entrypoints for the loaded DLLs with DLL_THREAD_ATTACH. Don't - call the entrypoint of the image. - * lib/ntdll/rtl/process.c (RtlpCreateFirstThread): Put the - argument to the NtProcessStartup function on the stack. - * lib/ntdll/rtl/process.c (KlInitPeb): Read the base address of - the new image from the PEB. - * lib/ntdll/rtl/process.c (RtlCreateUserProcess): Start the - first thread at the entrypoint of the new image. - * ntoskrnl/ke/i386/bthread.S (PsBeginThreadWithContextInternal): - Use the system call path to begin a usermode thread. - * ntoskrnl/ke/i386/thread.c (Ke386InitThreadWithContext): Convert - the supplied context into a trap frame. - * ntoskrnl/ldr/init.c (LdrLoadInitialProcess): Put the PEB argument - to the NtProcessStartup function on the new stack; start the - first thread at the entrypoint of the image. - * ntoskrnl/ps/create.c (NtCreateThread): Create an APC to call - LdrInitializeThunk in the context of a new thread before its - entrypoint. - -2002-08-08 David Welch - - * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Uninitialise - the cache on file cleanup. - * drivers/fs/vfat/fcb.c (vfatReleaseFcb): Don't uninitialise - the cache on file close. - * ntoskrnl/cc/copy.c: Renamed zero page global variable. - * ntoskrnl/cc/view.c: Added cache delete function. - -2002-07-13 Casper S. Hornstrup - - * rules.mak (RSYM): Define. - * include/ddk/zwtypes.h (DebugDbgLoadSymbols): Add to enum - _DEBUG_CONTROL_CODE. - * include/ntdll/ldr.h (LDR_SYMBOL_INFO, LdrpLoadUserModuleSymbols): Add. - (LdrLoadModuleSymbols): Remove. - * include/ntos/kdbgsyms.h (ST_FILENAME, ST_FUNCTION, - ST_LINENUMBER): Add. - (SYMBOL). Make Name an ANSI_STRING. - (IMAGE_SYMBOL_INFO, AreSymbolsParsed): Add. - * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call - LdrpLoadUserModuleSymbols() not LdrLoadModuleSymbols(). - * lib/ntdll/ldr/utils.c (LdrLoadModuleSymbols): Rename to - LdrpLoadUserModuleSymbols. - (LdrpLoadUserModuleSymbols): Use DebugDbgLoadSymbols debug control code. - (LdrLoadDll): assert if out of memory. - (LdrLoadDll): Call - LdrpLoadUserModuleSymbols(), not LdrLoadModuleSymbols(). - * lib/ntdll/string/ctype.c (_pctype): #undef. - * ntoskrnl/dbg/dbgctrl.c (NtSystemDebugControl): Call - LdrLoadUserModuleSymbols on DebugDbgLoadSymbols. - * ntoskrnl/include/internal/ldr.h (LdrGetAddressInformation): Add. - * ntoskrnl/include/internal/module.h (MODULE_TEXT_SECTION): Make SymbolInfo - an IMAGE_SYMBOL_INFO. - * ntoskrnl/ke/i386/exp.c (LdrGetAddressInformation): Add prototype. - (print_address): Change #ifdef KDBG to #ifdef DBG. - (KiDoubleFaultHandler, KiDumpTrapFrame, KeDumpStackFrames): Dump - one stack frame per line. - * ntoskrnl/ke/i386/multiboot.S: Create pagetables for more kernel - address space so larger modules can be passed from the boot loader. - * ntoskrnl/ke/i386/usertrap.c (LdrGetAddressInformation): Add prototype. - (print_user_address): Print symbols using LdrGetAddressInformation(). - * ntoskrnl/ldr/loader.c (SYMBOLFILE_HEADER, IMAGE_SYMBOL_INFO_CACHE, - STAB_ENTRY, N_FUN, N_SLINE, N_SO, SymbolListHead): Add. - (TAG_SYM_BUF): Remove. - (LdrInitDebug): Remove unneeded code. - (LdrInit1): Prepare for loading symbols. - (LdrpReadLine, HexL, LdrpParseLine, LdrpLoadModuleSymbolsFromBuffer, - LdrpLoadUserModuleSymbolsFromBuffer): Remove. - (LdrpParseImageSymbols, LdrpGetFileName, LdrpGetFunctionName, - LdrpGetLineNumber, LdrGetAddressInformation, LdrpLookupUserSymbolInfo): Add. - (LdrpLoadModuleSymbols, LdrInitializeBootStartDriver): Change to use new - symbol structures. - (LdrLoadUserModuleSymbols): Cache symbol buffers. - (LdrUnloadModuleSymbols): Implement. - (LdrLoadModule, LdrUnloadModule): Change #ifdef KDBG to #ifdef DBG. - (LdrPEProcessModule): Split a line into two lines. - (LdrPEProcessModule): Setup for loading symbols. - * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Open with FILE_SHARE_READ. - * ntoskrnl/ps/process.c (PiFreeSymbols): Call LdrUnloadModuleSymbols() to - free symbols. - (PiDeleteProcess): Change #ifdef KDBG to #ifdef DBG. - * ntoskrnl/rtl/ctype.c (_pctype): #undef. - * ntoskrnl/rtl/string.c (strncpy): Terminate destination string. - * tools/Makefile (rsym): Add target. - * tools/helper.mk: Include config and use -g if DBG = 1. - -2002-07-13 Casper S. Hornstrup - - * Makefile (install_before): Install system.hiv to correct location. - -2002-07-04 David Welch - - * subsys/win32k/include/callback.h: Fixed callback argument - definitions. - * subsys/win32k/ntuser/winpos.c: Implemented some more of the windows - sizing/moving code. - * subsys/win32k/ntuser/painting.c: Implemented some more of the - window painting code. - * subsys/win32k/objects/coord.c: Implemented LPtoDP and DPtoLP. - * subsys/win32k/objects/region.c: Added stubs for some more - region functions. - -2002-07-04 David Welch - - * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the - process desktop handle as well. - -2002-07-04 David Welch - - * ntoskrnl/se/token.c: Don't call the ZwXXX variant of - system calls when in system context. - -2002-07-04 David Welch - - * ntoskrnl/Makefile: Added file with MDA output code. - * ntoskrnl/kd/kdebug.c: Recognize MDA as a destination for - debug output. - -2002-07-04 David Welch - - * lib/user32/windows/defwnd.c: Implemented some more of the - default window handler. - -2002-07-04 David Welch - - * lib/user32/misc/stubs.c: Removed some stubs to seperate files. - -2002-07-04 David Welch - - * lib/user32/user32.def: Export ScreenToClient otherwise we - get problems when code in user32 tries to call it. - -2002-07-04 David Welch - - * include/win32k/region.h: Added prototypes for some missing - region functions. - -2002-07-04 David Welch - - * include/win32k/ntuser.h: Added prototypes for some missing - NtUserXXX functions. - -2002-07-04 David Welch - - * include/user32/wininternal.h: Added some constants for - private GetDCEx styles that WINE needs. - -2002-07-04 David Welch - - * include/user32/callback.h: Fixed callbacks for messages with - parameters. - -2002-07-04 David Welch - - * include/napi/win32.h (W32THREAD): Added pointer to the - thread's desktop. - * include/napi/win32.h (W32PROCESS): Removed handle table, - added a pointer to the process's window station. - * subsys/win32k/ntuser/guicheck.c (W32kGuiCheck): Reference - a process's window station on the first win32k system call. Reference - a thread's desktop on the first win32k system call. - -2002-07-04 David Welch - - * include/messages.h: Added some missing WM_XXX constants. - -2002-07-04 David Welch - - * drivers/dd/ide/makefile: Compiling with debugging messages - needs libgcc to be linked in. - -2002-07-04 David Welch - - * iface/addsys/genw32k.c: Generate a variable with the - number of system calls. - * iface/native/genntdll.c: Generate a proper stack frame for - the user system call stubs. - * ntoskrnl/ke/i386/syscall.S: Generate a proper stack frame for - the handler for system calls. - -2002-07-04 David Welch - - * Makefile: Build the GUI startup application. - * subsys/system/gstart/gstart.c: Application to start up - the GUI. - -2002-06-18 David Welch - - * tools/helper.mk: Make an import library a proper target - depending on the .def file. - -2002-06-18 David Welch - - * subsys/win32k/ntuser/window.c (NtUserGetWindowLong): Began - implementation. - -2002-06-18 David Welch - - * subsys/win32k/misc/object.c (ObmCreateHandle): Return the - correct handle value. - -2002-06-18 David Welch - - * subsys/win32k/makefile: Make win32k depend on the file containing - the service table. - -2002-06-18 David Welch - - * ntoskrnl/ke/i386/stkswitch.S (KeSwitchStackAndRet, - KePushAndStackSwitchAndSysRet): Push one value only. - * ntoskrnl/ps/w32call.c (NtCallbackReturn, NtW32Call): Moved - these functions to a new file. Restore the old trap frame after - returning from a callback. - -2002-06-18 David Welch - - * lib/user32/windows/message.c (CallWindowProcA, CallWindowProcW): - Convert message to Unicode or ASCII if necessary. - -2002-06-18 David Welch - - * include/user32/callback.h: Added WM_CREATE and WM_NCCALCSIZE - callbacks. - * lib/user32/windows/window.c (User32SendCREATEMessageForKernel, - User32SendNCCREATEMessageForKernel): Implemented. - * subsys/win32k/ntuser/callback.c (W32kSendCREATEMessage): - Implemented. - -2002-06-18 David Welch - - * include/structs.h: Added Unicode and ASCII versions of - CREATESTRUCT. - -2002-06-16 David Welch - - * tools/helper.mk: Make the install target depend on all the - files to be installed. - -2002-06-16 David Welch - - * ntoskrnl/ps/thread.c (NtCallbackReturn): Set TSS.Esp0 to the - top of the old stack. - * ntoskrnl/ps/thread.c (NtW32Call): Set TSS.Esp0 to the top of - the new stack. Free the callback stack correctly. Don't copy - portion of the trap frame that doesn't exist in non-v86-mode - interrupts. - * ntoskrnl/ps/thread.c (PsFreeCallbackStack): New function to - free a stack allocated with PsAllocateCallbackStack. - -2002-06-16 David Welch - - * drivers/dd/null/makefile: Commented out local LDFLAGS as - these cause bad relocations in the stripped image. - -2002-06-16 David Welch - - * config: Corrected spelling error. - -2002-06-11 David Welch - - * subsys/system/winlogon/winlogon.c (WinMain): Check for - failure when creating a window system. - -2002-06-11 David Welch - - * ntoskrnl/ob/handle.c (ObDuplicateObject): Added this internal - function for duplicating objects. - * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the parent - process's window station to the child process. - * ntoskrnl/ps/process.c (PsInitProcessManagement): Initialize the - first process's window station. - -2002-06-11 David Welch - - * ntoskrnl/mm/marea.c (MmCreateMemoryArea): Initialise - page operation structure members. - * ntoskrnl/mm/pageop.c (MmReleasePageOp, MmGetPageOp): Increment - or decrement the page operation count in the memory area. - * ntoskrnl/mm/virtual.c (MmNotPresentFaultVirtualMemory, - MmPageOutVirtualMemory): Check for a deleted memory area before - handling the fault. - * ntoskrnl/mm/virtual.c (MmFreeVirtualMemory): Wait for all - page operations to finish before freeing the memory area. - -2002-06-11 David Welch - - * ntoskrnl/ke/i386/syscall.S (interrupt_handler2e): Corrected - test for previous mode, upper 16-bit of CS on the stack after an - interrupt are arbitary. - -2002-06-11 David Welch - - * lib/user32/misc/winsta.c: Cleaned up indentation. - -2002-06-11 David Welch - - * apps/tests/winhello/winhello.c (WinMain, MainWndProc): - Cleaned up formatting, some more error checks. - -2002-06-04 David Welch - - * ntoskrnl/mm/virtual.c (MmSecureVirtualMemory, - MmUnsecureVirtualMemory, NtQueryVirtualMemory): Corrected indentation. - -2002-06-04 David Welch - - * ntoskrnl/ke/i386/exp.c (KiDoubleFaultHandler): Print CR3 - correctly. - -2002-06-04 David Welch - - * ntoskrnl/include/internal/ps.h: Added KTHREAD_STACK_LIMIT definition. - * ntoskrnl/ke/i386/tskswitch.S (Ki386ContextSwitch): Force all the - pages of the kernel stack to be accessible from this process. - -2002-06-04 David Welch - - * ntoskrnl/cc/view.c (ReadCacheSegmentChain): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/cc/copy.c (CcRosCreateCacheSegment): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/cc/copy.c (CcFreeCachePage): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/include/internal/mm.h: Changed prototypes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/include/internal/ps.h (KPROCESS): Changed type of - page directory base to PHYSICAL_ADDRESS. - * ntoskrnl/include/internal/i386/mm.h: Changed prototypes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/ke/kthread.c (KeFreeStackPage): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/ke/kthread.c (KeInitializeThread): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/ke/process.c (KeAttachProcess, KeDetachProcess): Changes - to use PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/ke/kernel.c (PcrPages, KeApplicationProcessorInit): Changes - to use PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/balance.c (MM_ALLOCATION_REQUEST): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/balance.c (MmReleasePageMemoryConsumer): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/balance.c (MmRequestPageMemoryConsumer): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/cont.c (MmFreeContinuousPage): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/cont.c (MmAllocateContinuousAlignedMemory): Changes to - use PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/freelist.c (MmTransferOwnershipPage, - MmGetLRUFirstUserPage, MmGetLRUNextUserPage, MmGetContinuousPages, - MmInitializePageList, MmSetFlagsPage, MmSetRmapListHeadPage, - MmGetRmapListHeadPage, MmMarkPageMapped, MmMarkPageUnmapped, - MmGetFlagsPage, MmSetSavedSwapEntryPage, MmGetSavedSwapEntryPage, - MmReferencePage, MmGetReferenceCountPage, MmIsUsablePage, - MmDereferencePage, MmGetLockCountPage, MmLockPage, MmUnlockPage, - MmAllocPage): Changes to use PHYSICAL_ADDRESS type for physical - addresses. - * ntoskrnl/mm/iospace.c (MmMapIoSpace): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/kmap.c (ExAllocatePage, MiZeroPage, MiCopyFromUserPage, - ExAllocatePageWithPhysPage): Changes to use PHYSICAL_ADDRESS type for - physical addresses. - * ntoskrnl/mm/marea.c (MmFreeMemoryArea): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/mdl.c (MmUnlockPages, MmMapLockedPages, - MmProbeAndLockPages): Changes to use PHYSICAL_ADDRESS type for - physical addresses. - * ntoskrnl/mm/mm.c (MmSharedDataPagePhysicalAddress, - MmCommitPagedPoolAddress, MmNotPresentFault): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/mminit.c (MmInitVirtualMemory): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/ncache.c (MmAllocateNonCachedMemory, - MmFreeNonCachedPage): Changes to use PHYSICAL_ADDRESS type for - physical addresses. - * ntoskrnl/mm/npool.c (grow_kernel_pool): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/rmap.c (MmPageOutPhysicalAddress, MmInsertRmap, - MmDeleteAllRmaps, MmDeleteRmap): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/section.c (MiReadPage, MmNotPresentFaultSectionView, - MmAccessFaultSectionView, MmPageOutDeleteMapping, - MmPageOutSectionView, MmFreeSectionPage): Changes to use - PHYSICAL_ADDRESS type for physical addresses. - * ntoskrnl/mm/slab.c (ExGrowSlabCache): Changes to use - PHYSICAL_ADDRESS type for physical address. - * ntoskrnl/mm/virtual.c (MmPageOutVirtualMemory, - MmNotPresentFaultVirtualMemory, MmFreeVirtualMemoryPage): Changes to - use PHYSICAL_ADDRESS type for physical address. - * ntoskrnl/mm/wset.c (MmTrimUserMemory): Changes to use - PHYSICAL_ADDRESS type for physical address. - * ntoskrnl/mm/page.c (Mmi386ReleaseMmInfo, MmCopyMmInfo, - MmGetPhysicalAddressForProcess, MmCreateVirtualMapping, - MmCreateVirtualMappingUnsafe, MmCreateVirtualMappingForProcess, - MmDeleteVirtualMapping): Changes to use PHYSICAL_ADDRESS type for - physical address. - * ntoskrnl/ps/process (PsInitProcessManagment): Changes to use - PHYSICAL_ADDRESS type for physical address. - * ntoskrnl/ps/thread.c (PsAllocateCallbackStack): Changes to use - PHYSICAL_ADDRESS type for physical address. - -2002-06-04 David Welch - - * Lots of change since the ChangeLog was last updated. - -2001-03-18 David Welch - - * ntoskrnl/ke/apc.c (KiDeliverApc): Bug fix. - * ntoskrnl/ke/apc.c (KeInsertQueueApc): More comments. - * ntoskrnl/ke/catch.c (KiDispatchException): Bug fix. - * ntoskrnl/ke/timer.c (KeDelayExecutionThread): Don't use removed - function KeAddTimeoutThread. - * ntoskrnl/ke/timer.c (KeAddTimeoutThread): Removed. - * ntoskrnl/ke/wait.c (KeWaitForSingleObject, KeWaitForMultipleObjects): - Don't use KeAddTimeoutThread. - * ntoskrnl/mm/freelist.c (MmAllocateContiguousAlignedMemory): Bug fix - * ntoskrnl/mm/freelist.c (MmAllocatePage): Allocate from the top - memory. - -2001-03-17 David Welch - - * ntoskrnl/ke/catch.c (KiDispatchException): Implementation of - exception handling, user-mode only. - -2001-03-16 David Welch - - * include/ddk/zw.h: Corrected declarations of NtCreateProfile, - NtQueryIntervalProfile, NtSetIntervalProfile. - * include/ddk/zwtypes.h: Added definitions of KPROFILE_SOURCE. - * ntoskrnl/include/internal/ke.h: Added the interrupted EIP as a - parameter to KiUpdateSystemTime for profiling purposes. - * ntoskrnl/include/internal/nt: Added declaration for profiling - support initialization. - * ntoskrnl/ke/timer.c (KiUpdateSystemTime, KeExpireTimers): Call - the profiling code on a timer interrupt with the interrupt EIP. - * ntoskrnl/ke/i386/irq.c (KiDispatchInterrupt): Pass the interrupted - EIP to KiUpdateSystemTime. - * ntoskrnl/mm/virtual.c (NtReadVirtualMemory, NtWriteVirtualMemory): - Release the MDLs used properly. - * ntoskrnl/nt/nt.c: Call the profiling support initialization. - * ntoskrnl/nt/ntevent.c (NtCreateEvent): Don't try copying the - ObjectAttributes parameter if it is NULL. - * ntoskrnl/nt/profile.c: Implemented profiling. - -2001-03-16 David Welch - - * ntoskrnl/include/internal/safe.h: Corrected typo. - * ntoskrnl/nt/ntevent.c (NtCreateEvent, NtOpenEvent, NtQueryEvent): - Corrected typos. - * ntoskrnl/rtl/mem.c: Missing header file. - -2001-03-16 David Welch - - * ntoskrnl/include/internal/safe.h: Add definitions for handling - potentially unsafe pointers. - -2001-03-16 David Welch - - * ntoskrnl/include/internal/mm.h: Removed MmSafeCopyToUser and - MmSafeCopyFromUser as source files need these but don't want internal - mm definitions. - * ntoskrnl/nt/ntevent.c (NtCreateEvent, NtOpenEvent, NtPulseEvent, - NtQueryEvent, NtResetEvent, NtSetEvent): Copy data to and from - user mode safely. - * ntoskrnl/rtl/mem.c (MmCopyToCaller, MmCopyFromCaller): Helper - functions for copying data to and from potentially unsafe pointers. - -2000-12-23 David Welch - - * All task switching is done in software. - * Beginnings of v86 mode support. - -2000-12-22 David Welch - - * ntoskrnl/ps/kill.c (PiTerminateProcessThreads): Drop - PiThreadListLock before calling PsTerminateOtherThread - -2000-12-16 David Welch - - * ntoskrnl/ex/fmutex.c (ExReleaseFastMutexUnsafe): Only set the - fast mutex's owner back to NULL if it is being released - -2000-12-10 David Welch - - * ntoskrnl/ke/i386/vm86_sup.S (Ki386RetToV86Mode): Added function - to do the raw switch to v86 mode. - * ntoskrnl/include/internal/vm86.h: Definitions for the v86 mode - support. - -2000-12-10 David Welch - - * ntoskrnl/ke/i386/trap.s (PsBeginThreadWithContextInternal): Moved - to ntoskrnl/ke/i386/bswitch.S. - * ntoskrnl/ke/i386/trap.s (interrupt_handler2e): Moved to - ntoskrnl/ke/i386/syscall.S. - * ntoskrnl/ke/i386/trap.s (old_interrupt_handler2e): Removed. - -2000-12-04 David Welch - - * ntoskrnl/ke/i386/irq.c (KiInterruptDispatch): Record the last PC - value for a rescheduled thread. - * ntoskrnl/ke/i386/irqhand.s: Construct a primitive trap frame - in interrupt handlers. - -2000-08-30 David Welch - - * Added calibration of KeStallExecutionProcessor timing - (code from linux 2.2.16). - - * Corrected compilation bugs in user32 library. - - * Corrected compilation bugs related to anonymous structs - in ndis code. - - * Pass command line to kernel from loadros. - - * Corrected PIC mask calculation. - -2000-05-27 David Welch - - * Fixed issue with closing non-existent or already closed - handle. - -2000-01-26 David Welch - - * ZwCreateProcess now maps ntdll rather than the user-mode - code. - -1999-09-06 David Welch - - * Implemented ZwOpenProcess. - - * Partially implemented killing other threads (possible memory - leaks). - - * Made a start on a proper implemention of APCs (based on - article in NT insider). - -1998-12-08 David Welch - - * Corrected bug in shell (Read two keypresses and assumed they - where the key going up and down respectively). - - * Corrected race in dpc handling. - - * Took out cleanup sections in ZwReadFile (now handled by the - APC). - - * Disabled broken code in kernel32. - - - - - - - - - - +2003-02-10 Casper S. Hornstrup + + * include/structs.h (OSVERSIONINFOEXA): Expand definition of + OSVERSIONINFOA. + (OSVERSIONINFOEXW): Expand definition of OSVERSIONINFOW. + * lib/msafd/misc/helpers.c (LocateHelperDLL): Cast AddressFamily, + SocketType, and Protocol to INT. + * lib/ws2_32/misc/catalog.c (LocateProvider): Ditto. + +2003-01-16 Casper S. Hornstrup + + * ntoskrnl/dbg/profile.c (KdbProfilerThreadMain): Make STDCALL. + +2003-01-15 Casper S. Hornstrup + + * drivers/net/tcpip/makefile (TCP_OBJECTS): Add transport/tcp/tcpcore.o, + transport/tcp/tcp_input.o, transport/tcp/tcp_ipv4.o, + transport/tcp/tcp_output.o, and transport/tcp/tcp_timer.o. + * drivers/net/tcpip/transport/tcp/tcp.c (TCPStartup): Call tcp_init(). + * drivers/net/tcpip/include/linux.h: New file. + * drivers/net/tcpip/include/tcpcore.h: Ditto. + * drivers/net/tcpip/include/tcpdef.h: Ditto. + * drivers/net/tcpip/transport/tcp/tcp_input.c: Ditto. + * drivers/net/tcpip/transport/tcp/tcp_ipv4.c: Ditto. + * drivers/net/tcpip/transport/tcp/tcp_output.c: Ditto. + * drivers/net/tcpip/transport/tcp/tcp_timer.c: Ditto. + * drivers/net/tcpip/transport/tcp/tcpcore.c: Ditto. + +2003-01-15 Casper S. Hornstrup + + * lib/kernel32/k32.h: New file. + * lib/kernel32/makefile (TARGET_CFLAGS): Add -I./. + (TARGET_PCH): Set to k32.h. + * lib/kernel32/except/except.c: Use . + * lib/kernel32/file/backup.c: Ditto. + * lib/kernel32/file/cnotify.c: Ditto. + * lib/kernel32/file/copy.c: Ditto. + * lib/kernel32/file/create.c: Ditto. + * lib/kernel32/file/curdir.c: Ditto. + * lib/kernel32/file/delete.c: Ditto. + * lib/kernel32/file/deviceio.c: Ditto. + * lib/kernel32/file/dir.c: Ditto. + * lib/kernel32/file/dosdev.c: Ditto. + * lib/kernel32/file/file.c: Ditto. + * lib/kernel32/file/find.c: Ditto. + * lib/kernel32/file/iocompl.c: Ditto. + * lib/kernel32/file/lfile.c: Ditto. + * lib/kernel32/file/lock.c: Ditto. + * lib/kernel32/file/mailslot.c: Ditto. + * lib/kernel32/file/move.c: Ditto. + * lib/kernel32/file/npipe.c: Ditto. + * lib/kernel32/file/pipe.c: Ditto. + * lib/kernel32/file/rw.c: Ditto. + * lib/kernel32/file/tape.c: Ditto. + * lib/kernel32/file/volume.c: Ditto. + * lib/kernel32/mem/global.c: Ditto. + * lib/kernel32/mem/heap.c: Ditto. + * lib/kernel32/mem/isbad.c: Ditto. + * lib/kernel32/mem/local.c: Ditto. + * lib/kernel32/mem/procmem.c: Ditto. + * lib/kernel32/mem/section.c: Ditto. + * lib/kernel32/mem/virtual.c: Ditto. + * lib/kernel32/misc/atom.c: Ditto. + * lib/kernel32/misc/comm.c: Ditto. + * lib/kernel32/misc/console.c: Ditto. + * lib/kernel32/misc/debug.c: Ditto. + * lib/kernel32/misc/dllmain.c: Ditto. + * lib/kernel32/misc/env.c: Ditto. + * lib/kernel32/misc/error.c: Ditto. + * lib/kernel32/misc/handle.c: Ditto. + * lib/kernel32/misc/ldr.c: Ditto. + * lib/kernel32/misc/profile.c: Ditto. + * lib/kernel32/misc/res.c: Ditto. + * lib/kernel32/misc/stubs.c: Ditto. + * lib/kernel32/misc/sysinfo.c: Ditto. + * lib/kernel32/misc/time.c: Ditto. + * lib/kernel32/process/cmdline.c: Ditto. + * lib/kernel32/process/create.c: Ditto. + * lib/kernel32/process/proc.c: Ditto. + * lib/kernel32/process/session.c: Ditto. + * lib/kernel32/string/lstring.c: Ditto. + * lib/kernel32/synch/critical.c: Ditto. + * lib/kernel32/synch/event.c: Ditto. + * lib/kernel32/synch/intrlck.c: Ditto. + * lib/kernel32/synch/mutex.c: Ditto. + * lib/kernel32/synch/sem.c: Ditto. + * lib/kernel32/synch/timer.c: Ditto. + * lib/kernel32/synch/wait.c: Ditto. + * lib/kernel32/thread/fiber.c: Ditto. + * lib/kernel32/thread/thread.c: Ditto. + * lib/kernel32/thread/tls.c: Ditto. + +2003-01-15 Casper S. Hornstrup + + * apps/testsets/Makefile (TEST_SETS): Remove ldr. + * include/msvcrt/ctype.h (towupper): Make returntype wchar_t. + +2003-01-15 Casper S. Hornstrup + + * tools/rtouch.c: Include , not . + +2003-01-15 Casper S. Hornstrup + + * tools/rtouch.c: New file. + * rules.mak (ROS_USE_PCH): Default to no. + (RTOUCH): Define. + * tools/Makefile: Add rtouch utility. + * tools/helper.mk: Support precompiled headers. + +2003-01-15 Casper S. Hornstrup + + * ntoskrnl/dbg/profile.c: New file. + * ntoskrnl/Makefile (OBJECTS_KDBG): Add dbg/profile.o. + * ntoskrnl/dbg/kdb.h: Define NTOS_MODE_KERNEL. Include . + (LdrGetAddressInformation, KdbInitProfiling, KdbInitProfiling2, + KdbDisableProfiling, KdbEnableProfiling, KdbProfileInterrupt) Prototype. + * ntoskrnl/kd/kdebug.c (KdInitSystem): Add /PROFILE option if KDBG=1. + * ntoskrnl/ke/main.c (ExpInitializeExecutive): Call KdbInitProfiling2() + if KDBG=1. + * ntoskrnl/ke/i386/irq.c: Include <../dbg/kdb.h> if KDBG=1. + (KiInterruptDispatch): Call KdbProfileInterrupt() on timer interrupt + if KDBG=1. + +2003-01-15 Casper S. Hornstrup + + * drivers/fs/vfat/create.c (VfatSupersedeFile): Only notify cache manager + about change in file size if caching is initiated on the file stream. + +2003-01-11 Casper S. Hornstrup + + * boot.bat: Use DOS end-of-line characters. + +2003-01-02 Casper S. Hornstrup + + * ntoskrnl/ke/timer.c (KeExpireTimers): Avoid signed/unsigned comparison + warning. + * lib/user32/controls/scrollbar.c (SCROLL_DrawScrollBar): Put a statement + at end. + +2002-12-15 Casper S. Hornstrup + + * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Only uninitialize caching + when initialized. + * drivers/fs/vfat/fcb.c (vfatReleaseFCB): Ditto. + * lib/kernel32/mem/section.c (CreateFileMappingW): Pass NULL as + MaximumSize to NtCreateSection if dwMaximumSizeHigh and dwMaximumSizeLow + are both 0. + * ntoskrnl/cc/pin.c (CcMapData): Assert if Bcb is NULL. + * ntoskrnl/cc/view.c (CcRosReleaseCacheSegment, CcRosLookupCacheSegment, + CcRosMarkDirtyCacheSegment, CcRosUnmapCacheSegment, + CcRosCreateCacheSegment, CcRosGetCacheSegmentChain, + CcRosGetCacheSegment, CcRosRequestCacheSegment, CcFlushCache, + CcRosDeleteFileCache, CcRosReferenceCache, CcRosDereferenceCache, + CcRosReleaseFileCache, CcGetFileObjectFromSectionPtrs): Ditto. + * ntoskrnl/mm/section.c (MiReadPage): Assert if Fcb->Bcb is NULL. + (MmCreateDataFileSection): Make sure caching is initialized for the file + stream. + +2002-11-15 Casper S. Hornstrup + + * include/ddk/ldrtypes.h: Move ... + * include/ntos/ldrtypes.h: ... here. + * include/ddk/ntddk.h: Include ldrtypes.h at new location. + +2002-11-13 Casper S. Hornstrup + + * drivers/bus/acpi/ospm/osl.c (acpi_os_readable, acpi_os_writable): + Match prototypes. + * include/ascii.h (AbortSystemShutdownA): Correct prototype. + * include/debug.h (assert): Wrap in #ifndef assert. + * include/funcs.h (AbortSystemShutdown): Remove duplicate prototype. + * include/ddk/rtltypes.h: Move ... + * include/ntos/rtltypes.h: ... here. + * include/ddk/rtl.h: Move ... + * include/ntos/rtl.h: ... here. + * include/ddk/zwtypes.h: Move ... + * include/ntos/zwtypes.h: ... here. + * include/ddk/zw.h: Move ... + * include/ntos/zw.h: ... here. + | include/ddk/cmfuncs.h: Remove file; Move NtCreateKey to ntos/zw.h. + * include/ntos.h: #include ntos/rtltypes.h, ntos/rtl.h, ntos/zwtypes.h, + and ntos/zw.h. + * include/unicode.h: (AbortSystemShutdownW): Correct prototype. + * include/ddk/ntddk.h: Include headers at new location; Don't include + removed files. + * include/defines.h: Wrap definitions in w32api in #ifndef __USE_W32API. + * include/ntos/zwtypes.h: Ditto. + * include/napi/lpc.h: Ditto. + * include/napi/shared_data.h: Ditto. + * include/napi/teb.h: Ditto. + * include/napi/types.h: Ditto. + * include/ntdll/ldr.h: Ditto. + * include/ntdll/rtl.h: Ditto. + * include/ntos/console.h: Ditto. + * include/ntos/disk.h: Ditto. + * include/ntos/except.h: Ditto. + * include/ntos/file.h: Ditto. + * include/ntos/gditypes.h: Ditto. + * include/ntos/heap.h: Ditto. + * include/ntos/keyboard.h: Ditto. + * include/ntos/mm.h: Ditto. + * include/ntos/ntdef.h: Ditto. + * include/ntos/ps.h: Ditto. + * include/ntos/registry.h: Ditto. + * include/ntos/security.h: Ditto. + * include/ntos/synch.h: Ditto. + * include/ntos/time.h: Ditto. + * include/ntos/types.h: Ditto. + * include/ntos/port.h: Ditto. + * lib/advapi32/misc/shutdown.c (AbortSystemShutdownW, + AbortSystemShutdownA): Correct prototype. + * lib/advapi32/reg/reg.c: #include ntos.h. + * lib/advapi32/sec/misc.c: Ditto. + * lib/advapi32/sec/sid.c: Ditto. + * lib/advapi32/service/sctrl.c: Ditto. + * lib/advapi32/token/token.c: Ditto. + * lib/kernel32/misc/dllmain.c: Ditto. + * ntoskrnl/ex/napi.c: Ditto. + * ntoskrnl/rtl/i386/exception.c: Ditto. + * lib/advapi32/sec/ac.c: Ditto. + (FindFirstFreeAce, GetAce): Change PACE* to PACE_HEADER*. + * lib/advapi32/service/scm.c (EnumServicesStatusExA, + EnumServicesStatusExW, QueryServiceStatusEx): Correct prototype. + * lib/ntdll/rtl/ppb.c (RtlDestroyProcessParameters): Match prototype. + * ntoskrnl/dbg/errinfo.c (DbgGetErrorText): Use %08x, not %08lx. + * ntoskrnl/io/arcname.c (IoCreateSystemRootLink): Use %u, not %lu. + * ntoskrnl/ke/main.c (ExpInitializeExecutive): Ditto. + * (_main): Use %d, not %ld. + * ntoskrnl/include/internal/i386/ke.h: Add #pragma GCC system_header. + * include/ddk/ntdef.h (NTSYSAPI, NTAPI, NTKERNELAPI): Define to STDCALL; + Check if already defined. + * include/base.h (STDCALL, CDECL, CALLBACK, PASCAL): Move to ntos/types.h. + +2002-11-13 Rick Gaiser + + * drivers/bus/isapnp/isapnp.c (FindNextReadPort): Increment Port before + checking wether port address is in NE2000 address space range and returning + port address value. + +2002-11-10 Casper S. Hornstrup + + * drivers/bus/acpi/include/acpi.h: Include platform/types.h. + * drivers/bus/acpi/include/actypes.h: (UINT8, BOOLEAN, UCHAR, UINT16, + INT32, UINT32, UINT64): Disable, use the OS defined types instead. + * drivers/bus/acpi/include/platform/types.h: Remove all types, + include ntos.h instead. + * drivers/bus/acpi/ospm/include/acpisys.h: Don't include + platform/types.h. + +2002-11-10 Casper S. Hornstrup + + * include/defines.h: Fix warnings when bulding with gcc 3.3. + * include/ddk/status.h: Ditto. + * include/freetype/internal/ftdebug.h: Ditto. + * include/net/ndis.h: Ditto. + * lib/msafd/misc/helpers.c: Ditto. + * lib/user32/windows/defwnd.c: Ditto. + * lib/user32/windows/window.c: Ditto. + * ntoskrnl/cm/ntfunc.c: Ditto. + * ntoskrnl/cm/regfile.c: Ditto. + * ntoskrnl/cm/regobj.c: Ditto. + * ntoskrnl/dbg/errinfo.c: Ditto. + * ntoskrnl/ex/hashtab.c: Ditto. + * ntoskrnl/include/internal/mm.h: Ditto. + * ntoskrnl/io/irp.c: Ditto. + * ntoskrnl/kd/gdbstub.c: Ditto. + * ntoskrnl/ke/queue.c: Ditto. + * ntoskrnl/ke/sem.c: Ditto. + * ntoskrnl/ldr/resource.c: Ditto. + * ntoskrnl/mm/balance.c: Ditto. + * ntoskrnl/mm/freelist.c: Ditto. + * ntoskrnl/mm/mdl.c: Ditto. + * ntoskrnl/mm/npool.c: Ditto. + * ntoskrnl/mm/section.c: Ditto. + * ntoskrnl/rtl/error.c: Ditto. + * ntoskrnl/rtl/mem.c: Ditto. + * ntoskrnl/rtl/string.c: Ditto. + * ntoskrnl/rtl/time.c: Ditto. + * ntoskrnl/rtl/unicode.c: Ditto. + * ntoskrnl/rtl/wstring.c: Ditto. + * ntoskrnl/rtl/i386/exception.c: Ditto. + * subsys/win32k/freetype/src/base/ftinit.c: Ditto. + +2002-11-03 Casper S. Hornstrup + + * apps/tests/lpc/lpcclt.c: Change LPC_MESSAGE_HEADER to LPC_MESSAGE. + * include/csrss/csrss.h: Ditto. + * include/lsass/lsass.h: Ditto. + * include/napi/dbg.h: Ditto. + * include/napi/lpc.h: Ditto. + * lib/kernel32/misc/console.c: Ditto. + * lib/ntdll/csr/lpc.c: Ditto. + * lib/ntdll/dbg/debug.c: Ditto. + * lib/secur32/lsa.c: Ditto. + * ntoskrnl/dbg/user.c: Ditto. + * ntoskrnl/include/internal/port.h: Ditto. + * ntoskrnl/lpc/connect.c: Ditto. + * ntoskrnl/lpc/reply.c: Ditto. + * ntoskrnl/ps/process.c: Ditto. + * subsys/csrss/api/conio.c: Ditto. + * subsys/csrss/api/process.c: Ditto. + * subsys/csrss/api/user.c: Ditto. + +2002-10-26 Casper S. Hornstrup + + * lib/msvcrt/except/seh.s: Fix end-of-line formatting. + * lib/ntdll/rtl/i386/exception.c: Ditto. + * lib/ntdll/rtl/i386/except.s: Ditto. + * ntoskrnl/rtl/i386/except.s: Ditto. + * ntoskrnl/rtl/i386/seh.s: Ditto. + +2002-10-26 Casper S. Hornstrup + + * lib/msvcrt/Makefile (OBJECTS_EXCEPT): Add except/seh.o; Remove + except/exhand3.o. + * lib/msvcrt/except/exhand2.c (MsvcrtDebug): New function. + * lib/msvcrt/except/unwind.c (PEXCEPTION_FRAME): Remove. + (_global_unwind2): Correct prototype. + * lib/ntdll/makefile (RTL_I386_OBJECTS, ARCH_OBJECTS): New groups. + (TARGET_OBJECTS): Add ARCH_OBJECTS group. + * lib/ntdll/rtl/exception.c (KiUserExceptionDispatcher): Set + NumberParameters in exception record. + (RtlRaiseStatus): Remove. + * ntoskrnl/Makefile (OBJECTS_RTL): Remove rtl/seh.o. + (OBJECTS_RTL_I386): Add rtl/i386/except.o, rtl/i386/exception.o, and + rtl/i386/seh.o. + * ntoskrnl/ke/catch.c (RtlpExecuteHandlerForException, + RtlpDumpExceptionRegistrations, RtlpDispatchException, + RtlpExecuteHandler, RtlpExceptionHandler, RtlpUnwindHandler, + RtlpExecuteHandlerForException, RtlpExecuteHandlerForUnwind, + RtlUnwind): Remove. + (RtlpDispatchException): Add prototype. + * ntoskrnl/ke/i386/usertrap.c (ExceptionTypeStrings): Remove. + * ntoskrnl/ps/create.c (PsCreateTeb): Mark end of exception + registration list. + * tools/helper.mk (TARGET_ASFLAGS): Add -g if DBG = 1. + * lib/msvcrt/except/exhand3.c: Remove. + * ntoskrnl/rtl/seh.c: Ditto. + * lib/msvcrt/except/seh.s: New file. + * lib/ntdll/rtl/i386/except.s: Ditto. + * lib/ntdll/rtl/i386/exception.c: Ditto. + * ntoskrnl/rtl/i386/except.s: Ditto. + * ntoskrnl/rtl/i386/exception.c: Ditto. + * ntoskrnl/rtl/i386/seh.s: Ditto. + +2002-10-26 Casper S. Hornstrup + + * lib/kernel32/process/create.c (_except_handler): New function. + (BaseProcessStart): Ditto. + (KlCreateFirstThread): Return INVALID_HANDLE_VALUE on error; Call + BaseProcessStart() before process entry point. + * lib/kernel32/thread/thread.c (_except_handler): New function. + (ThreadStartup): Protect thread using SEH constructs. + +2002-10-26 Casper S. Hornstrup + + * include/ddk/zw.h (NtProcessStartup): Use standard calling convention. + * subsys/csrss/csrss.c (NtProcessStartup): Ditto. + * subsys/smss/smss.c (NtProcessStartup): Ditto. + * subsys/system/autochk/autochk.c (NtProcessStartup): Ditto. + * subsys/system/usetup/usetup.c (NtProcessStartup): Ditto. + +2002-10-25 Casper S. Hornstrup + + * apps/tests/tokentest/tokentest.c (ROS_ACE_HEADER): Move field + AccessMask ... + (ROS_ACE): ... here. + (DisplayDacl): Make pAce an ROS_ACE*; Use new path for AceType; Use + sizeof(ACE) instead of sizeof(ACE_HEADER). + * include/ntos/security.h (ACE_HEADER): Move field AccessMask ... + (ACE): ... here. + * lib/ntdll/rtl/acl.c: Use new path for AccessMask. + * ntoskrnl/se/semgr.c: Ditto. + * ntoskrnl/se/acl.c (SepInitDACLs): Use new path for AccessMask; Use + sizeof(ACE) instead of sizeof(ACE_HEADER). + * ntoskrnl/se/token.c (SepCreateSystemProcessToken): Use sizeof(ACE) + instead of sizeof(ACE_HEADER). + +2002-10-20 Casper S. Hornstrup + + * include/napi/teb.h (RTL_USER_PROCESS_PARAMETERS): Use field names + as described in Windows NT/2000 Native API Reference. + * lib/kernel32/file/file.c: Use new field names. + * lib/kernel32/misc/console.c: Ditto. + * lib/kernel32/process/create.c: Ditto. + * lib/kernel32/process/proc.c: Ditto. + * lib/ntdll/rtl/path.c: Ditto. + * lib/ntdll/rtl/ppb.c: Ditto. + * lib/ntdll/rtl/process.c: Ditto. + +2002-10-19 Casper S. Hornstrup + + * include/ntos.h: Include relevant files. + * include/internal/ke.h: Include files relative to + ntoskrnl/include. + * include/internal/arch/ke.h: Ditto. + +2002-10-01 Casper S. Hornstrup + + * drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. + * drivers/fs/cdfs/fcb.c: Ditto. + * drivers/fs/cdfs/fsctl.c: Ditto. + * drivers/fs/cdfs/rw.c: Ditto. + * drivers/fs/ext2/dir.c: Ditto. + * drivers/fs/ext2/inode.c: Ditto. + * drivers/fs/ext2/rw.c: Ditto. + * drivers/fs/ext2/super.c: Ditto. + * drivers/fs/minix/blockdev.c: Ditto. + * drivers/fs/minix/cache.c: Ditto. + * drivers/fs/minix/inode.c: Ditto. + * drivers/fs/minix/rw.c: Ditto. + * drivers/fs/ntfs/fcb.c: Ditto. + * drivers/fs/ntfs/ntfs.h: Ditto. + * drivers/fs/vfat/create.c: Ditto. + * drivers/fs/vfat/direntry.c: Ditto. + * drivers/fs/vfat/dirwr.c: Ditto. + * drivers/fs/vfat/fat.c: Ditto. + * drivers/fs/vfat/fcb.c: Ditto. + * drivers/fs/vfat/fsctl.c: Ditto. + * drivers/fs/vfat/rw.c: Ditto. + * drivers/storage/class2/class2.c: Ditto. + * drivers/storage/scsiport/scsiport.c: Ditto. + * hal/halx86/adapter.c: Ditto. + * hal/halx86/mp.c: Ditto. + * include/ddk/mmfuncs.h: Ditto. + * include/ddk/mmtypes.h: Ditto. + * include/ddk/i386/pagesize.h: Ditto. + * include/ntdll/pagesize.h: Ditto. + * lib/kernel32/process/create.c: Ditto. + * lib/kernel32/thread/thread.c: Ditto. + * lib/ntdll/ldr/utils.c: Ditto. + * lib/ntdll/rtl/env.c: Ditto. + * lib/ntdll/rtl/heap.c: Ditto. + * lib/ntdll/rtl/ppb.c: Ditto. + * lib/ntdll/rtl/process.c: Ditto. + * lib/ntdll/rtl/thread.c: Ditto. + * ntoskrnl/cc/copy.c: Ditto. + * ntoskrnl/cc/view.c: Ditto. + * ntoskrnl/ex/sysinfo.c: Ditto. + * ntoskrnl/include/internal/i386/mm.h: Ditto. + * ntoskrnl/io/mdl.c: Ditto. + * ntoskrnl/ke/kthread.c: Ditto. + * ntoskrnl/ke/i386/kernel.c: Ditto. + * ntoskrnl/ldr/init.c: Ditto. + * ntoskrnl/ldr/loader.c: Ditto. + * ntoskrnl/mm/anonmem.c: Ditto. + * ntoskrnl/mm/cont.c: Ditto. + * ntoskrnl/mm/freelist.c: Ditto. + * ntoskrnl/mm/iospace.c: Ditto. + * ntoskrnl/mm/kmap.c: Ditto. + * ntoskrnl/mm/marea.c: Ditto. + * ntoskrnl/mm/mdl.c: Ditto. + * ntoskrnl/mm/mminit.c: Ditto. + * ntoskrnl/mm/ncache.c: Ditto. + * ntoskrnl/mm/npool.c: Ditto. + * ntoskrnl/mm/pagefile.c: Ditto. + * ntoskrnl/mm/pageop.c: Ditto. + * ntoskrnl/mm/section.c: Ditto. + * ntoskrnl/mm/slab.c: Ditto. + * ntoskrnl/mm/i386/page.c: Ditto. + * ntoskrnl/ob/handle.c: Ditto. + * ntoskrnl/ps/create.c: Ditto. + * ntoskrnl/ps/process.c: Ditto. + * ntoskrnl/ps/w32call.c: Ditto. + * subsys/win32k/include/object.h: Ditto. + +2002-10-01 Casper S. Hornstrup + + * lib/ntdll/string/ctype.c: Undefine __MSVCRT__ to not have mingw + runtime import _pctype. + +2002-09-30 Casper S. Hornstrup + + * lib/user32/misc/desktop.c (string.h): Include. + * lib/user32/misc/resources.c: Ditto. + * lib/user32/misc/winhelp.c: Ditto. + * lib/user32/windows/accel.c: Ditto. + * lib/user32/windows/bitmap.c: Ditto. + * subsys/win32k/freetype/ctype.c: Undefine __MSVCRT__ and _pctype to not + have mingw runtime import _pctype. + +2002-09-30 Casper S. Hornstrup + + * ntoskrnl/cc/view.c (alloca): Prototype. + * ntoskrnl/rtl/ctype.c: Undefine __MSVCRT__ to not have mingw runtime + import _pctype. + +2002-08-26 David Welch + + * lib/gdi32/misc/dllmain.c (GdiDllInitialize): Don't initialize + win32k.sys for each process. + * subsys/csrss/init.c (CsrServerInitialization): Initialize + win32k.sys as well. + +2002-08-26 David Welch + + * ntoskrnl/ps/process.c (NtCreateProcess): Reference the + parent process's handle using ExGetPreviousMode. + +2002-08-26 David Welch + + * lib/user32/misc/dllmain.c (Init): Initialize gdi32 as well. + +2002-08-26 David Welch + + * iface/addsys/genw32k.c (main, process): Generate a set of + stubs for csrss as well. + +2002-08-26 David Welch + + * lib/kernel32/process/create.c (CreateProcessW): Initialize + all the members of the new process's PPB. + +2002-08-17 David Welch + + * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): Ensure the + process isn't freed in the middle of our operations. + +2002-08-17 David Welch + + * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): Fixed. + +2002-08-17 David Welch + + * ntoskrnl/ps/create.c (PiDeleteThread): Don't dereference + the thread's process while holding the thread list lock. + +2002-08-17 David Welch + + * ntoskrnl/mm/section.c (MmMapViewOfSection): Check there is + enough space for all parts of an image before mapping it; if + there isn't enough space free at the preferred base address + then try to choose a different one. + +2002-08-17 David Welch + + * ntoskrnl/mm/mpw.c (MmInitMpwThread): Run the MPW thread at + idle priority. + +2002-08-17 David Welch + + * ntoskrnl/mm/kmap.c (ExUnmapPage, ExAllocatePageWithPhysPage, + MiFreeNonPagedPoolRegion, MiAllocNonPagedPoolRegion): Maintain + a hint of the next free page; makes running with whole page + allocation more bearable. + +2002-08-17 David Welch + + * ntoskrnl/mm/anonmem.c (MmPageOutVirtualMemory): Show an + out of swap space message if we are out of swap space. + * ntoskrnl/mm/section.c (MmPageOutSectionView): Show an + out of swap space message if we are out of swap space. + * ntoskrnl/mm/pagefile.c (MmAllocSwapPage): Don't automatically + show an out of swap space message on failure. + * ntoskrnl/mm/pagefile.c (MmShowOutOfSpaceMessagePagingFile): New + function to notify the user that the pagefile is full. + +2002-08-17 David Welch + + * drivers/lib/zlib/Makefile: Create a dummy zlib.sym + +2002-08-16 David Welch + + * ntoskrnl/mm/npool.c (ExAllocateWholePageBlock): Converted + to use PHYSICAL_ADDRESS type for page address. + +2002-08-16 David Welch + + * subsys/win32k/ntuser/class.c (W32kCreateClass): Corrected + typo when calculating the offset into the class object to + put the class name string. + +2002-08-16 David Welch + + * ntoskrnl/ps/thread.c (PsDispatchThreadNoLock): Don't call + the reaper function directly; set an event to wake up a seperate + reaper thread. + * ntoskrnl/ps/thread.c (PsReaperThreadMain): New function that + waits for a notification and then calls PsReapThreads. + * ntoskrnl/ps/thread.c (PsInitThreadManagement): Create the + reaper thread. + +2002-08-15 David Welch + + * lib/advapi32/misc/dllmain.c (DllMain): Removed debug message. + +2002-08-14 David Welch + + * subsys/smss/init.c (SmPagingFilesQueryRoutine): If possible + take the size of the paging file from the registry. + +2002-08-14 David Welch + + * ntoskrnl/mm/section.c (MmCreateDataFileSection): Extend the + section if necessary. + +2002-08-14 David Welch + + * ntoskrnl/mm/pagefile.c (NtCreatePagingFile): Set the file + size using the FileAllocationInformation class. + +2002-08-14 David Welch + + * ntoskrnl/mm/anonmem.c (MmWritePageVirtualMemory): Implemented + function to write anonymous memory pages to the swap file. + * ntoskrnl/mm/anonmem.c (MmFreeVirtualMemoryPage): Free any + swap page associated with the page. + * ntoskrnl/mm/mpw.c (MmWriteDirtyPages): New function to find + pages to write to disk. + * ntoskrnl/mm/mpw.c (MmMpwThreadMain): Implemented MPW functionality. + * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): New function + to write a single page back to disk. + * ntoskrnl/mm/rmap.c (MmSetCleanAllRmaps, MmSetDirtyAllRmaps, + MmIsDirtyPageRmap): New rmap function to support the MPW thread. + * ntoskrnl/mm/section.c (MmWritePageSectionView): Implemented + function to write back section pages. + * ntoskrnl/mm/section.c (MmFreeSectionPage): Free any swap + entry associated with the page; mark pages shared with + the cache as dirty if necessary. + +2002-08-14 David Welch + + * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set name of + the module into the module text structure. + +2002-08-14 David Welch + + * ntoskrnl/io/rw.c (NtReadFile, NtWriteFile): Use the correct + test for whether to wait for the completion of i/o. + +2002-08-14 David Welch + + * ntoskrnl/cm/ntfunc.c (NtFlushKey): Request synchronous i/o + from NtOpenFile. + * ntoskrnl/cm/regfile (CmiInitPermanentRegistryHive): Request + synchronous i/o from NtCreateFile. + * ntoskrnl/dbg/kdb_stabs.c (LdrpLoadModuleSymbols): Request + synchronous i/o from NtOpenFile. + * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Request synchronous i/o + from NtOpenFile. + +2002-08-14 David Welch + + * ntoskrnl/cc/view.c (CcRosSuggestFreeCacheSegment): Maintain the + correct reference count. + +2002-08-14 David Welch + + * ntoskrnl/cc/view.c (CcRosFlushCacheSegment): New function to + write back a modified cache segment. + * ntoskrnl/cc/view.c (CcRosFlushDirtyPages): New function to + flush some dirty pages from the cache. + * ntoskrnl/cc/view.c (CcRosMarkDirtyCacheSegment): New function to + mark a cache segment modified while mapped into memory as dirty. + +2002-08-14 David Welch + + * ntoskrnl/cc/pin.c (CcMapData, CcUnpinData, CcSetDirtyPinnedData): + Store the dirty status in the BCB; don't write back dirty data + immediately. + +2002-08-14 David Welch + + * include/ntos/mm.h: Added SEC_XXXX defines from 'Windows NT/2000 + Native API Reference' + +2002-08-14 David Welch + + * drivers/fs/vfat/ea.c (VfatSetExtendedAttributes): Empty + placeholder for extended attribute functions. + +2002-08-14 David Welch + + * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): + Added function to set allocation size. + +2002-08-14 David Welch + + * drivers/fs/vfat/fcb.c (vfatFCBInitializeCache): Renamed + to vfatFCBInitializeCacheFromVolume. + * drivers/fs/vfat/fcb.c (vfatMakeFCBFromDirEntry): Don't + initialise the cache with a file object representing the + volume unless the FCB is for a directory. + +2002-08-14 David Welch + + * drivers/fs/vfat/create.c (VfatPagingFileCreate): Added a + new function for handling paging file only code. + * drivers/fs/vfat/create.c (VfatSupersedeFile): Added a + new function for doing a file supersede. + * drivers/fs/vfat/create.c (VfatCreateFile): Reformatted and + adjusted control flow. Set allocation size and extended attributes + on create. + * drivers/fs/vfat/create.c (VfatCreate): Removed goto. + +2002-08-14 David Welch + + * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Renamed + updEntry to VfatUpdateEntry. + * drivers/fs/vfat/close.c (VfatCloseFile): Renamed + updEntry to VfatUpdateEntry. + * drivers/fs/vfat/dirwr.c (updEntry): Renamed to + VfatUpdateEntry. + * drivers/fs/vfat/dirwr.c (addEntry): Renamed to + VfatAddEntry. + +2002-08-14 David Welch + + * apps/tests/sectest/sectest.c (main): Fixed formatting. + +2002-08-10 David Welch + + * ntoskrnl/mm/i386/page.c (MmSetPageProtect): Fixed + behaviour when called on the system address space. + +2002-08-10 David Welch + + * ntoskrnl/mm/virtual.c (MmQueryAnonMem, MmProtectAnonMem, + NtAllocateVirtualMemory, NtFreeVirtualMemory): Renamed + segments to regions; moved region code to seperate file. + Implemented NtQueryVirtualMemory and NtProtectVirtualMemory + for anonymous memory areas. + +2002-08-10 David Welch + + * ntoskrnl/mm/anonmem.c: Moved functions relating to + areas created with NtAllocateVirtualMemory to a + seperate file. + +2002-08-10 David Welch + + * ntoskrnl/mm/section.c (MmQuerySectionView): Implemented + NtQueryVirtualMemory for section views. + +2002-08-10 David Welch + + * ntoskrnl/mm/section.c (MmAccessFaultSectionView, + MmNotPresentFaultSectionView, MmProtectSectionView, + MmMapViewOfSegment, MmAlterViewAttributes): Implemented + NtProtectVirtualMemory for section views. + +2002-08-10 David Welch + + * ntoskrnl/ke/main.c: Removed SEH test code. + +2002-08-10 David Welch + + * lib/ntdll/ldr/utils.c (LdrFixupImports): Remove the readonly + protection from the IAT before writing to it. + +2002-08-10 David Welch + + * lib/ntdll/ldr/utils.c (LdrAdjustDllName): Properly null terminate + the base name of the DLL. + +2002-08-10 David Welch + + * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set the text segment + of modules to readonly after loading. + +2002-08-09 David Welch + + * ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread + if NtCreateThread has CreateSuspended as TRUE. + * ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread, + PiSuspendThreadKernelRoutine): Fixed suspend functionality. + +2002-08-09 David Welch + + * ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy + the LDR variable from the right address. + +2002-08-09 David Welch + + * ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for + kernel APCs pending on exit from the kernel. + * ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc, + KiDeliverApc): Set the APC's inserted flag to FALSE after + removing it from the thread's queue. + +2002-08-09 David Welch + + * lib/kernel32/thread/thread.c (ThreadStartup): Don't + call DLL entrypoints; this is done by LdrInitializeThunk. + * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call + DLLs in initialization order; take the loader lock before + calling. + +2002-08-09 David Welch + + * apps/tests/thread/thread.c (main): Test suspend and + resume functionality. + +2002-08-08 David Welch + + * ntoskrnl/mm/section (NtQuerySection): Return the + right result length. + +2002-08-08 David Welch + + * ntoskrnl/ke/usertrap.c (print_user_address): Check for + a NULL LDR structure in the PEB; copy the LDR pointer in + safely. + +2002-08-08 David Welch + + * ntoskrnl/ke/apc.c (KiDeliverUserApc): Deliver all present + APCs; release the APC spinlock while acccessing user memory. + +2002-08-08 David Welch + + * include/internal/ps.h: Adjusted offsets into the ETHREAD + structure. + * include/internal/ps.h: Removed redundant members from the + KTHREAD structure. + * ntoskrnl/ke/kthread.c (KeInitializeThread): Removed + redundant members from the KTHREAD structure. + +2002-08-08 David Welch + + * ntoskrnl/dbg/kdb.c (KdbEnterDebuggerException): New + function to enter the debugger on an exception. + * ntoskrnl/kd/kdebug.c (KdInitSystem): Initialize the + local kernel debugger if enabled. + * ntoskrnl/ke/catch.c (KiDispatchException): Enter the + local kernel debugger on an exception. + +2002-08-08 David Welch + + * include/ntdll/ldr.h: Added definition for a DLL entrypoint. + * lib/kernel32/process/create.c (KlCreateFirstThread): Put + the argument to the NtProcessStartup function on the stack. + * lib/kernel32/process/create.c (KlInitPeb): Read the + base address of the new image from the PEB. + * lib/kernel32/process/create.c (CreateProcessW): Start the + first thread at the entrypoint of the new image. + * lib/ntdll/ldr/startup.c (LdrInitializeThunk): If the + function is called after the initial startup then just call the + entrypoints for the loaded DLLs with DLL_THREAD_ATTACH. Don't + call the entrypoint of the image. + * lib/ntdll/rtl/process.c (RtlpCreateFirstThread): Put the + argument to the NtProcessStartup function on the stack. + * lib/ntdll/rtl/process.c (KlInitPeb): Read the base address of + the new image from the PEB. + * lib/ntdll/rtl/process.c (RtlCreateUserProcess): Start the + first thread at the entrypoint of the new image. + * ntoskrnl/ke/i386/bthread.S (PsBeginThreadWithContextInternal): + Use the system call path to begin a usermode thread. + * ntoskrnl/ke/i386/thread.c (Ke386InitThreadWithContext): Convert + the supplied context into a trap frame. + * ntoskrnl/ldr/init.c (LdrLoadInitialProcess): Put the PEB argument + to the NtProcessStartup function on the new stack; start the + first thread at the entrypoint of the image. + * ntoskrnl/ps/create.c (NtCreateThread): Create an APC to call + LdrInitializeThunk in the context of a new thread before its + entrypoint. + +2002-08-08 David Welch + + * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Uninitialise + the cache on file cleanup. + * drivers/fs/vfat/fcb.c (vfatReleaseFcb): Don't uninitialise + the cache on file close. + * ntoskrnl/cc/copy.c: Renamed zero page global variable. + * ntoskrnl/cc/view.c: Added cache delete function. + +2002-07-13 Casper S. Hornstrup + + * rules.mak (RSYM): Define. + * include/ddk/zwtypes.h (DebugDbgLoadSymbols): Add to enum + _DEBUG_CONTROL_CODE. + * include/ntdll/ldr.h (LDR_SYMBOL_INFO, LdrpLoadUserModuleSymbols): Add. + (LdrLoadModuleSymbols): Remove. + * include/ntos/kdbgsyms.h (ST_FILENAME, ST_FUNCTION, + ST_LINENUMBER): Add. + (SYMBOL). Make Name an ANSI_STRING. + (IMAGE_SYMBOL_INFO, AreSymbolsParsed): Add. + * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call + LdrpLoadUserModuleSymbols() not LdrLoadModuleSymbols(). + * lib/ntdll/ldr/utils.c (LdrLoadModuleSymbols): Rename to + LdrpLoadUserModuleSymbols. + (LdrpLoadUserModuleSymbols): Use DebugDbgLoadSymbols debug control code. + (LdrLoadDll): assert if out of memory. + (LdrLoadDll): Call + LdrpLoadUserModuleSymbols(), not LdrLoadModuleSymbols(). + * lib/ntdll/string/ctype.c (_pctype): #undef. + * ntoskrnl/dbg/dbgctrl.c (NtSystemDebugControl): Call + LdrLoadUserModuleSymbols on DebugDbgLoadSymbols. + * ntoskrnl/include/internal/ldr.h (LdrGetAddressInformation): Add. + * ntoskrnl/include/internal/module.h (MODULE_TEXT_SECTION): Make SymbolInfo + an IMAGE_SYMBOL_INFO. + * ntoskrnl/ke/i386/exp.c (LdrGetAddressInformation): Add prototype. + (print_address): Change #ifdef KDBG to #ifdef DBG. + (KiDoubleFaultHandler, KiDumpTrapFrame, KeDumpStackFrames): Dump + one stack frame per line. + * ntoskrnl/ke/i386/multiboot.S: Create pagetables for more kernel + address space so larger modules can be passed from the boot loader. + * ntoskrnl/ke/i386/usertrap.c (LdrGetAddressInformation): Add prototype. + (print_user_address): Print symbols using LdrGetAddressInformation(). + * ntoskrnl/ldr/loader.c (SYMBOLFILE_HEADER, IMAGE_SYMBOL_INFO_CACHE, + STAB_ENTRY, N_FUN, N_SLINE, N_SO, SymbolListHead): Add. + (TAG_SYM_BUF): Remove. + (LdrInitDebug): Remove unneeded code. + (LdrInit1): Prepare for loading symbols. + (LdrpReadLine, HexL, LdrpParseLine, LdrpLoadModuleSymbolsFromBuffer, + LdrpLoadUserModuleSymbolsFromBuffer): Remove. + (LdrpParseImageSymbols, LdrpGetFileName, LdrpGetFunctionName, + LdrpGetLineNumber, LdrGetAddressInformation, LdrpLookupUserSymbolInfo): Add. + (LdrpLoadModuleSymbols, LdrInitializeBootStartDriver): Change to use new + symbol structures. + (LdrLoadUserModuleSymbols): Cache symbol buffers. + (LdrUnloadModuleSymbols): Implement. + (LdrLoadModule, LdrUnloadModule): Change #ifdef KDBG to #ifdef DBG. + (LdrPEProcessModule): Split a line into two lines. + (LdrPEProcessModule): Setup for loading symbols. + * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Open with FILE_SHARE_READ. + * ntoskrnl/ps/process.c (PiFreeSymbols): Call LdrUnloadModuleSymbols() to + free symbols. + (PiDeleteProcess): Change #ifdef KDBG to #ifdef DBG. + * ntoskrnl/rtl/ctype.c (_pctype): #undef. + * ntoskrnl/rtl/string.c (strncpy): Terminate destination string. + * tools/Makefile (rsym): Add target. + * tools/helper.mk: Include config and use -g if DBG = 1. + +2002-07-13 Casper S. Hornstrup + + * Makefile (install_before): Install system.hiv to correct location. + +2002-07-04 David Welch + + * subsys/win32k/include/callback.h: Fixed callback argument + definitions. + * subsys/win32k/ntuser/winpos.c: Implemented some more of the windows + sizing/moving code. + * subsys/win32k/ntuser/painting.c: Implemented some more of the + window painting code. + * subsys/win32k/objects/coord.c: Implemented LPtoDP and DPtoLP. + * subsys/win32k/objects/region.c: Added stubs for some more + region functions. + +2002-07-04 David Welch + + * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the + process desktop handle as well. + +2002-07-04 David Welch + + * ntoskrnl/se/token.c: Don't call the ZwXXX variant of + system calls when in system context. + +2002-07-04 David Welch + + * ntoskrnl/Makefile: Added file with MDA output code. + * ntoskrnl/kd/kdebug.c: Recognize MDA as a destination for + debug output. + +2002-07-04 David Welch + + * lib/user32/windows/defwnd.c: Implemented some more of the + default window handler. + +2002-07-04 David Welch + + * lib/user32/misc/stubs.c: Removed some stubs to seperate files. + +2002-07-04 David Welch + + * lib/user32/user32.def: Export ScreenToClient otherwise we + get problems when code in user32 tries to call it. + +2002-07-04 David Welch + + * include/win32k/region.h: Added prototypes for some missing + region functions. + +2002-07-04 David Welch + + * include/win32k/ntuser.h: Added prototypes for some missing + NtUserXXX functions. + +2002-07-04 David Welch + + * include/user32/wininternal.h: Added some constants for + private GetDCEx styles that WINE needs. + +2002-07-04 David Welch + + * include/user32/callback.h: Fixed callbacks for messages with + parameters. + +2002-07-04 David Welch + + * include/napi/win32.h (W32THREAD): Added pointer to the + thread's desktop. + * include/napi/win32.h (W32PROCESS): Removed handle table, + added a pointer to the process's window station. + * subsys/win32k/ntuser/guicheck.c (W32kGuiCheck): Reference + a process's window station on the first win32k system call. Reference + a thread's desktop on the first win32k system call. + +2002-07-04 David Welch + + * include/messages.h: Added some missing WM_XXX constants. + +2002-07-04 David Welch + + * drivers/dd/ide/makefile: Compiling with debugging messages + needs libgcc to be linked in. + +2002-07-04 David Welch + + * iface/addsys/genw32k.c: Generate a variable with the + number of system calls. + * iface/native/genntdll.c: Generate a proper stack frame for + the user system call stubs. + * ntoskrnl/ke/i386/syscall.S: Generate a proper stack frame for + the handler for system calls. + +2002-07-04 David Welch + + * Makefile: Build the GUI startup application. + * subsys/system/gstart/gstart.c: Application to start up + the GUI. + +2002-06-18 David Welch + + * tools/helper.mk: Make an import library a proper target + depending on the .def file. + +2002-06-18 David Welch + + * subsys/win32k/ntuser/window.c (NtUserGetWindowLong): Began + implementation. + +2002-06-18 David Welch + + * subsys/win32k/misc/object.c (ObmCreateHandle): Return the + correct handle value. + +2002-06-18 David Welch + + * subsys/win32k/makefile: Make win32k depend on the file containing + the service table. + +2002-06-18 David Welch + + * ntoskrnl/ke/i386/stkswitch.S (KeSwitchStackAndRet, + KePushAndStackSwitchAndSysRet): Push one value only. + * ntoskrnl/ps/w32call.c (NtCallbackReturn, NtW32Call): Moved + these functions to a new file. Restore the old trap frame after + returning from a callback. + +2002-06-18 David Welch + + * lib/user32/windows/message.c (CallWindowProcA, CallWindowProcW): + Convert message to Unicode or ASCII if necessary. + +2002-06-18 David Welch + + * include/user32/callback.h: Added WM_CREATE and WM_NCCALCSIZE + callbacks. + * lib/user32/windows/window.c (User32SendCREATEMessageForKernel, + User32SendNCCREATEMessageForKernel): Implemented. + * subsys/win32k/ntuser/callback.c (W32kSendCREATEMessage): + Implemented. + +2002-06-18 David Welch + + * include/structs.h: Added Unicode and ASCII versions of + CREATESTRUCT. + +2002-06-16 David Welch + + * tools/helper.mk: Make the install target depend on all the + files to be installed. + +2002-06-16 David Welch + + * ntoskrnl/ps/thread.c (NtCallbackReturn): Set TSS.Esp0 to the + top of the old stack. + * ntoskrnl/ps/thread.c (NtW32Call): Set TSS.Esp0 to the top of + the new stack. Free the callback stack correctly. Don't copy + portion of the trap frame that doesn't exist in non-v86-mode + interrupts. + * ntoskrnl/ps/thread.c (PsFreeCallbackStack): New function to + free a stack allocated with PsAllocateCallbackStack. + +2002-06-16 David Welch + + * drivers/dd/null/makefile: Commented out local LDFLAGS as + these cause bad relocations in the stripped image. + +2002-06-16 David Welch + + * config: Corrected spelling error. + +2002-06-11 David Welch + + * subsys/system/winlogon/winlogon.c (WinMain): Check for + failure when creating a window system. + +2002-06-11 David Welch + + * ntoskrnl/ob/handle.c (ObDuplicateObject): Added this internal + function for duplicating objects. + * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the parent + process's window station to the child process. + * ntoskrnl/ps/process.c (PsInitProcessManagement): Initialize the + first process's window station. + +2002-06-11 David Welch + + * ntoskrnl/mm/marea.c (MmCreateMemoryArea): Initialise + page operation structure members. + * ntoskrnl/mm/pageop.c (MmReleasePageOp, MmGetPageOp): Increment + or decrement the page operation count in the memory area. + * ntoskrnl/mm/virtual.c (MmNotPresentFaultVirtualMemory, + MmPageOutVirtualMemory): Check for a deleted memory area before + handling the fault. + * ntoskrnl/mm/virtual.c (MmFreeVirtualMemory): Wait for all + page operations to finish before freeing the memory area. + +2002-06-11 David Welch + + * ntoskrnl/ke/i386/syscall.S (interrupt_handler2e): Corrected + test for previous mode, upper 16-bit of CS on the stack after an + interrupt are arbitary. + +2002-06-11 David Welch + + * lib/user32/misc/winsta.c: Cleaned up indentation. + +2002-06-11 David Welch + + * apps/tests/winhello/winhello.c (WinMain, MainWndProc): + Cleaned up formatting, some more error checks. + +2002-06-04 David Welch + + * ntoskrnl/mm/virtual.c (MmSecureVirtualMemory, + MmUnsecureVirtualMemory, NtQueryVirtualMemory): Corrected indentation. + +2002-06-04 David Welch + + * ntoskrnl/ke/i386/exp.c (KiDoubleFaultHandler): Print CR3 + correctly. + +2002-06-04 David Welch + + * ntoskrnl/include/internal/ps.h: Added KTHREAD_STACK_LIMIT definition. + * ntoskrnl/ke/i386/tskswitch.S (Ki386ContextSwitch): Force all the + pages of the kernel stack to be accessible from this process. + +2002-06-04 David Welch + + * ntoskrnl/cc/view.c (ReadCacheSegmentChain): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/cc/copy.c (CcRosCreateCacheSegment): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/cc/copy.c (CcFreeCachePage): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/include/internal/mm.h: Changed prototypes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/include/internal/ps.h (KPROCESS): Changed type of + page directory base to PHYSICAL_ADDRESS. + * ntoskrnl/include/internal/i386/mm.h: Changed prototypes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/ke/kthread.c (KeFreeStackPage): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/ke/kthread.c (KeInitializeThread): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/ke/process.c (KeAttachProcess, KeDetachProcess): Changes + to use PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/ke/kernel.c (PcrPages, KeApplicationProcessorInit): Changes + to use PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/balance.c (MM_ALLOCATION_REQUEST): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/balance.c (MmReleasePageMemoryConsumer): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/balance.c (MmRequestPageMemoryConsumer): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/cont.c (MmFreeContinuousPage): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/cont.c (MmAllocateContinuousAlignedMemory): Changes to + use PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/freelist.c (MmTransferOwnershipPage, + MmGetLRUFirstUserPage, MmGetLRUNextUserPage, MmGetContinuousPages, + MmInitializePageList, MmSetFlagsPage, MmSetRmapListHeadPage, + MmGetRmapListHeadPage, MmMarkPageMapped, MmMarkPageUnmapped, + MmGetFlagsPage, MmSetSavedSwapEntryPage, MmGetSavedSwapEntryPage, + MmReferencePage, MmGetReferenceCountPage, MmIsUsablePage, + MmDereferencePage, MmGetLockCountPage, MmLockPage, MmUnlockPage, + MmAllocPage): Changes to use PHYSICAL_ADDRESS type for physical + addresses. + * ntoskrnl/mm/iospace.c (MmMapIoSpace): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/kmap.c (ExAllocatePage, MiZeroPage, MiCopyFromUserPage, + ExAllocatePageWithPhysPage): Changes to use PHYSICAL_ADDRESS type for + physical addresses. + * ntoskrnl/mm/marea.c (MmFreeMemoryArea): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/mdl.c (MmUnlockPages, MmMapLockedPages, + MmProbeAndLockPages): Changes to use PHYSICAL_ADDRESS type for + physical addresses. + * ntoskrnl/mm/mm.c (MmSharedDataPagePhysicalAddress, + MmCommitPagedPoolAddress, MmNotPresentFault): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/mminit.c (MmInitVirtualMemory): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/ncache.c (MmAllocateNonCachedMemory, + MmFreeNonCachedPage): Changes to use PHYSICAL_ADDRESS type for + physical addresses. + * ntoskrnl/mm/npool.c (grow_kernel_pool): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/rmap.c (MmPageOutPhysicalAddress, MmInsertRmap, + MmDeleteAllRmaps, MmDeleteRmap): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/section.c (MiReadPage, MmNotPresentFaultSectionView, + MmAccessFaultSectionView, MmPageOutDeleteMapping, + MmPageOutSectionView, MmFreeSectionPage): Changes to use + PHYSICAL_ADDRESS type for physical addresses. + * ntoskrnl/mm/slab.c (ExGrowSlabCache): Changes to use + PHYSICAL_ADDRESS type for physical address. + * ntoskrnl/mm/virtual.c (MmPageOutVirtualMemory, + MmNotPresentFaultVirtualMemory, MmFreeVirtualMemoryPage): Changes to + use PHYSICAL_ADDRESS type for physical address. + * ntoskrnl/mm/wset.c (MmTrimUserMemory): Changes to use + PHYSICAL_ADDRESS type for physical address. + * ntoskrnl/mm/page.c (Mmi386ReleaseMmInfo, MmCopyMmInfo, + MmGetPhysicalAddressForProcess, MmCreateVirtualMapping, + MmCreateVirtualMappingUnsafe, MmCreateVirtualMappingForProcess, + MmDeleteVirtualMapping): Changes to use PHYSICAL_ADDRESS type for + physical address. + * ntoskrnl/ps/process (PsInitProcessManagment): Changes to use + PHYSICAL_ADDRESS type for physical address. + * ntoskrnl/ps/thread.c (PsAllocateCallbackStack): Changes to use + PHYSICAL_ADDRESS type for physical address. + +2002-06-04 David Welch + + * Lots of change since the ChangeLog was last updated. + +2001-03-18 David Welch + + * ntoskrnl/ke/apc.c (KiDeliverApc): Bug fix. + * ntoskrnl/ke/apc.c (KeInsertQueueApc): More comments. + * ntoskrnl/ke/catch.c (KiDispatchException): Bug fix. + * ntoskrnl/ke/timer.c (KeDelayExecutionThread): Don't use removed + function KeAddTimeoutThread. + * ntoskrnl/ke/timer.c (KeAddTimeoutThread): Removed. + * ntoskrnl/ke/wait.c (KeWaitForSingleObject, KeWaitForMultipleObjects): + Don't use KeAddTimeoutThread. + * ntoskrnl/mm/freelist.c (MmAllocateContiguousAlignedMemory): Bug fix + * ntoskrnl/mm/freelist.c (MmAllocatePage): Allocate from the top + memory. + +2001-03-17 David Welch + + * ntoskrnl/ke/catch.c (KiDispatchException): Implementation of + exception handling, user-mode only. + +2001-03-16 David Welch + + * include/ddk/zw.h: Corrected declarations of NtCreateProfile, + NtQueryIntervalProfile, NtSetIntervalProfile. + * include/ddk/zwtypes.h: Added definitions of KPROFILE_SOURCE. + * ntoskrnl/include/internal/ke.h: Added the interrupted EIP as a + parameter to KiUpdateSystemTime for profiling purposes. + * ntoskrnl/include/internal/nt: Added declaration for profiling + support initialization. + * ntoskrnl/ke/timer.c (KiUpdateSystemTime, KeExpireTimers): Call + the profiling code on a timer interrupt with the interrupt EIP. + * ntoskrnl/ke/i386/irq.c (KiDispatchInterrupt): Pass the interrupted + EIP to KiUpdateSystemTime. + * ntoskrnl/mm/virtual.c (NtReadVirtualMemory, NtWriteVirtualMemory): + Release the MDLs used properly. + * ntoskrnl/nt/nt.c: Call the profiling support initialization. + * ntoskrnl/nt/ntevent.c (NtCreateEvent): Don't try copying the + ObjectAttributes parameter if it is NULL. + * ntoskrnl/nt/profile.c: Implemented profiling. + +2001-03-16 David Welch + + * ntoskrnl/include/internal/safe.h: Corrected typo. + * ntoskrnl/nt/ntevent.c (NtCreateEvent, NtOpenEvent, NtQueryEvent): + Corrected typos. + * ntoskrnl/rtl/mem.c: Missing header file. + +2001-03-16 David Welch + + * ntoskrnl/include/internal/safe.h: Add definitions for handling + potentially unsafe pointers. + +2001-03-16 David Welch + + * ntoskrnl/include/internal/mm.h: Removed MmSafeCopyToUser and + MmSafeCopyFromUser as source files need these but don't want internal + mm definitions. + * ntoskrnl/nt/ntevent.c (NtCreateEvent, NtOpenEvent, NtPulseEvent, + NtQueryEvent, NtResetEvent, NtSetEvent): Copy data to and from + user mode safely. + * ntoskrnl/rtl/mem.c (MmCopyToCaller, MmCopyFromCaller): Helper + functions for copying data to and from potentially unsafe pointers. + +2000-12-23 David Welch + + * All task switching is done in software. + * Beginnings of v86 mode support. + +2000-12-22 David Welch + + * ntoskrnl/ps/kill.c (PiTerminateProcessThreads): Drop + PiThreadListLock before calling PsTerminateOtherThread + +2000-12-16 David Welch + + * ntoskrnl/ex/fmutex.c (ExReleaseFastMutexUnsafe): Only set the + fast mutex's owner back to NULL if it is being released + +2000-12-10 David Welch + + * ntoskrnl/ke/i386/vm86_sup.S (Ki386RetToV86Mode): Added function + to do the raw switch to v86 mode. + * ntoskrnl/include/internal/vm86.h: Definitions for the v86 mode + support. + +2000-12-10 David Welch + + * ntoskrnl/ke/i386/trap.s (PsBeginThreadWithContextInternal): Moved + to ntoskrnl/ke/i386/bswitch.S. + * ntoskrnl/ke/i386/trap.s (interrupt_handler2e): Moved to + ntoskrnl/ke/i386/syscall.S. + * ntoskrnl/ke/i386/trap.s (old_interrupt_handler2e): Removed. + +2000-12-04 David Welch + + * ntoskrnl/ke/i386/irq.c (KiInterruptDispatch): Record the last PC + value for a rescheduled thread. + * ntoskrnl/ke/i386/irqhand.s: Construct a primitive trap frame + in interrupt handlers. + +2000-08-30 David Welch + + * Added calibration of KeStallExecutionProcessor timing + (code from linux 2.2.16). + + * Corrected compilation bugs in user32 library. + + * Corrected compilation bugs related to anonymous structs + in ndis code. + + * Pass command line to kernel from loadros. + + * Corrected PIC mask calculation. + +2000-05-27 David Welch + + * Fixed issue with closing non-existent or already closed + handle. + +2000-01-26 David Welch + + * ZwCreateProcess now maps ntdll rather than the user-mode + code. + +1999-09-06 David Welch + + * Implemented ZwOpenProcess. + + * Partially implemented killing other threads (possible memory + leaks). + + * Made a start on a proper implemention of APCs (based on + article in NT insider). + +1998-12-08 David Welch + + * Corrected bug in shell (Read two keypresses and assumed they + where the key going up and down respectively). + + * Corrected race in dpc handling. + + * Took out cleanup sections in ZwReadFile (now handled by the + APC). + + * Disabled broken code in kernel32. + + + + + + + + + + diff --git a/Makefile b/Makefile index f640f2b..45bdfe1 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,12 @@ PATH_TO_TOP = . # -# Define to build WINE modules +# Define to build ReactOS external targets # -ifeq ($(ROS_BUILD_WINE),) -ROS_BUILD_WINE = no +ifeq ($(ROS_BUILD_EXT),) +ROS_BUILD_EXT = no else -ROS_BUILD_WINE = yes +ROS_BUILD_EXT = yes endif include $(PATH_TO_TOP)/rules.mak @@ -18,7 +18,6 @@ include $(PATH_TO_TOP)/rules.mak # Required to run the system COMPONENTS = iface_native iface_additional hallib ntoskrnl - # Hardware Abstraction Layers # halx86 HALS = halx86 @@ -31,8 +30,9 @@ BUS = acpi isapnp pci # advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32 # oleaut32 psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda DLLS = advapi32 crtdll fmifs gdi32 kernel32 packet msafd msvcrt ntdll \ - secur32 user32 version winmm ws2help ws2_32 wshirda -SUBSYS = smss win32k csrss + secur32 user32 version winedbgc ws2help ws2_32 wshirda #winmm + +SUBSYS = smss win32k csrss ntvdm # # Select the server(s) you want to build @@ -49,8 +49,9 @@ LOADERS = dos DRIVERS_LIB = bzip2 zlib # Kernel mode device drivers -# beep blue floppy ide keyboard mouse null parallel ramdrv serenum serial vga vidport -DEVICE_DRIVERS = beep blue floppy ide null serial vga vidport +# Obsolete: ide +# beep blue floppy null parallel ramdrv serenum serial vga vidport +DEVICE_DRIVERS = beep blue floppy null serial vga vidport # Kernel mode input drivers # keyboard mouclass psaux sermouse @@ -61,8 +62,8 @@ INPUT_DRIVERS = keyboard mouclass psaux FS_DRIVERS = cdfs fs_rec ms np vfat mup ntfs # Kernel mode networking drivers -# afd ndis packet tcpip tdi wshtcpip -NET_DRIVERS = afd ndis packet tcpip tdi wshtcpip +# afd ndis npf tcpip tdi wshtcpip +NET_DRIVERS = afd ndis npf tcpip tdi wshtcpip # Kernel mode networking device drivers # ne2000 @@ -80,66 +81,43 @@ SYS_APPS = autochk services shell winlogon gstart usetup # rpcss eventlog SYS_SVC = rpcss eventlog -# Test applications -# alive apc args atomtest bench consume count dump_shared_data -# event file gditest hello isotest lpc mstest mutex nptest -# pteb regtest sectest shm simple thread vmtest winhello -TEST_APPS = alive apc args atomtest bench consume count dump_shared_data \ - event file gditest hello isotest lpc mstest mutex nptest \ - pteb regtest sectest shm simple thread tokentest vmtest winhello dibtest - -# Test applications -# cabman cat net objdir partinfo pice ps stats -UTIL_APPS = cat objdir partinfo stats - -# -# Win32 Subsystem support (Based on WINE) -# FIXME: Move to this its own Makefile -# - -WINE_OTHER = unicode library - -WINE_TOOLS = bin2res wrc winebuild - -WINE_DLLS = comcat crtdll comctl32 commdlg dsound dplayx imagehlp ole32 richedit \ -shlwapi shell32 shdocvw twain urlmon winspool \ -rpcrt4 # needed to make rcprt4 implib +APPS = tests testsets utils -# mapi32 oleaut32 oledlg olepro32 olecli olesvr shfolder -# winmm ddraw dinput dplay serialui tapi32 urlmon wintrust -# msinfo lzexpand (missing imports) -WINE_PROGS = control expand osversioncheck regedit regsvr32 winver uninstaller -# (waiting on wrc fix for the rest of these) -# clock cmdlgtst notepad progman wcmd -# winefile winemine winetest uninstaller +# External (sub)systems for ReactOS +# rosapps wine posix os2 (requires c++) java (non-existant) +EXTERNALS = rosapps wine posix os2 - -ifeq ($(ROS_BUILD_WINE),yes) -WINE_MODULES = $(WINE_OTHER) $(WINE_TOOLS) $(WINE_DLLS) $(WINE_PROGS) +ifeq ($(ROS_BUILD_EXT),yes) +EXT_MODULES = $(EXTERNALS) else -WINE_MODULES = +EXT_MODULES = endif KERNEL_DRIVERS = $(DRIVERS_LIB) $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) \ $(NET_DRIVERS) $(NET_DEVICE_DRIVERS) $(STORAGE_DRIVERS) all: tools dk implib $(COMPONENTS) $(HALS) $(BUS) $(DLLS) $(SUBSYS) \ - $(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(TEST_APPS) \ - $(UTIL_APPS) $(WINE_MODULES) + $(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) \ + $(APPS) $(EXT_MODULES) + +#config: $(TOOLS:%=%_config) + +depends: $(DLLS:%=%_depends) $(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \ + $(EXT_MODULES:%=%_depends) $(POSIX_LIBS:%=%_depends) implib: $(COMPONENTS:%=%_implib) $(HALS:%=%_implib) $(BUS:%=%_implib) \ $(DLLS:%=%_implib) $(LOADERS:%=%_implib) \ $(KERNEL_DRIVERS:%=%_implib) $(SUBSYS:%=%_implib) \ $(SYS_APPS:%=%_implib) $(SYS_SVC:%=%_implib) \ - $(TEST_APPS:%=%_implib) $(UTIL_APPS:%=%_implib) \ - $(WINE_MODULES:%=%_implib) + $(APPS:%=%_implib) $(EXT_MODULES:%=%_implib) clean: tools dk_clean $(HALS:%=%_clean) \ $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \ $(LOADERS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) $(SUBSYS:%=%_clean) \ - $(SYS_APPS:%=%_clean) $(SYS_SVC:%=%_clean) $(TEST_APPS:%=%_clean) \ - $(UTIL_APPS:%=%_clean) $(NET_APPS:%=%_clean) $(WINE_MODULES:%=%_clean) \ + $(SYS_APPS:%=%_clean) $(SYS_SVC:%=%_clean) \ + $(NET_APPS:%=%_clean) \ + $(APPS:%=%_clean) $(EXT_MODULES:%=%_clean) \ clean_after tools_clean clean_after: @@ -150,16 +128,16 @@ install: tools install_dirs install_before \ $(DLLS:%=%_install) $(LOADERS:%=%_install) \ $(KERNEL_DRIVERS:%=%_install) $(SUBSYS:%=%_install) \ $(SYS_APPS:%=%_install) $(SYS_SVC:%=%_install) \ - $(TEST_APPS:%=%_install) $(UTIL_APPS:%=%_install) \ - $(WINE_MODULES:%=%_install) + $(APPS:%=%_install) $(EXT_MODULES:%=%_install) dist: $(TOOLS_PATH)/rcopy$(EXE_POSTFIX) dist_clean dist_dirs \ $(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(DLLS:%=%_dist) \ $(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \ - $(SYS_APPS:%=%_dist) $(SYS_SVC:%=%_dist) $(TEST_APPS:%=%_dist) \ - $(UTIL_APPS:%=%_dist) $(NET_APPS:%=%_dist) $(WINE_MODULES:%=%_dist) + $(SYS_APPS:%=%_dist) $(SYS_SVC:%=%_dist) \ + $(NET_APPS:%=%_dist) \ + $(APPS:%=%_dist) $(EXT_MODULES:%=%_dist) -.PHONY: all implib clean clean_before install dist +.PHONY: all depends implib clean clean_before install dist # @@ -188,6 +166,9 @@ $(SYS_APPS:%=%_install): %_install: $(SYS_SVC): %: make -C services/$* +$(SYS_SVC:%=%_depends): %_depends: + make -C services/$* depends + $(SYS_SVC:%=%_implib): %_implib: make -C services/$* implib @@ -200,133 +181,55 @@ $(SYS_SVC:%=%_dist): %_dist: $(SYS_SVC:%=%_install): %_install: make -C services/$* install -.PHONY: $(SYS_SVC) $(SYS_SVC:%=%_implib) $(SYS_SVC:%=%_clean) $(SYS_SVC:%=%_install) $(SYS_SVC:%=%_dist) - - -# -# Test Applications -# -$(TEST_APPS): %: - make -C apps/tests/$* - -$(TEST_APPS:%=%_implib): %_implib: - make -C apps/tests/$* implib - -$(TEST_APPS:%=%_clean): %_clean: - make -C apps/tests/$* clean - -$(TEST_APPS:%=%_dist): %_dist: - make -C apps/tests/$* dist - -$(TEST_APPS:%=%_install): %_install: - make -C apps/tests/$* install - -.PHONY: $(TEST_APPS) $(TEST_APPS:%=%_implib) $(TEST_APPS:%=%_clean) $(TEST_APPS:%=%_install) $(TEST_APPS:%=%_dist) - - -# -# Utility Applications -# -$(UTIL_APPS): %: - make -C apps/utils/$* - -$(UTIL_APPS:%=%_implib): %_implib: - make -C apps/utils/$* implib - -$(UTIL_APPS:%=%_clean): %_clean: - make -C apps/utils/$* clean - -$(UTIL_APPS:%=%_dist): %_dist: - make -C apps/utils/$* dist - -$(UTIL_APPS:%=%_install): %_install: - make -C apps/utils/$* install - -.PHONY: $(UTIL_APPS) $(UTIL_APPS:%=%_implib) $(UTIL_APPS:%=%_clean) $(UTIL_APPS:%=%_install) $(UTIL_APPS:%=%_dist) +.PHONY: $(SYS_SVC) $(SYS_SVC:%=%_depends) $(SYS_SVC:%=%_implib) $(SYS_SVC:%=%_clean) $(SYS_SVC:%=%_install) $(SYS_SVC:%=%_dist) # -# Other Wine Modules +# Applications # -$(WINE_OTHER): %: - make -f makefile.ros -C $(WINE_PATH)/$* - -$(WINE_OTHER:%=%_implib): %_implib: - make -f makefile.ros -C $(WINE_PATH)/$* implib - -$(WINE_OTHER:%=%_clean): %_clean: - make -f makefile.ros -C $(WINE_PATH)/$* clean - -$(WINE_OTHER:%=%_dist): %_dist: - make -f makefile.ros -C $(WINE_PATH)/$* dist - -$(WINE_OTHER:%=%_install): %_install: - make -f makefile.ros -C $(WINE_PATH)/$* install - -.PHONY: $(WINE_OTHER) $(WINE_OTHER:%=%_implib) $(WINE_OTHER:%=%_clean) $(WINE_OTHER:%=%_install) $(WINE_OTHER:%=%_dist) - - # -# Wine Tools +# Extra (optional system) Applications # -$(WINE_TOOLS): %: - make -f makefile.ros -C $(WINE_PATH)/tools/$* +$(APPS): %: + make -C apps/$* -$(WINE_TOOLS:%=%_implib): %_implib: - make -f makefile.ros -C $(WINE_PATH)/tools/$* implib +$(APPS:%=%_implib): %_implib: + make -C apps/$* implib -$(WINE_TOOLS:%=%_clean): %_clean: - make -f makefile.ros -C $(WINE_PATH)/tools/$* clean +$(APPS:%=%_clean): %_clean: + make -C apps/$* clean -$(WINE_TOOLS:%=%_dist): %_dist: - make -f makefile.ros -C $(WINE_PATH)/tools/$* dist +$(APPS:%=%_dist): %_dist: + make -C apps/$* dist -$(WINE_TOOLS:%=%_install): %_install: - make -f makefile.ros -C $(WINE_PATH)/tools/$* install +$(APPS:%=%_install): %_install: + make -C apps/$* install -.PHONY: $(WINE_DLLS) $(WINE_DLLS:%=%_implib) $(WINE_DLLS:%=%_clean) $(WINE_DLLS:%=%_install) $(WINE_DLLS:%=%_dist) +.PHONY: $(APPS) $(APPS:%=%_implib) $(APPS:%=%_clean) $(APPS:%=%_install) $(APPS:%=%_dist) # -# Wine DLLs +# External ports and subsystem personalities # -$(WINE_DLLS): %: - make -f makefile.ros -C $(WINE_PATH)/dlls/$* - -$(WINE_DLLS:%=%_implib): %_implib: - make -f makefile.ros -C $(WINE_PATH)/dlls/$* implib - -$(WINE_DLLS:%=%_clean): %_clean: - make -f makefile.ros -C $(WINE_PATH)/dlls/$* clean - -$(WINE_DLLS:%=%_dist): %_dist: - make -f makefile.ros -C $(WINE_PATH)/dlls/$* dist - -$(WINE_DLLS:%=%_install): %_install: - make -f makefile.ros -C $(WINE_PATH)/dlls/$* install +$(EXTERNALS): %: + make -C $(ROOT_PATH)/$* -.PHONY: $(WINE_DLLS) $(WINE_DLLS:%=%_implib) $(WINE_DLLS:%=%_clean) $(WINE_DLLS:%=%_install) $(WINE_DLLS:%=%_dist) +$(EXTERNALS:%=%_depends): %_depends: + make -C $(ROOT_PATH)/$* depends +$(EXTERNALS:%=%_implib): %_implib: + make -C $(ROOT_PATH)/$* implib -# -# Wine programs -# -$(WINE_PROGS): %: - make -f makefile.ros -C $(WINE_PATH)/programs/$* - -$(WINE_PROGS:%=%_implib): %_implib: - make -f makefile.ros -C $(WINE_PATH)/programs/$* implib +$(EXTERNALS:%=%_clean): %_clean: + make -C $(ROOT_PATH)/$* clean -$(WINE_PROGS:%=%_clean): %_clean: - make -f makefile.ros -C $(WINE_PATH)/programs/$* clean +$(EXTERNALS:%=%_dist): %_dist: + make -C $(ROOT_PATH)/$* dist -$(WINE_PROGS:%=%_dist): %_dist: - make -f makefile.ros -C $(WINE_PATH)/programs/$* dist +$(EXTERNALS:%=%_install): %_install: + make -C $(ROOT_PATH)/$* install -$(WINE_PROGS:%=%_install): %_install: - make -f makefile.ros -C $(WINE_PATH)/programs/$* install - -.PHONY: $(WINE_PROGS) $(WINE_PROGS:%=%_implib) $(WINE_PROGS:%=%_clean) $(WINE_PROGS:%=%_install) $(WINE_PROGS:%=%_dist) +.PHONY: $(EXTERNALS) $(EXTERNALS:%=%_depends) $(EXTERNALS:%=%_implib) $(EXTERNALS:%=%_clean) $(EXTERNALS:%=%_install) $(EXTERNALS:%=%_dist) # @@ -672,6 +575,9 @@ $(HALS:%=%_dist): %_dist: $(DLLS): %: make -C lib/$* +$(DLLS:%=%_depends): %_depends: + make -C lib/$* depends + $(DLLS:%=%_implib): %_implib: make -C lib/$* implib @@ -684,7 +590,7 @@ $(DLLS:%=%_install): %_install: $(DLLS:%=%_dist): %_dist: make -C lib/$* dist -.PHONY: $(DLLS) $(DLLS:%=%_implib) $(DLLS:%=%_clean) $(DLLS:%=%_install) $(DLLS:%=%_dist) +.PHONY: $(DLLS) $(DLLS:%=%_depends) $(DLLS:%=%_implib) $(DLLS:%=%_clean) $(DLLS:%=%_install) $(DLLS:%=%_dist) # # Subsystem support modules @@ -693,6 +599,9 @@ $(DLLS:%=%_dist): %_dist: $(SUBSYS): %: make -C subsys/$* +$(SUBSYS:%=%_depends): %_depends: + make -C subsys/$* depends + $(SUBSYS:%=%_implib): %_implib: make -C subsys/$* implib @@ -705,7 +614,7 @@ $(SUBSYS:%=%_install): %_install: $(SUBSYS:%=%_dist): %_dist: make -C subsys/$* dist -.PHONY: $(SUBSYS) $(SUBSYS:%=%_implib) $(SUBSYS:%=%_clean) $(SUBSYS:%=%_install) \ +.PHONY: $(SUBSYS) $(SUBSYS:%=%_depends) $(SUBSYS:%=%_implib) $(SUBSYS:%=%_clean) $(SUBSYS:%=%_install) \ $(SUBSYS:%=%_dist) # diff --git a/apps/tests/Makefile b/apps/tests/Makefile new file mode 100644 index 0000000..f65539f --- /dev/null +++ b/apps/tests/Makefile @@ -0,0 +1,86 @@ +# +# ReactOS test applications makefile +# + +PATH_TO_TOP = ../.. + +include $(PATH_TO_TOP)/rules.mak + + +# Test applications +# alive apc args atomtest bench consume copymove count dump_shared_data +# event file gditest hello isotest lpc mstest mutex nptest +# pteb regtest sectest shm simple thread vmtest winhello +TEST_APPS = alive apc args atomtest bench consume copymove count dump_shared_data \ + event file gditest hello isotest lpc mstest mutex nptest \ + pteb regtest sectest shm simple thread tokentest vmtest winhello dibtest \ + lock hivetest + +TEST_MISC = + +all: $(TEST_APPS) $(TEST_MISC) + +depends: + +implib: $(TEST_APPS:%=%_implib) \ + $(TEST_MISC:%=%_implib) + +clean: $(TEST_APPS:%=%_clean) \ + $(TEST_MISC:%=%_clean) + +install: $(TEST_APPS:%=%_install) \ + $(TEST_MISC:%=%_install) + +dist: $(TEST_APPS:%=%_dist) \ + $(TEST_MISC:%=%_dist) + +.PHONY: all depends implib clean install dist + + +# +# Test Applications +# +$(TEST_APPS): %: + $(MAKE) -C $* + +$(TEST_APPS:%=%_implib): %_implib: + $(MAKE) -C $* implib + +$(TEST_APPS:%=%_clean): %_clean: + $(MAKE) -C $* clean + +$(TEST_APPS:%=%_dist): %_dist: + $(MAKE) -C $* dist + +$(TEST_APPS:%=%_install): %_install: + $(MAKE) -C $* install + +.PHONY: $(TEST_APPS) $(TEST_APPS:%=%_implib) $(TEST_APPS:%=%_clean) $(TEST_APPS:%=%_install) $(TEST_APPS:%=%_dist) + + +# +# Misc Test Applications +# +$(TEST_MISC): %: + $(MAKE) -C tests/$* + +$(TEST_MISC:%=%_implib): %_implib: + $(MAKE) -C tests/$* implib + +$(TEST_MISC:%=%_clean): %_clean: + $(MAKE) -C tests/$* clean + +$(TEST_MISC:%=%_dist): %_dist: + $(MAKE) -C tests/$* dist + +$(TEST_MISC:%=%_install): %_install: + $(MAKE) -C tests/$* install + +.PHONY: $(TEST_MISC) $(TEST_MISC:%=%_implib) $(TEST_MISC:%=%_clean) $(TEST_MISC:%=%_install) $(TEST_MISC:%=%_dist) + + +etags: + find . -name "*.[ch]" -print | etags --language=c - + +# EOF + diff --git a/apps/tests/alive/.cvsignore b/apps/tests/alive/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/alive/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/apc/.cvsignore b/apps/tests/apc/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/apc/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/args/.cvsignore b/apps/tests/args/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/args/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/atomtest/.cvsignore b/apps/tests/atomtest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/atomtest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/bench/.cvsignore b/apps/tests/bench/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/bench/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/bitblt/.cvsignore b/apps/tests/bitblt/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/bitblt/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/consume/.cvsignore b/apps/tests/consume/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/consume/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/copymove/.cvsignore b/apps/tests/copymove/.cvsignore new file mode 100644 index 0000000..343a060 --- /dev/null +++ b/apps/tests/copymove/.cvsignore @@ -0,0 +1,3 @@ +*.o +*.exe +*.sym diff --git a/apps/tests/copymove/Makefile b/apps/tests/copymove/Makefile new file mode 100644 index 0000000..e8d825f --- /dev/null +++ b/apps/tests/copymove/Makefile @@ -0,0 +1,19 @@ +# $Id$ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = copymove + +TARGET_OBJECTS = $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/tests/copymove/copymove.c b/apps/tests/copymove/copymove.c new file mode 100644 index 0000000..81c4a2e --- /dev/null +++ b/apps/tests/copymove/copymove.c @@ -0,0 +1,302 @@ +/* + * CopyFile, MoveFile and related routines test + */ + +#include +#include +#include +#include + +static TCHAR +FindOtherDrive() +{ + DWORD drives = GetLogicalDrives(); + BOOL found = FALSE; + TCHAR drive; + TCHAR rootdir[] = _T( "?:\\" ); + TCHAR currentdir[MAX_PATH + 1]; + + if (0 != GetCurrentDirectory(MAX_PATH + 1, currentdir)) { + for (drive = _T('A'); ! found && drive <= _T('Z'); drive++) { + if (0 != (drives & (1 << (drive - _T('A'))))&& + drive != _totupper(currentdir[0])) { + rootdir[0] = drive; + found = (DRIVE_FIXED == GetDriveType(rootdir)); + } + } + } + + return found ? drive - 1 : _T( ' ' ); +} + +static void +DeleteTestFile(LPCTSTR filename) +{ + SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL); + DeleteFile(filename); +} + +static void +CreateTestFile(LPCTSTR filename, DWORD attributes) +{ + HANDLE file; + char buffer[4096]; + DWORD wrote; + int c; + + DeleteTestFile(filename); + file = CreateFile(filename, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + 0, + 0); + + if (INVALID_HANDLE_VALUE == file) { + fprintf(stderr, "CreateFile failed with code %d\n", GetLastError()); + exit(1); + } + for(c = 0; c < sizeof(buffer); c++) { + buffer[c] = (char) c; + } + if (! WriteFile(file, buffer, sizeof(buffer), &wrote, NULL)) { + fprintf(stderr, "WriteFile failed with code %d\n", GetLastError()); + exit(1); + } + CloseHandle(file); + + if (! SetFileAttributes(filename, attributes)) { + fprintf(stderr, "SetFileAttributes failed with code %d\n", GetLastError()); + exit(1); + } +} + +static void +DeleteTestDir(LPCTSTR dirname) +{ + RemoveDirectory(dirname); +} + +static void +CreateTestDir(LPCTSTR dirname) +{ + if (! CreateDirectory(dirname, NULL)) { + fprintf(stderr, "CreateDirectory failed with code %d\n", GetLastError()); + exit(1); + } +} + +static void +CheckTestFile(LPCTSTR filename, DWORD attributes) +{ + HANDLE file; + char buffer[4096]; + DWORD read; + int c; + DWORD diskattr; + + file = CreateFile(filename, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + 0, + 0); + + if (INVALID_HANDLE_VALUE == file) { + fprintf(stderr, "CreateFile failed with code %d\n", GetLastError()); + exit(1); + } + + if (! ReadFile(file, buffer, sizeof(buffer), &read, NULL)) { + fprintf(stderr, "ReadFile failed with code %d\n", GetLastError()); + exit(1); + } + if (read != sizeof(buffer)) { + fprintf(stderr, "Trying to read %d bytes but got %d bytes\n", sizeof(buffer), read); + exit(1); + } + for(c = 0; c < sizeof(buffer); c++) { + if (buffer[c] != (char) c) { + fprintf(stderr, "File contents changed at position %d\n", c); + exit(1); + } + } + + CloseHandle(file); + + diskattr = GetFileAttributes(filename); + if (INVALID_FILE_ATTRIBUTES == diskattr) { + fprintf(stderr, "GetFileAttributes failed with code %d\n", GetLastError()); + exit(1); + } + if (diskattr != attributes) { + fprintf(stderr, "Attribute mismatch, expected 0x%08x found 0x%08x\n", attributes, diskattr); + exit(1); + } +} + +int +main(int argc, char *argv[]) +{ + TCHAR otherdrive; + TCHAR otherfile[ ] = _T("?:\\other.dat"); + + otherdrive = FindOtherDrive(); + + printf("Testing simple move\n"); + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(_T("end.dat")); + if (! MoveFile(_T("begin.dat"), _T("end.dat"))) { + fprintf(stderr, "MoveFile failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(_T("end.dat")); + + printf("Testing move of non-existing file\n"); + DeleteTestFile(_T("begin.dat")); + DeleteTestFile(_T("end.dat")); + if (MoveFile(_T("begin.dat"), _T("end.dat"))) { + fprintf(stderr, "MoveFile succeeded but shouldn't have\n"); + exit(1); + } else if (ERROR_FILE_NOT_FOUND != GetLastError()) { + fprintf(stderr, "MoveFile failed with unexpected code %d\n", GetLastError()); + exit(1); + } + DeleteTestFile(_T("end.dat")); + +/* Not correctly implemented in ros, destination file is kept open after this */ +#if 0 + printf("Testing move to existing file\n"); + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE); + if (MoveFile(_T("begin.dat"), _T("end.dat"))) { + fprintf(stderr, "MoveFile succeeded but shouldn't have\n"); + exit(1); + } else if (ERROR_ALREADY_EXISTS != GetLastError()) { + fprintf(stderr, "MoveFile failed with unexpected code %d\n", GetLastError()); + exit(1); + } + DeleteTestFile(_T("begin.dat")); + DeleteTestFile(_T("end.dat")); +#endif + +/* Not implemented yet in ros */ +#if 0 + printf("Testing directory move\n"); + CreateTestDir(_T("begin")); + CreateTestFile(_T("begin\\file.dat"), FILE_ATTRIBUTE_NORMAL); + DeleteTestDir(_T("end")); + if (! MoveFile(_T("begin"), _T("end"))) { + fprintf(stderr, "MoveFile failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(_T("end\\file.dat"), FILE_ATTRIBUTE_NORMAL); + DeleteTestFile(_T("end\\file.dat")); + DeleteTestDir(_T("end")); +#endif + + printf("Testing file move to different directory\n"); + CreateTestFile(_T("file.dat"), FILE_ATTRIBUTE_NORMAL); + CreateTestDir(_T("end")); + if (! MoveFile(_T("file.dat"), _T("end\\file.dat"))) { + fprintf(stderr, "MoveFile failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(_T("end\\file.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(_T("end\\file.dat")); + DeleteTestDir(_T("end")); + + printf("Testing move of read-only file\n"); + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_READONLY); + DeleteTestFile(_T("end.dat")); + if (! MoveFile(_T("begin.dat"), _T("end.dat"))) { + fprintf(stderr, "MoveFile failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY); + DeleteTestFile(_T("end.dat")); + + printf("Testing move to different drive\n"); + if (_T(' ') != otherdrive) { + otherfile[0] = otherdrive; + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(otherfile); + if (! MoveFile(_T("begin.dat"), otherfile)) { + fprintf(stderr, "MoveFile failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(otherfile, FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(otherfile); + } else { + printf(" Test skipped, no other drive available\n"); + } + + printf("Testing move/overwrite of existing file\n"); + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE); + if (! MoveFileEx(_T("begin.dat"), _T("end.dat"), MOVEFILE_REPLACE_EXISTING)) { + fprintf(stderr, "MoveFileEx failed with code %d\n", GetLastError()); + exit(1); + } + DeleteTestFile(_T("begin.dat")); + DeleteTestFile(_T("end.dat")); + +/* Not (correctly) implemented in ros yet */ +#if 0 + printf("Testing move/overwrite of existing readonly file\n"); + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_READONLY); + if (MoveFileEx(_T("begin.dat"), _T("end.dat"), MOVEFILE_REPLACE_EXISTING)) { + fprintf(stderr, "MoveFileEx succeeded but shouldn't have\n"); + exit(1); + } else if (ERROR_ALREADY_EXISTS != GetLastError() && + ERROR_ACCESS_DENIED != GetLastError()) { + fprintf(stderr, "MoveFileEx failed with unexpected code %d\n", GetLastError()); + exit(1); + } + DeleteTestFile(_T("begin.dat")); + DeleteTestFile(_T("end.dat")); +#endif + +/* Not implemented in ros yet */ +#if 0 + printf("Testing move to different drive without COPY_ALLOWED\n"); + if (_T(' ') != otherdrive) { + otherfile[0] = otherdrive; + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(otherfile); + if (MoveFileEx(_T("begin.dat"), otherfile, 0)) { + fprintf(stderr, "MoveFileEx succeeded but shouldn't have\n"); + exit(1); + } else if (ERROR_NOT_SAME_DEVICE != GetLastError()) { + fprintf(stderr, "MoveFileEx failed with unexpected code %d\n", GetLastError()); + exit(1); + } + DeleteTestFile(otherfile); + } else { + printf(" Test skipped, no other drive available\n"); + } +#endif + + printf("Testing move to different drive with COPY_ALLOWED\n"); + if (_T(' ') != otherdrive) { + otherfile[0] = otherdrive; + CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(otherfile); + if (! MoveFileEx(_T("begin.dat"), otherfile, MOVEFILE_COPY_ALLOWED)) { + fprintf(stderr, "MoveFileEx failed with code %d\n", GetLastError()); + exit(1); + } + CheckTestFile(otherfile, FILE_ATTRIBUTE_ARCHIVE); + DeleteTestFile(otherfile); + } else { + printf(" Test skipped, no other drive available\n"); + } + + printf("All tests successfully completed\n"); + + return 0; +} diff --git a/apps/tests/count/.cvsignore b/apps/tests/count/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/count/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/dibtest/.cvsignore b/apps/tests/dibtest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/dibtest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/dump_shared_data/.cvsignore b/apps/tests/dump_shared_data/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/dump_shared_data/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/event/.cvsignore b/apps/tests/event/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/event/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/file/.cvsignore b/apps/tests/file/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/file/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/gditest/.cvsignore b/apps/tests/gditest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/gditest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/hello/.cvsignore b/apps/tests/hello/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/hello/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/hivetest/.cvsignore b/apps/tests/hivetest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/hivetest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/hivetest/hivetest.c b/apps/tests/hivetest/hivetest.c new file mode 100644 index 0000000..587526c --- /dev/null +++ b/apps/tests/hivetest/hivetest.c @@ -0,0 +1,1205 @@ +#include +#include +#include +#include +#include + +HANDLE OutputHandle; +HANDLE InputHandle; + +void dprintf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args,fmt); + vsprintf(buffer,fmt,args); + WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); + va_end(args); +} + +void do_enumeratekey(PWSTR Name) +{ + ULONG Index,Length,i; + KEY_BASIC_INFORMATION KeyInformation[5]; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hKey1; + UNICODE_STRING KeyName; + + RtlInitUnicodeString(&KeyName, Name); + InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE + , NULL, NULL); + Status=NtOpenKey( &hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); + dprintf("NtEnumerateKey : \n"); + Index=0; + while(Status == STATUS_SUCCESS) + { + Status=NtEnumerateKey(hKey1,Index++,KeyBasicInformation + ,&KeyInformation[0], sizeof(KeyInformation) + ,&Length); + if(Status== STATUS_SUCCESS) + { + dprintf("\tSubKey Name = "); + for (i=0;i +#include + +HANDLE hFile; + +BOOL Slock(DWORD start,DWORD len) +{ + + OVERLAPPED overl; + BOOL stat; + overl.Offset = start; + overl.OffsetHigh = 0; + overl.hEvent = 0; + + + stat = LockFileEx(hFile,LOCKFILE_FAIL_IMMEDIATELY,0,len,0,&overl) ; + printf("Slock %i-%i %s\n",start,start+len,stat!=0 ? "OK" : "FAILED"); + return stat; + +} + +BOOL Xlock(DWORD start,DWORD len) +{ + + OVERLAPPED overl; + BOOL stat; + + overl.Offset = start; + overl.OffsetHigh = 0; + overl.hEvent = 0; + + stat = LockFileEx(hFile,LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,0,len,0,&overl); + + printf("Xlock %i-%i %s\n",start,start+len,stat!=0 ? "OK" : "FAILED"); + return stat; + + +} + +BOOL unlock(DWORD start,DWORD len) +{ + + OVERLAPPED overl; + BOOL stat; + overl.Offset = start; + overl.OffsetHigh = 0; + overl.hEvent = 0; + + stat = UnlockFileEx(hFile,0,len,0,&overl) ; + printf("unlock %i-%i %s\n",start,start+len,stat!=0 ? "OK" : "FAILED"); + return stat; + +} + + +BOOL mkfile() +{ + hFile = CreateFile("C:\\lock.test", + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + printf("mkfile %s\n",(hFile == INVALID_HANDLE_VALUE) ? "FAILED" : "OK"); + return !(hFile == INVALID_HANDLE_VALUE); + + +} + +void main(void) +{ + DWORD ass; + + printf("enter main\n"); + + mkfile(); + + Slock(8,10); + Slock(10,5); + Slock(10,5); + Slock(15,5); + Slock(5,10); + Slock(0,100); + Xlock(30,10); + Xlock(30,1); + unlock(30,1); + unlock(30,10); + Xlock(30,5); + Slock(35,5); + unlock(50,5); + unlock(0,100); + unlock(10,5); + + if (WriteFile(hFile,"ass",4,&ass,NULL) == 0) printf("write 1 failed\n"); + else printf("write 1 success\n"); + + CloseHandle(hFile); + mkfile(); + Slock(0,100); + + if (WriteFile(hFile,"ass",4,&ass,NULL) == 0) printf("write 2 failed\n"); + else printf("write 2 success\n"); + + + CloseHandle(hFile); + Sleep(10000); + + +} \ No newline at end of file diff --git a/apps/tests/lpc/.cvsignore b/apps/tests/lpc/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/lpc/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/mstest/.cvsignore b/apps/tests/mstest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/mstest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/mutex/.cvsignore b/apps/tests/mutex/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/mutex/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/nptest/.cvsignore b/apps/tests/nptest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/nptest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/pteb/.cvsignore b/apps/tests/pteb/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/pteb/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/regdump/main.c b/apps/tests/regdump/main.c new file mode 100644 index 0000000..dd474c3 --- /dev/null +++ b/apps/tests/regdump/main.c @@ -0,0 +1,45 @@ +// main.c : +// +#include +#include +#include "regdump.h" + + +HANDLE OutputHandle; +HANDLE InputHandle; + + +DWORD GetInput(char* Buffer, int buflen) +{ + DWORD Result; + + ReadConsoleA(InputHandle, Buffer, buflen, &Result, NULL); + return Result; +} + +int __cdecl main(int argc, char* argv[]) +{ + //AllocConsole(); + InputHandle = GetStdHandle(STD_INPUT_HANDLE); + OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + //return regmain(argc, argv); + return regdump(argc, argv); +} + + +#ifndef __GNUC__ + +//__declspec(dllimport) int __stdcall DllMain(void* hinstDll, unsigned long dwReason, void* reserved); + +char* args[] = { "regdump.exe", "0", "ansi", "verbose"}; + +int __cdecl mainCRTStartup(void) +{ + + //DllMain(NULL, DLL_PROCESS_ATTACH, NULL); + + main(1, args); + return 0; +} + +#endif /*__GNUC__*/ diff --git a/apps/tests/regdump/makefile b/apps/tests/regdump/makefile index cafcc19..e521248 100644 --- a/apps/tests/regdump/makefile +++ b/apps/tests/regdump/makefile @@ -11,9 +11,12 @@ TARGET_APPTYPE = console TARGET_NAME = regdump +#TARGET_CFLAGS = -DWIN32_REGDBG -DUNICODE -D_UNICODE +TARGET_CFLAGS = -DWIN32_REGDBG + TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a -TARGET_OBJECTS = $(TARGET_NAME).o +TARGET_OBJECTS = $(TARGET_NAME).o regcmds.o regproc.o main.o include $(PATH_TO_TOP)/rules.mak diff --git a/apps/tests/regdump/regcmds.c b/apps/tests/regdump/regcmds.c new file mode 100644 index 0000000..13ea7a1 --- /dev/null +++ b/apps/tests/regdump/regcmds.c @@ -0,0 +1,224 @@ +/* $Id$ + * + * ReactOS regedit + * + * regcmds.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Original Work Copyright 2002 Andriy Palamarchuk + * + * 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 WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include +#include + +#ifdef WIN32_REGDBG +#else +#include +#endif + +#include "regproc.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Global Variables: +// + +static char *usage = +"Usage:\n" +" regedit filename\n" +" regedit /E filename [regpath]\n" +" regedit /D regpath\n" +"\n" +"filename - registry file name\n" +"regpath - name of the registry key\n" +"\n" +"When is called without any switches adds contents of the specified\n" +"registry file to the registry\n" +"\n" +"Switches:\n" +" /E - exports contents of the specified registry key to the specified\n" +" file. Exports the whole registry if no key is specified.\n" +" /D - deletes specified registry key\n" +" /S - silent execution, can be used with any other switch.\n" +" The only existing mode, exists for compatibility with Windows regedit.\n" +" /V - advanced mode, can be used with any other switch.\n" +" Ignored, exists for compatibility with Windows regedit.\n" +" /L - location of system.dat file. Can be used with any other switch.\n" +" Ignored. Exists for compatibility with Windows regedit.\n" +" /R - location of user.dat file. Can be used with any other switch.\n" +" Ignored. Exists for compatibility with Windows regedit.\n" +" /? - print this help. Any other switches are ignored.\n" +" /C - create registry from. Not implemented.\n" +"\n" +"The switches are case-insensitive, can be prefixed either by '-' or '/'.\n" +"This program is command-line compatible with Microsoft Windows\n" +"regedit. The difference with Windows regedit - this application has\n" +"command-line interface only.\n"; + +typedef enum { + ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE, ACTION_VIEW +} REGEDIT_ACTION; + +/** + * Process unknown switch. + * + * Params: + * chu - the switch character in upper-case. + * s - the command line string where s points to the switch character. + */ +void error_unknown_switch(char chu, char *s) +{ + if (isalpha(chu)) { + printf("Undefined switch /%c!\n", chu); + } else { + printf("Alphabetic character is expected after '%c' " + "in switch specification\n", *(s - 1)); + } + //exit(1); +} + +BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s) +{ + TCHAR filename[MAX_PATH]; + TCHAR reg_key_name[KEY_MAX_LEN]; + + switch (action) { + case ACTION_ADD: + get_file_name(&s, filename, MAX_PATH); + if (!filename[0]) { + printf("No file name is specified\n%s", usage); + return FALSE; + //exit(1); + } + while (filename[0]) { + if (!import_registry_file(filename)) { + perror(""); + printf("Can't open file \"%s\"\n", filename); + return FALSE; + //exit(1); + } + get_file_name(&s, filename, MAX_PATH); + } + break; + case ACTION_DELETE: + get_file_name(&s, reg_key_name, KEY_MAX_LEN); + if (!reg_key_name[0]) { + printf("No registry key is specified for removal\n%s", usage); + return FALSE; + //exit(1); + } + delete_registry_key(reg_key_name); + break; + case ACTION_EXPORT: + filename[0] = '\0'; + get_file_name(&s, filename, MAX_PATH); + if (!filename[0]) { + printf("No file name is specified\n%s", usage); + return FALSE; + //exit(1); + } + if (s[0]) { + get_file_name(&s, reg_key_name, KEY_MAX_LEN); + export_registry_key(filename, reg_key_name); + } else { + export_registry_key(filename, NULL); + } + break; + default: + printf("Unhandled action!\n"); + return FALSE; + } + return TRUE; +} + +BOOL ProcessCmdLine(LPSTR lpCmdLine) +{ + REGEDIT_ACTION action = ACTION_UNDEF; + LPSTR s = lpCmdLine; /* command line pointer */ + CHAR ch = *s; /* current character */ + + while (ch && ((ch == '-') || (ch == '/'))) { + char chu; + char ch2; + + s++; + ch = *s; + ch2 = *(s+1); + chu = toupper(ch); + if (!ch2 || isspace(ch2)) { + if (chu == 'S' || chu == 'V') { + /* ignore these switches */ + } else { + switch (chu) { + case 'D': + action = ACTION_DELETE; + break; + case 'E': + action = ACTION_EXPORT; + break; + case 'V': + action = ACTION_VIEW; + break; + case '?': + printf(usage); + return FALSE; + //exit(0); + break; + default: + error_unknown_switch(chu, s); + return FALSE; + break; + } + } + s++; + } else { + if (ch2 == ':') { + switch (chu) { + case 'L': + /* fall through */ + case 'R': + s += 2; + while (*s && !isspace(*s)) { + s++; + } + break; + default: + error_unknown_switch(chu, s); + return FALSE; + break; + } + } else { + /* this is a file name, starting from '/' */ + s--; + break; + } + } + /* skip spaces to the next parameter */ + ch = *s; + while (ch && isspace(ch)) { + s++; + ch = *s; + } + } + if (action == ACTION_UNDEF) { + action = ACTION_ADD; + } + return PerformRegAction(action, s); +} diff --git a/apps/tests/regdump/regdump.c b/apps/tests/regdump/regdump.c index 93ac162..d133958 100644 --- a/apps/tests/regdump/regdump.c +++ b/apps/tests/regdump/regdump.c @@ -1,234 +1,167 @@ -#include -#include -#include +/* $Id$ + * + * ReactOS regedit + * + * regdump.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 #include -#include - -HANDLE OutputHandle; -HANDLE InputHandle; - -void dprintf(char* fmt, ...) -{ - va_list args; - char buffer[255]; - - va_start(args,fmt); - vsprintf(buffer,fmt,args); - WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); - va_end(args); -} - - -#define MAX_NAME_LEN 500 -/* -BOOL DumpRegKey(TCHAR* KeyPath, HKEY hKey) -{ - TCHAR keyPath[1000]; - int keyPathLen = 0; - - keyPath[0] = _T('\0'); +#include +#include "regdump.h" - dprintf("\n[%s]\n", KeyPath); - if (hKey != NULL) { - HKEY hNewKey; - LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey); - if (errCode == ERROR_SUCCESS) { - TCHAR Name[MAX_NAME_LEN]; - DWORD cName = MAX_NAME_LEN; - FILETIME LastWriteTime; - DWORD dwIndex = 0L; - while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) { - HKEY hSubKey; - DWORD dwCount = 0L; +#ifdef UNICODE +//#define dprintf _tprintf +#define dprintf printf +#else +#define dprintf printf +#endif - dprintf("\n[%s\\%s]\n", KeyPath, Name); +void RegKeyPrint(int which); - errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hSubKey); - if (errCode == ERROR_SUCCESS) { - TCHAR SubName[MAX_NAME_LEN]; - DWORD cSubName = MAX_NAME_LEN; -// if (RegEnumKeyEx(hSubKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - while (RegEnumKeyEx(hSubKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - dprintf("\t%s (%d)\n", SubName, dwCount); - cSubName = MAX_NAME_LEN; - ++dwCount; - } - } - RegCloseKey(hSubKey); - //AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwCount); - cName = MAX_NAME_LEN; - ++dwIndex; - } - RegCloseKey(hNewKey); - } - } else { - } - dprintf("\n"); - return TRUE; -} - */ -BOOL _DumpRegKey(TCHAR* KeyPath, HKEY hKey) -{ - if (hKey != NULL) { - HKEY hNewKey; - LONG errCode = RegOpenKeyEx(hKey, NULL, 0, KEY_READ, &hNewKey); - if (errCode == ERROR_SUCCESS) { - TCHAR Name[MAX_NAME_LEN]; - DWORD cName = MAX_NAME_LEN; - FILETIME LastWriteTime; - DWORD dwIndex = 0L; - TCHAR* pKeyName = &KeyPath[_tcslen(KeyPath)]; - while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) { - HKEY hSubKey; - DWORD dwCount = 0L; - _tcscat(KeyPath, _T("\\")); - _tcscat(KeyPath, Name); - dprintf("\n[%s]\n", KeyPath); - errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hSubKey); - if (errCode == ERROR_SUCCESS) { -#if 1 - _DumpRegKey(KeyPath, hSubKey); -#else - TCHAR SubName[MAX_NAME_LEN]; - DWORD cSubName = MAX_NAME_LEN; -// if (RegEnumKeyEx(hSubKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - while (RegEnumKeyEx(hSubKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - dprintf("\t%s (%d)\n", SubName, dwCount); - cSubName = MAX_NAME_LEN; - ++dwCount; - } -#endif - } - RegCloseKey(hSubKey); - cName = MAX_NAME_LEN; - *pKeyName = _T('\0'); - ++dwIndex; - } - RegCloseKey(hNewKey); - } - } else { - } - return TRUE; -} +const char* default_cmd_line1 = "/E HKLM_EXPORT.TXT HKEY_LOCAL_MACHINE"; +const char* default_cmd_line2 = "TEST_IMPORT.TXT"; +const char* default_cmd_line3 = "/P HKEY_LOCAL_MACHINE\\SYSTEM"; +const char* default_cmd_line4 = "/P HKEY_LOCAL_MACHINE\\SOFTWARE"; +const char* default_cmd_line5 = "/P HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes"; +const char* default_cmd_line6 = "/E HKCR_EXPORT.TXT HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes"; +const char* default_cmd_line7 = "/D HKEY_LOCAL_MACHINE\\SYSTEM"; +const char* default_cmd_line8 = "/D HKEY_LOCAL_MACHINE\\SOFTWARE"; +const char* default_cmd_line9 = "/D HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes"; -BOOL DumpRegKey(TCHAR* KeyPath, HKEY hKey) -{ - dprintf("\n[%s]\n", KeyPath); - return _DumpRegKey(KeyPath, hKey); +/* Show usage */ +void usage(const char* appName) +{ + fprintf(stderr, "%s: Dump registry key to console\n", appName); + fprintf(stderr, "%s HKCR | HKCU | HKLM | HKU | HKCC | HKRR\n", appName); } -void RegKeyPrint(int which) +void show_menu(void) { - TCHAR szKeyPath[1000]; - - switch (which) { - case '1': - strcpy(szKeyPath, _T("HKEY_CLASSES_ROOT")); - DumpRegKey(szKeyPath, HKEY_CLASSES_ROOT); - break; - case '2': - strcpy(szKeyPath, _T("HKEY_CURRENT_USER")); - DumpRegKey(szKeyPath, HKEY_CURRENT_USER); - break; - case '3': - strcpy(szKeyPath, _T("HKEY_LOCAL_MACHINE")); - DumpRegKey(szKeyPath, HKEY_LOCAL_MACHINE); - break; - case '4': - strcpy(szKeyPath, _T("HKEY_USERS")); - DumpRegKey(szKeyPath, HKEY_USERS); - break; - case '5': - strcpy(szKeyPath, _T("HKEY_CURRENT_CONFIG")); - DumpRegKey(szKeyPath, HKEY_CURRENT_CONFIG); - break; - case '6': -// DumpRegKey(szKeyPath, HKEY_CLASSES_ROOT); -// DumpRegKey(szKeyPath, HKEY_CURRENT_USER); -// DumpRegKey(szKeyPath, HKEY_LOCAL_MACHINE); -// DumpRegKey(szKeyPath, HKEY_USERS); -// DumpRegKey(szKeyPath, HKEY_CURRENT_CONFIG); - dprintf("unimplemented...\n"); - break; - } - + _tprintf(_T("\nchoose test :\n")); + _tprintf(_T(" 0 = Exit\n")); + printf(" 1 = %s\n", default_cmd_line1); + printf(" 2 = %s\n", default_cmd_line2); + printf(" 3 = %s\n", default_cmd_line3); + printf(" 4 = %s\n", default_cmd_line4); + printf(" 5 = %s\n", default_cmd_line5); + printf(" 6 = %s\n", default_cmd_line6); + printf(" 7 = %s\n", default_cmd_line7); + printf(" 8 = %s\n", default_cmd_line8); + printf(" 9 = %s\n", default_cmd_line9); +/* + _tprintf(_T(" 1 = %s\n"), default_cmd_line1); + _tprintf(_T(" 2 = %s\n"), default_cmd_line2); + _tprintf(_T(" 3 = %s\n"), default_cmd_line3); + _tprintf(_T(" 4 = %s\n"), default_cmd_line4); + _tprintf(_T(" 5 = %s\n"), default_cmd_line5); + _tprintf(_T(" 6 = %s\n"), default_cmd_line6); + _tprintf(_T(" 7 = %s\n"), default_cmd_line7); + _tprintf(_T(" 8 = %s\n"), default_cmd_line8); + _tprintf(_T(" 9 = %s\n"), default_cmd_line9); + */ +// _tprintf(_T(" A = HKEY_CLASSES_ROOT\n")); +// _tprintf(_T(" B = HKEY_CURRENT_USER\n")); +// _tprintf(_T(" C = HKEY_LOCAL_MACHINE\n")); +// _tprintf(_T(" D = HKEY_USERS\n")); +// _tprintf(_T(" E = HKEY_CURRENT_CONFIG\n")); +// _tprintf(_T(" F = REGISTRY ROOT\n")); } -int main(int argc, char* argv[]) +int regdump(int argc, char* argv[]) { - char Buffer[10]; - TCHAR szKeyPath[1000]; - DWORD Result; - - AllocConsole(); - InputHandle = GetStdHandle(STD_INPUT_HANDLE); - OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); - - if (argc > 1) { - -// if (0 == _tcsstr(argv[1], _T("HKLM"))) { - - if (strstr(argv[1], _T("help"))) { - - } else if (strstr(argv[1], _T("HKCR"))) { - RegKeyPrint('1'); - } else if (strstr(argv[1], _T("HKCU"))) { - RegKeyPrint('2'); - } else if (strstr(argv[1], _T("HKLM"))) { - RegKeyPrint('3'); - } else if (strstr(argv[1], _T("HKU"))) { - RegKeyPrint('4'); - } else if (strstr(argv[1], _T("HKCC"))) { - RegKeyPrint('5'); - } else if (strstr(argv[1], _T("HKRR"))) { - RegKeyPrint('6'); - } else { + char Buffer[500]; + + if (argc > 1) { +// if (0 == _tcsstr(argv[1], _T("HKLM"))) { + if (strstr(argv[1], "help")) { + usage(argv[0]); + } else if (strstr(argv[1], "HKCR")) { + RegKeyPrint('1'); + } else if (strstr(argv[1], "HKCU")) { + RegKeyPrint('2'); + } else if (strstr(argv[1], "HKLM")) { + RegKeyPrint('3'); + } else if (strstr(argv[1], "HKU")) { + RegKeyPrint('4'); + } else if (strstr(argv[1], "HKCC")) { + RegKeyPrint('5'); + } else if (strstr(argv[1], "HKRR")) { + RegKeyPrint('6'); + } else { dprintf("started with argc = %d, argv[1] = %s (unknown?)\n", argc, argv[1]); - } - - } else while (1) { - dprintf("choose test :\n"); - dprintf(" 0 = Exit\n"); - dprintf(" 1 = HKEY_CLASSES_ROOT\n"); - dprintf(" 2 = HKEY_CURRENT_USER\n"); - dprintf(" 3 = HKEY_LOCAL_MACHINE\n"); - dprintf(" 4 = HKEY_USERS\n"); - dprintf(" 5 = HKEY_CURRENT_CONFIG\n"); - dprintf(" 6 = REGISTRY ROOT\n"); - ReadConsoleA(InputHandle, Buffer, 3, &Result, NULL) ; - switch (Buffer[0]) { + } + return 0; + } + show_menu(); + while (1) { + GetInput(Buffer, sizeof(Buffer)); + switch (toupper(Buffer[0])) { case '0': return(0); case '1': + strcpy(Buffer, default_cmd_line1); + goto doit; case '2': + strcpy(Buffer, default_cmd_line2); + goto doit; case '3': + strcpy(Buffer, default_cmd_line3); + goto doit; case '4': + strcpy(Buffer, default_cmd_line4); + goto doit; case '5': + strcpy(Buffer, default_cmd_line5); + goto doit; case '6': - RegKeyPrint(Buffer[0]/* - '0'*/); + strcpy(Buffer, default_cmd_line6); + goto doit; + case '7': + strcpy(Buffer, default_cmd_line7); + goto doit; + case '8': + strcpy(Buffer, default_cmd_line8); + goto doit; + case '9': + strcpy(Buffer, default_cmd_line9); + goto doit; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + RegKeyPrint(toupper(Buffer[0]) - 'A' + 1); break; - default: - dprintf("invalid input.\n"); - break; - } - } + default: doit: + if (!ProcessCmdLine(Buffer)) { + dprintf("invalid input.\n"); + show_menu(); + } else { + dprintf("done.\n"); + } + break; + } + } return 0; } -/* -[HKEY_LOCAL_MACHINE] - -[HKEY_LOCAL_MACHINE\HARDWARE] - -[HKEY_LOCAL_MACHINE\HARDWARE\ACPI] - -[HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT] - -[HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT\VIA694] - -[HKEY_LOCAL_MACHINE\HARDWARE\ACPI\DSDT\VIA694\AWRDACPI] - - */ \ No newline at end of file diff --git a/apps/tests/regdump/regdump.h b/apps/tests/regdump/regdump.h new file mode 100644 index 0000000..be2c895 --- /dev/null +++ b/apps/tests/regdump/regdump.h @@ -0,0 +1,44 @@ +/* + * ReactOS + * + * regdump.h + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __REGDUMP_H__ +#define __REGDUMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +extern HANDLE OutputHandle; +extern HANDLE InputHandle; + +DWORD GetInput(char* Buffer, int buflen); +//void dprintf(char* fmt, ...); +int regdump(int argc, char* argv[]); +BOOL ProcessCmdLine(LPSTR lpCmdLine); + + +#ifdef __cplusplus +}; +#endif + +#endif // __REGDUMP_H__ diff --git a/apps/tests/regdump/regproc.c b/apps/tests/regdump/regproc.c new file mode 100644 index 0000000..6fb0a2d --- /dev/null +++ b/apps/tests/regdump/regproc.c @@ -0,0 +1,1491 @@ +/* + * Registry processing routines. Routines, common for registry + * processing frontends. + * + * Copyright 1999 Sylvain St-Germain + * Copyright 2002 Andriy Palamarchuk + * + * 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 + */ + +#ifdef WIN32_REGDBG +#include +#include +#ifndef __GNUC__ +#include +#else +#include +#endif +#include +#include +#include +#include +//#include +#include "regdump.h" +#else + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#endif + +#include "regproc.h" + + +#define REG_VAL_BUF_SIZE 4096 + +/* Delimiters used to parse the "value" to query queryValue*/ +#define QUERY_VALUE_MAX_ARGS 1 + +/* maximal number of characters in hexadecimal data line, + not including '\' character */ +#define REG_FILE_HEX_LINE_LEN 76 + +/* Globals used by the api setValue, queryValue */ +static LPTSTR currentKeyName = NULL; +static HKEY currentKeyClass = 0; +static HKEY currentKeyHandle = 0; +static BOOL bTheKeyIsOpen = FALSE; + +static TCHAR *reg_class_names[] = { + _T("HKEY_LOCAL_MACHINE"), + _T("HKEY_USERS"), + _T("HKEY_CLASSES_ROOT"), + _T("HKEY_CURRENT_CONFIG"), + _T("HKEY_CURRENT_USER") +}; + +#define REG_CLASS_NUMBER (sizeof(reg_class_names) / sizeof(reg_class_names[0])) + +static HKEY reg_class_keys[REG_CLASS_NUMBER] = { + HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, + HKEY_CURRENT_CONFIG, HKEY_CURRENT_USER +}; + +/* return values */ +#define NOT_ENOUGH_MEMORY 1 +#define IO_ERROR 2 + +/* processing macros */ + +/* common check of memory allocation results */ +#ifdef UNICODE +#define CHECK_ENOUGH_MEMORY(p) \ + if (!(p)) \ + { \ + _tprintf(_T("file %S, line %d: Not enough memory"), __FILE__, __LINE__); \ + assert(0);\ + exit(NOT_ENOUGH_MEMORY); \ + } +#else +#define CHECK_ENOUGH_MEMORY(p) \ + if (!(p)) \ + { \ + _tprintf(_T("file %s, line %d: Not enough memory"), __FILE__, __LINE__); \ + assert(0);\ + exit(NOT_ENOUGH_MEMORY); \ + } +#endif + +#ifdef UNICODE +#define _TEOF WEOF +#else +#define _TEOF EOF +#endif + +/****************************************************************************** + * This is a replacement for strsep which is not portable (missing on Solaris). + */ +#if 0 +/* DISABLED */ +char* getToken(char** str, const char* delims) +{ + char* token; + + if (*str==NULL) { + /* No more tokens */ + return NULL; + } + + token=*str; + while (**str!='\0') { + if (strchr(delims,**str)!=NULL) { + **str='\0'; + (*str)++; + return token; + } + (*str)++; + } + /* There is no other token */ + *str=NULL; + return token; +} +#endif + +/****************************************************************************** + * Copies file name from command line string to the buffer. + * Rewinds the command line string pointer to the next non-spece character + * after the file name. + * Buffer contains an empty string if no filename was found; + * + * params: + * command_line - command line current position pointer + * where *s[0] is the first symbol of the file name. + * file_name - buffer to write the file name to. + */ +void get_file_nameA(CHAR **command_line, CHAR *file_name, int max_filename) +{ + CHAR *s = *command_line; + int pos = 0; /* position of pointer "s" in *command_line */ + file_name[0] = 0; + + if (!s[0]) { + return; + } + if (s[0] == '"') { + s++; + (*command_line)++; + while (s[0] != '"') { + if (!s[0]) { + _tprintf(_T("Unexpected end of file name!\n")); + assert(0); + //exit(1); + } + s++; + pos++; + } + } else { + while (s[0] && !isspace(s[0])) { + s++; + pos++; + } + } + memcpy(file_name, *command_line, pos * sizeof((*command_line)[0])); + /* remove the last backslash */ + if (file_name[pos - 1] == '\\') { + file_name[pos - 1] = '\0'; + } else { + file_name[pos] = '\0'; + } + if (s[0]) { + s++; + pos++; + } + while (s[0] && isspace(s[0])) { + s++; + pos++; + } + (*command_line) += pos; +} + +void get_file_nameW(CHAR** command_line, WCHAR* filename, int max_filename) +{ + CHAR filenameA[_MAX_PATH]; + int len; + + get_file_nameA(command_line, filenameA, _MAX_PATH); + len = strlen(filenameA); + OemToCharBuffW(filenameA, filename, max_filename); + filename[len] = _T('\0'); +/* + UNICODE_STRING UnicodeString; + ANSI_STRING AnsiString; + CHAR filenameA[_MAX_PATH]; + + get_file_nameA(command_line, filenameA, _MAX_PATH); + + //RtlInitAnsiString(&AnsiString, filenameA); + UnicodeString.Buffer = filename; + UnicodeString.MaximumLength = max_filename;//MAX_PATH; + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); + */ +} + +/****************************************************************************** + * Converts a hex representation of a DWORD into a DWORD. + */ +DWORD convertHexToDWord(TCHAR* str, BYTE* buf) +{ + DWORD dw; + TCHAR xbuf[9]; + + memcpy(xbuf, str, 8 * sizeof(TCHAR)); + xbuf[88 * sizeof(TCHAR)] = '\0'; + _stscanf(xbuf, _T("%08lx"), &dw); + memcpy(buf, &dw, sizeof(DWORD)); + return sizeof(DWORD); +} + +/****************************************************************************** + * Converts a hex buffer into a hex comma separated values + */ +TCHAR* convertHexToHexCSV(BYTE* buf, ULONG bufLen) +{ + TCHAR* str; + TCHAR* ptrStr; + BYTE* ptrBuf; + + ULONG current = 0; + str = HeapAlloc(GetProcessHeap(), 0, (bufLen+1)*2*sizeof(TCHAR)); + memset(str, 0, (bufLen+1)*2); + ptrStr = str; /* Pointer to result */ + ptrBuf = buf; /* Pointer to current */ + while (current < bufLen) { + BYTE bCur = ptrBuf[current++]; + TCHAR res[3]; + _stprintf(res, _T("%02x"), (unsigned int)*&bCur); + _tcscat(str, res); + _tcscat(str, _T(",")); + } + /* Get rid of the last comma */ + str[_tcslen(str)-1] = _T('\0'); + return str; +} + +/****************************************************************************** + * Converts a hex buffer into a DWORD string + */ +TCHAR* convertHexToDWORDStr(BYTE* buf, ULONG bufLen) +{ + TCHAR* str; + DWORD dw; + + if (bufLen != sizeof(DWORD)) return NULL; + str = HeapAlloc(GetProcessHeap(), 0, ((bufLen*2)+1)*sizeof(TCHAR)); + memcpy(&dw, buf, sizeof(DWORD)); + _stprintf(str, _T("%08lx"), dw); + /* Get rid of the last comma */ + return str; +} + +/****************************************************************************** + * Converts a hex comma separated values list into a hex list. + * The Hex input string must be in exactly the correct form. + */ +DWORD convertHexCSVToHex(TCHAR* str, BYTE* buf, ULONG bufLen) +{ + TCHAR* s = str; /* Pointer to current */ + CHAR* b = buf; /* Pointer to result */ + ULONG strLen = _tcslen(str); + ULONG strPos = 0; + DWORD byteCount = 0; + + memset(buf, 0, bufLen); + /* + * warn the user if we are here with a string longer than 2 bytes that does + * not contains ",". It is more likely because the data is invalid. + */ + if ((strLen > 2) && (_tcschr(str, _T(',')) == NULL)) { + _tprintf(_T("WARNING converting CSV hex stream with no comma, ") \ + _T("input data seems invalid.\n")); + } + if (strLen > 3*bufLen) { + _tprintf(_T("ERROR converting CSV hex stream. Too long\n")); + } + while (strPos < strLen) { + TCHAR xbuf[3]; + TCHAR wc; + memcpy(xbuf, s, 2); + xbuf[3] = _T('\0'); + _stscanf(xbuf, _T("%02x"), (UINT*)&wc); + if (byteCount < bufLen) + *b++ = (unsigned char)wc; + s += 3; + strPos += 3; + ++byteCount; + } + return byteCount; +} + +/****************************************************************************** + * This function returns the HKEY associated with the data type encoded in the + * value. It modifies the input parameter (key value) in order to skip this + * "now useless" data type information. + * + * Note: Updated based on the algorithm used in 'server/registry.c' + */ +DWORD getDataType(LPTSTR* lpValue, DWORD* parse_type) +{ + struct data_type { const TCHAR *tag; int len; int type; int parse_type; }; + + static const struct data_type data_types[] = + { /* actual type */ /* type to assume for parsing */ + { _T("\""), 1, REG_SZ, REG_SZ }, + { _T("str:\""), 5, REG_SZ, REG_SZ }, +// { _T("str(2):\""), 8, REG_EXPAND_SZ, REG_SZ }, + { _T("expand:\""), 8, REG_EXPAND_SZ, REG_EXPAND_SZ }, + { _T("hex:"), 4, REG_BINARY, REG_BINARY }, + { _T("dword:"), 6, REG_DWORD, REG_DWORD }, + { _T("hex("), 4, -1, REG_BINARY }, + { NULL, 0, 0, 0 } + }; + + const struct data_type *ptr; + int type; + + for (ptr = data_types; ptr->tag; ptr++) { + if (memcmp(ptr->tag, *lpValue, ptr->len)) + continue; + + /* Found! */ + *parse_type = ptr->parse_type; + type = ptr->type; + *lpValue += ptr->len; + if (type == -1) { + TCHAR* end; + /* "hex(xx):" is special */ + type = (int)_tcstoul(*lpValue , &end, 16); + if (**lpValue == _T('\0') || *end != _T(')') || *(end+1) != _T(':')) { + type = REG_NONE; + } else { + *lpValue = end + 2; + } + } + return type; + } + return (**lpValue == _T('\0') ? REG_SZ : REG_NONE); +} + +/****************************************************************************** + * Returns an allocated buffer with a cleaned copy (removed the surrounding + * dbl quotes) of the passed value. + */ +LPTSTR getArg(LPTSTR arg) +{ + LPTSTR tmp = NULL; + ULONG len; + + if (arg == NULL) return NULL; + + // Get rid of surrounding quotes + len = _tcslen(arg); + if (arg[len-1] == _T('\"')) arg[len-1] = _T('\0'); + if (arg[0] == _T('\"')) arg++; + tmp = HeapAlloc(GetProcessHeap(), 0, (_tcslen(arg)+1) * sizeof(TCHAR)); + _tcscpy(tmp, arg); + return tmp; +} + +/****************************************************************************** + * Replaces escape sequences with the characters. + */ +void REGPROC_unescape_string(LPTSTR str) +{ + int str_idx = 0; /* current character under analysis */ + int val_idx = 0; /* the last character of the unescaped string */ + int len = _tcslen(str); + for (str_idx = 0; str_idx < len; str_idx++, val_idx++) { + if (str[str_idx] == _T('\\')) { + str_idx++; + switch (str[str_idx]) { + case _T('n'): + str[val_idx] = _T('\n'); + break; + case _T('\\'): + case _T('"'): + str[val_idx] = str[str_idx]; + break; + default: + _tprintf(_T("Warning! Unrecognized escape sequence: \\%c'\n"), str[str_idx]); + str[val_idx] = str[str_idx]; + break; + } + } else { + str[val_idx] = str[str_idx]; + } + } + str[val_idx] = _T('\0'); +} + +/****************************************************************************** + * Sets the value with name val_name to the data in val_data for the currently + * opened key. + * + * Parameters: + * val_name - name of the registry value + * val_data - registry value data + */ +HRESULT setValue(LPTSTR val_name, LPTSTR val_data) +{ + HRESULT hRes; + DWORD dwDataType, dwParseType; + LPBYTE lpbData; + BYTE convert[KEY_MAX_LEN]; + BYTE *bBigBuffer = 0; + DWORD dwLen; + + if ((val_name == NULL) || (val_data == NULL)) + return ERROR_INVALID_PARAMETER; + + /* Get the data type stored into the value field */ + dwDataType = getDataType(&val_data, &dwParseType); + +// if (dwParseType == REG_EXPAND_SZ) { +// } +// if (dwParseType == REG_SZ || dwParseType == REG_EXPAND_SZ) { /* no conversion for string */ + + if (dwParseType == REG_SZ) { /* no conversion for string */ + dwLen = _tcslen(val_data); + if (dwLen > 0 && val_data[dwLen-1] == _T('"')) { + dwLen--; + val_data[dwLen] = _T('\0'); + } + dwLen++; + dwLen *= sizeof(TCHAR); + REGPROC_unescape_string(val_data); + lpbData = val_data; + } else if (dwParseType == REG_DWORD) { /* Convert the dword types */ + dwLen = convertHexToDWord(val_data, convert); + lpbData = convert; + } else { /* Convert the hexadecimal types */ + int b_len = _tcslen(val_data)+2/3; + if (b_len > KEY_MAX_LEN) { + bBigBuffer = HeapAlloc (GetProcessHeap(), 0, b_len * sizeof(TCHAR)); + if (bBigBuffer == NULL) { + return ERROR_REGISTRY_IO_FAILED; + } + CHECK_ENOUGH_MEMORY(bBigBuffer); + dwLen = convertHexCSVToHex(val_data, bBigBuffer, b_len); + lpbData = bBigBuffer; + } else { + dwLen = convertHexCSVToHex(val_data, convert, KEY_MAX_LEN); + lpbData = convert; + } + } + hRes = RegSetValueEx(currentKeyHandle, val_name, + 0, /* Reserved */dwDataType, lpbData, dwLen); + + _tprintf(_T(" Value: %s, Data: %s\n"), val_name, lpbData); + + + if (bBigBuffer) + HeapFree(GetProcessHeap(), 0, bBigBuffer); + return hRes; +} + + +/****************************************************************************** + * Open the key + */ +HRESULT openKey(LPTSTR stdInput) +{ + DWORD dwDisp; + HRESULT hRes; + + /* Sanity checks */ + if (stdInput == NULL) + return ERROR_INVALID_PARAMETER; + + /* Get the registry class */ + currentKeyClass = getRegClass(stdInput); /* Sets global variable */ + if (currentKeyClass == (HKEY)ERROR_INVALID_PARAMETER) + return (HRESULT)ERROR_INVALID_PARAMETER; + + /* Get the key name */ + currentKeyName = getRegKeyName(stdInput); /* Sets global variable */ + if (currentKeyName == NULL) + return ERROR_INVALID_PARAMETER; + + hRes = RegCreateKeyEx( + currentKeyClass, /* Class */ + currentKeyName, /* Sub Key */ + 0, /* MUST BE 0 */ + NULL, /* object type */ + REG_OPTION_NON_VOLATILE, /* option, REG_OPTION_NON_VOLATILE ... */ + KEY_ALL_ACCESS, /* access mask, KEY_ALL_ACCESS */ + NULL, /* security attribute */ + ¤tKeyHandle, /* result */ + &dwDisp); /* disposition, REG_CREATED_NEW_KEY or + REG_OPENED_EXISTING_KEY */ + + if (hRes == ERROR_SUCCESS) + bTheKeyIsOpen = TRUE; + + return hRes; + +} + +/****************************************************************************** + * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line + * the key name (what starts after the first '\') + */ +LPTSTR getRegKeyName(LPTSTR lpLine) +{ + LPTSTR keyNameBeg; + TCHAR lpLineCopy[KEY_MAX_LEN]; + + if (lpLine == NULL) + return NULL; + + _tcscpy(lpLineCopy, lpLine); + keyNameBeg = _tcschr(lpLineCopy, _T('\\')); /* The key name start by '\' */ + if (keyNameBeg) { + LPTSTR keyNameEnd; + + keyNameBeg++; /* is not part of the name */ + keyNameEnd = _tcschr(lpLineCopy, _T(']')); + if (keyNameEnd) { + *keyNameEnd = _T('\0'); /* remove ']' from the key name */ + } + } else { + keyNameBeg = lpLineCopy + _tcslen(lpLineCopy); /* branch - empty string */ + } + currentKeyName = HeapAlloc(GetProcessHeap(), 0, (_tcslen(keyNameBeg)+1)*sizeof(TCHAR)); + CHECK_ENOUGH_MEMORY(currentKeyName); + _tcscpy(currentKeyName, keyNameBeg); + return currentKeyName; +} + +/****************************************************************************** + * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line + * the key class (what ends before the first '\') + */ +HKEY getRegClass(LPTSTR lpClass) +{ + LPTSTR classNameEnd; + LPTSTR classNameBeg; + int i; + + TCHAR lpClassCopy[KEY_MAX_LEN]; + + if (lpClass == NULL) + return (HKEY)ERROR_INVALID_PARAMETER; + + _tcsncpy(lpClassCopy, lpClass, KEY_MAX_LEN); + + classNameEnd = _tcschr(lpClassCopy, _T('\\')); /* The class name ends by '\' */ + if (!classNameEnd) { /* or the whole string */ + classNameEnd = lpClassCopy + _tcslen(lpClassCopy); + if (classNameEnd[-1] == _T(']')) { + classNameEnd--; + } + } + *classNameEnd = _T('\0'); /* Isolate the class name */ + if (lpClassCopy[0] == _T('[')) { + classNameBeg = lpClassCopy + 1; + } else { + classNameBeg = lpClassCopy; + } + for (i = 0; i < REG_CLASS_NUMBER; i++) { + if (!_tcscmp(classNameBeg, reg_class_names[i])) { + return reg_class_keys[i]; + } + } + return (HKEY)ERROR_INVALID_PARAMETER; +} + +/****************************************************************************** + * Close the currently opened key. + */ +void closeKey(VOID) +{ + RegCloseKey(currentKeyHandle); + HeapFree(GetProcessHeap(), 0, currentKeyName); /* Allocated by getKeyName */ + bTheKeyIsOpen = FALSE; + currentKeyName = NULL; + currentKeyClass = 0; + currentKeyHandle = 0; +} + +/****************************************************************************** + * This function is the main entry point to the setValue type of action. It + * receives the currently read line and dispatch the work depending on the + * context. + */ +void doSetValue(LPTSTR stdInput) +{ + /* + * We encountered the end of the file, make sure we + * close the opened key and exit + */ + if (stdInput == NULL) { + if (bTheKeyIsOpen != FALSE) + closeKey(); + return; + } + + if (stdInput[0] == _T('[')) { /* We are reading a new key */ + if (bTheKeyIsOpen != FALSE) { + closeKey(); /* Close the previous key before */ + } + if (openKey(stdInput) != ERROR_SUCCESS) { + _tprintf(_T("doSetValue failed to open key %s\n"), stdInput); + } + } else if ((bTheKeyIsOpen) && + ((stdInput[0] == _T('@')) || /* reading a default @=data pair */ + (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */ + processSetValue(stdInput); + } else { /* since we are assuming that the file format is */ + if (bTheKeyIsOpen) /* valid we must be reading a blank line which */ + closeKey(); /* indicate end of this key processing */ + } +} + +/****************************************************************************** + * This funtion is the main entry point to the queryValue type of action. It + * receives the currently read line and dispatch the work depending on the + * context. + */ +void doQueryValue(LPTSTR stdInput) { + /* + * We encoutered the end of the file, make sure we + * close the opened key and exit + */ + if (stdInput == NULL) { + if (bTheKeyIsOpen != FALSE) + closeKey(); + return; + } + + if (stdInput[0] == _T('[')) { /* We are reading a new key */ + if (bTheKeyIsOpen != FALSE) + closeKey(); /* Close the previous key before */ + if (openKey(stdInput) != ERROR_SUCCESS ) { + _tprintf(_T("doQueryValue failed to open key %s\n"), stdInput); + } + } + else if( (bTheKeyIsOpen) && + ((stdInput[0] == _T('@')) || /* reading a default @=data pair */ + (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */ + processQueryValue(stdInput); + } else { /* since we are assuming that the file format is */ + if (bTheKeyIsOpen) /* valid we must be reading a blank line which */ + closeKey(); /* indicate end of this key processing */ + } +} + +/****************************************************************************** + * This funtion is the main entry point to the deletetValue type of action. It + * receives the currently read line and dispatch the work depending on the + * context. + */ +void doDeleteValue(LPTSTR line) { + _tprintf(_T("deleteValue not yet implemented\n")); +} + +/****************************************************************************** + * This funtion is the main entry point to the deleteKey type of action. It + * receives the currently read line and dispatch the work depending on the + * context. + */ +void doDeleteKey(LPTSTR line) { + _tprintf(_T("deleteKey not yet implemented\n")); +} + +/****************************************************************************** + * This funtion is the main entry point to the createKey type of action. It + * receives the currently read line and dispatch the work depending on the + * context. + */ +void doCreateKey(LPTSTR line) { + _tprintf(_T("createKey not yet implemented\n")); +} + +/****************************************************************************** + * This function is a wrapper for the setValue function. It prepares the + * land and clean the area once completed. + * Note: this function modifies the line parameter. + * + * line - registry file unwrapped line. Should have the registry value name and + * complete registry value data. + */ +void processSetValue(LPTSTR line) +{ + LPTSTR val_name; /* registry value name */ + LPTSTR val_data; /* registry value data */ + + int line_idx = 0; /* current character under analysis */ + HRESULT hRes = 0; + + /* get value name */ + if (line[line_idx] == _T('@') && line[line_idx + 1] == _T('=')) { + line[line_idx] = _T('\0'); + val_name = line; + line_idx++; + } else if (line[line_idx] == _T('\"')) { + line_idx++; + val_name = line + line_idx; + while (TRUE) { + if (line[line_idx] == _T('\\')) { /* skip escaped character */ + line_idx += 2; + } else { + if (line[line_idx] == _T('\"')) { + line[line_idx] = _T('\0'); + line_idx++; + break; + } else { + line_idx++; + } + } + } + if (line[line_idx] != _T('=')) { + line[line_idx] = _T('\"'); + _tprintf(_T("Warning! uncrecognized line:\n%s\n"), line); + return; + } + } else { + _tprintf(_T("Warning! unrecognized line:\n%s\n"), line); + return; + } + line_idx++; /* skip the '=' character */ + val_data = line + line_idx; + REGPROC_unescape_string(val_name); + + _tprintf(_T("Key: %s, Value: %s, Data: %s\n"), currentKeyName, val_name, val_data); + + hRes = setValue(val_name, val_data); + if (hRes != ERROR_SUCCESS) { + _tprintf(_T("ERROR Key %s not created. Value: %s, Data: %s\n"), currentKeyName, val_name, val_data); + } +} + +/****************************************************************************** + * This function is a wrapper for the queryValue function. It prepares the + * land and clean the area once completed. + */ +void processQueryValue(LPTSTR cmdline) +{ + _tprintf(_T("ERROR!!! - temporary disabled")); + //exit(1); + return; +#if 0 + LPSTR argv[QUERY_VALUE_MAX_ARGS];/* args storage */ + LPSTR token = NULL; /* current token analized */ + ULONG argCounter = 0; /* counter of args */ + INT counter; + HRESULT hRes = 0; + LPSTR keyValue = NULL; + LPSTR lpsRes = NULL; + + /* + * Init storage and parse the line + */ + for (counter = 0; counter < QUERY_VALUE_MAX_ARGS; counter++) + argv[counter] = NULL; + + while ((token = getToken(&cmdline, queryValueDelim[argCounter])) != NULL) { + argv[argCounter++] = getArg(token); + if (argCounter == QUERY_VALUE_MAX_ARGS) + break; /* Stop processing args no matter what */ + } + + /* The value we look for is the first token on the line */ + if (argv[0] == NULL) + return; /* SHOULD NOT HAPPEN */ + else + keyValue = argv[0]; + + if ((keyValue[0] == '@') && (_tcslen(keyValue) == 1)) { + LONG lLen = KEY_MAX_LEN; + TCHAR* lpsData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,KEY_MAX_LEN); + /* + * We need to query the key default value + */ + hRes = RegQueryValue(currentKeyHandle, currentKeyName, (LPBYTE)lpsData, &lLen); + if (hRes == ERROR_MORE_DATA) { + lpsData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpsData, lLen); + hRes = RegQueryValue(currentKeyHandle, currentKeyName, (LPBYTE)lpsData, &lLen); + } + if (hRes == ERROR_SUCCESS) { + lpsRes = HeapAlloc(GetProcessHeap(), 0, lLen); + strncpy(lpsRes, lpsData, lLen); + lpsRes[lLen-1]='\0'; + } + } else { + DWORD dwLen = KEY_MAX_LEN; + BYTE* lpbData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KEY_MAX_LEN); + DWORD dwType; + /* + * We need to query a specific value for the key + */ + hRes = RegQueryValueEx( + currentKeyHandle, + keyValue, + 0, + &dwType, + (LPBYTE)lpbData, + &dwLen); + + if (hRes == ERROR_MORE_DATA) { + lpbData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpbData, dwLen * sizeof(TCHAR)); + hRes = RegQueryValueEx(currentKeyHandle, keyValue, NULL, &dwType, (LPBYTE)lpbData, &dwLen); + } + + if (hRes == ERROR_SUCCESS) { + /* + * Convert the returned data to a displayable format + */ + switch (dwType) { + case REG_SZ: + case REG_EXPAND_SZ: + lpsRes = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(TCHAR)); + strncpy(lpsRes, lpbData, dwLen); + lpsRes[dwLen-1] = '\0'; + break; + case REG_DWORD: + lpsRes = convertHexToDWORDStr(lpbData, dwLen); + break; + default: + lpsRes = convertHexToHexCSV(lpbData, dwLen); + break; + } + } + + HeapFree(GetProcessHeap(), 0, lpbData); + } + if (hRes == ERROR_SUCCESS) { + _tprintf(_T("Value \"%s\" = \"%s\" in key [%s]\n"), keyValue, lpsRes, currentKeyName); + + } else { + _tprintf(_T("ERROR Value \"%s\" not found. for key \"%s\"\n"), keyValue, currentKeyName); + } + + /* + * Do some cleanup + */ + for (counter=0; counter= line && s <= line + lineSize); + size_remaining = lineSize - (s-line); + if (size_remaining < 2) { /* room for 1 character and the \0 */ + TCHAR *new_buffer; + size_t new_size = lineSize + REG_VAL_BUF_SIZE; + if (new_size > lineSize) /* no arithmetic overflow */ + new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size * sizeof(TCHAR)); + else + new_buffer = NULL; + CHECK_ENOUGH_MEMORY(new_buffer); + line = new_buffer; + s = line + lineSize - size_remaining; + lineSize = new_size; + size_remaining = lineSize - (s-line); + } + + /* Get as much as possible into the buffer, terminated either by + * eof, error, eol or getting the maximum amount. Abort on error. + */ +// +// This line is surely foobar, don't want to read INT_MAX in buffer at s, it's never going to be that big... +// size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining); +// +// Looks as if 'lineSize' contains the number of characters of buffer size +// + size_to_get = (size_remaining > lineSize ? lineSize : size_remaining); + + if (NULL == _fgetts(s, size_to_get, in)) { + if (ferror(in)) { + //_tperror(_T("While reading input")); + perror ("While reading input"); + //exit(IO_ERROR); + return; + } else { + assert (feof(in)); + *s = _T('\0'); + /* It is not clear to me from the definition that the + * contents of the buffer are well defined on detecting + * an eof without managing to read anything. + */ + } + } + + /* If we didn't read the eol nor the eof go around for the rest */ + s_eol = _tcschr (s, _T('\n')); + if (!feof (in) && !s_eol) { + s = _tcschr (s, _T('\0')); + /* It should be s + size_to_get - 1 but this is safer */ + continue; + } + + /* If it is a comment line then discard it and go around again */ + if (line [0] == _T('#')) { + s = line; + continue; + } + + /* Remove any line feed. Leave s_eol on the \0 */ + if (s_eol) { + *s_eol = _T('\0'); + if (s_eol > line && *(s_eol-1) == _T('\r')) + *--s_eol = _T('\0'); + } else { + s_eol = _tcschr (s, _T('\0')); + } + /* If there is a concatenating \\ then go around again */ + if (s_eol > line && *(s_eol-1) == _T('\\')) { + int c; + s = s_eol-1; + /* The following error protection could be made more self- + * correcting but I thought it not worth trying. + */ + + if ((c = _fgettc(in)) == _TEOF || c != _T(' ') || + (c = _fgettc(in)) == _TEOF || c != _T(' ')) + _tprintf(_T("ERROR - invalid continuation.\n")); + continue; + } + break; /* That is the full virtual line */ + } + command(line); + } + command(NULL); + HeapFree(GetProcessHeap(), 0, line); +} + +/****************************************************************************** + * This funtion is the main entry point to the registerDLL action. It + * receives the currently read line, then loads and registers the requested DLLs + */ +void doRegisterDLL(LPTSTR stdInput) +{ + HMODULE theLib = 0; + UINT retVal = 0; + + /* Check for valid input */ + if (stdInput == NULL) return; + + /* Load and register the library, then free it */ + theLib = LoadLibrary(stdInput); + if (theLib) { + FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllRegisterServer"); + if (lpfnDLLRegProc) { + retVal = (*lpfnDLLRegProc)(); + } else { + _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput); + } + if (retVal != S_OK) { + _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput); + } + FreeLibrary(theLib); + } else { + _tprintf(_T("Could not load DLL '%s'.\n"), stdInput); + } +} + +/****************************************************************************** + * This funtion is the main entry point to the unregisterDLL action. It + * receives the currently read line, then loads and unregisters the requested DLLs + */ +void doUnregisterDLL(LPTSTR stdInput) +{ + HMODULE theLib = 0; + UINT retVal = 0; + + /* Check for valid input */ + if (stdInput == NULL) return; + + /* Load and unregister the library, then free it */ + theLib = LoadLibrary(stdInput); + if (theLib) { + FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllUnregisterServer"); + if (lpfnDLLRegProc) { + retVal = (*lpfnDLLRegProc)(); + } else { + _tprintf(_T("Couldn't find DllUnregisterServer proc in '%s'.\n"), stdInput); + } + if (retVal != S_OK) { + _tprintf(_T("DLLUnregisterServer error 0x%x in '%s'.\n"), retVal, stdInput); + } + FreeLibrary(theLib); + } else { + _tprintf(_T("Could not load DLL '%s'.\n"), stdInput); + } +} + +/**************************************************************************** + * REGPROC_print_error + * + * Print the message for GetLastError + */ + +void REGPROC_print_error(VOID) +{ + LPVOID lpMsgBuf; + DWORD error_code; + int status; + + error_code = GetLastError (); + status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL); + if (!status) { + _tprintf(_T("Cannot display message for error %ld, status %ld\n"), error_code, GetLastError()); + } else { + _tprintf(_T("REGPROC_print_error() - ")); + puts(lpMsgBuf); + LocalFree((HLOCAL)lpMsgBuf); + } + //exit(1); +} + +/****************************************************************************** + * Checks whether the buffer has enough room for the string or required size. + * Resizes the buffer if necessary. + * + * Parameters: + * buffer - pointer to a buffer for string + * len - current length of the buffer in characters. + * required_len - length of the string to place to the buffer in characters. + * The length does not include the terminating null character. + */ +void REGPROC_resize_char_buffer(TCHAR **buffer, DWORD *len, DWORD required_len) +{ + required_len++; + if (required_len > *len) { + *len = required_len; + *buffer = HeapReAlloc(GetProcessHeap(), 0, *buffer, *len * sizeof(**buffer)); + CHECK_ENOUGH_MEMORY(*buffer); + } +} + +/****************************************************************************** + * Prints string str to file + */ +void REGPROC_export_string(FILE *file, TCHAR *str) +{ + size_t len = _tcslen(str); + size_t i; + + /* escaping characters */ + for (i = 0; i < len; i++) { + TCHAR c = str[i]; + switch (c) { + //case _T('\\'): _fputts(_T("\\\\"), file); break; + case _T('\"'): _fputts(_T("\\\""), file); break; + case _T('\n'): _fputts(_T("\\\n"), file); break; + default: _fputtc(c, file); break; + } + } +} + +/****************************************************************************** + * Writes contents of the registry key to the specified file stream. + * + * Parameters: + * file - writable file stream to export registry branch to. + * key - registry branch to export. + * reg_key_name_buf - name of the key with registry class. + * Is resized if necessary. + * reg_key_name_len - length of the buffer for the registry class in characters. + * val_name_buf - buffer for storing value name. + * Is resized if necessary. + * val_name_len - length of the buffer for storing value names in characters. + * val_buf - buffer for storing values while extracting. + * Is resized if necessary. + * val_size - size of the buffer for storing values in bytes. + */ +void export_hkey(FILE *file, HKEY key, + TCHAR **reg_key_name_buf, DWORD *reg_key_name_len, + TCHAR **val_name_buf, DWORD *val_name_len, + BYTE **val_buf, DWORD *val_size) +{ + DWORD max_sub_key_len; + DWORD max_val_name_len; + DWORD max_val_size; + DWORD curr_len; + DWORD i; + BOOL more_data; + LONG ret; + + /* get size information and resize the buffers if necessary */ + if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, &max_sub_key_len, NULL, + NULL, &max_val_name_len, &max_val_size, NULL, NULL) != ERROR_SUCCESS) { + REGPROC_print_error(); + } + curr_len = _tcslen(*reg_key_name_buf); + REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1); + REGPROC_resize_char_buffer(val_name_buf, val_name_len, max_val_name_len); + if (max_val_size > *val_size) { + *val_size = max_val_size; + *val_buf = HeapReAlloc(GetProcessHeap(), 0, *val_buf, *val_size * sizeof(TCHAR)); + CHECK_ENOUGH_MEMORY(val_buf); + } + /* output data for the current key */ + _fputts(_T("\n["), file); + _fputts(*reg_key_name_buf, file); + _fputts(_T("]\n"), file); + /* print all the values */ + i = 0; + more_data = TRUE; + while (more_data) { + DWORD value_type; + DWORD val_name_len1 = *val_name_len; + DWORD val_size1 = *val_size; + ret = RegEnumValue(key, i, *val_name_buf, &val_name_len1, NULL, &value_type, *val_buf, &val_size1); + if (ret != ERROR_SUCCESS) { + more_data = FALSE; + if (ret != ERROR_NO_MORE_ITEMS) { + REGPROC_print_error(); + } + } else { + i++; + if ((*val_name_buf)[0]) { + _fputts(_T("\""), file); + REGPROC_export_string(file, *val_name_buf); + _fputts(_T("\"="), file); + } else { + _fputts(_T("@="), file); + } + switch (value_type) { + case REG_EXPAND_SZ: + _fputts(_T("expand:"), file); + case REG_SZ: + _fputts(_T("\""), file); + REGPROC_export_string(file, *val_buf); + _fputts(_T("\"\n"), file); + break; + case REG_DWORD: + _ftprintf(file, _T("dword:%08lx\n"), *((DWORD *)*val_buf)); + break; + default: +/* + _tprintf(_T("warning - unsupported registry format '%ld', ") \ + _T("treating as binary\n"), value_type); + _tprintf(_T("key name: \"%s\"\n"), *reg_key_name_buf); + _tprintf(_T("value name:\"%s\"\n\n"), *val_name_buf); + */ + /* falls through */ + case REG_MULTI_SZ: + /* falls through */ + case REG_BINARY: + { + DWORD i1; + TCHAR *hex_prefix; + TCHAR buf[20]; + int cur_pos; + + if (value_type == REG_BINARY) { + hex_prefix = _T("hex:"); + } else { + hex_prefix = buf; + _stprintf(buf, _T("hex(%ld):"), value_type); + } + /* position of where the next character will be printed */ + /* NOTE: yes, _tcslen("hex:") is used even for hex(x): */ + cur_pos = _tcslen(_T("\"\"=")) + _tcslen(_T("hex:")) + + _tcslen(*val_name_buf); + _fputts(hex_prefix, file); + for (i1 = 0; i1 < val_size1; i1++) { + _ftprintf(file, _T("%02x"), (unsigned int)(*val_buf)[i1]); + if (i1 + 1 < val_size1) { + _fputts(_T(","), file); + } + cur_pos += 3; + /* wrap the line */ + if (cur_pos > REG_FILE_HEX_LINE_LEN) { + _fputts(_T("\\\n "), file); + cur_pos = 2; + } + } + _fputts(_T("\n"), file); + break; + } + } + } + } + i = 0; + more_data = TRUE; + (*reg_key_name_buf)[curr_len] = _T('\\'); + while (more_data) { + DWORD buf_len = *reg_key_name_len - curr_len; + ret = RegEnumKeyEx(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) { + more_data = FALSE; + if (ret != ERROR_NO_MORE_ITEMS) { + REGPROC_print_error(); + } + } else { + HKEY subkey; + + i++; + if (RegOpenKey(key, *reg_key_name_buf + curr_len + 1, &subkey) == ERROR_SUCCESS) { + export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len, val_name_buf, val_name_len, val_buf, val_size); + RegCloseKey(subkey); + } else { + REGPROC_print_error(); + } + } + } + (*reg_key_name_buf)[curr_len] = _T('\0'); +} +/* +#define REG_NONE ( 0 ) // No value type +#define REG_SZ ( 1 ) // Unicode nul terminated string +#define REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string + // (with environment variable references) +#define REG_BINARY ( 3 ) // Free form binary +#define REG_DWORD ( 4 ) // 32-bit number +#define REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD) +#define REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number +#define REG_LINK ( 6 ) // Symbolic Link (unicode) +#define REG_MULTI_SZ ( 7 ) // Multiple Unicode strings +#define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map +#define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description +#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 ) + + */ +/****************************************************************************** + * Open file for export. + */ +FILE *REGPROC_open_export_file(TCHAR *file_name) +{ +//_CRTIMP FILE * __cdecl _wfopen(const wchar_t *, const wchar_t *); + +//FILE* fopen (const char* szFileName, const char* szMode); +//FILE* _wfopen(const wchar_t *file, const wchar_t *mode); + + FILE *file = _tfopen(file_name, _T("w")); + if (!file) { + perror(""); + _tprintf(_T("REGPROC_open_export_file(%s) - Can't open file.\n"), file_name); + //exit(1); + return NULL; + } + _fputts(_T("REGEDIT4\n"), file); + return file; +} + +/****************************************************************************** + * Writes contents of the registry key to the specified file stream. + * + * Parameters: + * file_name - name of a file to export registry branch to. + * reg_key_name - registry branch to export. The whole registry is exported if + * reg_key_name is NULL or contains an empty string. + */ +BOOL export_registry_key(TCHAR* file_name, TCHAR* reg_key_name) +{ + HKEY reg_key_class; + + TCHAR *reg_key_name_buf; + TCHAR *val_name_buf; + BYTE *val_buf; + DWORD reg_key_name_len = KEY_MAX_LEN; + DWORD val_name_len = KEY_MAX_LEN; + DWORD val_size = REG_VAL_BUF_SIZE; + FILE *file = NULL; + + //_tprintf(_T("export_registry_key(%s, %s)\n"), reg_key_name, file_name); + + reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_len * sizeof(*reg_key_name_buf)); + val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_len * sizeof(*val_name_buf)); + val_buf = HeapAlloc(GetProcessHeap(), 0, val_size); + CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf); + + if (reg_key_name && reg_key_name[0]) { + TCHAR *branch_name; + HKEY key; + + REGPROC_resize_char_buffer(®_key_name_buf, ®_key_name_len, + _tcslen(reg_key_name)); + _tcscpy(reg_key_name_buf, reg_key_name); + + /* open the specified key */ + reg_key_class = getRegClass(reg_key_name); + if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) { + _tprintf(_T("Incorrect registry class specification in '%s\n"), reg_key_name); + //exit(1); + return FALSE; + } + branch_name = getRegKeyName(reg_key_name); + CHECK_ENOUGH_MEMORY(branch_name); + if (!branch_name[0]) { + /* no branch - registry class is specified */ + file = REGPROC_open_export_file(file_name); + export_hkey(file, reg_key_class, + ®_key_name_buf, ®_key_name_len, + &val_name_buf, &val_name_len, + &val_buf, &val_size); + } else if (RegOpenKey(reg_key_class, branch_name, &key) == ERROR_SUCCESS) { + file = REGPROC_open_export_file(file_name); + export_hkey(file, key, + ®_key_name_buf, ®_key_name_len, + &val_name_buf, &val_name_len, + &val_buf, &val_size); + RegCloseKey(key); + } else { + _tprintf(_T("Can't export. Registry key '%s does not exist!\n"), reg_key_name); + REGPROC_print_error(); + } + HeapFree(GetProcessHeap(), 0, branch_name); + } else { + int i; + + /* export all registry classes */ + file = REGPROC_open_export_file(file_name); + for (i = 0; i < REG_CLASS_NUMBER; i++) { + /* do not export HKEY_CLASSES_ROOT */ + if (reg_class_keys[i] != HKEY_CLASSES_ROOT && + reg_class_keys[i] != HKEY_CURRENT_USER && + reg_class_keys[i] != HKEY_CURRENT_CONFIG) { + _tcscpy(reg_key_name_buf, reg_class_names[i]); + export_hkey(file, reg_class_keys[i], + ®_key_name_buf, ®_key_name_len, + &val_name_buf, &val_name_len, + &val_buf, &val_size); + } + } + } + if (file) { + fclose(file); + } +// HeapFree(GetProcessHeap(), 0, reg_key_name); + HeapFree(GetProcessHeap(), 0, val_buf); + HeapFree(GetProcessHeap(), 0, val_name_buf); + HeapFree(GetProcessHeap(), 0, reg_key_name_buf); + return TRUE; +} + +/****************************************************************************** + * Reads contents of the specified file into the registry. + */ +BOOL import_registry_file(LPTSTR filename) +{ + FILE* reg_file = _tfopen(filename, _T("r")); + + if (reg_file) { + processRegLines(reg_file, doSetValue); + return TRUE; + } + return FALSE; +} + +/****************************************************************************** + * Recursive function which removes the registry key with all subkeys. + */ +BOOL delete_branch(HKEY key, TCHAR** reg_key_name_buf, DWORD* reg_key_name_len) +{ + HKEY branch_key; + DWORD max_sub_key_len; + DWORD subkeys; + DWORD curr_len; + LONG ret; + long int i; + + if (RegOpenKey(key, *reg_key_name_buf, &branch_key) != ERROR_SUCCESS) { + REGPROC_print_error(); + return FALSE; + } + + /* get size information and resize the buffers if necessary */ + if (RegQueryInfoKey(branch_key, NULL, NULL, NULL, &subkeys, &max_sub_key_len, + NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { + REGPROC_print_error(); + RegCloseKey(branch_key); + return FALSE; + } + curr_len = _tcslen(*reg_key_name_buf); + REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1); + + (*reg_key_name_buf)[curr_len] = '\\'; + for (i = subkeys - 1; i >= 0; i--) { + DWORD buf_len = *reg_key_name_len - curr_len; + ret = RegEnumKeyEx(branch_key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA && ret != ERROR_NO_MORE_ITEMS) { + REGPROC_print_error(); + RegCloseKey(branch_key); + return FALSE; + } else { + delete_branch(key, reg_key_name_buf, reg_key_name_len); + } + } + (*reg_key_name_buf)[curr_len] = '\0'; + RegCloseKey(branch_key); + RegDeleteKey(key, *reg_key_name_buf); + return TRUE; +} + +/****************************************************************************** + * Removes the registry key with all subkeys. Parses full key name. + * + * Parameters: + * reg_key_name - full name of registry branch to delete. Ignored if is NULL, + * empty, points to register key class, does not exist. + */ +void delete_registry_key(TCHAR* reg_key_name) +{ + TCHAR* branch_name; + DWORD branch_name_len; + HKEY reg_key_class; + HKEY branch_key; + + if (!reg_key_name || !reg_key_name[0]) { + return; + } + /* open the specified key */ + reg_key_class = getRegClass(reg_key_name); + if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) { + _tprintf(_T("Incorrect registry class specification in '%s'\n"), reg_key_name); + //exit(1); + return; + } + branch_name = getRegKeyName(reg_key_name); + CHECK_ENOUGH_MEMORY(branch_name); + branch_name_len = _tcslen(branch_name); + if (!branch_name[0]) { + _tprintf(_T("Can't delete registry class '%s'\n"), reg_key_name); + //exit(1); + return; + } + if (RegOpenKey(reg_key_class, branch_name, &branch_key) == ERROR_SUCCESS) { + /* check whether the key exists */ + RegCloseKey(branch_key); + delete_branch(reg_key_class, &branch_name, &branch_name_len); + } + HeapFree(GetProcessHeap(), 0, branch_name); +} + diff --git a/apps/tests/regdump/regproc.h b/apps/tests/regdump/regproc.h new file mode 100644 index 0000000..70215a1 --- /dev/null +++ b/apps/tests/regdump/regproc.h @@ -0,0 +1,110 @@ +/* + * Copyright 1999 Sylvain St-Germain + * Copyright 2002 Andriy Palamarchuk + * + * 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 + */ + +/****************************************************************************** + * Defines and consts + */ +#define KEY_MAX_LEN 1024 + +/* Return values */ +#define SUCCESS 0 +#define KEY_VALUE_ALREADY_SET 2 + +typedef void (*CommandAPI)(LPTSTR lpsLine); + +void doSetValue(LPTSTR lpsLine); +void doDeleteValue(LPTSTR lpsLine); +void doCreateKey(LPTSTR lpsLine); +void doDeleteKey(LPTSTR lpsLine); +void doQueryValue(LPTSTR lpsLine); +void doRegisterDLL(LPTSTR lpsLine); +void doUnregisterDLL(LPTSTR lpsLine); + +BOOL export_registry_key(TCHAR* file_name, TCHAR* reg_key_name); +BOOL import_registry_file(LPTSTR filename); +void delete_registry_key(TCHAR* reg_key_name); + +void processRegLines(FILE* in, CommandAPI command); + +/* + * Generic prototypes + */ +#ifdef _UNICODE +#define get_file_name get_file_nameW +#else +#define get_file_name get_file_nameA +#endif + +char* getToken(char** str, const char* delims); +void get_file_nameA(CHAR** command_line, CHAR* filename, int max_filename); +void get_file_nameW(CHAR** command_line, WCHAR* filename, int max_filename); +DWORD convertHexToDWord(TCHAR* str, BYTE* buf); +DWORD convertHexCSVToHex(TCHAR* str, BYTE* buf, ULONG bufLen); +LPTSTR convertHexToHexCSV(BYTE* buf, ULONG len); +LPTSTR convertHexToDWORDStr(BYTE* buf, ULONG len); +LPTSTR getRegKeyName(LPTSTR lpLine); +HKEY getRegClass(LPTSTR lpLine); +DWORD getDataType(LPTSTR* lpValue, DWORD* parse_type); +LPTSTR getArg(LPTSTR arg); +HRESULT openKey(LPTSTR stdInput); +void closeKey(VOID); + +/* + * api setValue prototypes + */ +void processSetValue(LPTSTR cmdline); +HRESULT setValue(LPTSTR val_name, LPTSTR val_data); + +/* + * api queryValue prototypes + */ +void processQueryValue(LPTSTR cmdline); + +#ifdef __GNUC__ +#ifdef WIN32_REGDBG +//typedef UINT_PTR SIZE_T, *PSIZE_T; +//#define _MAX_PATH 260 /* max. length of full pathname */ +#endif /*WIN32_REGDBG*/ + +#ifdef UNICODE +#define _tfopen _wfopen +#else +#define _tfopen fopen +#endif + +#endif /*__GNUC__*/ + +LPVOID RegHeapAlloc( + HANDLE hHeap, // handle to private heap block + DWORD dwFlags, // heap allocation control + SIZE_T dwBytes // number of bytes to allocate +); + +LPVOID RegHeapReAlloc( + HANDLE hHeap, // handle to heap block + DWORD dwFlags, // heap reallocation options + LPVOID lpMem, // pointer to memory to reallocate + SIZE_T dwBytes // number of bytes to reallocate +); + +BOOL RegHeapFree( + HANDLE hHeap, // handle to heap + DWORD dwFlags, // heap free options + LPVOID lpMem // pointer to memory +); diff --git a/apps/tests/regtest/.cvsignore b/apps/tests/regtest/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/tests/regtest/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/tests/regtest/regtest.c b/apps/tests/regtest/regtest.c index 88e11b2..d137e5f 100644 --- a/apps/tests/regtest/regtest.c +++ b/apps/tests/regtest/regtest.c @@ -51,7 +51,7 @@ void do_enumeratekey(PWSTR Name) void test1(void) { - HKEY hKey = NULL,hKey1; + HKEY hKey = NULL, hKey1; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry"); @@ -128,17 +128,17 @@ void test1(void) dprintf("\t\t\t\tStatus =%x\n",Status); if (Status == STATUS_SUCCESS) { - dprintf("\tValue:DO=%d, DL=%d, NL=%d, Name = " - ,KeyValueInformation[0].DataOffset - ,KeyValueInformation[0].DataLength - ,KeyValueInformation[0].NameLength); - for (i=0;i<10 && i +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, + LPTSTR lpCmdLine, int nCmdShow) +{ + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = HInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = + reinterpret_cast(COLOR_BTNFACE + 1); + wc.lpszClassName = WndClassName; + + if (RegisterClass(&wc)) + { + HWND HWnd = + CreateWindow(WndClassName, TEXT("WM_PAINT Demo"), + WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, 200, 150, + NULL, NULL, HInstance, NULL); + + if (HWnd) + { + ShowWindow(HWnd, nCmdShow); + UpdateWindow(HWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} +//------------------------------------------------------------------ + + +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam) +{ + switch (Msg) + { + case WM_PAINT: + { + // determine the invalidated area of the window + RECT RUpdate; + GetUpdateRect(HWnd, &RUpdate, false); + + // grab a handle to our window's + // common display device context + HDC Hdc = GetDC(HWnd); +#if 0 + try +#endif + { + RECT RClient; + GetClientRect(HWnd, &RClient); + + // set the clipping region + IntersectClipRect(Hdc, RUpdate.left, RUpdate.top, + RUpdate.right, RUpdate.bottom); + + // fill the client area with the background brush + HBRUSH HBrush = + reinterpret_cast( + GetClassLong(HWnd, GCL_HBRBACKGROUND) + ); + FillRect(Hdc, &RClient, HBrush); + + // render the persistent text + const char* text = "Persistent Text"; + SetTextColor(Hdc, PALETTERGB(0, 0, 255)); + DrawText(Hdc, text, strlen(text), &RClient, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + } +#if 0 + catch (...) +#endif + { + // release the device context + ReleaseDC(HWnd, Hdc); + + // validate the update area + ValidateRect(HWnd, &RUpdate); + } + // release the device context + ReleaseDC(HWnd, Hdc); + + // validate the update area + ValidateRect(HWnd, &RUpdate); + + break; + } + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(HWnd, Msg, WParam, LParam); +} +//------------------------------------------------------------------ + diff --git a/apps/tests/wm_paint/makefile b/apps/tests/wm_paint/makefile new file mode 100644 index 0000000..c606328 --- /dev/null +++ b/apps/tests/wm_paint/makefile @@ -0,0 +1,66 @@ +# Makefile - Proj_Listing1_1.dsp + +ifndef CFG +CFG=Proj_Listing1_1 - Win32 Debug +endif +CC=gcc +CFLAGS= +CXX=g++ +CXXFLAGS=$(CFLAGS) +RC=windres -O COFF +ifeq "$(CFG)" "Proj_Listing1_1 - Win32 Release" +CFLAGS+=-fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -W +LD=$(CXX) $(CXXFLAGS) +LDFLAGS= +LDFLAGS+=-Wl,--subsystem,windows +LIBS+=-lkernel32 -luser32 -lgdi32 +else +ifeq "$(CFG)" "Proj_Listing1_1 - Win32 Debug" +CFLAGS+=-fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W +LD=$(CXX) $(CXXFLAGS) +LDFLAGS= +LDFLAGS+=-Wl,--subsystem,windows +LIBS+=-lkernel32 -luser32 -lgdi32 +endif +endif + +ifndef TARGET +TARGET=WM_PAINT.exe +endif + +.PHONY: all +all: $(TARGET) + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< + +%.o: %.cpp + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $< + +%.res: %.rc + $(RC) $(CPPFLAGS) -o $@ -i $< + +SOURCE_FILES= \ + Listing1_1.cpp + +HEADER_FILES= + +RESOURCE_FILES= + +SRCS=$(SOURCE_FILES) $(HEADER_FILES) $(RESOURCE_FILES) + +OBJS=$(patsubst %.rc,%.res,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(filter %.c %.cpp %.rc,$(SRCS))))) + +$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +.PHONY: clean +clean: + -del $(OBJS) $(TARGET) + +.PHONY: depends +depends: + -$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $(filter %.c %.cpp,$(SRCS)) > Proj_Listing1_1.dep + +-include Proj_Listing1_1.dep + diff --git a/apps/testsets/Makefile b/apps/testsets/Makefile new file mode 100644 index 0000000..8aaf049 --- /dev/null +++ b/apps/testsets/Makefile @@ -0,0 +1,188 @@ +# +# ReactOS system testsets makefile +# + +PATH_TO_TOP = ../.. + +include $(PATH_TO_TOP)/rules.mak + + +# Testset applications +TEST_SETS = loadlib + +TEST_KERNEL32 = + +TEST_MSVCRT = + +TEST_COM = + +TEST_SEH = + +TEST_REGRESSIONS = + +all: $(TEST_SETS) $(TEST_KERNEL32) $(TEST_MSVCRT) $(TEST_COM) $(TEST_SEH) $(TEST_REGRESSIONS) + +depends: + +implib: $(TEST_SETS:%=%_implib) \ + $(TEST_KERNEL32:%=%_implib) \ + $(TEST_MSVCRT:%=%_implib) \ + $(TEST_COM:%=%_implib) \ + $(TEST_SEH:%=%_implib) \ + $(TEST_REGRESSIONS:%=%_implib) + +clean: $(TEST_SETS:%=%_clean) \ + $(TEST_KERNEL32:%=%_clean) \ + $(TEST_MSVCRT:%=%_clean) \ + $(TEST_COM:%=%_clean) \ + $(TEST_SEH:%=%_clean) \ + $(TEST_REGRESSIONS:%=%_clean) + +install: $(TEST_SETS:%=%_install) \ + $(TEST_KERNEL32:%=%_install) \ + $(TEST_MSVCRT:%=%_install) \ + $(TEST_COM:%=%_install) \ + $(TEST_SEH:%=%_install) \ + $(TEST_REGRESSIONS:%=%_install) + +dist: $(TEST_SETS:%=%_dist) \ + $(TEST_KERNEL32:%=%_dist) \ + $(TEST_MSVCRT:%=%_dist) \ + $(TEST_COM:%=%_dist) \ + $(TEST_SEH:%=%_dist) \ + $(TEST_REGRESSIONS:%=%_dist) + +.PHONY: all depends implib clean install dist + + +# +# Testset Applications +# +$(TEST_SETS): %: + make -C $* + +$(TEST_SETS:%=%_implib): %_implib: + make -C $* implib + +$(TEST_SETS:%=%_clean): %_clean: + make -C $* clean + +$(TEST_SETS:%=%_dist): %_dist: + make -C $* dist + +$(TEST_SETS:%=%_install): %_install: + make -C $* install + +.PHONY: $(TEST_SETS) $(TEST_SETS:%=%_implib) $(TEST_SETS:%=%_clean) $(TEST_SETS:%=%_install) $(TEST_SETS:%=%_dist) + + +# +# Kernel32 Test Applications +# +$(TEST_KERNEL32): %: + make -C kernel32/$* + +$(TEST_KERNEL32:%=%_implib): %_implib: + make -C kernel32/$* implib + +$(TEST_KERNEL32:%=%_clean): %_clean: + make -C kernel32/$* clean + +$(TEST_KERNEL32:%=%_dist): %_dist: + make -C kernel32/$* dist + +$(TEST_KERNEL32:%=%_install): %_install: + make -C kernel32/$* install + +.PHONY: $(TEST_KERNEL32) $(TEST_KERNEL32:%=%_implib) $(TEST_KERNEL32:%=%_clean) $(TEST_KERNEL32:%=%_install) $(TEST_KERNEL32:%=%_dist) + + +# +# msvcrt Test Applications +# +$(TEST_MSVCRT): %: + make -C msvcrt/$* + +$(TEST_MSVCRT:%=%_implib): %_implib: + make -C msvcrt/$* implib + +$(TEST_MSVCRT:%=%_clean): %_clean: + make -C msvcrt/$* clean + +$(TEST_MSVCRT:%=%_dist): %_dist: + make -C msvcrt/$* dist + +$(TEST_MSVCRT:%=%_install): %_install: + make -C msvcrt/$* install + +.PHONY: $(TEST_MSVCRT) $(TEST_MSVCRT:%=%_implib) $(TEST_MSVCRT:%=%_clean) $(TEST_MSVCRT:%=%_install) $(TEST_MSVCRT:%=%_dist) + + +# +# COM Test Applications +# +$(TEST_COM): %: + make -C com/$* + +$(TEST_COM:%=%_implib): %_implib: + make -C com/$* implib + +$(TEST_COM:%=%_clean): %_clean: + make -C com/$* clean + +$(TEST_COM:%=%_dist): %_dist: + make -C com/$* dist + +$(TEST_COM:%=%_install): %_install: + make -C com/$* install + +.PHONY: $(TEST_COM) $(TEST_COM:%=%_implib) $(TEST_COM:%=%_clean) $(TEST_COM:%=%_install) $(TEST_COM:%=%_dist) + + +# +# SEH Test Applications +# +$(TEST_SEH): %: + make -C seh/$* + +$(TEST_SEH:%=%_implib): %_implib: + make -C seh/$* implib + +$(TEST_SEH:%=%_clean): %_clean: + make -C seh/$* clean + +$(TEST_SEH:%=%_dist): %_dist: + make -C seh/$* dist + +$(TEST_SEH:%=%_install): %_install: + make -C seh/$* install + +.PHONY: $(TEST_SEH) $(TEST_SEH:%=%_implib) $(TEST_SEH:%=%_clean) $(TEST_SEH:%=%_install) $(TEST_SEH:%=%_dist) + + +# +# Regression Test Applications +# +$(TEST_REGRESSIONS): %: + make -C regres/$* + +$(TEST_REGRESSIONS:%=%_implib): %_implib: + make -C regres/$* implib + +$(TEST_REGRESSIONS:%=%_clean): %_clean: + make -C regres/$* clean + +$(TEST_REGRESSIONS:%=%_dist): %_dist: + make -C regres/$* dist + +$(TEST_REGRESSIONS:%=%_install): %_install: + make -C regres/$* install + +.PHONY: $(TEST_REGRESSIONS) $(TEST_REGRESSIONS:%=%_implib) $(TEST_REGRESSIONS:%=%_clean) $(TEST_REGRESSIONS:%=%_install) $(TEST_REGRESSIONS:%=%_dist) + + +etags: + find . -name "*.[ch]" -print | etags --language=c - + +# EOF + diff --git a/apps/testsets/loadlib/.cvsignore b/apps/testsets/loadlib/.cvsignore new file mode 100644 index 0000000..bd2c3a8 --- /dev/null +++ b/apps/testsets/loadlib/.cvsignore @@ -0,0 +1,9 @@ +*.o +*.d +*.exe +*.coff +*.sym +*.dsp +*.dsw +*.ncb +*.opt diff --git a/apps/testsets/loadlib/loadlib.c b/apps/testsets/loadlib/loadlib.c new file mode 100644 index 0000000..fd767c0 --- /dev/null +++ b/apps/testsets/loadlib/loadlib.c @@ -0,0 +1,222 @@ +/* + * ReactOS test program - + * + * loadlib.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include "loadlib.h" + + +#define APP_VERSION 1 +#define MAX_LIBS 25 + +#ifdef UNICODE +#define TARGET "UNICODE" +BOOL bUseAnsi = FALSE; +#else +#define TARGET "MBCS" +BOOL bUseAnsi = TRUE; +#endif +BOOL verbose_flagged = FALSE; +BOOL debug_flagged = FALSE; +BOOL loop_flagged = FALSE; +BOOL recursive_flagged = FALSE; + +HANDLE OutputHandle; +HANDLE InputHandle; + + +void dprintf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args, fmt); + wvsprintfA(buffer, fmt, args); + WriteConsoleA(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL); + va_end(args); +} + +long getinput(char* buf, int buflen) +{ + DWORD result; + + ReadConsoleA(InputHandle, buf, buflen, &result, NULL); + return (long)result; +} + +DWORD ReportLastError(void) +{ + DWORD dwError = GetLastError(); + if (dwError != ERROR_SUCCESS) { + PSTR msg = NULL; + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, dwError, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PSTR)&msg, 0, NULL)) { + if (msg != NULL) { + dprintf("ReportLastError() %d - %s\n", dwError, msg); + } else { + dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError); + } + } else { + dprintf("ReportLastError() %d - unknown error\n", dwError); + } + if (msg != NULL) { + LocalFree(msg); + } + } + return dwError; +} + +const char* appName(const char* argv0) +{ + const char* name; + + name = (const char*)strrchr(argv0, '\\'); + if (name != NULL) + return name + 1; + return argv0; +} + +int usage(const char* appName) +{ + dprintf("USAGE: %s libname [libname ...] [unicode]|[ansi] [loop][recurse]\n", appName); + dprintf("\tWhere libname(s) is one or more libraries to load.\n"); + dprintf("\t[unicode] - perform tests using UNICODE api calls\n"); + dprintf("\t[ansi] - perform tests using ANSI api calls\n"); + dprintf("\t default is %s\n", TARGET); + dprintf("\t[loop] - run test process in continuous loop\n"); + dprintf("\t[recurse] - load libraries recursively rather than sequentually\n"); + dprintf("\t[debug] - enable debug mode (unused)\n"); + dprintf("\t[verbose] - enable verbose output (unused)\n"); + return 0; +} + +DWORD LoadLibraryList(char** libnames, int counter, BOOL bUseAnsi) +{ + HMODULE hModule; + + dprintf("Attempting to LoadLibrary"); + if (bUseAnsi) { + dprintf("A(%s) - ", *libnames); + hModule = LoadLibraryA(*libnames); + } else { + int len; + wchar_t libnameW[500]; + len = mbstowcs(libnameW, *libnames, strlen(*libnames)); + if (len) { + libnameW[len] = L'\0'; + dprintf("W(%S) - ", libnameW); + hModule = LoadLibraryW(libnameW); + } else { + return ERROR_INVALID_PARAMETER; + } + } + if (hModule == NULL) { + dprintf("\nERROR: failed to obtain handle to module %s - %x\n", *libnames, hModule); + return ReportLastError(); + } + dprintf("%x\n", hModule); + + if (counter--) { + LoadLibraryList(++libnames, counter, bUseAnsi); + } + + if (!FreeLibrary(hModule)) { + dprintf("ERROR: failed to free module %s - %x\n", *libnames, hModule); + return ReportLastError(); + } else { + dprintf("FreeLibrary(%x) - successfull.\n", hModule); + } + return 0L; +} + +int __cdecl main(int argc, char* argv[]) +{ + char* libs[MAX_LIBS]; + int lib_count = 0; + int test_num = 0; + int result = 0; + int i = 0; + + AllocConsole(); + InputHandle = GetStdHandle(STD_INPUT_HANDLE); + OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + + dprintf("%s application - build %03d (default: %s)\n", appName(argv[0]), APP_VERSION, TARGET); + if (argc < 2) { + /*return */usage(appName(argv[0])); + } + memset(libs, 0, sizeof(libs)); + for (i = 1; i < argc; i++) { + if (lstrcmpiA(argv[i], "ansi") == 0) { + bUseAnsi = TRUE; + } else if (lstrcmpiA(argv[i], "unicode") == 0) { + bUseAnsi = FALSE; + } else if (lstrcmpiA(argv[i], "loop") == 0) { + loop_flagged = 1; + } else if (lstrcmpiA(argv[i], "recurse") == 0) { + recursive_flagged = 1; + } else if (lstrcmpiA(argv[i], "verbose") == 0) { + verbose_flagged = 1; + } else if (lstrcmpiA(argv[i], "debug") == 0) { + debug_flagged = 1; + } else { + if (lib_count < MAX_LIBS) { + libs[lib_count] = argv[i]; + ++lib_count; + } + } + } + if (lib_count) { + do { + if (recursive_flagged) { + result = LoadLibraryList(libs, lib_count - 1, bUseAnsi); + } else { + for (i = 0; i < lib_count; i++) { + result = LoadLibraryList(&libs[i], 0, bUseAnsi); + //if (result != 0) break; + } + } + } while (loop_flagged); + } else { + int len; + char buffer[500]; + do { + dprintf("\nEnter library name to attempt loading: "); + len = getinput(buffer, sizeof(buffer) - 1); + if (len > 2) { + char* buf = buffer; + buffer[len-2] = '\0'; + result = LoadLibraryList(&buf, 0, bUseAnsi); + } else break; + } while (!result && len); + } + dprintf("finished\n"); + return result; +} + + +#ifdef _NOCRT +char* args[] = { "loadlib.exe", "advapi32.dll", "user32.dll", "recurse"}; +int __cdecl mainCRTStartup(void) +{ + return main(3, args); +} +#endif /*__GNUC__*/ diff --git a/apps/testsets/loadlib/loadlib.h b/apps/testsets/loadlib/loadlib.h new file mode 100644 index 0000000..51210d4 --- /dev/null +++ b/apps/testsets/loadlib/loadlib.h @@ -0,0 +1,45 @@ +/* + * ReactOS test program - + * + * loadlib.h + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LOADLIB_H__ +#define __LOADLIB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +extern BOOL verbose_flagged; +extern BOOL debug_flagged; +extern BOOL loop_flagged; +extern BOOL recursive_flagged; + +DWORD ReportLastError(void); +long getinput(char* Buffer, int buflen); +void dprintf(char* fmt, ...); + + +#ifdef __cplusplus +}; +#endif + +#endif // __LOADLIB_H__ diff --git a/apps/testsets/loadlib/makefile b/apps/testsets/loadlib/makefile new file mode 100644 index 0000000..a10e244 --- /dev/null +++ b/apps/testsets/loadlib/makefile @@ -0,0 +1,24 @@ +# +# $Id: makefile,v 1.0 + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = loadlib + +#TARGET_CFLAGS = -DDBG -DUNICODE -D_UNICODE + +TARGET_SDKLIBS = kernel32.a ntdll.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/testsets/msvcrt/fileio/.cvsignore b/apps/testsets/msvcrt/fileio/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/testsets/msvcrt/fileio/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/testsets/msvcrt/fileio/_tfileio.c b/apps/testsets/msvcrt/fileio/_tfileio.c new file mode 100644 index 0000000..84d0e1a --- /dev/null +++ b/apps/testsets/msvcrt/fileio/_tfileio.c @@ -0,0 +1,421 @@ +/* + * ReactOS test program - + * + * _tfileio.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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. + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + + +#ifdef UNICODE +#define _tfopen _wfopen +#define _tunlink _wunlink +#define _TEOF WEOF +#define _gettchar getwchar +#define _puttchar putwchar +#define _THEX_FORMAT _T("0x%04x ") +#else /*UNICODE*/ +#define _tfopen fopen +#define _tunlink _unlink +#define _TEOF EOF +#define _gettchar getchar +#define _puttchar putchar +#define _THEX_FORMAT "0x%02x " +#endif /*UNICODE*/ + + +#define TEST_BUFFER_SIZE 200 +#define TEST_FILE_LINES 4 + +extern BOOL verbose_flagged; +extern BOOL status_flagged; + +static TCHAR test_buffer[TEST_BUFFER_SIZE]; + +static TCHAR dos_data[] = _T("line1: this is a bunch of readable text.\r\n")\ + _T("line2: some more printable text and punctuation !@#$%^&*()\r\n")\ + _T("line3: followed up with some numerals 1234567890\r\n")\ + _T("line4: done.\r\n"); + +static TCHAR nix_data[] = _T("line1: this is a bunch of readable text.\n")\ + _T("line2: some more printable text and punctuation !@#$%^&*()\n")\ + _T("line3: followed up with some numerals 1234567890\n")\ + _T("line4: done.\n"); + +#ifdef UNICODE +#define TEST_B1_FILE_SIZE ((((sizeof(dos_data)/2)-1)+TEST_FILE_LINES)/2) // (166+4)/2=85 +#define TEST_B2_FILE_SIZE (((sizeof(dos_data)/2)-1)*2) // (166*2) =332 +#define TEST_B3_FILE_SIZE ((((sizeof(nix_data)/2)-1)+TEST_FILE_LINES)/2) // (162+4)/2=83 +#define TEST_B4_FILE_SIZE (((sizeof(nix_data)/2)-1)*2) // (162*2) =324 +#else /*UNICODE*/ +#define TEST_B1_FILE_SIZE (sizeof(dos_data)-1+TEST_FILE_LINES) // (166+4)=170 +#define TEST_B2_FILE_SIZE (sizeof(dos_data)-1-TEST_FILE_LINES) // (166-4)=162 +#define TEST_B3_FILE_SIZE (sizeof(nix_data)-1+TEST_FILE_LINES) // (162+4)=166 +#define TEST_B4_FILE_SIZE (sizeof(nix_data)-1) // (162) =162 +#endif /*UNICODE*/ + + +// result = create_test_file(file_name, _T("wb"), _T("rb"), file_data); + +static BOOL test_file_truncate(TCHAR* file_name) +{ + BOOL result = FALSE; + int count = -1; + int error_code; + TCHAR ch; + TCHAR* file_data = _T("this file should have been truncated to zero bytes..."); + FILE *file = _tfopen(file_name, _T("wb")); + + if (verbose_flagged) { + _tprintf(_T("test_file_truncate(\"%s\")\n"), file_name); + } + + if (file != NULL) { + if (_fputts(file_data, file) != _TEOF) { + } else { + _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name); + _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); + } + fclose(file); + } else { + _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name); + _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); + } + + file = _tfopen(file_name, _T("wb")); + if (file != NULL) { + error_code = ferror(file); + if (error_code) { + _tprintf(_T("ERROR: (%s) ferror returned %d\n"), file_name, error_code); + } + fclose(file); + } else { + _tprintf(_T("ERROR: (%s) failed to open file for truncating\n"), file_name); + } + + file = _tfopen(file_name, _T("rb")); + if (file != NULL) { + count = 0; + while ((ch = _fgettc(file)) != _TEOF) { + if (verbose_flagged) { + _tprintf(_THEX_FORMAT, ch); + } + ++count; + } + error_code = ferror(file); + if (error_code) { + _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); + perror("Read error"); + } + fclose(file); + } else { + _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name); + } + if (count) { + result = TRUE; + } + return result; +} + +static BOOL create_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data) +{ + BOOL result = FALSE; + FILE *file = _tfopen(file_name, file_mode); + if (file != NULL) { + if (_fputts(file_data, file) != _TEOF) { + result = TRUE; + } else { + _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name); + _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); + } + fclose(file); + } else { + _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name); + _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); + } + return result; +} + +static BOOL verify_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data) +{ + int error_code; + int offset = 0; + int line_num = 0; + BOOL result = FALSE; + BOOL error_flagged = FALSE; + FILE* file = _tfopen(file_name, file_mode); + if (file == NULL) { + _tprintf(_T("ERROR: (%s) Can't open file for reading\n"), file_name); + _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); + return FALSE; + } else if (status_flagged) { + _tprintf(_T("STATUS: (%s) opened file for reading\n"), file_name); + } + while (_fgetts(test_buffer, TEST_BUFFER_SIZE, file)) { + int length = _tcslen(test_buffer); + int req_len = _tcschr(file_data+offset, _T('\n')) - (file_data+offset) + 1; + + ++line_num; + if (length > req_len) { + _tprintf(_T("ERROR: read excess bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len); + error_flagged = TRUE; + break; + } + if (length < req_len) { + _tprintf(_T("ERROR: read to few bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len); + error_flagged = TRUE; + break; + } + if (status_flagged) { + _tprintf(_T("STATUS: Verifying %d bytes read from line %d\n"), length, line_num); + } + if (_tcsncmp(test_buffer, file_data+offset, length - 1) == 0) { + result = TRUE; + } else { + if (status_flagged) { + int i; + _tprintf(_T("WARNING: (%s) failed to verify file\n"), file_name); + for (i = 0; i < length; i++) { + if (file_data[offset+i] != test_buffer[i]) { + _tprintf(_T("line %d, offset %d expected: 0x%04x found: 0x%04x\n"), line_num, i, (int)file_data[offset+i], (int)test_buffer[i]); + } + } + _tprintf(_T("\n")); + } else { + error_flagged = TRUE; + } + } + offset += length; + } + error_code = ferror(file); + if (error_code) { + _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); + perror("Read error"); + } + if (!line_num) { + _tprintf(_T("ERROR: (%s) failed to read from file\n"), file_name); + } + if (error_flagged == TRUE) { + _tprintf(_T("ERROR: (%s) failed to verify file\n"), file_name); + result = FALSE; + } + fclose(file); + return result; +} + +static int create_test_file(TCHAR* file_name, TCHAR* write_mode, TCHAR* read_mode, TCHAR* file_data) +{ + if (status_flagged) { + _tprintf(_T("STATUS: Attempting to create output file %s\n"), file_name); + } + if (create_output_file(file_name, write_mode, file_data)) { + if (status_flagged) { + _tprintf(_T("STATUS: Attempting to verify output file %s\n"), file_name); + } + if (verify_output_file(file_name, read_mode, file_data)) { + if (status_flagged) { + _tprintf(_T("SUCCESS: %s verified ok\n"), file_name); + } + } else { + //_tprintf(_T("ERROR: failed to verify file %s\n"), file_name); + return 2; + } + } else { + _tprintf(_T("ERROR: failed to create file %s\n"), file_name); + return 1; + } + return 0; +} + +static int check_file_size(TCHAR* file_name, TCHAR* file_mode, int expected) +{ + int count = 0; + FILE* file; + TCHAR ch; + int error_code; + + if (status_flagged) { + //_tprintf(_T("STATUS: (%s) checking for %d bytes in %s mode\n"), file_name, expected, _tcschr(file_mode, _T('b')) ? _T("binary") : _T("text")); + _tprintf(_T("STATUS: (%s) checking for %d bytes with mode %s\n"), file_name, expected, file_mode); + } + file = _tfopen(file_name, file_mode); + if (file == NULL) { + _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name); + return 1; + } + while ((ch = _fgettc(file)) != _TEOF) { + if (verbose_flagged) { + _tprintf(_THEX_FORMAT, ch); + } + ++count; + } + error_code = ferror(file); + if (error_code) { + _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); + perror("Read error"); + } + + if (verbose_flagged) { +// _puttc(_T('\n'), stdout); + } + fclose(file); + if (count == expected) { + if (status_flagged) { + _tprintf(_T("PASSED: (%s) read %d bytes\n"), file_name, count); + } + } else { + _tprintf(_T("FAILED: (%s) read %d bytes but expected %d using mode \"%s\"\n"), file_name, count, expected, file_mode); + } + return (count == expected) ? 0 : -1; +} + +static int test_console_io(void) +{ + TCHAR buffer[81]; + TCHAR ch; + int i, j; + + _tprintf(_T("Enter a line for echoing:\n")); + + //for (i = 0; (i < 80) && ((ch = _gettchar()) != _TEOF) && (ch != _T('\n')); i++) { + for (i = 0; (i < 80) && ((ch = _gettc(stdin)) != _TEOF) && (ch != _T('\n')); i++) { + buffer[i] = (TCHAR)ch; + } + buffer[i] = _T('\0'); + for (j = 0; j < i; j++) { + _puttc(buffer[j], stdout); + } + _puttc(_T('\n'), stdout); + _tprintf(_T("%s\n"), buffer); + return 0; +} + +static int test_console_getchar(void) +{ + int result = 0; + TCHAR ch; + + _tprintf(_T("Enter lines for dumping or to finish:\n")); + + //while ((ch = _gettchar()) != _TEOF) { + while ((ch = _gettc(stdin)) != _TEOF) { + _tprintf(_THEX_FORMAT, ch); + //printf("0x%04x ", ch); + } + return result; +} + +static int test_console_putch(void) +{ + int result = 0; + + _putch('1'); + _putch('@'); + _putch('3'); + _putch(':'); + _putch('\n'); + _putch('a'); + _putch('B'); + _putch('c'); + _putch(':'); + _putch('\n'); + return result; +} + +static int test_unlink_files(void) +{ + int result = 0; + + //printf("sizeof dos_data: %d\n", sizeof(dos_data)); + //printf("sizeof nix_data: %d\n", sizeof(nix_data)); + + result |= _tunlink(_T("binary.dos")); + result |= _tunlink(_T("binary.nix")); + result |= _tunlink(_T("text.dos")); + result |= _tunlink(_T("text.nix")); + return result; +} + +static int test_text_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize) +{ + int result = 0; + + result = create_test_file(file_name, _T("w"), _T("r"), file_data); + result = check_file_size(file_name, _T("r"), tsize); + result = check_file_size(file_name, _T("rb"), bsize); + return result; +} + +static int test_binary_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize) +{ + int result = 0; + + result = create_test_file(file_name, _T("wb"), _T("rb"), file_data); + result = check_file_size(file_name, _T("r"), tsize); + result = check_file_size(file_name, _T("rb"), bsize); + return result; +} + +static int test_files(int test_num, char* type) +{ + int result = 0; + + printf("performing test: %d (%s)\n", test_num, type); + + + if (test_file_truncate(_T("zerosize.foo"))) { + printf("System unable to truncate files yet, unlinking:\n"); + test_unlink_files(); + } + + switch (test_num) { + case 1: + result = test_text_fileio(_T("text.dos"), dos_data, 166, TEST_B1_FILE_SIZE); + break; + case 2: + result = test_binary_fileio(_T("binary.dos"), dos_data, TEST_B2_FILE_SIZE, 166); + break; + case 3: + result = test_text_fileio(_T("text.nix"), nix_data, 162, TEST_B3_FILE_SIZE); + break; + case 4: + result = test_binary_fileio(_T("binary.nix"), nix_data, TEST_B4_FILE_SIZE, 162); + break; + case 5: + result = test_console_io(); + break; + case 6: + result = test_console_getchar(); + break; + case 7: + result = test_console_putch(); + break; + case -1: + result = test_unlink_files(); + break; + default: + _tprintf(_T("no test number selected\n")); + break; + } + return result; +} diff --git a/apps/testsets/msvcrt/fileio/fileio.c b/apps/testsets/msvcrt/fileio/fileio.c new file mode 100644 index 0000000..ab29300 --- /dev/null +++ b/apps/testsets/msvcrt/fileio/fileio.c @@ -0,0 +1,31 @@ +/* + * ReactOS test program - + * + * _fileio.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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. + */ + +#undef UNICODE +#undef _UNICODE +#include "_tfileio.c" + + +int run_ansi_tests(int test_num) +{ + return test_files(test_num, "ANSI"); +} diff --git a/apps/testsets/msvcrt/fileio/main.c b/apps/testsets/msvcrt/fileio/main.c new file mode 100644 index 0000000..64f5476 --- /dev/null +++ b/apps/testsets/msvcrt/fileio/main.c @@ -0,0 +1,124 @@ +/* + * ReactOS test program - + * + * main.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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. + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include "main.h" + + +#define VERSION 1 + +#ifdef UNICODE +#define TARGET "UNICODE" +#else +#define TARGET "MBCS" +#endif + +BOOL verbose_flagged = 0; +BOOL status_flagged = 0; + +int usage(char* argv0) +{ + printf("USAGE: %s test_id [unicode]|[ansi] [clean]|[status][verbose]\n", argv0); + printf("\tWhere test_id is one of:\n"); + printf("\t0 - (default) regression mode, run tests 1-4 displaying failures only\n"); + printf("\t1 - Write DOS style eol data to file in text mode (text.dos)\n"); + printf("\t2 - Write NIX style eol data to file in binary mode (binary.dos)\n"); + printf("\t3 - Write DOS style eol data to file in text mode (text.nix)\n"); + printf("\t4 - Write NIX style eol data to file in binary mode (binary.nix)\n"); + printf("\t5 - Echo console line input\n"); + printf("\t6 - Dump console line input in hex format\n"); + printf("\t7 - The source code is your friend\n"); + printf("\t[unicode] - perform tests using UNICODE versions of library functions\n"); + printf("\t[ansi] - perform tests using ANSI versions of library functions\n"); + printf("\t If neither unicode or ansi is specified build default is used\n"); + printf("\t[clean] - delete all temporary test output files\n"); + printf("\t[status] - enable extra status display while running\n"); + printf("\t[verbose] - enable verbose output when running\n"); + return 0; +} + +int __cdecl main(int argc, char* argv[]) +{ + int test_num = 0; + int version = 0; + int result = 0; + int i = 0; + + printf("%s test application - build %03d (default: %s)\n", argv[0], VERSION, TARGET); + if (argc < 2) { + return usage(argv[0]); + } + for (i = 1; i < argc; i++) { + if (strstr(argv[i], "ansi") || strstr(argv[i], "ANSI")) { + version = 1; + } else if (strstr(argv[i], "unicode") || strstr(argv[i], "UNICODE")) { + version = 2; + } else if (strstr(argv[i], "clean") || strstr(argv[i], "CLEAN")) { + test_num = -1; + } else if (strstr(argv[i], "verbose") || strstr(argv[i], "VERBOSE")) { + verbose_flagged = 1; + } else if (strstr(argv[i], "status") || strstr(argv[i], "STATUS")) { + status_flagged = 1; + } else { + test_num = atoi(argv[1]); + //if (test_num < 0 + } + } + for (i = test_num; i <= test_num; i++) { + if (!test_num) { + test_num = 4; + i = 1; + } + switch (version) { + case 1: + result = run_ansi_tests(i); + break; + case 2: + result = run_unicode_tests(i); + break; + default: + result = run_ansi_tests(i); + result = run_unicode_tests(i); + break; + } + } + printf("finished\n"); + return result; +} + +#ifndef __GNUC__ + +char* args[] = { "fileio.exe", "0", "unicode", "verbose"}; + +int __cdecl mainCRTStartup(void) +{ + main(2, args); + return 0; +} + +#endif /*__GNUC__*/ diff --git a/apps/testsets/msvcrt/fileio/main.h b/apps/testsets/msvcrt/fileio/main.h new file mode 100644 index 0000000..ee20fbe --- /dev/null +++ b/apps/testsets/msvcrt/fileio/main.h @@ -0,0 +1,42 @@ +/* + * ReactOS test program - + * + * main.h + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +int app_main(int argc, char* argv[]); +DWORD GetInput(char* Buffer, int buflen); + +int test_ansi_files(int test_num); +int test_unicode_files(int test_num); + + +#ifdef __cplusplus +}; +#endif + +#endif // __MAIN_H__ diff --git a/apps/testsets/msvcrt/fileio/makefile b/apps/testsets/msvcrt/fileio/makefile new file mode 100644 index 0000000..e0a22da --- /dev/null +++ b/apps/testsets/msvcrt/fileio/makefile @@ -0,0 +1,27 @@ +# +# $Id: makefile,v 1.0 + +PATH_TO_TOP = ../../../.. + +TEST_ROOT = $(PATH_TO_TOP)/apps/testsets/test + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = fileio + +#TARGET_CFLAGS = -I$(TEST_ROOT) -DDBG -DUNICODE -D_UNICODE +TARGET_CFLAGS = -I$(TEST_ROOT) -DDBG + +TARGET_SDKLIBS = ntdll.a kernel32.a + +TARGET_OBJECTS = $(TARGET_NAME).o wfileio.o main.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/testsets/msvcrt/fileio/wfileio.c b/apps/testsets/msvcrt/fileio/wfileio.c new file mode 100644 index 0000000..5985a8a --- /dev/null +++ b/apps/testsets/msvcrt/fileio/wfileio.c @@ -0,0 +1,31 @@ +/* + * ReactOS test program - + * + * wfileio.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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. + */ + +#define UNICODE +#define _UNICODE +#include "_tfileio.c" + + +int run_unicode_tests(int test_num) +{ + return test_files(test_num, "UNICODE"); +} diff --git a/apps/utils/Makefile b/apps/utils/Makefile new file mode 100644 index 0000000..a9b1033 --- /dev/null +++ b/apps/utils/Makefile @@ -0,0 +1,82 @@ +# +# ReactOS system utilities makefile +# + +PATH_TO_TOP = ../.. + +include $(PATH_TO_TOP)/rules.mak + + +# Console system utilities +# cabman cat net objdir partinfo pice ps sc stats +UTIL_APPS = cat objdir partinfo sc stats tickcount + +UTIL_NET_APPS = + + +all: $(UTIL_APPS) $(UTIL_NET_APPS) + +depends: + +implib: $(UTIL_APPS:%=%_implib) \ + $(UTIL_NET_APPS:%=%_implib) + +clean: $(UTIL_APPS:%=%_clean) \ + $(UTIL_NET_APPS:%=%_clean) + +install: $(UTIL_APPS:%=%_install) \ + $(UTIL_NET_APPS:%=%_install) + +dist: $(UTIL_APPS:%=%_dist) \ + $(UTIL_NET_APPS:%=%_dist) + +.PHONY: all depends implib clean install dist + + +# +# Utility Applications +# +$(UTIL_APPS): %: + make -C $* + +$(UTIL_APPS:%=%_implib): %_implib: + make -C $* implib + +$(UTIL_APPS:%=%_clean): %_clean: + make -C $* clean + +$(UTIL_APPS:%=%_dist): %_dist: + make -C $* dist + +$(UTIL_APPS:%=%_install): %_install: + make -C $* install + +.PHONY: $(UTIL_APPS) $(UTIL_APPS:%=%_implib) $(UTIL_APPS:%=%_clean) $(UTIL_APPS:%=%_install) $(UTIL_APPS:%=%_dist) + + +# +# GUI Utility Applications +# +$(UTIL_NET_APPS): %: + make -C net/$* + +$(UTIL_NET_APPS:%=%_implib): %_implib: + make -C net/$* implib + +$(UTIL_NET_APPS:%=%_clean): %_clean: + make -C net/$* clean + +$(UTIL_NET_APPS:%=%_dist): %_dist: + make -C net/$* dist + +$(UTIL_NET_APPS:%=%_install): %_install: + make -C net/$* install + +.PHONY: $(UTIL_NET_APPS) $(UTIL_NET_APPS:%=%_implib) $(UTIL_NET_APPS:%=%_clean) $(UTIL_NET_APPS:%=%_install) $(UTIL_NET_APPS:%=%_dist) + + +etags: + find . -name "*.[ch]" -print | etags --language=c - + +# EOF + diff --git a/apps/utils/cabman/.cvsignore b/apps/utils/cabman/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/cabman/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/cabman/makefile b/apps/utils/cabman/makefile index 2d3a1ab..eda0930 100644 --- a/apps/utils/cabman/makefile +++ b/apps/utils/cabman/makefile @@ -4,8 +4,8 @@ PATH_TO_TOP = ../../.. #FIXME: why doesn't this work? -#ZLIB_OBJECTS = $(PATH_TO_TOP)/lib/zlib/zlib.a -ZLIB_PATH = $(PATH_TO_TOP)/lib/zlib +#ZLIB_OBJECTS = $(PATH_TO_TOP)/drivers/lib/zlib/zlib.a +ZLIB_PATH = $(PATH_TO_TOP)/drivers/lib/zlib ZLIB_OBJECTS = $(ZLIB_PATH)/adler32.o $(ZLIB_PATH)/deflate.o \ $(ZLIB_PATH)/infblock.o $(ZLIB_PATH)/infcodes.o \ @@ -53,12 +53,12 @@ $(ZLIB_PATH)/zlib.a: make -C $(ZLIB_PATH) -f makefile.reactos $(TARGET).exe: $(OBJECTS) $(ZLIB_PATH)/zlib.a - $(CC) $(OBJECTS) -o $(TARGET).exe + $(CC) $(OBJECTS) -lstdc++ -o $(TARGET).exe $(NM) --numeric-sort $(TARGET).exe > $(TARGET).sym test.exe: $(TEST_OBJECTS) - $(CC) $(TEST_OBJECTS) -o test.exe + $(CC) $(TEST_OBJECTS) -lstdc++ -o test.exe $(NM) --numeric-sort test.exe > test.sym -include ../../rules.mak +include ../../../rules.mak diff --git a/apps/utils/cat/.cvsignore b/apps/utils/cat/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/cat/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/net/ping/.cvsignore b/apps/utils/net/ping/.cvsignore index 0707518..7e87816 100644 --- a/apps/utils/net/ping/.cvsignore +++ b/apps/utils/net/ping/.cvsignore @@ -1 +1,5 @@ -ping.coff \ No newline at end of file +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/net/roshttpd/.cvsignore b/apps/utils/net/roshttpd/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/net/roshttpd/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/net/roshttpd/include/socket.h b/apps/utils/net/roshttpd/include/socket.h index af80807..06ed020 100644 --- a/apps/utils/net/roshttpd/include/socket.h +++ b/apps/utils/net/roshttpd/include/socket.h @@ -5,7 +5,7 @@ */ #ifndef __SOCKET_H #define __SOCKET_H -#include +#include #include #include #include diff --git a/apps/utils/net/telnet/.cvsignore b/apps/utils/net/telnet/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/net/telnet/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/objdir/.cvsignore b/apps/utils/objdir/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/objdir/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/partinfo/.cvsignore b/apps/utils/partinfo/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/partinfo/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/pice/.cvsignore b/apps/utils/pice/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/pice/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/ps/.cvsignore b/apps/utils/ps/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/ps/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/ps/ps.c b/apps/utils/ps/ps.c new file mode 100644 index 0000000..2b226ed --- /dev/null +++ b/apps/utils/ps/ps.c @@ -0,0 +1,70 @@ +/* $Id$ + * + * ReactOS ps - process list console viewer + * + * ps.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +static char* title = " PID PARENT TIME NAME\n"; +char buf[256]; + +int main() +{ + DWORD r; + HANDLE pl; + PROCESSENTRY32 pe; + HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); + + WriteFile(stdout, title, lstrlen(title), &r, NULL); + pl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + pe.dwSize = sizeof(PROCESSENTRY32); + pe.th32ParentProcessID = 0; + + if (Process32First(pl, &pe)) do { + int hour; + int minute; + WORD fatdate; + WORD fattime; + HANDLE p = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID); + FILETIME cr; + FILETIME ex; + FILETIME kt; + FILETIME ut; + GetProcessTimes(p, &cr, &ex, &kt, &ut); + FileTimeToDosDateTime(&cr, &fatdate, &fattime); + hour = (fattime & 0xf800) >> 11; + minute = (fattime & 0x07e0) >> 5; + wsprintf(buf,"%08X %08X %2d:%02d %s\n", pe.th32ProcessID, pe.th32ParentProcessID, hour, minute, pe.szExeFile); + WriteFile(stdout, buf, lstrlen(buf), &r, NULL); + CloseHandle(p); + pe.th32ParentProcessID = 0; + } while (Process32Next(pl, &pe)); + + CloseHandle(pl); +} +/* +WINBOOL +STDCALL +FileTimeToDosDateTime( + CONST FILETIME *lpFileTime, + LPWORD lpFatDate, + LPWORD lpFatTime + ); + */ diff --git a/apps/utils/ps/ps.cpp b/apps/utils/ps/ps.cpp deleted file mode 100644 index 568b053..0000000 --- a/apps/utils/ps/ps.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include - -static char* title = " PID PARENT TIME NAME\n"; -char buf[256]; - -void main() -{ - HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); - - DWORD r; - WriteFile(stdout,title,lstrlen(title),&r,NULL); - - HANDLE pl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); - - PROCESSENTRY32 pe; - pe.dwSize = sizeof(PROCESSENTRY32); - pe.th32ParentProcessID = 0; - - if(Process32First(pl,&pe)) do - { - HANDLE p =OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe.th32ProcessID); - FILETIME cr; - FILETIME ex; - FILETIME kt; - FILETIME ut; - GetProcessTimes(p,&cr,&ex,&kt,&ut); - WORD fatdate; - WORD fattime; - FileTimeToDosDateTime(&cr,&fatdate,&fattime); - int hour = (fattime & 0xf800) >> 11; - int minute = (fattime & 0x07e0) >> 5; - - wsprintf(buf,"%08X %08X %2d:%02d %s\n",pe.th32ProcessID,pe.th32ParentProcessID,hour,minute,pe.szExeFile); - WriteFile(stdout,buf,lstrlen(buf),&r,NULL); - CloseHandle(p); - pe.th32ParentProcessID = 0; - - } while( Process32Next(pl,&pe)); - - CloseHandle(pl); -} \ No newline at end of file diff --git a/apps/utils/sc/.cvsignore b/apps/utils/sc/.cvsignore new file mode 100644 index 0000000..efa8e8d --- /dev/null +++ b/apps/utils/sc/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +sc.exe +sc.nostrip.exe +sc.coff +sc.sym +sc.map diff --git a/apps/utils/sc/command.c b/apps/utils/sc/command.c new file mode 100644 index 0000000..60066dd --- /dev/null +++ b/apps/utils/sc/command.c @@ -0,0 +1,109 @@ +/* + * ReactOS SC - service control console program + * + * command.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "main.h" + + +int sc_Lock(SC_HANDLE hSCManager) +{ + dprintf("sc_Lock(%x) - not implemented.\n", hSCManager); + return 0; +} + +int sc_QueryLock(SC_HANDLE hSCManager) +{ + QUERY_SERVICE_LOCK_STATUS LockStatus; + DWORD cbBufSize = sizeof(QUERY_SERVICE_LOCK_STATUS); + DWORD cbBytesNeeded; + + dprintf("sc_QueryLock() - called.\n"); + + if (QueryServiceLockStatus(hSCManager, &LockStatus, cbBufSize, &cbBytesNeeded)) { + + } else { + dprintf("Failed to Query Service Lock Status.\n"); + ReportLastError(); + } + + if (!CloseServiceHandle(hSCManager)) { + dprintf("Failed to CLOSE handle to SCM.\n"); + ReportLastError(); + } + + return 0; +} + +int sc_control(SC_HANDLE hSCManager, char* service, DWORD dwControl) +{ + int ret = 0; + SC_HANDLE schService; + SERVICE_STATUS serviceStatus; + + dprintf("sc_control(%x, %s, %d) - called.\n", hSCManager, service, dwControl); + + schService = OpenServiceA(hSCManager, service, SERVICE_ALL_ACCESS); + if (schService != NULL) { + ret = ControlService(schService, dwControl, &serviceStatus); + dprintf("ControlService(%x, %x, %x) returned %d\n", schService, dwControl, &serviceStatus, ret); + if (!ret) { + + + } + CloseServiceHandle(schService); + } + return ret; +} + +int sc_command(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]) +{ +// dprintf("sc_command(%x, %d, %s) - called.\n", hSCManager, sc_cmd, argv[]); + switch (sc_cmd) { + case SC_CMD_START: + //return sc_control(hSCManager, sc_cmd_arg, SERVICE_CONTROL_START); + dprintf(" - not implemented.\n"); + break; + case SC_CMD_PAUSE: + return sc_control(hSCManager, argv[0], SERVICE_CONTROL_PAUSE); + case SC_CMD_INTERROGATE: + return sc_control(hSCManager, argv[0], SERVICE_CONTROL_INTERROGATE); + case SC_CMD_CONTINUE: + return sc_control(hSCManager, argv[0], SERVICE_CONTROL_CONTINUE); + case SC_CMD_STOP: + return sc_control(hSCManager, argv[0], SERVICE_CONTROL_STOP); + +// case SC_CMD_CONFIG: +// case SC_CMD_DESCRIPTION: +// case SC_CMD_CONTROL: + + case SC_CMD_LOCK: + return sc_Lock(hSCManager); + case SC_CMD_QUERYLOCK: + return sc_QueryLock(hSCManager); + default: + dprintf("sc_command(%x, %d, %s) - unknown command.\n", hSCManager, sc_cmd, argv[0]); + break; + } + return 0; +} diff --git a/apps/utils/sc/config.c b/apps/utils/sc/config.c new file mode 100644 index 0000000..87f4ae7 --- /dev/null +++ b/apps/utils/sc/config.c @@ -0,0 +1,75 @@ +/* + * ReactOS SC - service control console program + * + * config.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "main.h" + + +int sc_config(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]) +{ + dprintf("sc_config(%x, %d, %s) - called.\n", hSCManager, sc_cmd, argv[0]); + + switch (sc_cmd) { + case SC_CMD_CONFIG: + case SC_CMD_DESCRIPTION: + case SC_CMD_FAILURE: + case SC_CMD_SDSHOW: + case SC_CMD_SDSET: + dprintf(" - not implemented.\n"); + break; + default: + dprintf("sc_config(%x, %d, %s) - unknown command.\n", hSCManager, sc_cmd, argv[0]); + break; + } + return 0; +} +/* + switch (sc_cmd) { + case SC_CMD_QUERY: + case SC_CMD_QUERYEX: + case SC_CMD_START: + case SC_CMD_PAUSE: + case SC_CMD_INTERROGATE: + case SC_CMD_CONTINUE: + case SC_CMD_STOP: + case SC_CMD_CONFIG: + case SC_CMD_DESCRIPTION: + case SC_CMD_FAILURE: + case SC_CMD_QC: + case SC_CMD_QDESCRIPTION: + case SC_CMD_QFAILURE: + case SC_CMD_DELETE: + case SC_CMD_CREATE: + case SC_CMD_CONTROL: + case SC_CMD_SDSHOW: + case SC_CMD_SDSET: + case SC_CMD_GETDISPLAYNAME: + case SC_CMD_GETKEYNAME: + case SC_CMD_ENUMDEPEND: + case SC_CMD_BOOT: + case SC_CMD_LOCK: + case SC_CMD_QUERYLOCK: + break; + } + */ diff --git a/apps/utils/sc/main.c b/apps/utils/sc/main.c new file mode 100644 index 0000000..507d749 --- /dev/null +++ b/apps/utils/sc/main.c @@ -0,0 +1,248 @@ +/* + * ReactOS SC - service control console program + * + * main.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "main.h" + + +#define VERSION 1 + +#ifdef UNICODE +#define TARGET "UNICODE" +#else +#define TARGET "MBCS" +#endif + +BOOL verbose_flagged = 0; +BOOL status_flagged = 0; + +HANDLE OutputHandle; +HANDLE InputHandle; + + +void dprintf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args, fmt); + wvsprintfA(buffer, fmt, args); + WriteConsoleA(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL); + va_end(args); +} + +long getinput(char* buf, int buflen) +{ + DWORD result; + + ReadConsoleA(InputHandle, buf, buflen, &result, NULL); + return (long)result; +} + +DWORD ReportLastError(void) +{ + DWORD dwError = GetLastError(); + if (dwError != ERROR_SUCCESS) { + PTSTR msg = NULL; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, dwError, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) { + if (msg != NULL) { + dprintf("ReportLastError() %d - %s\n", dwError, msg); + } else { + dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError); + } + } else { + dprintf("ReportLastError() %d - unknown error\n", dwError); + } + if (msg != NULL) { + LocalFree(msg); + } + } + return dwError; +} + +int usage(char* argv0) +{ + dprintf("DESCRIPTION:\n"); + dprintf("\tSC is a command line program used for communicating with\n"); + dprintf("\tthe Service Control Manager and its services.\n"); + dprintf("USAGE:\n"); + dprintf("\tsc [command] [service name] ...\n"); + + dprintf("\tThe optional parameter has the form \"\\ServerName\"\n"); + dprintf("\tFurther help on commands can be obtained by typing: \"sc [command]\"\n"); + dprintf("\tService Commands:\n"); + dprintf("\t query : Queries the status for a service, or\n"); + dprintf("\t enumerates the status for types of services.\n"); + dprintf("\t queryex : Queries the extended status for a service, or\n"); + dprintf("\t enumerates the status for types of services.\n"); + dprintf("\t start : Starts a service.\n"); + dprintf("\t pause : Sends a PAUSE control request to a service.\n"); + dprintf("\t interrogate : Sends a INTERROGATE control request to a service.\n"); + dprintf("\t continue : Sends a CONTINUE control request to a service.\n"); + dprintf("\t stop : Sends a STOP request to a service.\n"); + dprintf("\t config : Changes the configuration of a service (persistant).\n"); + dprintf("\t description : Changes the description of a service.\n"); + dprintf("\t failure : Changes the actions taken by a service upon failure.\n"); + dprintf("\t qc : Queries the configuration information for a service.\n"); + dprintf("\t qdescription : Queries the description for a service.\n"); + dprintf("\t qfailure : Queries the actions taken by a service upon failure.\n"); + dprintf("\t delete : Deletes a service (from the registry).\n"); + dprintf("\t create : Creates a service. (adds it to the registry).\n"); + dprintf("\t control : Sends a control to a service.\n"); +// dprintf("\t sdshow : Displays a service's security descriptor.\n"); +// dprintf("\t sdset : Sets a service's security descriptor.\n"); + dprintf("\t GetDisplayName : Gets the DisplayName for a service.\n"); + dprintf("\t GetKeyName : Gets the ServiceKeyName for a service.\n"); + dprintf("\t EnumDepend : Enumerates Service Dependencies.\n"); + dprintf("\n"); + dprintf("\tService Name Independant Commands:\n"); + dprintf("\t boot : (ok | bad) Indicates whether the last boot should\n"); + dprintf("\t be saved as the last-known-good boot configuration\n"); + dprintf("\t Lock : Locks the SCM Database\n"); + dprintf("\t QueryLock : Queries the LockStatus for the SCM Database\n"); + + return 0; +} + + +typedef int (*sc_cmd_proc)(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]); + +typedef struct { + SC_CMDS sc_cmd; + const char* cmd_str; + sc_cmd_proc funcptr; + DWORD dwDesiredAccess; +} sc_cmd_entry; + +sc_cmd_entry sc_cmds_table[] = { + { SC_CMD_QUERY, "query", sc_query, SC_MANAGER_ALL_ACCESS }, + { SC_CMD_QUERYEX, "queryex", sc_query, SC_MANAGER_ALL_ACCESS }, + { SC_CMD_START, "start", sc_command, 0L }, + { SC_CMD_PAUSE, "pause", sc_command, 0L }, + { SC_CMD_INTERROGATE, "interrogate", sc_command, 0L }, + { SC_CMD_CONTINUE, "continue", sc_command, 0L }, + { SC_CMD_STOP, "stop", sc_command, 0L }, + { SC_CMD_CONFIG, "config", sc_setup, 0L }, + { SC_CMD_DESCRIPTION, "description", sc_setup, 0L }, + { SC_CMD_FAILURE, "failure", sc_setup, 0L }, + { SC_CMD_QC, "qc", sc_query, 0L }, + { SC_CMD_QDESCRIPTION, "qdescription", sc_query, 0L }, + { SC_CMD_QFAILURE, "qfailure", sc_query, 0L }, + { SC_CMD_DELETE, "delete", sc_setup, 0L }, + { SC_CMD_CREATE, "create", sc_setup, 0L }, + { SC_CMD_CONTROL, "control", sc_setup, 0L }, + { SC_CMD_SDSHOW, "sdshow", sc_query, 0L }, + { SC_CMD_SDSET, "sdset", sc_setup, 0L }, + { SC_CMD_GETDISPLAYNAME, "GetDisplayName", sc_query, 0L }, + { SC_CMD_GETKEYNAME, "GetKeyName", sc_query, 0L }, + { SC_CMD_ENUMDEPEND, "EnumDepend", sc_query, 0L }, + { SC_CMD_BOOT, "boot", sc_config, 0L }, + { SC_CMD_LOCK, "Lock", sc_config, 0L }, + { SC_CMD_QUERYLOCK, "QueryLock", sc_config, 0L } +}; + + +int sc_main(const sc_cmd_entry* cmd_entry, + const char* sc_machine_name, + char* sc_cmd_arg[]) +{ + int result = 1; + SC_HANDLE hSCManager; + DWORD dwDesiredAccess; + + dprintf("sc_main(%s) - called.\n", cmd_entry->cmd_str); + if (sc_machine_name) { + dprintf("remote service control not yet implemented.\n"); + return 2; + } + dwDesiredAccess = cmd_entry->dwDesiredAccess; + if (!dwDesiredAccess) dwDesiredAccess = SC_MANAGER_CONNECT + GENERIC_READ; + + hSCManager = OpenSCManagerA(sc_machine_name, NULL, dwDesiredAccess); + //hSCManager = OpenSCManagerW(NULL, NULL, dwDesiredAccess); + if (hSCManager != NULL) { + result = cmd_entry->funcptr(hSCManager, cmd_entry->sc_cmd, sc_cmd_arg); + if (!CloseServiceHandle(hSCManager)) { + dprintf("Failed to CLOSE handle to SCM.\n"); + ReportLastError(); + } + } else { + dprintf("Failed to open Service Control Manager.\n"); + ReportLastError(); + } + return result; +} + + +int __cdecl main(int argc, char* argv[]) +{ + int i; + const char* sc_machine_name = NULL; + const char* sc_cmd_str = argv[1]; + char** sc_cmd_arg = NULL; + + AllocConsole(); + InputHandle = GetStdHandle(STD_INPUT_HANDLE); + OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + + dprintf("%s application - build %03d (default: %s)\n", argv[0], VERSION, TARGET); + if (argc < 2) { + return usage(argv[0]); + } + + if ((argv[1][0] == '\\') && (argv[1][1] == '\\')) { + if (argc < 3) { + return usage(argv[0]); + } + sc_machine_name = argv[1]; + sc_cmd_str = argv[2]; + sc_cmd_arg = &argv[3]; + } else { + sc_machine_name = NULL; + sc_cmd_str = argv[1]; + sc_cmd_arg = &argv[2]; + } + + for (i = 0; i < sizeof(sc_cmds_table)/sizeof(sc_cmd_entry); i++) { + sc_cmd_entry* cmd_entry = &(sc_cmds_table[i]); + if (lstrcmpiA(sc_cmd_str, cmd_entry->cmd_str) == 0) { + return sc_main(cmd_entry, sc_machine_name, sc_cmd_arg); + } + } + return usage(argv[0]); +} + + +#ifdef _NOCRT + +//char* args[] = { "sc.exe", "pause", "smplserv" }; +char* args[] = { "sc.exe", "EnumDepend", "" }; + +int __cdecl mainCRTStartup(void) +{ + main(3, args); + return 0; +} + +#endif /*_NOCRT*/ diff --git a/apps/utils/sc/main.h b/apps/utils/sc/main.h new file mode 100644 index 0000000..c178571 --- /dev/null +++ b/apps/utils/sc/main.h @@ -0,0 +1,72 @@ +/* + * ReactOS test program - + * + * main.h + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +DWORD ReportLastError(void); +long getinput(char* Buffer, int buflen); +void dprintf(char* fmt, ...); + +typedef enum tag_SC_CMDS { + SC_CMD_QUERY, + SC_CMD_QUERYEX, + SC_CMD_START, + SC_CMD_PAUSE, + SC_CMD_INTERROGATE, + SC_CMD_CONTINUE, + SC_CMD_STOP, + SC_CMD_CONFIG, + SC_CMD_DESCRIPTION, + SC_CMD_FAILURE, + SC_CMD_QC, + SC_CMD_QDESCRIPTION, + SC_CMD_QFAILURE, + SC_CMD_DELETE, + SC_CMD_CREATE, + SC_CMD_CONTROL, + SC_CMD_SDSHOW, + SC_CMD_SDSET, + SC_CMD_GETDISPLAYNAME, + SC_CMD_GETKEYNAME, + SC_CMD_ENUMDEPEND, + SC_CMD_BOOT, + SC_CMD_LOCK, + SC_CMD_QUERYLOCK +} SC_CMDS; + +int sc_query(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]); +int sc_setup(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]); +int sc_config(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]); +int sc_command(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]); + + +#ifdef __cplusplus +}; +#endif + +#endif // __MAIN_H__ diff --git a/apps/utils/sc/makefile b/apps/utils/sc/makefile new file mode 100644 index 0000000..4cadccf --- /dev/null +++ b/apps/utils/sc/makefile @@ -0,0 +1,24 @@ +# +# $Id: makefile,v 1.0 + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = sc + +TARGET_CFLAGS = -DDBG + +TARGET_SDKLIBS = kernel32.a ntdll.a advapi32.a + +TARGET_OBJECTS = command.o config.o main.o query.o setup.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/utils/sc/query.c b/apps/utils/sc/query.c new file mode 100644 index 0000000..fd03b2a --- /dev/null +++ b/apps/utils/sc/query.c @@ -0,0 +1,111 @@ +/* + * ReactOS SC - service control console program + * + * query.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "main.h" + + + +int DisplayServiceInfo(BOOL display_ex) +{ + const char* type_str = "WIN32_SHARE_PROCESS"; + const char* state_str = "RUNNING"; + const char* flags_str = "RUNS_IN_SYSTEM_PROCESS"; + const char* features_str = "NOT_STOPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN"; + + const char* ServiceName = "none"; + const char* DisplayName = "none"; + int Type; + int State; + int Win32ExitCode; + int ServiceExitCode; + int CheckPoint; + int WaitHint; + int Pid; + int Flags; + + Type = 20; + State = 4; + Win32ExitCode = 0; + ServiceExitCode = 0; + CheckPoint = 0; + WaitHint = 0; + Pid = 0; + Flags = 0; + + dprintf("\nSERVICE_NAME: %s\n", ServiceName); + dprintf("DISPLAY_NAME: %s\n", DisplayName); + dprintf("\tTYPE : %d %s\n", Type, type_str); + dprintf("\tSTATE : %d %s\n", State, state_str); + dprintf("\t : (%s)\n", features_str); + dprintf("\tWIN32_EXIT_CODE : %d (0x%01x)\n", Win32ExitCode, Win32ExitCode); + dprintf("\tSERVICE_EXIT_CODE : %d (0x%01x)\n", ServiceExitCode, ServiceExitCode); + dprintf("\tCHECKPOINT : 0x%01x\n", CheckPoint); + dprintf("\tWAIT_HINT : 0x%01x\n", WaitHint); + + if (display_ex) { + dprintf("\tPID : %d\n", Pid); + dprintf("\tFLAGS : %s\n", flags_str); + } + + return 0; +} + +int EnumServicesInfo(void) +{ + int entriesRead = 0; + int resumeIndex = 0; + + dprintf("Enum: entriesRead = %d\n", entriesRead); + dprintf("Enum: resumeIndex = %d\n", resumeIndex); + + DisplayServiceInfo(1); + + return 0; +} + +int sc_query(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]) +{ + switch (sc_cmd) { + case SC_CMD_QUERY: + case SC_CMD_QUERYEX: + case SC_CMD_QC: + case SC_CMD_QDESCRIPTION: + case SC_CMD_QFAILURE: + case SC_CMD_SDSHOW: + case SC_CMD_GETDISPLAYNAME: + case SC_CMD_GETKEYNAME: + dprintf("sc_query(%x, %d, %s) - command not implemented.\n", hSCManager, sc_cmd, argv[0]); + break; + case SC_CMD_ENUMDEPEND: + return EnumServicesInfo(); +// case SC_CMD_QUERYLOCK: +// return sc_QueryLock(hSCManager); + default: + dprintf("sc_query(%x, %d, %s) - unknown command.\n", hSCManager, sc_cmd, argv[0]); + break; + } + return 0; +} + diff --git a/apps/utils/sc/setup.c b/apps/utils/sc/setup.c new file mode 100644 index 0000000..ccbe9bc --- /dev/null +++ b/apps/utils/sc/setup.c @@ -0,0 +1,62 @@ +/* + * ReactOS SC - service control console program + * + * setup.c + * + * Copyright (C) 2002 Robert Dickenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "main.h" + +int sc_delete(char* argv[]) +{ + dprintf("sc_delete(%s) - not implemented.\n", argv[0]); + return 0; +} + +int sc_boot(char* arg) +{ + dprintf("sc_boot(%s) - not implemented.\n", arg); + return 0; +} + +int sc_setup(SC_HANDLE hSCManager, SC_CMDS sc_cmd, char* argv[]) +{ + dprintf("sc_setup(%x, %d, %s) - called.\n", hSCManager, sc_cmd, argv[0]); + + switch (sc_cmd) { +// case SC_CMD_DESCRIPTION: +// case SC_CMD_FAILURE: + case SC_CMD_DELETE: + return sc_delete(argv); + case SC_CMD_CREATE: + dprintf(" - not implemented.\n"); + break; +// case SC_CMD_SDSHOW: +// case SC_CMD_SDSET: + case SC_CMD_BOOT: + return sc_boot(argv[0]); + default: + dprintf("sc_setup(%x, %d, %s) - unknown command.\n", hSCManager, sc_cmd, argv[0]); + break; + } + return 0; +} + diff --git a/apps/utils/stats/.cvsignore b/apps/utils/stats/.cvsignore new file mode 100644 index 0000000..7e87816 --- /dev/null +++ b/apps/utils/stats/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/apps/utils/tickcount/makefile b/apps/utils/tickcount/makefile new file mode 100644 index 0000000..9679181 --- /dev/null +++ b/apps/utils/tickcount/makefile @@ -0,0 +1,19 @@ +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = tickcount + +TARGET_SDKLIBS = kernel32.a + +TARGET_OBJECTS = tickcount.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/utils/tickcount/tickcount.c b/apps/utils/tickcount/tickcount.c new file mode 100644 index 0000000..c00674d --- /dev/null +++ b/apps/utils/tickcount/tickcount.c @@ -0,0 +1,142 @@ +/* $Id$ +*/ +/* + tickcount -- Display the kernel tick count in human-readable format + + This is public domain software +*/ + +#include +#include +#include +#include + +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#define TICKS_YEAR (TICKS_DAY * ((uint64_t)365)) +#define TICKS_MONTH (TICKS_DAY * ((uint64_t)30)) +#define TICKS_WEEK (TICKS_DAY * ((uint64_t)7)) +#define TICKS_DAY (TICKS_HOUR * ((uint64_t)24)) +#define TICKS_HOUR (TICKS_MINUTE * ((uint64_t)60)) +#define TICKS_MINUTE (TICKS_SECOND * ((uint64_t)60)) +#define TICKS_SECOND ((uint64_t)1000) + +#define SLICES_COUNT (sizeof(ticks_per_slice) / sizeof(ticks_per_slice[0])) + +uint64_t ticks_per_slice[] = +{ + TICKS_YEAR, + TICKS_MONTH, + TICKS_WEEK, + TICKS_DAY, + TICKS_HOUR, + TICKS_MINUTE, + TICKS_SECOND, + 1 +}; + +_TCHAR * slice_names_singular[] = +{ + _T("year"), + _T("month"), + _T("week"), + _T("day"), + _T("hour"), + _T("minute"), + _T("second"), + _T("millisecond") +}; + +_TCHAR * slice_names_plural[] = +{ + _T("years"), + _T("months"), + _T("weeks"), + _T("days"), + _T("hours"), + _T("minutes"), + _T("seconds"), + _T("milliseconds") +}; + +void print_uptime +( + uint64_t tickcount, + uint64_t prevsliceval, + _TCHAR * prevsliceunit, + int curslice +) +{ + uint64_t tick_cur = tickcount / ticks_per_slice[curslice]; + uint64_t tick_residual = tickcount % ticks_per_slice[curslice]; + + assert(tick_cur <= (~((unsigned)0))); + + if(tick_residual == 0) + { + /* the current slice is the last */ + + if(prevsliceval == 0) + { + /* the current slice is the only */ + _tprintf + ( + _T("%u %s"), + (unsigned)tick_cur, + (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice] + ); + } + else + { + /* the current slice is the last, and there's a previous slice */ + assert(prevsliceunit); + + /* print the previous and the current slice, and terminate */ + _tprintf + ( + _T("%u %s %s %u %s"), + (unsigned)prevsliceval, + prevsliceunit, + _T("and"), + (unsigned)tick_cur, + (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice] + ); + } + } + else if(tick_cur != 0) + { + /* the current slice is not the last, and non-zero */ + + if(prevsliceval != 0) + { + /* there's a previous slice: print it */ + assert(prevsliceunit); + _tprintf(_T("%u %s, "), (unsigned)prevsliceval, prevsliceunit); + } + + /* recursion on the next slice size, storing the current slice */ + print_uptime + ( + tick_residual, + tick_cur, + (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice], + curslice + 1 + ); + } + else + { + /* + the current slice is not the last, and zero: recursion, remembering the + previous non-zero slice + */ + print_uptime(tick_residual, prevsliceval, prevsliceunit, curslice + 1); + } +} + +int _tmain() +{ + print_uptime((uint64_t)GetTickCount(), 0, NULL, 0); + _puttc(_T('\n'), stdout); + return 0; +} diff --git a/boot.bat b/boot.bat index 9c497d4..0fb1374 100644 --- a/boot.bat +++ b/boot.bat @@ -1 +1 @@ -loadros system32\ntoskrnl.exe system32\hal.dll /DEBUGPORT=SCREEN bootc.lst +loadros system32\ntoskrnl.exe system32\hal.dll /DEBUGPORT=BOCHS bootc.lst diff --git a/bootcd.bat b/bootcd.bat index f1e1c30..5a7a45d 100755 --- a/bootcd.bat +++ b/bootcd.bat @@ -1,5 +1,6 @@ @echo off set BOOTCD_DIR=..\bootcd +set FREELDR_DIR=..\freeldr md %BOOTCD_DIR% md %BOOTCD_DIR%\disk @@ -7,6 +8,19 @@ md %BOOTCD_DIR%\disk\bootdisk md %BOOTCD_DIR%\disk\install md %BOOTCD_DIR%\disk\reactos md %BOOTCD_DIR%\disk\reactos\system32 +md %BOOTCD_DIR%\disk\loader + +rem copy FreeLoader files +copy /Y %FREELDR_DIR%\bootsect\isoboot.bin %BOOTCD_DIR% +copy /Y %FREELDR_DIR%\freeldr\obj\i386\setupldr.sys %BOOTCD_DIR%\disk\reactos + +copy /Y %FREELDR_DIR%\bootsect\ext2.bin %BOOTCD_DIR%\disk\loader +copy /Y %FREELDR_DIR%\bootsect\fat.bin %BOOTCD_DIR%\disk\loader +copy /Y %FREELDR_DIR%\bootsect\fat32.bin %BOOTCD_DIR%\disk\loader +copy /Y %FREELDR_DIR%\bootsect\isoboot.bin %BOOTCD_DIR%\disk\loader +copy /Y %FREELDR_DIR%\freeldr\obj\i386\freeldr.sys %BOOTCD_DIR%\disk\loader + +rem copy boot files copy /Y ntoskrnl\ntoskrnl.exe %BOOTCD_DIR%\disk\reactos copy /Y hal\halx86\hal.dll %BOOTCD_DIR%\disk\reactos copy /Y drivers\fs\vfat\vfatfs.sys %BOOTCD_DIR%\disk\reactos @@ -22,3 +36,88 @@ copy /Y drivers\storage\disk\disk.sys %BOOTCD_DIR%\disk\reactos copy /Y drivers\storage\class2\class2.sys %BOOTCD_DIR%\disk\reactos copy /Y lib\ntdll\ntdll.dll %BOOTCD_DIR%\disk\reactos\system32 copy /Y subsys\system\usetup\usetup.exe %BOOTCD_DIR%\disk\reactos\system32\smss.exe + +rem copy install files +copy /Y txtsetup.sif %BOOTCD_DIR%\disk\install +copy /Y system.hiv %BOOTCD_DIR%\disk\install + +copy /Y ntoskrnl\ntoskrnl.exe %BOOTCD_DIR%\disk\install +copy /Y hal\halx86\hal.dll %BOOTCD_DIR%\disk\install + +copy /Y drivers\bus\acpi\acpi.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\bus\isapnp\isapnp.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\dd\beep\beep.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\blue\blue.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\floppy\floppy.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\null\null.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\serial\serial.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\vga\display\vgaddi.dll %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\vga\miniport\vgamp.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\vidport\vidport.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\fs\cdfs\cdfs.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\fs_rec\fs_rec.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\ms\msfs.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\mup\mup.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\np\npfs.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\ntfs\ntfs.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\fs\vfat\vfatfs.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\input\keyboard\keyboard.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\input\mouclass\mouclass.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\input\psaux\psaux.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\lib\bzip2\unbzip2.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\net\afd\afd.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\dd\ne2000\ne2000.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\ndis\ndis.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\npf\npf.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\packet\packet.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\tcpip\tcpip.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\net\tdi\tdi.sys %BOOTCD_DIR%\disk\install + +copy /Y drivers\storage\atapi\atapi.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\storage\cdrom\cdrom.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\storage\class2\class2.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\storage\disk\disk.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\storage\scsiport\scsiport.sys %BOOTCD_DIR%\disk\install + +copy /Y lib\advapi32\advapi32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\crtdll\crtdll.dll %BOOTCD_DIR%\disk\install +copy /Y lib\fmifs\fmifs.dll %BOOTCD_DIR%\disk\install +copy /Y lib\gdi32\gdi32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\kernel32\kernel32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\msafd\msafd.dll %BOOTCD_DIR%\disk\install +copy /Y lib\msvcrt\msvcrt.dll %BOOTCD_DIR%\disk\install +copy /Y lib\ntdll\ntdll.dll %BOOTCD_DIR%\disk\install +copy /Y lib\ole32\ole32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\oleaut32\oleaut32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\packet\packet.dll %BOOTCD_DIR%\disk\install +copy /Y lib\secur32\secur32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\shell32\shell32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\user32\user32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\version\version.dll %BOOTCD_DIR%\disk\install +copy /Y lib\winedbgc\winedbgc.dll %BOOTCD_DIR%\disk\install +copy /Y lib\winmm\winmm.dll %BOOTCD_DIR%\disk\install +copy /Y lib\ws2_32\ws2_32.dll %BOOTCD_DIR%\disk\install +copy /Y lib\ws2help\ws2help.dll %BOOTCD_DIR%\disk\install +copy /Y lib\wshirda\wshirda.dll %BOOTCD_DIR%\disk\install + +copy /Y services\eventlog\eventlog.exe %BOOTCD_DIR%\disk\install +copy /Y services\rpcss\rpcss.exe %BOOTCD_DIR%\disk\install + +copy /Y subsys\csrss\csrss.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\ntvdm\ntvdm.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\smss\smss.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\autochk\autochk.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\gstart\gstart.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\lsass\lsass.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\services\services.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\shell\shell.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\winlogon\winlogon.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\win32k\win32k.sys %BOOTCD_DIR%\disk\install + +copy /Y media\fonts\helb____.ttf %BOOTCD_DIR%\disk\install +copy /Y media\fonts\timr____.ttf %BOOTCD_DIR%\disk\install diff --git a/dk/w32/Makefile b/dk/w32/Makefile index aa142c7..b353a5b 100644 --- a/dk/w32/Makefile +++ b/dk/w32/Makefile @@ -44,9 +44,9 @@ MODULES_NET=\ $(TARGET_FOLDER_LIB)/wshirda.a\ $(TARGET_FOLDER_LIB)/wsock32.a -MODULES_COM=\ - $(TARGET_FOLDER_LIB)/ole32.a\ - $(TARGET_FOLDER_LIB)/oleaut32.a +#MODULES_COM=\ +# $(TARGET_FOLDER_LIB)/ole32.a\ +# $(TARGET_FOLDER_LIB)/oleaut32.a\ # $(TARGET_FOLDER_LIB)/rpcrt4.a MODULES_CRT=\ @@ -56,14 +56,30 @@ MODULES_CRT=\ MODULES_MISC=\ $(TARGET_FOLDER_LIB)/version.a +MODULES_WINE=\ + $(TARGET_FOLDER_LIB)/libwine.a\ + $(TARGET_FOLDER_LIB)/rpcrt4.a\ + $(TARGET_FOLDER_LIB)/shlwapi.a\ + $(TARGET_FOLDER_LIB)/ole32.a\ + $(TARGET_FOLDER_LIB)/oleaut32.a\ + $(TARGET_FOLDER_LIB)/lz32.a\ + $(TARGET_FOLDER_LIB)/wininet.a\ + $(TARGET_FOLDER_LIB)/wine_unicode.a + +MODULES_CONTRIB=\ + $(TARGET_FOLDER_LIB)/perl58.a + MODULES =\ $(MODULES_CORE)\ + $(MODULES_COM)\ $(MODULES_ADVANCED)\ $(MODULES_SHELL)\ $(MODULES_NET)\ - $(MODULES_COM)\ $(MODULES_CRT)\ - $(MODULES_MISC) + $(MODULES_MISC)\ + $(MODULES_WINE) + +# $(MODULES_CONTRIB)\ # --- Rules --- @@ -175,23 +191,23 @@ $(TARGET_FOLDER_LIB)/wsock32.a: $(PATH_TO_TOP)/lib/wsock32/wsock32.def # --- COM --- -$(TARGET_FOLDER_LIB)/ole32.a: $(PATH_TO_TOP)/lib/ole32/ole32.def - $(DLLTOOL) \ - $(DTFLAGS)\ - -D ole32.dll\ - -d $(PATH_TO_TOP)/lib/ole32/ole32.def +#$(TARGET_FOLDER_LIB)/ole32.a: $(PATH_TO_TOP)/lib/ole32/ole32.def +# $(DLLTOOL) \ +# $(DTFLAGS)\ +# -D ole32.dll\ +# -d $(PATH_TO_TOP)/lib/ole32/ole32.def -$(TARGET_FOLDER_LIB)/oleaut32.a: $(PATH_TO_TOP)/lib/oleaut32/oleaut32.def - $(DLLTOOL) \ - $(DTFLAGS)\ - -D oleaut32.dll\ - -d $(PATH_TO_TOP)/lib/oleaut32/oleaut32.def +#$(TARGET_FOLDER_LIB)/oleaut32.a: $(PATH_TO_TOP)/lib/oleaut32/oleaut32.def +# $(DLLTOOL) \ +# $(DTFLAGS)\ +# -D oleaut32.dll\ +# -d $(PATH_TO_TOP)/lib/oleaut32/oleaut32.def -$(TARGET_FOLDER_LIB)/rpcrt4.a: $(PATH_TO_TOP)/lib/rpcrt4/rpcrt4.def - $(DLLTOOL) \ - $(DTFLAGS)\ - -D rpcrt4.dll\ - -d $(PATH_TO_TOP)/lib/rpcrt4/rpcrt4.def +#$(TARGET_FOLDER_LIB)/rpcrt4.a: $(PATH_TO_TOP)/lib/rpcrt4/rpcrt4.def +# $(DLLTOOL) \ +# $(DTFLAGS)\ +# -D rpcrt4.dll\ +# -d $(PATH_TO_TOP)/lib/rpcrt4/rpcrt4.def # --- CRT --- @@ -215,6 +231,65 @@ $(TARGET_FOLDER_LIB)/version.a: $(PATH_TO_TOP)/lib/version/version.def -D version.dll\ -d $(PATH_TO_TOP)/lib/version/version.def +# --- WINE --- + +$(TARGET_FOLDER_LIB)/ole32.a: $(PATH_TO_TOP)/../wine/dlls/ole32/ole32.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D ole32.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/ole32/ole32.def + +$(TARGET_FOLDER_LIB)/oleaut32.a: $(PATH_TO_TOP)/../wine/dlls/oleaut32/oleaut32.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D oleaut32.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/oleaut32/oleaut32.def + +$(TARGET_FOLDER_LIB)/rpcrt4.a: $(PATH_TO_TOP)/../wine/dlls/rpcrt4/rpcrt4.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D rpcrt4.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/rpcrt4/rpcrt4.def + +$(TARGET_FOLDER_LIB)/shlwapi.a: $(PATH_TO_TOP)/../wine/dlls/shlwapi/shlwapi.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D shlwapi.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/shlwapi/shlwapi.def + + +$(TARGET_FOLDER_LIB)/wininet.a: $(PATH_TO_TOP)/../wine/dlls/wininet/wininet.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D wininet.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/wininet/wininet.def + +$(TARGET_FOLDER_LIB)/lz32.a: $(PATH_TO_TOP)/../wine/dlls/lzexpand/lz32.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D lz32.dll\ + -d $(PATH_TO_TOP)/../wine/dlls/lzexpand/lz32.def + +$(TARGET_FOLDER_LIB)/libwine.a: $(PATH_TO_TOP)/../wine/library/libwine.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D libwine.dll\ + -d $(PATH_TO_TOP)/../wine/library/libwine.def + +$(TARGET_FOLDER_LIB)/wine_unicode.a: $(PATH_TO_TOP)/../wine/unicode/wine_unicode.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D wine_unicode.dll\ + -d $(PATH_TO_TOP)/../wine/unicode/wine_unicode.def + +# --- CONTRIB --- + +$(TARGET_FOLDER_LIB)/perl58.a: $(PATH_TO_TOP)/../contrib/perl-5.8.0/win32/perldll.def + $(DLLTOOL) \ + $(DTFLAGS)\ + -D perl58.dll\ + -d $(PATH_TO_TOP)/../contrib/perl-5.8.0/win32/perldll.def + # --- Service rules --- clean: diff --git a/drivers/bus/acpi/.cvsignore b/drivers/bus/acpi/.cvsignore index dfa5ac2..b30e21a 100644 --- a/drivers/bus/acpi/.cvsignore +++ b/drivers/bus/acpi/.cvsignore @@ -3,3 +3,4 @@ objects *.d *.o *.sym +*.sys diff --git a/drivers/bus/acpi/include/acpi.h b/drivers/bus/acpi/include/acpi.h index 59514c4..7e4ece2 100644 --- a/drivers/bus/acpi/include/acpi.h +++ b/drivers/bus/acpi/include/acpi.h @@ -26,6 +26,10 @@ #ifndef __ACPI_H__ #define __ACPI_H__ +#include "platform/types.h" +#undef ROUND_DOWN +#undef ROUND_UP + /* * Common includes for all ACPI driver files * We put them here because we don't want to duplicate them diff --git a/drivers/bus/acpi/include/actypes.h b/drivers/bus/acpi/include/actypes.h index fbb49ef..ea41e05 100644 --- a/drivers/bus/acpi/include/actypes.h +++ b/drivers/bus/acpi/include/actypes.h @@ -113,13 +113,13 @@ typedef char *ACPI_PHYSICAL_ADDRESS; /* * 32-bit type definitions (default) */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned char UCHAR; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_UINT64 UINT64; +//typedef unsigned char UINT8; +//typedef unsigned char BOOLEAN; +//typedef unsigned char UCHAR; +//typedef unsigned short UINT16; +//typedef int INT32; +//typedef unsigned int UINT32; +//typedef COMPILER_DEPENDENT_UINT64 UINT64; typedef UINT32 NATIVE_UINT; typedef INT32 NATIVE_INT; diff --git a/drivers/bus/acpi/include/platform/types.h b/drivers/bus/acpi/include/platform/types.h index 6326448..75ef637 100644 --- a/drivers/bus/acpi/include/platform/types.h +++ b/drivers/bus/acpi/include/platform/types.h @@ -10,787 +10,9 @@ * 27/06/00: Created * 01/05/01: Portabillity changes */ - -#ifndef __INCLUDE_ACPI_TYPES_H -#define __INCLUDE_ACPI_TYPES_H - -/* Fixed precision types */ -typedef signed char INT8, *PINT8; -typedef signed short INT16, *PINT16; -#if 0 -typedef signed int INT32, *PINT32; -#endif -typedef signed long long INT64, *PINT64; -#if 0 -typedef unsigned char UINT8, *PUINT8; -typedef unsigned short UINT16, *PUINT16; -typedef unsigned int UINT32, *PUINT32; -typedef unsigned long long UINT64, *PUINT64; -#endif - -typedef signed long int LONG32, *PLONG32; -typedef unsigned long int ULONG32, *PULONG32; -typedef unsigned long int DWORD32, *PDWORD32; - - -#ifdef _WIN64 - -/* 64-bit architecture */ - -typedef INT64 INT, *PINT; -typedef LONG64 LONG, *PLONG; -typedef DWORD64 DWORD, *PDWORD; -typedef UINT64 UINT, *PUINT; -typedef ULONG64 ULONG, *PULONG; - -/* Pointer precision types */ -typedef long long INT_PTR, *PINT_PTR; -typedef unsigned long long UINT_PTR, *PUINT_PTR; -typedef long long LONG_PTR, *PLONG_PTR; -typedef unsigned long long ULONG_PTR, *PULONG_PTR; -typedef unsigned long long HANDLE_PTR; -typedef unsigned int UHALF_PTR, *PUHALF_PTR; -typedef int HALF_PTR, *PHALF_PTR; - -#else /* _WIN64 */ - -/* 32-bit architecture */ - -typedef INT32 INT, *PINT; -typedef LONG32 LONG, *PLONG; -typedef DWORD32 DWORD, *PDWORD; -typedef UINT32 UINT, *PUINT; -typedef ULONG32 ULONG, *PULONG; - - -/* Pointer precision types */ -typedef int INT_PTR, *PINT_PTR; -typedef unsigned int UINT_PTR, *PUINT_PTR; -typedef long LONG_PTR, *PLONG_PTR; -typedef unsigned long ULONG_PTR, *PULONG_PTR; -typedef unsigned short UHALF_PTR, *PUHALF_PTR; -typedef short HALF_PTR, *PHALF_PTR; -typedef unsigned long HANDLE_PTR; - -#endif /* _WIN64 */ - -typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; - -typedef long long LONG64, *PLONG64; - -typedef unsigned long long ULONG64, *PULONG64; -typedef unsigned long long DWORD64, *PDWORD64; - - -#if 0 -typedef unsigned char UCHAR; -#endif -typedef unsigned short USHORT; -typedef unsigned short WCHAR; -typedef unsigned short WORD; -typedef int BOOL; -#if 0 -typedef unsigned char BOOLEAN; -#endif -typedef BOOLEAN* PBOOLEAN; -typedef unsigned short *LPWSTR; -typedef unsigned short *PWSTR; -typedef unsigned char *PUCHAR; -typedef unsigned short *PUSHORT; -typedef void *PVOID; -typedef unsigned char BYTE; -typedef void *LPVOID; -typedef float *PFLOAT; -typedef unsigned short *PWCH; -typedef unsigned short *PWORD; - -typedef long long LONGLONG; -typedef unsigned long long ULONGLONG; -typedef long long *PLONGLONG; -typedef unsigned long long *PULONGLONG; - -/* Check VOID before defining CHAR, SHORT */ -#ifndef VOID -#define VOID void -typedef char CHAR; -typedef short SHORT; -#endif - -typedef CHAR *PCHAR; -typedef CHAR *PCH; -typedef void *HANDLE; -typedef char CCHAR; -typedef CCHAR *PCCHAR; - -#if 0 -#define FALSE 0 -#define TRUE 1 -#endif - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void*)0) -#endif /* __cplusplus */ -#endif /* NULL */ - -typedef const unsigned short *PCWSTR; - -typedef char* PCSZ; - -typedef union _LARGE_INTEGER -{ - struct - { - DWORD LowPart; - LONG HighPart; - } u; -#ifdef ANONYMOUSUNIONS - struct - { - DWORD LowPart; - LONG HighPart; - }; -#endif /* ANONYMOUSUNIONS */ - LONGLONG QuadPart; -} LARGE_INTEGER, *PLARGE_INTEGER; - -typedef union _ULARGE_INTEGER -{ - struct - { - DWORD LowPart; - DWORD HighPart; - } u; -#ifdef ANONYMOUSUNIONS - struct - { - DWORD LowPart; - DWORD HighPart; - }; -#endif /* ANONYMOUSUNIONS */ - ULONGLONG QuadPart; -} ULARGE_INTEGER, *PULARGE_INTEGER; - -typedef struct _FILETIME -{ - DWORD dwLowDateTime; - DWORD dwHighDateTime; -} FILETIME, *LPFILETIME, *PFILETIME; - -#define CONST const - -#ifdef i386 -#define STDCALL __attribute__ ((stdcall)) -#define CDECL __attribute((cdecl)) -#define CALLBACK WINAPI -#define PASCAL WINAPI -#else -#define STDCALL -#define CDECL -#define CALLBACK -#define PASCAL -#endif - -typedef struct _LIST_ENTRY { - struct _LIST_ENTRY *Flink; - struct _LIST_ENTRY *Blink; -} LIST_ENTRY, *PLIST_ENTRY; - -typedef struct _SINGLE_LIST_ENTRY { - struct _SINGLE_LIST_ENTRY *Next; -} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; - -typedef DWORD STDCALL (*PTHREAD_START_ROUTINE) (LPVOID); -typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; - -typedef unsigned short *PWCHAR; - -#ifdef __PPC__ -#define CONTEXT_CONTROL 1L -#define CONTEXT_FLOATING_POINT 2L -#define CONTEXT_INTEGER 4L -#define CONTEXT_DEBUG_REGISTERS 8L - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) -#define CONTEXT_DEBUGGER (CONTEXT_FULL) - -#else /* x86 */ -/* The doc refered me to winnt.h, so I had to look... */ -#define SIZE_OF_80387_REGISTERS 80 - -/* Values for contextflags */ -#define CONTEXT_i386 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386 | 1) -#define CONTEXT_INTEGER (CONTEXT_i386 | 2) -#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10) -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) - -/* our own invention */ -#define FLAG_TRACE_BIT 0x100 -#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) - -#endif - -#ifdef __i386__ - -typedef struct _FLOATING_SAVE_AREA { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - BYTE RegisterArea[80]; - DWORD Cr0NpxState; -} FLOATING_SAVE_AREA; - -typedef struct _CONTEXT { - DWORD ContextFlags; - - DWORD Dr0; - DWORD Dr1; - DWORD Dr2; - DWORD Dr3; - DWORD Dr6; - DWORD Dr7; - - FLOATING_SAVE_AREA FloatSave; - - DWORD SegGs; - DWORD SegFs; - DWORD SegEs; - DWORD SegDs; - - DWORD Edi; - DWORD Esi; - DWORD Ebx; - DWORD Edx; - DWORD Ecx; - DWORD Eax; - - DWORD Ebp; - DWORD Eip; - DWORD SegCs; - DWORD EFlags; - DWORD Esp; - DWORD SegSs; -} CONTEXT, *PCONTEXT, *LPCONTEXT; - -#else /* __ppc__ */ - -typedef struct - { - /* Floating point registers returned when CONTEXT_FLOATING_POINT is set */ - double Fpr0; - double Fpr1; - double Fpr2; - double Fpr3; - double Fpr4; - double Fpr5; - double Fpr6; - double Fpr7; - double Fpr8; - double Fpr9; - double Fpr10; - double Fpr11; - double Fpr12; - double Fpr13; - double Fpr14; - double Fpr15; - double Fpr16; - double Fpr17; - double Fpr18; - double Fpr19; - double Fpr20; - double Fpr21; - double Fpr22; - double Fpr23; - double Fpr24; - double Fpr25; - double Fpr26; - double Fpr27; - double Fpr28; - double Fpr29; - double Fpr30; - double Fpr31; - double Fpscr; - - /* Integer registers returned when CONTEXT_INTEGER is set. */ - DWORD Gpr0; - DWORD Gpr1; - DWORD Gpr2; - DWORD Gpr3; - DWORD Gpr4; - DWORD Gpr5; - DWORD Gpr6; - DWORD Gpr7; - DWORD Gpr8; - DWORD Gpr9; - DWORD Gpr10; - DWORD Gpr11; - DWORD Gpr12; - DWORD Gpr13; - DWORD Gpr14; - DWORD Gpr15; - DWORD Gpr16; - DWORD Gpr17; - DWORD Gpr18; - DWORD Gpr19; - DWORD Gpr20; - DWORD Gpr21; - DWORD Gpr22; - DWORD Gpr23; - DWORD Gpr24; - DWORD Gpr25; - DWORD Gpr26; - DWORD Gpr27; - DWORD Gpr28; - DWORD Gpr29; - DWORD Gpr30; - DWORD Gpr31; - - DWORD Cr; /* Condition register */ - DWORD Xer; /* Fixed point exception register */ - - /* The following are set when CONTEXT_CONTROL is set. */ - DWORD Msr; /* Machine status register */ - DWORD Iar; /* Instruction address register */ - DWORD Lr; /* Link register */ - DWORD Ctr; /* Control register */ - - /* Control which context values are returned */ - DWORD ContextFlags; - DWORD Fill[3]; - - /* Registers returned if CONTEXT_DEBUG_REGISTERS is set. */ - DWORD Dr0; /* Breakpoint Register 1 */ - DWORD Dr1; /* Breakpoint Register 2 */ - DWORD Dr2; /* Breakpoint Register 3 */ - DWORD Dr3; /* Breakpoint Register 4 */ - DWORD Dr4; /* Breakpoint Register 5 */ - DWORD Dr5; /* Breakpoint Register 6 */ - DWORD Dr6; /* Debug Status Register */ - DWORD Dr7; /* Debug Control Register */ -} CONTEXT, *PCONTEXT, *LPCONTEXT; -#endif - -typedef HANDLE *PHANDLE; - -typedef struct value_ent { - LPWSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} WVALENT, *PWVALENT; - - -typedef const void *LPCVOID; -typedef BYTE *LPBYTE, *PBYTE; - -typedef BOOL *PBOOL; - -typedef DWORD LCID; -typedef DWORD *PLCID; - -typedef const char *LPCSTR; - -typedef char *LPSTR; - -typedef const unsigned short *LPCWSTR; - -typedef unsigned short RTL_ATOM; -typedef unsigned short *PRTL_ATOM; -typedef WORD ATOM; - -typedef struct _COORD { - SHORT X; - SHORT Y; -} COORD; - -typedef struct _SMALL_RECT { - SHORT Left; - SHORT Top; - SHORT Right; - SHORT Bottom; -} SMALL_RECT, *PSMALL_RECT; - - -typedef -VOID -(*PTIMERAPCROUTINE)( - LPVOID lpArgToCompletionRoutine, - DWORD dwTimerLowValue, - DWORD dwTimerHighValue - ); - -#include - -#endif /* __INCLUDE_ACPI_TYPES_H */ - - - -#if 0 - - -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: include/types.h - * PURPOSE: Types used by all the parts of the system - * PROGRAMMER: David Welch - * UPDATE HISTORY: - * 27/06/00: Created - */ - #ifndef __INCLUDE_ACPI_TYPES_H #define __INCLUDE_ACPI_TYPES_H -#if 0 -typedef unsigned char UCHAR; -#endif -typedef unsigned int UINT; -typedef unsigned long ULONG; -typedef unsigned short USHORT; -typedef unsigned short WCHAR; -typedef unsigned short WORD; -typedef int BOOL; -#if 0 -typedef unsigned char BOOLEAN; -#endif -typedef BOOLEAN* PBOOLEAN; -typedef unsigned int DWORD; /* was unsigned long */ -typedef unsigned short *LPWSTR; -typedef unsigned short *PWSTR; -typedef unsigned char *PUCHAR; -typedef unsigned int *PUINT; -typedef unsigned long *PULONG; -typedef unsigned short *PUSHORT; -typedef void *PVOID; -typedef unsigned char BYTE; -typedef void *LPVOID; -typedef DWORD *PDWORD; -typedef float *PFLOAT; -typedef unsigned short *PWCH; -typedef unsigned short *PWORD; - -typedef long long LONGLONG; -typedef unsigned long long ULONGLONG; -typedef long long *PLONGLONG; -typedef unsigned long long *PULONGLONG; - -/* Check VOID before defining CHAR, SHORT, and LONG */ -#ifndef VOID -#define VOID void -typedef char CHAR; -typedef short SHORT; -typedef long LONG; -#endif - -typedef CHAR *PCHAR; -typedef CHAR *PCH; -typedef void *HANDLE; -typedef char CCHAR; - -#if 0 -#define FALSE 0 -#define TRUE 1 -#endif - -typedef const unsigned short *PCWSTR; - -typedef char* PCSZ; - -typedef union _LARGE_INTEGER -{ - struct - { - DWORD LowPart; - LONG HighPart; - } u; -#ifdef ANONYMOUSUNIONS - struct - { - DWORD LowPart; - LONG HighPart; - }; -#endif /* ANONYMOUSUNIONS */ - LONGLONG QuadPart; -} LARGE_INTEGER, *PLARGE_INTEGER; - -typedef union _ULARGE_INTEGER -{ - struct - { - DWORD LowPart; - DWORD HighPart; - } u; -#ifdef ANONYMOUSUNIONS - struct - { - DWORD LowPart; - DWORD HighPart; - }; -#endif /* ANONYMOUSUNIONS */ - ULONGLONG QuadPart; -} ULARGE_INTEGER, *PULARGE_INTEGER; - -#define CONST const - -#ifdef i386 -#define STDCALL __attribute__ ((stdcall)) -#define CDECL __attribute((cdecl)) -#define CALLBACK WINAPI -#define PASCAL WINAPI -#else -#define STDCALL -#define CDECL -#define CALLBACK -#define PASCAL -#endif - -typedef struct _LIST_ENTRY { - struct _LIST_ENTRY *Flink; - struct _LIST_ENTRY *Blink; -} LIST_ENTRY, *PLIST_ENTRY; - -typedef struct _SINGLE_LIST_ENTRY { - struct _SINGLE_LIST_ENTRY *Next; -} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; - -typedef DWORD STDCALL (*PTHREAD_START_ROUTINE) (LPVOID); -typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; - -typedef unsigned short *PWCHAR; - -#ifdef __PPC__ -#define CONTEXT_CONTROL 1L -#define CONTEXT_FLOATING_POINT 2L -#define CONTEXT_INTEGER 4L -#define CONTEXT_DEBUG_REGISTERS 8L - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) -#define CONTEXT_DEBUGGER (CONTEXT_FULL) -#else /* x86 */ -/* The doc refered me to winnt.h, so I had to look... */ -#define SIZE_OF_80387_REGISTERS 80 - -/* Values for contextflags */ -#define CONTEXT_i386 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386 | 1) -#define CONTEXT_INTEGER (CONTEXT_i386 | 2) -#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10) -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) - -/* our own invention */ -#define FLAG_TRACE_BIT 0x100 -#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) - -#endif - -#ifdef __i386__ - -typedef struct _FLOATING_SAVE_AREA { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - BYTE RegisterArea[80]; - DWORD Cr0NpxState; -} FLOATING_SAVE_AREA; - -typedef struct _CONTEXT { - DWORD ContextFlags; - - DWORD Dr0; - DWORD Dr1; - DWORD Dr2; - DWORD Dr3; - DWORD Dr6; - DWORD Dr7; - - FLOATING_SAVE_AREA FloatSave; - - DWORD SegGs; - DWORD SegFs; - DWORD SegEs; - DWORD SegDs; - - DWORD Edi; - DWORD Esi; - DWORD Ebx; - DWORD Edx; - DWORD Ecx; - DWORD Eax; - - DWORD Ebp; - DWORD Eip; - DWORD SegCs; - DWORD EFlags; - DWORD Esp; - DWORD SegSs; -} CONTEXT, *PCONTEXT, *LPCONTEXT; - -#else /* __ppc__ */ - -typedef struct - { - /* Floating point registers returned when CONTEXT_FLOATING_POINT is set */ - double Fpr0; - double Fpr1; - double Fpr2; - double Fpr3; - double Fpr4; - double Fpr5; - double Fpr6; - double Fpr7; - double Fpr8; - double Fpr9; - double Fpr10; - double Fpr11; - double Fpr12; - double Fpr13; - double Fpr14; - double Fpr15; - double Fpr16; - double Fpr17; - double Fpr18; - double Fpr19; - double Fpr20; - double Fpr21; - double Fpr22; - double Fpr23; - double Fpr24; - double Fpr25; - double Fpr26; - double Fpr27; - double Fpr28; - double Fpr29; - double Fpr30; - double Fpr31; - double Fpscr; - - /* Integer registers returned when CONTEXT_INTEGER is set. */ - DWORD Gpr0; - DWORD Gpr1; - DWORD Gpr2; - DWORD Gpr3; - DWORD Gpr4; - DWORD Gpr5; - DWORD Gpr6; - DWORD Gpr7; - DWORD Gpr8; - DWORD Gpr9; - DWORD Gpr10; - DWORD Gpr11; - DWORD Gpr12; - DWORD Gpr13; - DWORD Gpr14; - DWORD Gpr15; - DWORD Gpr16; - DWORD Gpr17; - DWORD Gpr18; - DWORD Gpr19; - DWORD Gpr20; - DWORD Gpr21; - DWORD Gpr22; - DWORD Gpr23; - DWORD Gpr24; - DWORD Gpr25; - DWORD Gpr26; - DWORD Gpr27; - DWORD Gpr28; - DWORD Gpr29; - DWORD Gpr30; - DWORD Gpr31; - - DWORD Cr; /* Condition register */ - DWORD Xer; /* Fixed point exception register */ - - /* The following are set when CONTEXT_CONTROL is set. */ - DWORD Msr; /* Machine status register */ - DWORD Iar; /* Instruction address register */ - DWORD Lr; /* Link register */ - DWORD Ctr; /* Control register */ - - /* Control which context values are returned */ - DWORD ContextFlags; - DWORD Fill[3]; - - /* Registers returned if CONTEXT_DEBUG_REGISTERS is set. */ - DWORD Dr0; /* Breakpoint Register 1 */ - DWORD Dr1; /* Breakpoint Register 2 */ - DWORD Dr2; /* Breakpoint Register 3 */ - DWORD Dr3; /* Breakpoint Register 4 */ - DWORD Dr4; /* Breakpoint Register 5 */ - DWORD Dr5; /* Breakpoint Register 6 */ - DWORD Dr6; /* Debug Status Register */ - DWORD Dr7; /* Debug Control Register */ -} CONTEXT, *PCONTEXT, *LPCONTEXT; -#endif - -typedef HANDLE *PHANDLE; - -typedef struct value_ent { - LPWSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} WVALENT, *PWVALENT; - -typedef long *PLONG; - -typedef const void *LPCVOID; -typedef BYTE *LPBYTE; - -typedef BYTE *PBYTE; - -typedef DWORD LCID; -typedef DWORD *PLCID; - -typedef const char *LPCSTR; - -typedef char *LPSTR; - -typedef const unsigned short *LPCWSTR; - -typedef unsigned short RTL_ATOM; -typedef unsigned short *PRTL_ATOM; -typedef WORD ATOM; - -typedef struct _COORD { - SHORT X; - SHORT Y; -} COORD; - -typedef struct _SMALL_RECT { - SHORT Left; - SHORT Top; - SHORT Right; - SHORT Bottom; -} SMALL_RECT, *PSMALL_RECT; - - -typedef -VOID -(*PTIMERAPCROUTINE)( - LPVOID lpArgToCompletionRoutine, - DWORD dwTimerLowValue, - DWORD dwTimerHighValue - ); - -#include +#include #endif /* __INCLUDE_ACPI_TYPES_H */ - -#endif - diff --git a/drivers/bus/acpi/ospm/.cvsignore b/drivers/bus/acpi/ospm/.cvsignore index dfa5ac2..31dc307 100644 --- a/drivers/bus/acpi/ospm/.cvsignore +++ b/drivers/bus/acpi/ospm/.cvsignore @@ -1,5 +1,2 @@ -acpi.coff -objects *.d *.o -*.sym diff --git a/drivers/bus/acpi/ospm/busmgr/.cvsignore b/drivers/bus/acpi/ospm/busmgr/.cvsignore new file mode 100644 index 0000000..31dc307 --- /dev/null +++ b/drivers/bus/acpi/ospm/busmgr/.cvsignore @@ -0,0 +1,2 @@ +*.d +*.o diff --git a/drivers/bus/acpi/ospm/include/acpisys.h b/drivers/bus/acpi/ospm/include/acpisys.h index e8f4f85..ea89815 100644 --- a/drivers/bus/acpi/ospm/include/acpisys.h +++ b/drivers/bus/acpi/ospm/include/acpisys.h @@ -5,9 +5,6 @@ */ #define ACPI_DEBUG #include -#define __INCLUDE_TYPES_H -#include -#undef ROUND_UP #include #include diff --git a/drivers/bus/acpi/ospm/osl.c b/drivers/bus/acpi/ospm/osl.c index f46fd17..bae1851 100644 --- a/drivers/bus/acpi/ospm/osl.c +++ b/drivers/bus/acpi/ospm/osl.c @@ -148,15 +148,11 @@ acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt) } } - if ((ULONG)phys >= 0x100000) { - Address.QuadPart = (ULONG)phys; - *virt = MmMapIoSpace(Address, size, FALSE); - if (!*virt) - return AE_ERROR; - } else { - *virt = (PVOID)((ULONG)phys); - } - + Address.QuadPart = (ULONG)phys; + *virt = MmMapIoSpace(Address, size, FALSE); + if (!*virt) + return AE_ERROR; + return AE_OK; } @@ -171,9 +167,7 @@ acpi_os_unmap_memory(void *virt, u32 size) IVTVirtualAddress = NULL; return; } - /* FIXME: Causes "Memory area is NULL" bugcheck in marea.c */ - //if ((ULONG)virt >= 0x100000) - //MmUnmapIoSpace(virt, size); + MmUnmapIoSpace(virt, size); } ACPI_STATUS @@ -592,14 +586,14 @@ acpi_os_get_line(NATIVE_CHAR *buffer) return 0; } -BOOLEAN +u8 acpi_os_readable(void *ptr, u32 len) { /* Always readable */ return TRUE; } -BOOLEAN +u8 acpi_os_writable(void *ptr, u32 len) { /* Always writable */ diff --git a/drivers/bus/acpi/resource/.cvsignore b/drivers/bus/acpi/resource/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/bus/acpi/resource/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/bus/isapnp/.cvsignore b/drivers/bus/isapnp/.cvsignore index 3481446..927e454 100644 --- a/drivers/bus/isapnp/.cvsignore +++ b/drivers/bus/isapnp/.cvsignore @@ -6,3 +6,4 @@ isapnp.sys.unstripped *.d *.o *.sym +*.sys diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index ae6569d..4578c75 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -215,21 +215,26 @@ VOID DeactivateLogicalDevice(UCHAR LogicalDevice) static ULONG FindNextReadPort(VOID) { - ULONG Port; - - Port = (ULONG)IsaPnPReadPort; - while (Port <= ISAPNP_MAX_READ_PORT) { - /* - * We cannot use NE2000 probe spaces for - * ISAPnP or we will lock up machines - */ - if ((Port < 0x280) || (Port > 0x380)) - { - return Port; - } - Port += READ_DATA_PORT_STEP; - } - return 0; + ULONG Port; + + Port = (ULONG)IsaPnPReadPort; + while (TRUE) { + Port += READ_DATA_PORT_STEP; + + if (Port > ISAPNP_MAX_READ_PORT) + { + return 0; + } + + /* + * We cannot use NE2000 probe spaces for + * ISAPnP or we will lock up machines + */ + if ((Port < 0x280) || (Port > 0x380)) + { + return Port; + } + } } static BOOLEAN IsolateReadDataPortSelect(VOID) diff --git a/drivers/bus/isapnp/isapnp.rc b/drivers/bus/isapnp/isapnp.rc index 205420a..a5e9847 100644 --- a/drivers/bus/isapnp/isapnp.rc +++ b/drivers/bus/isapnp/isapnp.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/bus/pci/.cvsignore b/drivers/bus/pci/.cvsignore index 9ce3594..879e26d 100644 --- a/drivers/bus/pci/.cvsignore +++ b/drivers/bus/pci/.cvsignore @@ -2,3 +2,4 @@ pci.coff *.d *.o *.sym +*.sys diff --git a/drivers/bus/pci/pci.rc b/drivers/bus/pci/pci.rc index e21a994..c7dc861 100644 --- a/drivers/bus/pci/pci.rc +++ b/drivers/bus/pci/pci.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/dd/beep/.cvsignore b/drivers/dd/beep/.cvsignore index ca1cbcf..68ae269 100644 --- a/drivers/dd/beep/.cvsignore +++ b/drivers/dd/beep/.cvsignore @@ -2,3 +2,6 @@ base.tmp junk.tmp temp.exp beep.coff +*.o +*.sym +*.sys diff --git a/drivers/dd/beep/beep.rc b/drivers/dd/beep/beep.rc index c48ff21..ff7c484 100644 --- a/drivers/dd/beep/beep.rc +++ b/drivers/dd/beep/beep.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/dd/blue/.cvsignore b/drivers/dd/blue/.cvsignore index ae9bad6..776fd2f 100644 --- a/drivers/dd/blue/.cvsignore +++ b/drivers/dd/blue/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp blue.coff -blue.sys.unstripped \ No newline at end of file +*.o +*.sym +*.sys diff --git a/drivers/dd/blue/blue.rc b/drivers/dd/blue/blue.rc index dafbe1f..971d805 100644 --- a/drivers/dd/blue/blue.rc +++ b/drivers/dd/blue/blue.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/dd/floppy/.cvsignore b/drivers/dd/floppy/.cvsignore index 8bfa9ae..6a46e57 100644 --- a/drivers/dd/floppy/.cvsignore +++ b/drivers/dd/floppy/.cvsignore @@ -1,2 +1,4 @@ -floppy.sys.unstripped floppy.coff +*.sys +*.o +*.sym diff --git a/drivers/dd/floppy/floppy.c b/drivers/dd/floppy/floppy.c index e5e54e4..d40c5f0 100644 --- a/drivers/dd/floppy/floppy.c +++ b/drivers/dd/floppy/floppy.c @@ -23,8 +23,8 @@ FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] = { - {0x03f0, 6, 6, 2, 6, LevelSensitive, 0xffff} - // {0x0370, 6, 6, 6, LevelSensitive, 0xffff}, + {0x03f0, 6, 2, Latched} + // {0x0370, 6, 6, Latched} }; const FLOPPY_MEDIA_TYPE MediaTypes[] = { @@ -50,8 +50,17 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, PCONFIGURATION_INFORMATION Config; DEVICE_DESCRIPTION DeviceDescription; ULONG MaxMapRegs; + ULONG MappedIrq; + KIRQL Dirql; + KAFFINITY Affinity; - /* FIXME: Register port ranges and interrupts with HAL */ + /* FIXME: Register port ranges with HAL */ + MappedIrq = HalGetInterruptVector(Isa, + 0, + ControllerParameters->Vector, + ControllerParameters->Vector, + &Dirql, + &Affinity); /* Create controller object for FDC */ ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION)); @@ -67,7 +76,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, ControllerObject->ControllerExtension; ControllerExtension->Number = Index; ControllerExtension->PortBase = ControllerParameters->PortBase; - ControllerExtension->Vector = ControllerParameters->Vector; + ControllerExtension->Vector = MappedIrq; KeInitializeEvent( &ControllerExtension->Event, SynchronizationEvent, FALSE ); ControllerExtension->Device = 0; // no active device ControllerExtension->Irp = 0; // no active IRP @@ -81,12 +90,12 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, FloppyIsr, ControllerObject, &ControllerExtension->SpinLock, - ControllerExtension->Vector, - ControllerParameters->IrqL, - ControllerParameters->SynchronizeIrqL, + MappedIrq, + Dirql, + Dirql, ControllerParameters->InterruptMode, FALSE, - ControllerParameters->Affinity, + Affinity, FALSE); if (!NT_SUCCESS(Status)) { diff --git a/drivers/dd/floppy/floppy.h b/drivers/dd/floppy/floppy.h index 4568c47..3ac15d3 100644 --- a/drivers/dd/floppy/floppy.h +++ b/drivers/dd/floppy/floppy.h @@ -171,11 +171,8 @@ typedef struct _FLOPPY_CONTROLLER_PARAMETERS { ULONG PortBase; ULONG Vector; - ULONG IrqL; ULONG DmaChannel; - ULONG SynchronizeIrqL; KINTERRUPT_MODE InterruptMode; - KAFFINITY Affinity; } FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS; #define FLOPPY_MAX_CONTROLLERS 1 diff --git a/drivers/dd/floppy/floppy.rc b/drivers/dd/floppy/floppy.rc index 61da49f..fd1d0e3 100644 --- a/drivers/dd/floppy/floppy.rc +++ b/drivers/dd/floppy/floppy.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/dd/ide/.cvsignore b/drivers/dd/ide/.cvsignore index dc98dbc..ddc929b 100644 --- a/drivers/dd/ide/.cvsignore +++ b/drivers/dd/ide/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp ide.coff -ide.sys.unstripped +*.sys +*.sym +*.o diff --git a/drivers/dd/ide/ide.c b/drivers/dd/ide/ide.c index 073d30d..8369998 100644 --- a/drivers/dd/ide/ide.c +++ b/drivers/dd/ide/ide.c @@ -90,10 +90,7 @@ typedef struct _IDE_CONTROLLER_PARAMETERS int ControlPortBase; int ControlPortSpan; int Vector; - int IrqL; - int SynchronizeIrqL; KINTERRUPT_MODE InterruptMode; - KAFFINITY Affinity; } IDE_CONTROLLER_PARAMETERS, *PIDE_CONTROLLER_PARAMETERS; // NOTE: Do not increase max drives above 2 @@ -103,10 +100,10 @@ typedef struct _IDE_CONTROLLER_PARAMETERS #define IDE_MAX_CONTROLLERS 2 IDE_CONTROLLER_PARAMETERS Controllers[IDE_MAX_CONTROLLERS] = { - {0x01f0, 8, 0x03f6, 1, 14, 14, 15, LevelSensitive, 0xffff}, - {0x0170, 8, 0x0376, 1, 15, 15, 15, LevelSensitive, 0xffff} -/* {0x01E8, 8, 0x03ee, 1, 11, 11, 15, LevelSensitive, 0xffff}, - {0x0168, 8, 0x036e, 1, 10, 10, 15, LevelSensitive, 0xffff}*/ + {0x01f0, 8, 0x03f6, 1, 14, Latched}, + {0x0170, 8, 0x0376, 1, 15, Latched} +/* {0x01E8, 8, 0x03ee, 1, 11, LevelSensitive}, + {0x0168, 8, 0x036e, 1, 10, LevelSensitive}*/ }; static BOOLEAN IDEInitialized = FALSE; @@ -487,6 +484,9 @@ IdeCreateController(IN PDRIVER_OBJECT DriverObject, NTSTATUS RC; PCONTROLLER_OBJECT ControllerObject; PIDE_CONTROLLER_EXTENSION ControllerExtension; + ULONG MappedIrq; + KIRQL Dirql; + KAFFINITY Affinity; ControllerObject = IoCreateController(sizeof(IDE_CONTROLLER_EXTENSION)); if (ControllerObject == NULL) @@ -496,13 +496,20 @@ IdeCreateController(IN PDRIVER_OBJECT DriverObject, return STATUS_NO_SUCH_DEVICE; } + MappedIrq = HalGetInterruptVector(Isa, + 0, + ControllerParams->Vector, + ControllerParams->Vector, + &Dirql, + &Affinity); + // Fill out Controller extension data ControllerExtension = (PIDE_CONTROLLER_EXTENSION) ControllerObject->ControllerExtension; ControllerExtension->Number = ControllerIdx; ControllerExtension->CommandPortBase = ControllerParams->CommandPortBase; ControllerExtension->ControlPortBase = ControllerParams->ControlPortBase; - ControllerExtension->Vector = ControllerParams->Vector; + ControllerExtension->Vector = MappedIrq; ControllerExtension->DMASupported = FALSE; ControllerExtension->ControllerInterruptBug = FALSE; ControllerExtension->OperationInProgress = FALSE; @@ -516,11 +523,11 @@ IdeCreateController(IN PDRIVER_OBJECT DriverObject, ControllerExtension, &ControllerExtension->SpinLock, ControllerExtension->Vector, - ControllerParams->IrqL, - ControllerParams->SynchronizeIrqL, + Dirql, + Dirql, ControllerParams->InterruptMode, FALSE, - ControllerParams->Affinity, + Affinity, FALSE); if (!NT_SUCCESS(RC)) { diff --git a/drivers/dd/null/.cvsignore b/drivers/dd/null/.cvsignore index 03978ec..f29f9a9 100644 --- a/drivers/dd/null/.cvsignore +++ b/drivers/dd/null/.cvsignore @@ -1,7 +1,7 @@ -null.coff -null.sys -null.sys.unstripped base.tmp junk.tmp temp.exp - +null.coff +*.sym +*.o +*.sys diff --git a/drivers/dd/vga/display/.cvsignore b/drivers/dd/vga/display/.cvsignore index ea9f9c0..9d2f7c9 100644 --- a/drivers/dd/vga/display/.cvsignore +++ b/drivers/dd/vga/display/.cvsignore @@ -1,3 +1,4 @@ vgaddi.coff -vgaddi.dll -vgaddi.nostrip.dll \ No newline at end of file +*.sym +*.o +*.dll diff --git a/drivers/dd/vga/display/main/.cvsignore b/drivers/dd/vga/display/main/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/dd/vga/display/main/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/dd/vga/display/objects/.cvsignore b/drivers/dd/vga/display/objects/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/dd/vga/display/objects/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/dd/vga/display/objects/bitblt.c b/drivers/dd/vga/display/objects/bitblt.c index 963b66b..02fd0bc 100644 --- a/drivers/dd/vga/display/objects/bitblt.c +++ b/drivers/dd/vga/display/objects/bitblt.c @@ -8,7 +8,7 @@ typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*); -BOOL +BOOL DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint) { @@ -16,25 +16,25 @@ DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, BYTE *GDIpos, *initial, *tMask, *lMask; GDIpos = Source->pvBits; - + dx = DestRect->right - DestRect->left; dy = DestRect->bottom - DestRect->top; - + alterx = abs(SourcePoint->x - DestRect->left); altery = abs(SourcePoint->y - DestRect->top); if (ColorTranslation == NULL) - { - DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, + { + DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, Source->lDelta); - } + } else { /* Perform color translation */ for (j = SourcePoint->y; j < SourcePoint->y+dy; j++) { initial = GDIpos; - + for (i=SourcePoint->x; ix+dx; i++) { idxColor = XLATEOBJ_iXlate(ColorTranslation, *GDIpos); @@ -97,7 +97,7 @@ DFBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, // Do DFBs need color translation?? } -BOOL +BOOL VGAtoDFB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint) { @@ -200,14 +200,14 @@ VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect, /* Fill any pixels on the left which don't fall into a full row of eight. */ if ((DestRect->left % 8) != 0) - { + { /* Disable writes to pixels outside of the destination rectangle. */ Mask = (1 << (8 - (DestRect->left % 8))) - 1; if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8))) { Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1); } - WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); /* Write the same color to each pixel. */ @@ -220,7 +220,7 @@ VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect, } /* Enable writes to all pixels. */ - WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); /* Have we finished. */ @@ -231,9 +231,9 @@ VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect, /* Fill any whole rows of eight pixels. */ Left = (DestRect->left + 7) & ~0x7; - Length = (DestRect->right >> 3) - (Left >> 3); + Length = (DestRect->right >> 3) - (Left >> 3); for (i = DestRect->top; i < DestRect->bottom; i++) - { + { Video = (PUCHAR)vidmem + i * 80 + (Left >> 3); for (j = 0; j < Length; j++, Video++) { @@ -246,7 +246,7 @@ VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect, { /* Disable writes to pixels outside the destination rectangle. */ Mask = ~((1 << (8 - (DestRect->right % 8))) - 1); - WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3); @@ -259,7 +259,7 @@ VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect, } /* Restore the default write masks. */ - WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); } return(TRUE); @@ -273,17 +273,17 @@ VGADDI_BltSrc(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, BOOL EnumMore; PFN_VGABlt BltOperation; ULONG SourceType; - + SourceType = Source->iType; if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE) { BltOperation = DIBtoVGA; - } + } else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP) { BltOperation = VGAtoDIB; - } + } else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE) { BltOperation = VGAtoVGA; @@ -313,12 +313,12 @@ VGADDI_BltMask(SURFOBJ *Dest, SURFOBJ *Mask, XLATEOBJ *ColorTranslation, { LONG i, j, dx, dy, idxColor, RGBulong = 0, c8; BYTE *initial, *tMask, *lMask; - + dx = DestRect->right - DestRect->left; dy = DestRect->bottom - DestRect->top; - + if (ColorTranslation == NULL) - { + { if (Mask != NULL) { tMask = Mask->pvBits; @@ -369,7 +369,7 @@ DrvBitBlt(SURFOBJ *Dest, BrushPoint, rop4)); case SRCCOPY: - return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, + return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, SourcePoint)); case 0xAACC: diff --git a/drivers/dd/vga/display/objects/offscreen.c b/drivers/dd/vga/display/objects/offscreen.c index 4c8fba8..b01ad60 100644 --- a/drivers/dd/vga/display/objects/offscreen.c +++ b/drivers/dd/vga/display/objects/offscreen.c @@ -54,7 +54,8 @@ VGADDI_BltFromSavedScreenBits(ULONG DestX, for (i = 0; i < SizeY; i++) { DestOffset = (PUCHAR)vidmem + (i + DestY) * 80 + (DestX >> 3); - for (j = 0; j < SizeX; j++, SrcOffset++, DestOffset++) + //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes + for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++) { (VOID)READ_REGISTER_UCHAR(SrcOffset); WRITE_REGISTER_UCHAR(DestOffset, 0); @@ -86,7 +87,8 @@ VGADDI_BltToSavedScreenBits(PSAVED_SCREEN_BITS Dest, for (i = 0; i < SizeY; i++) { SrcOffset = (PUCHAR)vidmem + (SourceY + i) * 80 + (SourceX >> 3); - for (j = 0; j < SizeX; j++, SrcOffset++, DestOffset++) + //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes + for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++) { (VOID)READ_REGISTER_UCHAR(SrcOffset); WRITE_REGISTER_UCHAR(DestOffset, 0); @@ -107,7 +109,7 @@ VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits) { PSAVED_SCREEN_BITS Previous; - Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink, + Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink, SAVED_SCREEN_BITS, ListEntry); if (Previous->Free) { @@ -121,7 +123,7 @@ VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits) { PSAVED_SCREEN_BITS Next; - Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS, + Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS, ListEntry); if (Next->Free) { diff --git a/drivers/dd/vga/display/objects/pointer.c b/drivers/dd/vga/display/objects/pointer.c index 3178ee8..8b6460a 100644 --- a/drivers/dd/vga/display/objects/pointer.c +++ b/drivers/dd/vga/display/objects/pointer.c @@ -72,9 +72,9 @@ VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, Mask &= ~((1 << (8 - (EndX % 8))) - 1); } WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); - WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); - /* Write the mask. */ + /* Write the mask. */ Video = (PUCHAR)vidmem + StartY * 80 + (StartX >> 3); Src = MaskBits; for (i = 0; i < SizeY; i++, Video+=80, Src+=MaskPitch) @@ -97,9 +97,9 @@ VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, /* Fill any whole rows of eight pixels. */ Left = (StartX + 7) & ~0x7; - Length = (EndX >> 3) - (Left >> 3); + Length = (EndX >> 3) - (Left >> 3); for (i = StartY; i < EndY; i++) - { + { Video = (PUCHAR)vidmem + i * 80 + (Left >> 3); Src = MaskBits + (i - StartY) * MaskPitch; for (j = 0; j < Length; j++, Video++, Src++) @@ -185,19 +185,19 @@ DrvMovePointer(IN PSURFOBJ pso, IN PRECTL prcl) { PPDEV ppdev = (PPDEV)pso->dhpdev; - - if (x == -1) + + if (x < 0 ) { - /* x == -1 and y == -1 indicates we must hide the cursor */ + /* x < 0 and y < 0 indicates we must hide the cursor */ VGADDI_HideCursor(ppdev); return; } - + ppdev->xyCursor.x = x; ppdev->xyCursor.y = y; VGADDI_ShowCursor(ppdev); - + /* Give feedback on the new cursor rectangle */ /*if (prcl != NULL) ComputePointerRect(ppdev, prcl);*/ } @@ -224,7 +224,7 @@ DrvSetPointerShape(PSURFOBJ pso, NewHeight = (psoMask->cjBits / psoMask->lDelta) / 2; /* Hide the cursor */ - if(ppdev->pPointerAttributes->Enable != 0) + if(ppdev->pPointerAttributes->Enable != 0) { VGADDI_HideCursor(ppdev); } @@ -256,7 +256,7 @@ DrvSetPointerShape(PSURFOBJ pso, ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); } - /* Copy the new cursor in. */ + /* Copy the new cursor in. */ for (i = 0; i < (NewHeight * 2); i++) { Src = (PUCHAR)psoMask->pvBits; @@ -281,7 +281,7 @@ DrvSetPointerShape(PSURFOBJ pso, VGADDI_ShowCursor(ppdev); } -VOID +VOID VGADDI_HideCursor(PPDEV ppdev) { ULONG i, j, cx, cy, bitpos; @@ -291,7 +291,7 @@ VGADDI_HideCursor(PPDEV ppdev) SizeX = ((oldx + ppdev->pPointerAttributes->Width) + 7) & ~0x7; SizeX -= (oldx & ~0x7); VGADDI_BltFromSavedScreenBits(oldx & ~0x7, - oldy, + oldy, ImageBehindCursor, SizeX, ppdev->pPointerAttributes->Height); @@ -299,14 +299,14 @@ VGADDI_HideCursor(PPDEV ppdev) ppdev->pPointerAttributes->Enable = 0; } -VOID +VOID VGADDI_ShowCursor(PPDEV ppdev) { ULONG i, j, cx, cy; PUCHAR AndMask; ULONG SizeX; - if (ppdev->pPointerAttributes->Enable != 0) + if (ppdev->pPointerAttributes->Enable != 0) { VGADDI_HideCursor(ppdev); } @@ -318,6 +318,7 @@ VGADDI_ShowCursor(PPDEV ppdev) /* Used to repaint background */ SizeX = ((cx + ppdev->pPointerAttributes->Width) + 7) & ~0x7; SizeX -= (cx & ~0x7); + VGADDI_BltToSavedScreenBits(ImageBehindCursor, cx & ~0x7, cy, @@ -326,14 +327,14 @@ VGADDI_ShowCursor(PPDEV ppdev) /* Display the cursor. */ AndMask = ppdev->pPointerAttributes->Pixels + - ppdev->pPointerAttributes->WidthInBytes * + ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height; VGADDI_BltPointerToVGA(ppdev->xyCursor.x, ppdev->xyCursor.y, ppdev->pPointerAttributes->Width, ppdev->pPointerAttributes->Height, AndMask, - VGA_AND); + VGA_AND); VGADDI_BltPointerToVGA(ppdev->xyCursor.x, ppdev->xyCursor.y, ppdev->pPointerAttributes->Width, diff --git a/drivers/dd/vga/display/vgaddi.rc b/drivers/dd/vga/display/vgaddi.rc index 5c34e3d..8a3dd7c 100644 --- a/drivers/dd/vga/display/vgaddi.rc +++ b/drivers/dd/vga/display/vgaddi.rc @@ -1,5 +1,5 @@ -#include "../../../../include/defines.h" -#include "../../../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/drivers/dd/vga/display/vgavideo/.cvsignore b/drivers/dd/vga/display/vgavideo/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/dd/vga/display/vgavideo/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/dd/vga/miniport/.cvsignore b/drivers/dd/vga/miniport/.cvsignore index 5e596a5..1630a60 100644 --- a/drivers/dd/vga/miniport/.cvsignore +++ b/drivers/dd/vga/miniport/.cvsignore @@ -2,5 +2,6 @@ junk.tmp base.tmp temp.exp vgamp.coff -vgamp.sys -vgamp.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/dd/vga/miniport/vgamp.rc b/drivers/dd/vga/miniport/vgamp.rc index b9c24bd..1497680 100644 --- a/drivers/dd/vga/miniport/vgamp.rc +++ b/drivers/dd/vga/miniport/vgamp.rc @@ -1,5 +1,5 @@ -#include "../../../../include/defines.h" -#include "../../../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/drivers/dd/vidport/.cvsignore b/drivers/dd/vidport/.cvsignore index 6469429..ed28e11 100644 --- a/drivers/dd/vidport/.cvsignore +++ b/drivers/dd/vidport/.cvsignore @@ -1,2 +1,4 @@ vidport.coff -vidport.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/fs/cdfs/.cvsignore b/drivers/fs/cdfs/.cvsignore index 19a0241..40376bf 100644 --- a/drivers/fs/cdfs/.cvsignore +++ b/drivers/fs/cdfs/.cvsignore @@ -2,5 +2,7 @@ base.tmp junk.tmp temp.exp cdfs.coff -cdfs.sys.unstripped -*.d \ No newline at end of file +*.d +*.sys +*.o +*.sym diff --git a/drivers/fs/cdfs/cleanup.c b/drivers/fs/cdfs/cleanup.c index d989897..4f0a71a 100644 --- a/drivers/fs/cdfs/cleanup.c +++ b/drivers/fs/cdfs/cleanup.c @@ -58,8 +58,11 @@ CdfsCleanupFile(PDEVICE_EXTENSION DeviceExt, return STATUS_SUCCESS; } - /* Uninitialize the file cache. */ - CcRosReleaseFileCache (FileObject, Ccb->Fcb->RFCB.Bcb); + /* Uninitialize file cache if initialized for this file object. */ + if (Ccb->Fcb->RFCB.Bcb != NULL) + { + CcRosReleaseFileCache (FileObject, Ccb->Fcb->RFCB.Bcb); + } return STATUS_SUCCESS; } diff --git a/drivers/fs/cdfs/finfo.c b/drivers/fs/cdfs/finfo.c index f3d6638..2290658 100644 --- a/drivers/fs/cdfs/finfo.c +++ b/drivers/fs/cdfs/finfo.c @@ -403,7 +403,7 @@ CdfsSetInformation(PDEVICE_OBJECT DeviceObject, NTSTATUS Status = STATUS_SUCCESS; - DPRINT1("CdfsSetInformation() called\n"); + DPRINT("CdfsSetInformation() called\n"); Stack = IoGetCurrentIrpStackLocation(Irp); FileInformationClass = Stack->Parameters.SetFile.FileInformationClass; diff --git a/drivers/fs/cdfs/rw.c b/drivers/fs/cdfs/rw.c index 75eda1b..82ae382 100644 --- a/drivers/fs/cdfs/rw.c +++ b/drivers/fs/cdfs/rw.c @@ -68,24 +68,23 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, *LengthRead = 0; if (Length == 0) - return STATUS_SUCCESS; + return(STATUS_SUCCESS); Ccb = (PCCB)FileObject->FsContext2; Fcb = Ccb->Fcb; - if (ReadOffset + Length > Fcb->Entry.DataLengthL) - Length = Fcb->Entry.DataLengthL - ReadOffset; + if (ReadOffset >= Fcb->Entry.DataLengthL) + return(STATUS_END_OF_FILE); DPRINT("Reading %d bytes at %d\n", Length, ReadOffset); - if (Length == 0) - return(STATUS_UNSUCCESSFUL); - if (!(IrpFlags & (IRP_NOCACHE|IRP_PAGING_IO))) { LARGE_INTEGER FileOffset; IO_STATUS_BLOCK IoStatus; + if (ReadOffset + Length > Fcb->Entry.DataLengthL) + Length = Fcb->Entry.DataLengthL - ReadOffset; if (FileObject->PrivateCacheMap == NULL) { CcRosInitializeFileCache(FileObject, &Fcb->RFCB.Bcb, PAGE_SIZE); @@ -103,60 +102,25 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, return(IoStatus.Status); } - if ((ReadOffset % BLOCKSIZE) != 0) + if ((ReadOffset % BLOCKSIZE) != 0 || (Length % BLOCKSIZE) != 0) { - TempLength = min(Length, BLOCKSIZE - (ReadOffset % BLOCKSIZE)); - TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE); - - Status = CdfsReadSectors(DeviceExt->StorageDevice, - Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE), - 1, - TempBuffer); - if (NT_SUCCESS(Status)) - { - memcpy(Buffer, TempBuffer + (ReadOffset % BLOCKSIZE), TempLength); - (*LengthRead) = (*LengthRead) + TempLength; - Length = Length - TempLength; - Buffer = Buffer + TempLength; - ReadOffset = ReadOffset + TempLength; - } - ExFreePool(TempBuffer); + return STATUS_INVALID_PARAMETER; } + if (ReadOffset + Length > ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE)) + Length = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE) - ReadOffset; - DPRINT("Status %lx\n", Status); - - if ((Length / BLOCKSIZE) != 0 && NT_SUCCESS(Status)) - { - TempLength = ROUND_DOWN(Length, BLOCKSIZE); - Status = CdfsReadSectors(DeviceExt->StorageDevice, - Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE), - TempLength / BLOCKSIZE, - Buffer); - if (NT_SUCCESS(Status)) - { - (*LengthRead) = (*LengthRead) + TempLength; - Length = Length - TempLength; - Buffer = Buffer + TempLength; - ReadOffset = ReadOffset + TempLength; - } - } - - DPRINT("Status %lx\n", Status); - - if (Length > 0 && NT_SUCCESS(Status)) + Status = CdfsReadSectors(DeviceExt->StorageDevice, + Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE), + Length / BLOCKSIZE, + Buffer); + if (NT_SUCCESS(Status)) { - TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE); - - Status = CdfsReadSectors(DeviceExt->StorageDevice, - Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE), - 1, - TempBuffer); - if (NT_SUCCESS(Status)) - { - memcpy(Buffer, TempBuffer, Length); - (*LengthRead) = (*LengthRead) + Length; - } - ExFreePool(TempBuffer); + *LengthRead = Length; + if (Length + ReadOffset > Fcb->Entry.DataLengthL) + { + memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset, + 0, Length + ReadOffset - Fcb->Entry.DataLengthL); + } } return(Status); diff --git a/drivers/fs/fs_rec/.cvsignore b/drivers/fs/fs_rec/.cvsignore index 43fea5d..b676d35 100644 --- a/drivers/fs/fs_rec/.cvsignore +++ b/drivers/fs/fs_rec/.cvsignore @@ -2,5 +2,7 @@ base.tmp junk.tmp temp.exp fs_rec.coff -fs_rec.sys.unstripped -*.d \ No newline at end of file +*.d +*.o +*.sym +*.sys diff --git a/drivers/fs/fs_rec/cdfs.c b/drivers/fs/fs_rec/cdfs.c index f65143d..518ada3 100644 --- a/drivers/fs/fs_rec/cdfs.c +++ b/drivers/fs/fs_rec/cdfs.c @@ -76,6 +76,7 @@ FsRecIsCdfsVolume(IN PDEVICE_OBJECT DeviceObject) if (!NT_SUCCESS(Status)) { DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status); + ExFreePool(Buffer); return(Status); } diff --git a/drivers/fs/fs_rec/fat.c b/drivers/fs/fs_rec/fat.c index 5d884c4..f3ad203 100644 --- a/drivers/fs/fs_rec/fat.c +++ b/drivers/fs/fs_rec/fat.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/fs_rec/vfat.c + * FILE: drivers/fs/fs_rec/vfat.c * PURPOSE: Filesystem recognizer driver * PROGRAMMER: Eric Kohl */ @@ -73,6 +73,7 @@ FsRecIsFatVolume(IN PDEVICE_OBJECT DeviceObject) Buffer); if (!NT_SUCCESS(Status)) { + ExFreePool(Buffer); return(Status); } diff --git a/drivers/fs/fs_rec/fs_rec.c b/drivers/fs/fs_rec/fs_rec.c index 89943d1..8342d34 100644 --- a/drivers/fs/fs_rec/fs_rec.c +++ b/drivers/fs/fs_rec/fs_rec.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/fs_rec/fs_rec.c + * FILE: drivers/fs/fs_rec/fs_rec.c * PURPOSE: Filesystem recognizer driver * PROGRAMMER: Eric Kohl */ @@ -81,12 +81,16 @@ FsRecFsControl(IN PDEVICE_OBJECT DeviceObject, Status = FsRecVfatFsControl(DeviceObject, Irp); break; + case FS_TYPE_NTFS: + Status = FsRecNtfsFsControl(DeviceObject, Irp); + break; + case FS_TYPE_CDFS: Status = FsRecCdfsFsControl(DeviceObject, Irp); break; - case FS_TYPE_NTFS: - Status = FsRecNtfsFsControl(DeviceObject, Irp); + case FS_TYPE_UDFS: + Status = FsRecUdfsFsControl(DeviceObject, Irp); break; default: @@ -192,7 +196,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, ULONG DeviceCount; NTSTATUS Status; - DPRINT("FileSystem recognizer 0.0.1\n"); + DPRINT("FileSystem recognizer 0.0.2\n"); DeviceCount = 0; @@ -215,6 +219,16 @@ DriverEntry(PDRIVER_OBJECT DriverObject, { DeviceCount++; } + + Status = FsRecRegisterFs(DriverObject, + L"\\Udfs", + L"\\FileSystem\\UdfsRecognizer", + FILE_DEVICE_CD_ROM_FILE_SYSTEM, + FS_TYPE_UDFS); + if (NT_SUCCESS(Status)) + { + DeviceCount++; + } } Status = FsRecRegisterFs(DriverObject, diff --git a/drivers/fs/fs_rec/fs_rec.h b/drivers/fs/fs_rec/fs_rec.h index f3c9a90..18834cb 100644 --- a/drivers/fs/fs_rec/fs_rec.h +++ b/drivers/fs/fs_rec/fs_rec.h @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/fs_rec/fs_rec.h + * FILE: drivers/fs/fs_rec/fs_rec.h * PURPOSE: Filesystem recognizer driver * PROGRAMMER: Eric Kohl */ @@ -32,6 +32,7 @@ #define FS_TYPE_VFAT 1 #define FS_TYPE_NTFS 2 #define FS_TYPE_CDFS 3 +#define FS_TYPE_UDFS 4 typedef struct _DEVICE_EXTENSION @@ -78,4 +79,11 @@ NTSTATUS FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); + +/* udfs.c */ + +NTSTATUS +FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + /* EOF */ diff --git a/drivers/fs/fs_rec/makefile b/drivers/fs/fs_rec/makefile index 2ab49dc..20c4d96 100644 --- a/drivers/fs/fs_rec/makefile +++ b/drivers/fs/fs_rec/makefile @@ -11,7 +11,8 @@ TARGET_OBJECTS = \ fs_rec.o \ cdfs.o \ fat.o \ - ntfs.o + ntfs.o \ + udfs.o DEP_OBJECTS = $(TARGET_OBJECTS) diff --git a/drivers/fs/fs_rec/ntfs.c b/drivers/fs/fs_rec/ntfs.c index 01b6190..e938cd4 100644 --- a/drivers/fs/fs_rec/ntfs.c +++ b/drivers/fs/fs_rec/ntfs.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/fs_rec/ntfs.c + * FILE: drivers/fs/fs_rec/ntfs.c * PURPOSE: Filesystem recognizer driver * PROGRAMMER: Eric Kohl */ @@ -74,6 +74,7 @@ FsRecIsNtfsVolume(IN PDEVICE_OBJECT DeviceObject) if (!NT_SUCCESS(Status)) { DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status); + ExFreePool(Buffer); return(Status); } diff --git a/drivers/fs/fs_rec/udfs.c b/drivers/fs/fs_rec/udfs.c new file mode 100644 index 0000000..ba7c1cf --- /dev/null +++ b/drivers/fs/fs_rec/udfs.c @@ -0,0 +1,296 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 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$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/fs/fs_rec/udfs.c + * PURPOSE: Filesystem recognizer driver + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + +#include "fs_rec.h" + + +#define UDFS_VRS_START_SECTOR 16 +#define UDFS_AVDP_SECTOR 256 + +/* TYPES ********************************************************************/ + +typedef struct _TAG +{ + USHORT Identifier; + USHORT Version; + UCHAR Checksum; + UCHAR Reserved; + USHORT SerialNumber; + USHORT Crc; + USHORT CrcLength; + ULONG Location; +} PACKED TAG, *PTAG; + +typedef struct _EXTENT +{ + ULONG Length; + ULONG Location; +} PACKED EXTENT, *PEXTENT; + +typedef struct _AVDP +{ + TAG DescriptorTag; + EXTENT MainVolumeDescriptorExtent; + EXTENT ReserveVolumeDescriptorExtent; +} PACKED AVDP, *PAVDP; + +/* FUNCTIONS ****************************************************************/ + +static NTSTATUS +FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize) +{ + PUCHAR Buffer; + ULONG Sector; + NTSTATUS Status; + ULONG State; + + Buffer = ExAllocatePool(NonPagedPool, + SectorSize); + if (Buffer == NULL) + { + return(STATUS_INSUFFICIENT_RESOURCES); + } + + State = 0; + Sector = UDFS_VRS_START_SECTOR; + while (TRUE) + { + Status = FsRecReadSectors(DeviceObject, + Sector, + 1, + SectorSize, + Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status); + break; + } + + DPRINT1("Descriptor identifier: [%.5s]\n", Buffer + 1); + + switch (State) + { + case 0: + if ((Sector == UDFS_VRS_START_SECTOR) && + (Buffer[1] == 'B') && + (Buffer[2] == 'E') && + (Buffer[3] == 'A') && + (Buffer[4] == '0') && + (Buffer[5] == '1')) + { + State = 1; + } + else + { + DPRINT1("VRS start sector is not 'BEA01'\n"); + ExFreePool(Buffer); + return(STATUS_UNRECOGNIZED_VOLUME); + } + break; + + case 1: + if ((Buffer[1] == 'N') && + (Buffer[2] == 'S') && + (Buffer[3] == 'R') && + (Buffer[4] == '0') && + ((Buffer[5] == '2') || (Buffer[5] == '3'))) + { + State = 2; + } + break; + + case 2: + if ((Buffer[1] == 'T') && + (Buffer[2] == 'E') && + (Buffer[3] == 'A') && + (Buffer[4] == '0') && + (Buffer[5] == '1')) + { + DPRINT1("Found 'TEA01'\n"); + ExFreePool(Buffer); + return(STATUS_SUCCESS); + } + break; + } + + Sector++; + if (Sector == UDFS_AVDP_SECTOR) + { + DPRINT1("No 'TEA01' found\n"); + ExFreePool(Buffer); + return(STATUS_UNRECOGNIZED_VOLUME); + } + } + + ExFreePool(Buffer); + + return(STATUS_UNRECOGNIZED_VOLUME); +} + + +static NTSTATUS +FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize) +{ + PUCHAR Buffer; + ULONG Sector; + NTSTATUS Status; + PAVDP Avdp; + + Buffer = ExAllocatePool(NonPagedPool, + SectorSize); + if (Buffer == NULL) + { + return(STATUS_INSUFFICIENT_RESOURCES); + } + + Sector = UDFS_AVDP_SECTOR; + Status = FsRecReadSectors(DeviceObject, + Sector, + 1, + SectorSize, + Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status); + ExFreePool(Buffer); + return(Status); + } + + Avdp = (PAVDP)Buffer; + DPRINT1("Descriptor identifier: %hu\n", Avdp->DescriptorTag.Identifier); + + DPRINT1("Main volume descriptor sequence location: %lu\n", + Avdp->MainVolumeDescriptorExtent.Location); + + DPRINT1("Main volume descriptor sequence length: %lu\n", + Avdp->MainVolumeDescriptorExtent.Length); + + DPRINT1("Reserve volume descriptor sequence location: %lu\n", + Avdp->ReserveVolumeDescriptorExtent.Location); + + DPRINT1("Reserve volume descriptor sequence length: %lu\n", + Avdp->ReserveVolumeDescriptorExtent.Length); + + ExFreePool(Buffer); + +// return(Status); + return(STATUS_SUCCESS); +} + + +static NTSTATUS +FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject) +{ + DISK_GEOMETRY DiskGeometry; + ULONG Size; + NTSTATUS Status; + + Size = sizeof(DISK_GEOMETRY); + Status = FsRecDeviceIoControl(DeviceObject, + IOCTL_CDROM_GET_DRIVE_GEOMETRY, + NULL, + 0, + &DiskGeometry, + &Size); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FsRecDeviceIoControl() failed (Status %lx)\n", Status); + return(Status); + } + DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector); + + /* Check the volume recognition sequence */ + Status = FsRecCheckVolumeRecognitionSequence(DeviceObject, + DiskGeometry.BytesPerSector); + if (!NT_SUCCESS(Status)) + return(Status); + + Status = FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject, + DiskGeometry.BytesPerSector); + if (!NT_SUCCESS(Status)) + return(Status); + + + return(STATUS_SUCCESS); +} + + +NTSTATUS +FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + UNICODE_STRING RegistryPath; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + + switch (Stack->MinorFunction) + { + case IRP_MN_MOUNT_VOLUME: + DPRINT("Udfs: IRP_MN_MOUNT_VOLUME\n"); + Status = FsRecIsUdfsVolume(Stack->Parameters.MountVolume.DeviceObject); + if (NT_SUCCESS(Status)) + { + DPRINT("Identified UDFS volume\n"); + Status = STATUS_FS_DRIVER_REQUIRED; + } + break; + + case IRP_MN_LOAD_FILE_SYSTEM: + DPRINT("Udfs: IRP_MN_LOAD_FILE_SYSTEM\n"); + RtlInitUnicodeStringFromLiteral(&RegistryPath, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs"); + Status = ZwLoadDriver(&RegistryPath); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwLoadDriver failed (Status %x)\n", Status); + } + else + { + IoUnregisterFileSystem(DeviceObject); + } + break; + + default: + DPRINT("Udfs: Unknown minor function %lx\n", Stack->MinorFunction); + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + return(Status); +} + +/* EOF */ diff --git a/drivers/fs/ms/.cvsignore b/drivers/fs/ms/.cvsignore index 4742e3b..751ce5b 100644 --- a/drivers/fs/ms/.cvsignore +++ b/drivers/fs/ms/.cvsignore @@ -1,2 +1,4 @@ msfs.coff -msfs.sys.unstripped \ No newline at end of file +*.o +*.sym +*.sys diff --git a/drivers/fs/mup/.cvsignore b/drivers/fs/mup/.cvsignore index 6f7e8c9..e796501 100644 --- a/drivers/fs/mup/.cvsignore +++ b/drivers/fs/mup/.cvsignore @@ -2,5 +2,6 @@ base.tmp junk.tmp temp.exp mup.coff -mup.sys.unstripped -*.d \ No newline at end of file +*.o +*.sys +*.sym diff --git a/drivers/fs/np/.cvsignore b/drivers/fs/np/.cvsignore index c725dab..38f31ec 100644 --- a/drivers/fs/np/.cvsignore +++ b/drivers/fs/np/.cvsignore @@ -2,5 +2,6 @@ base.tmp junk.tmp temp.exp npfs.coff -npfs.sys -npfs.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/fs/np/create.c b/drivers/fs/np/create.c index 34624e7..fb3eca1 100644 --- a/drivers/fs/np/create.c +++ b/drivers/fs/np/create.c @@ -37,7 +37,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, KIRQL oldIrql; ULONG Disposition; - DPRINT1("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -199,7 +199,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PNPFS_PIPE current; PIO_PIPE_CREATE_BUFFER Buffer; - DPRINT1("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -343,7 +343,7 @@ NpfsClose(PDEVICE_OBJECT DeviceObject, PNPFS_PIPE_DATA Current; - DPRINT1("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; diff --git a/drivers/fs/ntfs/.cvsignore b/drivers/fs/ntfs/.cvsignore index 56392de..03b6733 100644 --- a/drivers/fs/ntfs/.cvsignore +++ b/drivers/fs/ntfs/.cvsignore @@ -2,5 +2,6 @@ base.tmp junk.tmp temp.exp ntfs.coff -ntfs.sys.unstripped -*.d \ No newline at end of file +*.o +*.sym +*.sys diff --git a/drivers/fs/ntfs/attrib.c b/drivers/fs/ntfs/attrib.c index 3d3c062..acdb2b6 100644 --- a/drivers/fs/ntfs/attrib.c +++ b/drivers/fs/ntfs/attrib.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/ntfs/attrib.c + * FILE: drivers/fs/ntfs/attrib.c * PURPOSE: NTFS filesystem driver * PROGRAMMER: Eric Kohl */ @@ -29,7 +29,7 @@ #include -//#define NDEBUG +#define NDEBUG #include #include "ntfs.h" @@ -38,6 +38,57 @@ /* FUNCTIONS ****************************************************************/ VOID +NtfsDumpFileNameAttribute(PATTRIBUTE Attribute) +{ + PRESIDENT_ATTRIBUTE ResAttr; + PFILENAME_ATTRIBUTE FileNameAttr; + + DbgPrint(" $FILE_NAME "); + + ResAttr = (PRESIDENT_ATTRIBUTE)Attribute; +// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset); + + FileNameAttr = (PFILENAME_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset); + DbgPrint(" '%.*S' ", FileNameAttr->NameLength, FileNameAttr->Name); +} + + +VOID +NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute) +{ + PRESIDENT_ATTRIBUTE ResAttr; + PWCHAR VolumeName; + + DbgPrint(" $VOLUME_NAME "); + + ResAttr = (PRESIDENT_ATTRIBUTE)Attribute; +// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset); + + VolumeName = (PWCHAR)((PVOID)ResAttr + ResAttr->ValueOffset); + DbgPrint(" '%.*S' ", ResAttr->ValueLength/2, VolumeName); +} + + +VOID +NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute) +{ + PRESIDENT_ATTRIBUTE ResAttr; + PVOLINFO_ATTRIBUTE VolInfoAttr; + + DbgPrint(" $VOLUME_INFORMATION "); + + ResAttr = (PRESIDENT_ATTRIBUTE)Attribute; +// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset); + + VolInfoAttr = (PVOLINFO_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset); + DbgPrint(" NTFS Version %u.%u Flags 0x%04hx ", + VolInfoAttr->MajorVersion, + VolInfoAttr->MinorVersion, + VolInfoAttr->Flags); +} + + +VOID NtfsDumpAttribute(PATTRIBUTE Attribute) { PNONRESIDENT_ATTRIBUTE NresAttr; @@ -59,7 +110,7 @@ NtfsDumpAttribute(PATTRIBUTE Attribute) break; case AttributeFileName: - DbgPrint(" $FILE_NAME "); + NtfsDumpFileNameAttribute(Attribute); break; case AttributeObjectId: @@ -71,11 +122,11 @@ NtfsDumpAttribute(PATTRIBUTE Attribute) break; case AttributeVolumeName: - DbgPrint(" $VOLUME_NAME "); + NtfsDumpVolumeNameAttribute(Attribute); break; case AttributeVolumeInformation: - DbgPrint(" $VOLUME_INFORMATION "); + NtfsDumpVolumeInformationAttribute(Attribute); break; case AttributeData: @@ -130,7 +181,7 @@ NtfsDumpAttribute(PATTRIBUTE Attribute) } DbgPrint("(%s)\n", - Attribute->Nonresident ? "nonresident" : "resident"); + Attribute->Nonresident ? "non-resident" : "resident"); if (Attribute->Nonresident != 0) { diff --git a/drivers/fs/ntfs/dirctl.c b/drivers/fs/ntfs/dirctl.c index 2646066..aa89ee7 100644 --- a/drivers/fs/ntfs/dirctl.c +++ b/drivers/fs/ntfs/dirctl.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2002 ReactOS Team + * Copyright (C) 2002,2003 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 @@ -20,7 +20,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/ntfs/dirctl.c + * FILE: drivers/fs/ntfs/dirctl.c * PURPOSE: NTFS filesystem driver * PROGRAMMER: Eric Kohl */ @@ -664,7 +664,8 @@ NtfsQueryDirectory(PDEVICE_OBJECT DeviceObject, Status = STATUS_SUCCESS; } - return(Status); +// return(Status); + return(STATUS_NO_MORE_FILES); } diff --git a/drivers/fs/ntfs/ntfs.h b/drivers/fs/ntfs/ntfs.h index 5998345..b700ddd 100644 --- a/drivers/fs/ntfs/ntfs.h +++ b/drivers/fs/ntfs/ntfs.h @@ -254,6 +254,14 @@ typedef struct WCHAR Name[1]; } FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE; +typedef struct +{ + ULONGLONG Unknown1; + UCHAR MajorVersion; + UCHAR MinorVersion; + USHORT Flags; + ULONG Unknown2; +} VOLINFO_ATTRIBUTE, *PVOLINFO_ATTRIBUTE; extern PNTFS_GLOBAL_DATA NtfsGlobalData; diff --git a/drivers/fs/vfat/.cvsignore b/drivers/fs/vfat/.cvsignore index 4f613ad..0788052 100644 --- a/drivers/fs/vfat/.cvsignore +++ b/drivers/fs/vfat/.cvsignore @@ -2,5 +2,7 @@ base.tmp junk.tmp temp.exp vfatfs.coff -vfatfs.sys.unstripped -*.d \ No newline at end of file +*.d +*.o +*.sys +*.sym diff --git a/drivers/fs/vfat/cleanup.c b/drivers/fs/vfat/cleanup.c index 7d65a10..8ab965b 100644 --- a/drivers/fs/vfat/cleanup.c +++ b/drivers/fs/vfat/cleanup.c @@ -19,14 +19,15 @@ /* FUNCTIONS ****************************************************************/ static NTSTATUS -VfatCleanupFile(PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject) +VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Cleans up after a file has been closed. */ { PVFATCCB pCcb; PVFATFCB pFcb; + PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; + PFILE_OBJECT FileObject = IrpContext->FileObject; DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); @@ -39,17 +40,22 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt, } pFcb = pCcb->pFcb; - if (FileObject->FileName.Buffer) + if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && + FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) + { + /* remove all locks this process have on this file */ + FsRtlFastUnlockAll(&pFcb->FileLock, + FileObject, + IoGetRequestorProcess(IrpContext->Irp), + NULL + ); + } + + /* Uninitialize file cache if initialized for this file object. */ + if (pFcb->RFCB.Bcb != NULL) { - if (pFcb->Flags & FCB_UPDATE_DIRENTRY) - { - VfatUpdateEntry (DeviceExt, FileObject); - pFcb->Flags &= ~FCB_UPDATE_DIRENTRY; - } + CcRosReleaseFileCache (FileObject, pFcb->RFCB.Bcb); } - - /* Uninitialize the file cache. */ - CcRosReleaseFileCache (FileObject, pFcb->RFCB.Bcb); return STATUS_SUCCESS; } @@ -74,7 +80,7 @@ NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext) return VfatQueueRequest (IrpContext); } - Status = VfatCleanupFile(IrpContext->DeviceExt, IrpContext->FileObject); + Status = VfatCleanupFile(IrpContext); ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); diff --git a/drivers/fs/vfat/close.c b/drivers/fs/vfat/close.c index 6dffc5c..7fae9a7 100644 --- a/drivers/fs/vfat/close.c +++ b/drivers/fs/vfat/close.c @@ -56,26 +56,18 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) if (pFcb->Flags & FCB_DELETE_PENDING) { delEntry (DeviceExt, FileObject); - pFcb->Flags &= ~FCB_UPDATE_DIRENTRY; } else Status = STATUS_DELETE_PENDING; } - if (pFcb->Flags & FCB_UPDATE_DIRENTRY) - { - VfatUpdateEntry (DeviceExt, FileObject); - pFcb->Flags &= ~FCB_UPDATE_DIRENTRY; - } FileObject->FsContext2 = NULL; vfatReleaseFCB (DeviceExt, pFcb); } else FileObject->FsContext2 = NULL; - if (pCcb->DirectorySearchPattern) - ExFreePool(pCcb->DirectorySearchPattern); - ExFreePool (pCcb); - + vfatDestroyCCB(pCcb); + return Status; } @@ -94,8 +86,13 @@ NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext) Status = STATUS_SUCCESS; goto ByeBye; } - +#if 0 + /* There occurs a dead look at the call to CcRosDeleteFileCache/ObDereferenceObject/VfatClose + in CmLazyCloseThreadMain if VfatClose is execute asynchronous in a worker thread. */ if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) +#else + if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE)) +#endif { return VfatQueueRequest (IrpContext); } diff --git a/drivers/fs/vfat/create.c b/drivers/fs/vfat/create.c index c9be403..3aa7ac1 100644 --- a/drivers/fs/vfat/create.c +++ b/drivers/fs/vfat/create.c @@ -42,203 +42,82 @@ /* FUNCTIONS *****************************************************************/ -BOOLEAN -IsLastEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determine if the given directory entry is the last - */ -{ - return (((FATDirEntry *) Block)[Offset].Filename[0] == 0); -} - -BOOLEAN -IsVolEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determine if the given directory entry is a vol entry - */ -{ - if ((((FATDirEntry *) Block)[Offset].Attrib) == 0x28) - return TRUE; - else - return FALSE; -} - -BOOLEAN -IsDeletedEntry (PVOID Block, ULONG Offset) -/* - * FUNCTION: Determines if the given entry is a deleted one - */ -{ - /* Checks special character */ - - return ((((FATDirEntry *) Block)[Offset].Filename[0] == 0xe5) || - (((FATDirEntry *) Block)[Offset].Filename[0] == 0)); -} - -void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName) +void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PWSTR pName) { int fromIndex, toIndex; fromIndex = toIndex = 0; - while (fromIndex < 8 && pBasename [fromIndex] != ' ') + while (fromIndex < 8 && pEntry->Filename [fromIndex] != ' ') { - pName [toIndex++] = pBasename [fromIndex++]; + if (pEntry->lCase & VFAT_CASE_LOWER_BASE) + { + pName [toIndex++] = tolower(pEntry->Filename [fromIndex++]); + } + else + { + pName [toIndex++] = pEntry->Filename [fromIndex++]; + } } - if (pExtension [0] != ' ') + if (pEntry->Ext [0] != ' ') { pName [toIndex++] = L'.'; fromIndex = 0; - while (fromIndex < 3 && pExtension [fromIndex] != ' ') + while (fromIndex < 3 && pEntry->Ext [fromIndex] != ' ') { - pName [toIndex++] = pExtension [fromIndex++]; + if (pEntry->lCase & VFAT_CASE_LOWER_EXT) + { + pName [toIndex++] = tolower(pEntry->Ext [fromIndex++]); + } + else + { + pName [toIndex++] = pEntry->Ext [fromIndex++]; + } } } pName [toIndex] = L'\0'; } -static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pName) +static void vfat8Dot3ToVolumeLabel (PFAT_DIR_ENTRY pEntry, PWSTR pName) { int fromIndex, toIndex; fromIndex = toIndex = 0; - while (fromIndex < 8 && pBasename [fromIndex] != ' ') + while (fromIndex < 8 && pEntry->Filename [fromIndex] != ' ') { - pName [toIndex++] = pBasename [fromIndex++]; + if (pEntry->lCase & VFAT_CASE_LOWER_BASE) + { + pName [toIndex++] = tolower(pEntry->Filename [fromIndex++]); + } + else + { + pName [toIndex++] = pEntry->Filename [fromIndex++]; + } } - if (pExtension [0] != ' ') + if (pEntry->Ext [0] != ' ') { fromIndex = 0; - while (fromIndex < 3 && pBasename [fromIndex] != ' ') + while (fromIndex < 3 && pEntry->Ext [fromIndex] != ' ') { - pName [toIndex++] = pExtension [fromIndex++]; + if (pEntry->lCase & VFAT_CASE_LOWER_EXT) + { + pName [toIndex++] = tolower(pEntry->Ext [fromIndex++]); + } + else + { + pName [toIndex++] = pEntry->Ext [fromIndex++]; + } } } pName [toIndex] = L'\0'; } NTSTATUS -GetEntryName(PVOID *pContext, - PVOID *Block, - PFILE_OBJECT FileObject, - PWSTR Name, - PULONG pIndex, - PULONG pIndex2) -/* - * FUNCTION: Retrieves the file name, be it in short or long file name format - */ -{ - NTSTATUS Status; - FATDirEntry * test; - slot * test2; - ULONG cpos; - ULONG Offset = *pIndex % ENTRIES_PER_PAGE; - ULONG Read; - LARGE_INTEGER FileOffset; - - *Name = 0; - while (TRUE) - { - test = (FATDirEntry *) *Block; - test2 = (slot *) *Block; - if (vfatIsDirEntryEndMarker(&test[Offset])) - { - return STATUS_NO_MORE_ENTRIES; - } - if (test2[Offset].attr == 0x0f && !vfatIsDirEntryDeleted(&test[Offset])) - { - *Name = 0; - if (pIndex2) - *pIndex2 = *pIndex; // start of dir entry - - DPRINT (" long name entry found at %d\n", *pIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, test2 [Offset].name0_4, - 6, test2 [Offset].name5_10, - 2, test2 [Offset].name11_12); - - vfat_initstr (Name, 255); - vfat_wcsncpy (Name, test2[Offset].name0_4, 5); - vfat_wcsncat (Name, test2[Offset].name5_10, 5, 6); - vfat_wcsncat (Name, test2[Offset].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", Name); - cpos = 0; - while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) && - (test2[Offset].attr > 0)) - { - (*pIndex)++; - Offset++; - - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - CcUnpinData(*pContext); - FileOffset.QuadPart = *pIndex * sizeof(FATDirEntry); - if(!CcMapData(FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, Block)) - { - *pContext = NULL; - return STATUS_NO_MORE_ENTRIES; - } - test2 = (slot *) *Block; - } - DPRINT (" long name entry found at %d\n", *pIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, test2 [Offset].name0_4, - 6, test2 [Offset].name5_10, - 2, test2 [Offset].name11_12); - - cpos++; - vfat_movstr (Name, 13, 0, cpos * 13); - vfat_wcsncpy (Name, test2[Offset].name0_4, 5); - vfat_wcsncat (Name, test2[Offset].name5_10, 5, 6); - vfat_wcsncat (Name, test2[Offset].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", Name); - } - (*pIndex)++; - Offset++; - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - CcUnpinData(*pContext); - FileOffset.QuadPart = *pIndex * sizeof(FATDirEntry); - if(!CcMapData(FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, Block)) - { - *pContext = NULL; - return STATUS_NO_MORE_ENTRIES; - } - test2 = (slot *) *Block; - test = (FATDirEntry*) *Block; - } - } - else - { - if (vfatIsDirEntryEndMarker(&test[Offset])) - return STATUS_NO_MORE_ENTRIES; - if (vfatIsDirEntryDeleted(&test[Offset])) - return STATUS_UNSUCCESSFUL; - if (*Name == 0) - { - vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name); - if (pIndex2) - *pIndex2 = *pIndex; - } - break; - } - } - return STATUS_SUCCESS; -} - -NTSTATUS ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) /* * FUNCTION: Read the volume label */ { PVOID Context = NULL; - ULONG Offset = 0; ULONG DirIndex = 0; FATDirEntry* Entry; PVFATFCB pFcb; @@ -249,44 +128,39 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) pFcb = vfatOpenRootFCB (DeviceExt); - while (TRUE) - { - if (Context == NULL || Offset == ENTRIES_PER_PAGE) - { - if (Offset == ENTRIES_PER_PAGE) - { - Offset = 0; - } - if (Context) - { - CcUnpinData(Context); - } - FileOffset.u.HighPart = 0; - FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry); - if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) - { - Context = NULL; - break; - } - } - if (IsVolEntry(Entry, Offset)) - { - /* copy volume label */ - vfat8Dot3ToVolumeLabel (Entry[Offset].Filename, Entry[Offset].Ext, Vpb->VolumeLabel); - Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR); - break; - } - if (IsLastEntry(Entry, Offset)) - { - break; - } - Offset++; - DirIndex++; - } - - if (Context) + FileOffset.QuadPart = 0; + if (CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) { - CcUnpinData(Context); + while (TRUE) + { + if (vfatIsDirEntryVolume(Entry)) + { + /* copy volume label */ + vfat8Dot3ToVolumeLabel (Entry, Vpb->VolumeLabel); + Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR); + break; + } + if (vfatIsDirEntryEndMarker(Entry)) + { + break; + } + DirIndex++; + Entry++; + if ((DirIndex % ENTRIES_PER_PAGE) == 0) + { + CcUnpinData(Context); + FileOffset.u.LowPart += PAGE_SIZE; + if (!CcMapData(pFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry)) + { + Context = NULL; + break; + } + } + } + if (Context) + { + CcUnpinData(Context); + } } vfatReleaseFCB (DeviceExt, pFcb); @@ -306,17 +180,18 @@ FindFile (PDEVICE_EXTENSION DeviceExt, { WCHAR name[256]; WCHAR name2[14]; - char * block; WCHAR TempStr[2]; NTSTATUS Status; ULONG len; ULONG DirIndex; - ULONG Offset; ULONG FirstCluster; ULONG Read; BOOL isRoot; - LARGE_INTEGER FileOffset; PVOID Context = NULL; + PVOID Page; + PVFATFCB rcFcb; + + FATDirEntry fatDirEntry; DPRINT ("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0); DPRINT ("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName); @@ -326,7 +201,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt, if (wcslen (FileToFind) == 0) { CHECKPOINT; - TempStr[0] = (WCHAR) '.'; + TempStr[0] = (WCHAR) '*'; TempStr[1] = 0; FileToFind = (PWSTR)&TempStr; } @@ -355,30 +230,30 @@ FindFile (PDEVICE_EXTENSION DeviceExt, if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0) || (FileToFind[0] == '.' && FileToFind[1] == 0)) - { - /* it's root : complete essentials fields then return ok */ - CHECKPOINT; - memset (Fcb, 0, sizeof (VFATFCB)); - memset (Fcb->entry.Filename, ' ', 11); - CHECKPOINT; - Fcb->PathName[0]='\\'; - Fcb->ObjectName = &Fcb->PathName[1]; - Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector; - Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; - if (DeviceExt->FatInfo.FatType == FAT32) - { - Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0]; - Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1]; - } - else - Fcb->entry.FirstCluster = 1; - if (pDirIndex) - *pDirIndex = 0; - if (pDirIndex2) - *pDirIndex2 = 0; - DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName); - return (STATUS_SUCCESS); - } + { + /* it's root : complete essentials fields then return ok */ + CHECKPOINT; + memset (Fcb, 0, sizeof (VFATFCB)); + memset (Fcb->entry.Filename, ' ', 11); + CHECKPOINT; + Fcb->PathName[0]='\\'; + Fcb->ObjectName = &Fcb->PathName[1]; + Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector; + Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; + if (DeviceExt->FatInfo.FatType == FAT32) + { + Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0]; + Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1]; + } + else + Fcb->entry.FirstCluster = 1; + if (pDirIndex) + *pDirIndex = 0; + if (pDirIndex2) + *pDirIndex2 = 0; + DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName); + return (STATUS_SUCCESS); + } } else { @@ -388,78 +263,97 @@ FindFile (PDEVICE_EXTENSION DeviceExt, if (pDirIndex && (*pDirIndex)) DirIndex = *pDirIndex; - Offset = DirIndex % ENTRIES_PER_PAGE; + if (NULL == wcschr(FileToFind, L'?') && NULL == wcschr(FileToFind, L'*')) + { + /* if there is no '*?' in the search name, than look first for an existing fcb */ + len = wcslen(Parent->PathName); + memcpy(name, Parent->PathName, len * sizeof(WCHAR)); + if (!vfatFCBIsRoot(Parent)) + { + name[len++] = L'\\'; + } + wcscpy(name + len, FileToFind); + rcFcb = vfatGrabFCBFromTable(DeviceExt, name); + if (rcFcb) + { + if(rcFcb->startIndex >= DirIndex) + { + wcscpy(Fcb->PathName, name); + Fcb->ObjectName = &Fcb->PathName[len]; + memcpy(&Fcb->entry, &rcFcb->entry, sizeof(FATDirEntry)); + if (pDirIndex) + { + *pDirIndex = rcFcb->dirIndex; + } + if (pDirIndex2) + { + *pDirIndex2 = rcFcb->startIndex; + } + DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d (%d)\n",Fcb->PathName, Fcb->ObjectName, rcFcb->dirIndex, rcFcb->startIndex); + vfatReleaseFCB(DeviceExt, rcFcb); + return STATUS_SUCCESS; + } + else + { + vfatReleaseFCB(DeviceExt, rcFcb); + return STATUS_UNSUCCESSFUL; + } + vfatReleaseFCB(DeviceExt, rcFcb); + } + } + while(TRUE) { - if (Context == NULL || Offset == ENTRIES_PER_PAGE) + Status = vfatGetNextDirEntry(&Context, &Page, Parent, &DirIndex, name, &fatDirEntry, pDirIndex2); + if (Status == STATUS_NO_MORE_ENTRIES) { - if (Offset == ENTRIES_PER_PAGE) - Offset = 0; - if (Context) - { - CcUnpinData(Context); - } - FileOffset.QuadPart = (DirIndex - Offset) * sizeof(FATDirEntry); - if (!CcMapData(Parent->FileObject, &FileOffset, PAGE_SIZE, TRUE, - &Context, (PVOID*)&block)) - { - Context = NULL; - break; - } + break; } - if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset])) + if (vfatIsDirEntryVolume(&fatDirEntry)) { - Offset++; DirIndex++; - continue; + continue; } - Status = GetEntryName (&Context, (PVOID*)&block, Parent->FileObject, name, - &DirIndex, pDirIndex2); - if (Status == STATUS_NO_MORE_ENTRIES) - break; - Offset = DirIndex % ENTRIES_PER_PAGE; - if (NT_SUCCESS(Status)) - { - vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2); - if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind)) + vfat8Dot3ToString(&fatDirEntry, name2); + if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind)) + { + if (Parent && Parent->PathName) + { + len = wcslen(Parent->PathName); + CHECKPOINT; + memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR)); + Fcb->ObjectName=&Fcb->PathName[len]; + if (len != 1 || Fcb->PathName[0] != '\\') { - if (Parent && Parent->PathName) - { - len = wcslen(Parent->PathName); - CHECKPOINT; - memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR)); - Fcb->ObjectName=&Fcb->PathName[len]; - if (len != 1 || Fcb->PathName[0] != '\\') - { - Fcb->ObjectName[0] = '\\'; - Fcb->ObjectName = &Fcb->ObjectName[1]; - } - } - else - { - Fcb->ObjectName=Fcb->PathName; - Fcb->ObjectName[0]='\\'; - Fcb->ObjectName=&Fcb->ObjectName[1]; - } - - memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset], - sizeof (FATDirEntry)); - vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH); - if (pDirIndex) - *pDirIndex = DirIndex; - DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex); - if (Context) - CcUnpinData(Context); - return STATUS_SUCCESS; + Fcb->ObjectName[0] = '\\'; + Fcb->ObjectName = &Fcb->ObjectName[1]; } + } + else + { + Fcb->ObjectName=Fcb->PathName; + Fcb->ObjectName[0]='\\'; + Fcb->ObjectName=&Fcb->ObjectName[1]; + } + memcpy(&Fcb->entry, &fatDirEntry, sizeof(FATDirEntry)); + wcsncpy(Fcb->ObjectName, *name == 0 ? name2 : name, MAX_PATH); + if (pDirIndex) + *pDirIndex = DirIndex; + DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex); + + if (Context) + CcUnpinData(Context); + + return STATUS_SUCCESS; } - Offset++; DirIndex++; } if (pDirIndex) - *pDirIndex = DirIndex; + *pDirIndex = DirIndex; + if (Context) - CcUnpinData(Context); + CcUnpinData(Context); + return (STATUS_UNSUCCESSFUL); } @@ -635,7 +529,12 @@ VfatSupersedeFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Fcb->RFCB.AllocationSize.QuadPart = 0; Fcb->RFCB.FileSize.QuadPart = 0; Fcb->RFCB.ValidDataLength.QuadPart = 0; - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize); + /* Notify cache manager about the change in file size if caching is + initialized on the file stream */ + if (FileObject->SectionObjectPointers->SharedCacheMap != NULL) + { + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize); + } } while (Cluster != 0xffffffff && Cluster > 1) { @@ -659,7 +558,8 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) PVFATCCB pCcb; PVFATFCB pFcb; PWCHAR c; - BOOLEAN PagingFileCreate = FALSE; + BOOLEAN PagingFileCreate = FALSE; + LARGE_INTEGER AllocationSize; /* Unpack the various parameters. */ Stack = IoGetCurrentIrpStackLocation (Irp); @@ -692,7 +592,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) return(STATUS_NOT_A_DIRECTORY); } pFcb = DeviceExt->VolumeFcb; - pCcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + pCcb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (pCcb == NULL) { return (STATUS_INSUFFICIENT_RESOURCES); @@ -785,6 +685,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) if (RequestedDisposition == FILE_CREATE) { Irp->IoStatus.Information = FILE_EXISTS; + VfatCloseFile (DeviceExt, FileObject); return(STATUS_OBJECT_NAME_COLLISION); } @@ -806,6 +707,22 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) VfatCloseFile (DeviceExt, FileObject); return(STATUS_NOT_A_DIRECTORY); } + + if (RequestedDisposition == FILE_OVERWRITE || + RequestedDisposition == FILE_OVERWRITE_IF) + { + AllocationSize.QuadPart = 0; + Status = VfatSetAllocationSizeInformation (FileObject, + pFcb, + DeviceExt, + &AllocationSize); + if (!NT_SUCCESS (Status)) + { + VfatCloseFile (DeviceExt, FileObject); + return(Status); + } + } + /* Supersede the file */ if (RequestedDisposition == FILE_SUPERSEDE) diff --git a/drivers/fs/vfat/dir.c b/drivers/fs/vfat/dir.c index 91dbe1d..e9c1a67 100644 --- a/drivers/fs/vfat/dir.c +++ b/drivers/fs/vfat/dir.c @@ -75,32 +75,14 @@ FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime) } - -unsigned long -vfat_wstrlen (PWSTR s) -{ - WCHAR c = ' '; - unsigned int len = 0; - - while (c != 0) - { - c = *s; - s++; - len++; - }; - s -= len; - - return len - 1; -} - -#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) ) +#define DWORD_ROUND_UP(x) ROUND_UP((x), (sizeof(DWORD))) NTSTATUS VfatGetFileNameInformation (PVFATFCB pFcb, PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength) { ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -116,9 +98,8 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb, PFILE_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -132,13 +113,12 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; return STATUS_SUCCESS; @@ -150,9 +130,8 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb, PFILE_FULL_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; @@ -166,13 +145,12 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; // pInfo->EaSize=; return STATUS_SUCCESS; @@ -184,15 +162,19 @@ VfatGetFileBothInformation (PVFATFCB pFcb, PFILE_BOTH_DIRECTORY_INFORMATION pInfo, ULONG BufferLength) { - short i; - unsigned long long AllocSize; ULONG Length; - Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR); + Length = wcslen (pFcb->ObjectName) * sizeof(WCHAR); if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength) return STATUS_BUFFER_OVERFLOW; pInfo->FileNameLength = Length; - pInfo->NextEntryOffset = + pInfo->NextEntryOffset = DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length); + /* + * vfatGetDirEntryName must be called befor the long name is copyed. + * The terminating null will overwrite the first character from long name. + */ + vfatGetDirEntryName(&pFcb->entry, pInfo->ShortName); + pInfo->ShortNameLength = wcslen(pInfo->ShortName) * sizeof(WCHAR); memcpy (pInfo->FileName, pFcb->ObjectName, Length); // pInfo->FileIndex=; FsdDosDateTimeToFileTime (pFcb->entry.CreationDate, @@ -201,24 +183,14 @@ VfatGetFileBothInformation (PVFATFCB pFcb, &pInfo->LastAccessTime); FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, &pInfo->LastWriteTime); - FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime, - &pInfo->ChangeTime); - pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize); + pInfo->ChangeTime = pInfo->LastWriteTime; + pInfo->EndOfFile.u.HighPart = 0; + pInfo->EndOfFile.u.LowPart = pFcb->entry.FileSize; /* Make allocsize a rounded up multiple of BytesPerCluster */ - AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / - DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster; - pInfo->AllocationSize.QuadPart = AllocSize; + pInfo->AllocationSize.u.HighPart = 0; + pInfo->AllocationSize.u.LowPart = ROUND_UP(pFcb->entry.FileSize, DeviceExt->FatInfo.BytesPerCluster); pInfo->FileAttributes = pFcb->entry.Attrib; // pInfo->EaSize=; - for (i = 0; i < 8 && (pFcb->entry.Filename[i] != ' '); i++) - pInfo->ShortName[i] = pFcb->entry.Filename[i]; - pInfo->ShortNameLength = i; - pInfo->ShortName[i] = '.'; - for (i = 0; i < 3 && (pFcb->entry.Ext[i] != ' '); i++) - pInfo->ShortName[i + 1 + pInfo->ShortNameLength] = pFcb->entry.Ext[i]; - if (i) - pInfo->ShortNameLength += (i + 1); - pInfo->ShortNameLength *= sizeof(WCHAR); return STATUS_SUCCESS; } diff --git a/drivers/fs/vfat/direntry.c b/drivers/fs/vfat/direntry.c index 97ca117..c394ef8 100644 --- a/drivers/fs/vfat/direntry.c +++ b/drivers/fs/vfat/direntry.c @@ -20,12 +20,7 @@ #include "vfat.h" -#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ - (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) - -#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \ - (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector))) - +#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry)) ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, @@ -67,140 +62,135 @@ vfatIsDirEntryLongName (FATDirEntry * pFatDirEntry) BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry) { - return pFatDirEntry->Attrib == 0x28; + return 0x08 == (pFatDirEntry->Attrib & 0x1f); } void vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName) { - vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName); + vfat8Dot3ToString (dirEntry, entryName); } -NTSTATUS -vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt, - PVFATFCB pDirectoryFCB, - ULONG * pDirectoryIndex, - PWSTR pLongFileName, - PFAT_DIR_ENTRY pDirEntry) + +NTSTATUS vfatGetNextDirEntry(PVOID * pContext, + PVOID * pPage, + IN PVFATFCB pDirFcb, + IN OUT PULONG pDirIndex, + OUT PWSTR pFileName, + OUT PFAT_DIR_ENTRY pDirEntry, + OUT PULONG pStartIndex) { - ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt); - ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt); - PVOID currentPage = NULL; - FATDirEntry * fatDirEntry; - slot * longNameEntry; - ULONG cpos; - LARGE_INTEGER FileOffset; - PVOID Context; - - DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n", - pDeviceExt, - pDirectoryFCB, - *pDirectoryIndex, - pLongFileName, - pDirEntry); - - *pLongFileName = 0; - - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } + ULONG dirMap; + PWCHAR pName; + LARGE_INTEGER FileOffset; + FATDirEntry * fatDirEntry; + slot * longNameEntry; + ULONG index; - while (TRUE) - { - fatDirEntry = (FATDirEntry *) currentPage; + *pFileName = 0; - if (vfatIsDirEntryEndMarker (&fatDirEntry [indexInPage])) + FileOffset.u.HighPart = 0; + FileOffset.u.LowPart = ROUND_DOWN(*pDirIndex * sizeof(FATDirEntry), PAGE_SIZE); + + if (*pContext == NULL || (*pDirIndex % ENTRIES_PER_PAGE) == 0) { - DPRINT ("end of directory, returning no more entries\n"); - CcUnpinData(Context); - return STATUS_NO_MORE_ENTRIES; + if (*pContext != NULL) + { + CcUnpinData(*pContext); + } + if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage)) + { + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } } - else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage]) - && !vfatIsDirEntryDeleted (&fatDirEntry [indexInPage])) + + + fatDirEntry = (FATDirEntry*)(*pPage) + *pDirIndex % ENTRIES_PER_PAGE; + longNameEntry = (slot*) fatDirEntry; + dirMap = 0; + + if (pStartIndex) { - DPRINT (" long name entry found at %d\n", *pDirectoryIndex); - longNameEntry = (slot *) currentPage; - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, longNameEntry [indexInPage].name0_4, - 6, longNameEntry [indexInPage].name5_10, - 2, longNameEntry [indexInPage].name11_12); - - vfat_initstr (pLongFileName, 256); - vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", pLongFileName); - - cpos = 0; - while ((longNameEntry [indexInPage].id != 0x41) && - (longNameEntry [indexInPage].id != 0x01) && - (longNameEntry [indexInPage].attr > 0)) - { - (*pDirectoryIndex)++; - indexInPage++; - if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt)) - { - indexInPage = 0; - pageNumber++; - - CcUnpinData(Context); - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } - longNameEntry = (slot *) currentPage; - } - DPRINT (" index %d\n", *pDirectoryIndex); - - DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", - 5, longNameEntry [indexInPage].name0_4, - 6, longNameEntry [indexInPage].name5_10, - 2, longNameEntry [indexInPage].name11_12); - - cpos++; - vfat_movstr (pLongFileName, 13, 0, cpos * 13); - vfat_wcsncpy (pLongFileName, longNameEntry [indexInPage].name0_4, 5); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name5_10, 5, 6); - vfat_wcsncat (pLongFileName, longNameEntry [indexInPage].name11_12, 11, 2); - - DPRINT (" longName: [%S]\n", pLongFileName); - - } - (*pDirectoryIndex)++; - indexInPage++; - if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt)) - { - indexInPage = 0; - pageNumber++; - - CcUnpinData(Context); - FileOffset.QuadPart = pageNumber * CACHEPAGESIZE(pDeviceExt); - if (!CcMapData(pDirectoryFCB->FileObject, &FileOffset, - CACHEPAGESIZE(pDeviceExt), TRUE, &Context, ¤tPage)) - { - return STATUS_UNSUCCESSFUL; - } - } + *pStartIndex = *pDirIndex; } - else + + while (TRUE) { - memcpy (pDirEntry, &fatDirEntry [indexInPage], sizeof (FAT_DIR_ENTRY)); - (*pDirectoryIndex)++; - break; + if (vfatIsDirEntryEndMarker(fatDirEntry)) + { + CcUnpinData(*pContext); + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } + + if (vfatIsDirEntryDeleted (fatDirEntry)) + { + dirMap = 0; + *pFileName = 0; + if (pStartIndex) + { + *pStartIndex = *pDirIndex + 1; + } + } + else + { + if (vfatIsDirEntryLongName (fatDirEntry)) + { + if (dirMap == 0) + { + DPRINT (" long name entry found at %d\n", *pDirIndex); + memset(pFileName, 0, 256 * sizeof(WCHAR)); + } + + DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n", + 5, longNameEntry->name0_4, + 6, longNameEntry->name5_10, + 2, longNameEntry->name11_12); + + index = (longNameEntry->id & 0x1f) - 1; + dirMap |= 1 << index; + pName = pFileName + 13 * index; + + memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR)); + memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR)); + memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR)); + + DPRINT (" longName: [%S]\n", pFileName); + } + else + { + memcpy (pDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY)); + break; + } + } + (*pDirIndex)++; + if ((*pDirIndex % ENTRIES_PER_PAGE) == 0) + { + CcUnpinData(*pContext); + FileOffset.u.LowPart += PAGE_SIZE; + if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage)) + { + CHECKPOINT; + *pContext = NULL; + return STATUS_NO_MORE_ENTRIES; + } + fatDirEntry = (FATDirEntry*)*pPage; + longNameEntry = (slot*) *pPage; + } + else + { + fatDirEntry++; + longNameEntry++; + } } - } - CcUnpinData(Context); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } + + + diff --git a/drivers/fs/vfat/dirwr.c b/drivers/fs/vfat/dirwr.c index e78d8d0..2f5e54d 100644 --- a/drivers/fs/vfat/dirwr.c +++ b/drivers/fs/vfat/dirwr.c @@ -39,22 +39,16 @@ VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) { PVOID Context; PVOID Buffer; - NTSTATUS status; - PVFATFCB pDirFcb = NULL, pFcb = NULL; + PVFATFCB pDirFcb, pFcb; LARGE_INTEGER Offset; DPRINT ("updEntry PathFileName \'%S\'\n", ((PVFATCCB)(pFileObject->FsContext2))->pFcb->PathName); - status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, - ((PVFATCCB)(pFileObject->FsContext2))->pFcb->PathName); - if (!NT_SUCCESS(status)) - { - if (pDirFcb != NULL) - { - vfatReleaseFCB(DeviceExt, pDirFcb); - } - return status; - } + + pFcb = ((PVFATCCB)(pFileObject->FsContext2))->pFcb; + assert (pFcb); + pDirFcb = pFcb->parentFcb; + assert (pDirFcb); Offset.u.HighPart = 0; Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry); @@ -67,8 +61,7 @@ VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) } else DPRINT1 ("Failed write to \'%S\'.\n", pDirFcb->PathName); - vfatReleaseFCB(DeviceExt, pDirFcb); - vfatReleaseFCB(DeviceExt, pFcb); + return STATUS_SUCCESS; } @@ -192,6 +185,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, short nbSlots = 0, nbFree = 0, j, posCar, NameLen; PUCHAR Buffer; BOOLEAN needTilde = FALSE, needLong = FALSE; + BOOLEAN lCaseBase, uCaseBase, lCaseExt, uCaseExt; PVFATFCB newFCB; ULONG CurrentCluster; LARGE_INTEGER SystemTime, LocalTime, FileOffset; @@ -334,7 +328,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, } pEntry->Filename[posCar - 2] = '~'; pEntry->Filename[posCar - 1] = '1'; - vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName); + vfat8Dot3ToString (pEntry, DirName); //try first with xxxxxx~y.zzz for (i = 1; i < 10; i++) { @@ -356,7 +350,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, pEntry->Filename[posCar - 3] = '~'; pEntry->Filename[posCar - 2] = '1'; pEntry->Filename[posCar - 1] = '0'; - vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName); + vfat8Dot3ToString (pEntry, DirName); //try second with xxxxx~yy.zzz for (i = 10; i < 100; i++) { @@ -381,9 +375,20 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, else { DPRINT ("check if long name entry needed, needlong=%d\n", needLong); + lCaseBase = uCaseBase = lCaseExt = uCaseExt = FALSE; for (i = 0; i < posCar; i++) { - if ((USHORT) pEntry->Filename[i] != FileName[i]) + if ((USHORT) tolower(pEntry->Filename[i]) == FileName[i]) + { + DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]); + lCaseBase = TRUE; + } + else if ((USHORT) pEntry->Filename[i] == FileName[i]) + { + DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]); + uCaseBase = TRUE; + } + else { DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]); needLong = TRUE; @@ -392,16 +397,30 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, if (FileName[i]) { i++; //jump on point char - for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++) + for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++, j++) { - if ((USHORT) pEntry->Ext[j++] != FileName[i]) + if ((USHORT) tolower(pEntry->Ext[j]) == FileName[i]) + { + DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]); + lCaseExt = TRUE; + } + else if ((USHORT) pEntry->Ext[j] == FileName[i]) + { + DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]); + uCaseExt = TRUE; + } + else { - DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i], - FileName[i]); + DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]); needLong = TRUE; } } } + if ((lCaseBase && uCaseBase) || (lCaseExt && uCaseExt)) + { + CHECKPOINT; + needLong = TRUE; + } } if (needLong == FALSE) { @@ -409,6 +428,14 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, memcpy (Buffer, pEntry, sizeof (FATDirEntry)); memset (pEntry, 0, sizeof (FATDirEntry)); pEntry = (FATDirEntry *) Buffer; + if (lCaseBase) + { + pEntry->lCase |= VFAT_CASE_LOWER_BASE; + } + if (lCaseExt) + { + pEntry->lCase |= VFAT_CASE_LOWER_EXT; + } } else { @@ -427,39 +454,51 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, /* set dates and times */ KeQuerySystemTime (&SystemTime); ExSystemTimeToLocalTime (&SystemTime, &LocalTime); +#if 0 + { + TIME_FIELDS tf; + RtlTimeToTimeFields (&LocalTime, &tf); + DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%S'\n", + tf.Day, tf.Month, tf.Year, tf.Hour, + tf.Minute, tf.Second, tf.Milliseconds, + pFileObject->FileName.Buffer); + } +#endif FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate, &pEntry->CreationTime); pEntry->UpdateDate = pEntry->CreationDate; pEntry->UpdateTime = pEntry->CreationTime; pEntry->AccessDate = pEntry->CreationDate; - // calculate checksum for 8.3 name - for (pSlots[0].alias_checksum = i = 0; i < 11; i++) - { - pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7 - | ((pSlots[0].alias_checksum & 0xfe) >> 1)) - + pEntry->Filename[i]); - } - //construct slots and entry - for (i = nbSlots - 2; i >= 0; i--) + if (needLong) { - DPRINT ("construct slot %d\n", i); - pSlots[i].attr = 0xf; - if (i) + // calculate checksum for 8.3 name + for (pSlots[0].alias_checksum = i = 0; i < 11; i++) { - pSlots[i].id = nbSlots - i - 1; + pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7 + | ((pSlots[0].alias_checksum & 0xfe) >> 1)) + + pEntry->Filename[i]); } - else + //construct slots and entry + for (i = nbSlots - 2; i >= 0; i--) { - pSlots[i].id = nbSlots - i - 1 + 0x40; - } - pSlots[i].alias_checksum = pSlots[0].alias_checksum; + DPRINT ("construct slot %d\n", i); + pSlots[i].attr = 0xf; + if (i) + { + pSlots[i].id = nbSlots - i - 1; + } + else + { + pSlots[i].id = nbSlots - i - 1 + 0x40; + } + pSlots[i].alias_checksum = pSlots[0].alias_checksum; //FIXME pSlots[i].start=; - memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10); - memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12); - memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4); + memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10); + memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12); + memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4); + } } - //try to find nbSlots contiguous entries frees in directory if (!findDirSpace(DeviceExt, pDirFcb, nbSlots, &start)) { @@ -522,7 +561,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, // FEXME: check status vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry, - start + nbSlots - 1, &newFCB); + start, start + nbSlots - 1, &newFCB); vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject); DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename); diff --git a/drivers/fs/vfat/fat.c b/drivers/fs/vfat/fat.c index 499f1a3..c435602 100644 --- a/drivers/fs/vfat/fat.c +++ b/drivers/fs/vfat/fat.c @@ -632,7 +632,7 @@ WriteCluster(PDEVICE_EXTENSION DeviceExt, return(Status); } -ULONG +ULONGLONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster) /* @@ -641,7 +641,8 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt, */ { return DeviceExt->FatInfo.dataStart + - ((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster); + ((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster); + } NTSTATUS @@ -774,44 +775,4 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt, return(Status); } - -NTSTATUS -GetNextSector(PDEVICE_EXTENSION DeviceExt, - ULONG CurrentSector, - PULONG NextSector, - BOOLEAN Extend) -/* Some functions don't have access to the cluster they're really reading from. - Maybe this is a dirty solution, but it will allow them to handle fragmentation. */ -{ - NTSTATUS Status; - - DPRINT("GetNextSector(DeviceExt %x, CurrentSector %x)\n", - DeviceExt, - CurrentSector); - if (CurrentSectorFatInfo.dataStart || ((CurrentSector - DeviceExt->FatInfo.dataStart + 1) % DeviceExt->FatInfo.SectorsPerCluster)) - /* Basically, if the next sequential sector would be on a cluster border, then we'll need to check in the FAT */ - { - (*NextSector)=CurrentSector+1; - return (STATUS_SUCCESS); - } - else - { - CurrentSector = (CurrentSector - DeviceExt->FatInfo.dataStart) / DeviceExt->FatInfo.SectorsPerCluster + 2; - - Status = GetNextCluster(DeviceExt, CurrentSector, NextSector, Extend); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - if ((*NextSector) == 0 || (*NextSector) == 0xffffffff) - { - /* The caller wants to know a sector. These FAT codes don't correspond to any sector. */ - return(STATUS_UNSUCCESSFUL); - } - - (*NextSector) = ClusterToSector(DeviceExt,(*NextSector)); - return(STATUS_SUCCESS); - } -} - /* EOF */ diff --git a/drivers/fs/vfat/fcb.c b/drivers/fs/vfat/fcb.c index bf0a6cb..2c7adbe 100644 --- a/drivers/fs/vfat/fcb.c +++ b/drivers/fs/vfat/fcb.c @@ -29,42 +29,66 @@ /* -------------------------------------------------------- PUBLICS */ +ULONG vfatNameHash(ULONG hash, PWCHAR name) +{ + WCHAR c; + while(c = *name++) + { + c = towlower(c); + hash = (hash + (c << 4) + (c >> 4)) * 11; + } + return hash; +} + PVFATFCB vfatNewFCB(PWCHAR pFileName) { PVFATFCB rcFCB; - rcFCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB); + rcFCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->FcbLookasideList); memset (rcFCB, 0, sizeof (VFATFCB)); if (pFileName) { wcscpy (rcFCB->PathName, pFileName); - if (wcsrchr (rcFCB->PathName, '\\') != 0) - { - rcFCB->ObjectName = wcsrchr (rcFCB->PathName, '\\'); - } - else + rcFCB->ObjectName = wcsrchr(rcFCB->PathName, L'\\'); + if (rcFCB->ObjectName == NULL) { rcFCB->ObjectName = rcFCB->PathName; } + rcFCB->Hash.Hash = vfatNameHash(0, rcFCB->PathName); + DPRINT("%08x (%03x) '%S'\n", rcFCB->Hash.Hash, rcFCB->Hash.Hash % FCB_HASH_TABLE_SIZE, pFileName); } + rcFCB->Hash.self = rcFCB; + rcFCB->ShortHash.self = rcFCB; ExInitializeResourceLite(&rcFCB->PagingIoResource); ExInitializeResourceLite(&rcFCB->MainResource); + FsRtlInitializeFileLock(&rcFCB->FileLock, NULL, NULL); return rcFCB; } +VOID +vfatDestroyCCB(PVFATCCB pCcb) +{ + if (pCcb->DirectorySearchPattern) + { + ExFreePool(pCcb->DirectorySearchPattern); + } + ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb); +} + VOID vfatDestroyFCB(PVFATFCB pFCB) { + FsRtlUninitializeFileLock(&pFCB->FileLock); ExDeleteResourceLite(&pFCB->PagingIoResource); ExDeleteResourceLite(&pFCB->MainResource); if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize) ExFreePool(pFCB->FatChain); - ExFreePool (pFCB); + ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB); } BOOL -vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB) +vfatFCBIsDirectory(PVFATFCB FCB) { return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY; } @@ -72,61 +96,109 @@ vfatFCBIsDirectory(PDEVICE_EXTENSION pVCB, PVFATFCB FCB) BOOL vfatFCBIsRoot(PVFATFCB FCB) { - return wcscmp (FCB->PathName, L"\\") == 0; -} - -VOID -vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) -{ - KIRQL oldIrql; - - DPRINT ("grabbing FCB at %x: %S, refCount:%d\n", - pFCB, - pFCB->PathName, - pFCB->RefCount); - - KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - pFCB->RefCount++; - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return FCB->PathName[0] == L'\\' && FCB->PathName[1] == 0 ? TRUE : FALSE; } VOID vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) { KIRQL oldIrql; + HASHENTRY* entry; + ULONG Index; + ULONG ShortIndex; + PVFATFCB tmpFcb; DPRINT ("releasing FCB at %x: %S, refCount:%d\n", pFCB, pFCB->PathName, pFCB->RefCount); - KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - pFCB->RefCount--; - if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING)) + while (pFCB) { - RemoveEntryList (&pFCB->FcbListEntry); - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); - if (vfatFCBIsDirectory(pVCB, pFCB)) - { - CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb); - ExFreePool(pFCB->FileObject->FsContext2); - pFCB->FileObject->FsContext2 = NULL; - ObDereferenceObject(pFCB->FileObject); - } - vfatDestroyFCB (pFCB); + Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; + ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE; + KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); + pFCB->RefCount--; + if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING)) + { + tmpFcb = pFCB->parentFcb; + RemoveEntryList (&pFCB->FcbListEntry); + if (pFCB->Hash.Hash != pFCB->ShortHash.Hash) + { + entry = pVCB->FcbHashTable[ShortIndex]; + if (entry->self == pFCB) + { + pVCB->FcbHashTable[ShortIndex] = entry->next; + } + else + { + while (entry->next->self != pFCB) + { + entry = entry->next; + } + entry->next = pFCB->ShortHash.next; + } + } + entry = pVCB->FcbHashTable[Index]; + if (entry->self == pFCB) + { + pVCB->FcbHashTable[Index] = entry->next; + } + else + { + while (entry->next->self != pFCB) + { + entry = entry->next; + } + entry->next = pFCB->Hash.next; + } + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + if (vfatFCBIsDirectory(pFCB)) + { + /* Uninitialize file cache if initialized for this file object. */ + if (pFCB->RFCB.Bcb != NULL) + { + CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb); + } + vfatDestroyCCB(pFCB->FileObject->FsContext2); + pFCB->FileObject->FsContext2 = NULL; + ObDereferenceObject(pFCB->FileObject); + } + vfatDestroyFCB (pFCB); + } + else + { + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + tmpFcb = NULL; + } + pFCB = tmpFcb; } - else - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); } VOID vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) { KIRQL oldIrql; + ULONG Index; + ULONG ShortIndex; + Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; + ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE; KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); pFCB->pDevExt = pVCB; InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry); + + pFCB->Hash.next = pVCB->FcbHashTable[Index]; + pVCB->FcbHashTable[Index] = &pFCB->Hash; + if (pFCB->Hash.Hash != pFCB->ShortHash.Hash) + { + pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex]; + pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash; + } + if (pFCB->parentFcb) + { + pFCB->parentFcb->RefCount++; + } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); } @@ -136,23 +208,60 @@ vfatGrabFCBFromTable(PDEVICE_EXTENSION pVCB, PWSTR pFileName) KIRQL oldIrql; PVFATFCB rcFCB; PLIST_ENTRY current_entry; + ULONG Hash; + PWCHAR ObjectName = NULL; + ULONG len; + ULONG index; + ULONG currentindex; + + HASHENTRY* entry; - KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - current_entry = pVCB->FcbListHead.Flink; - while (current_entry != &pVCB->FcbListHead) - { - rcFCB = CONTAINING_RECORD (current_entry, VFATFCB, FcbListEntry); - - if (wstrcmpi (pFileName, rcFCB->PathName)) - { - rcFCB->RefCount++; - KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); - return rcFCB; - } + Hash = vfatNameHash(0, pFileName); - //FIXME: need to compare against short name in FCB here + KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); + entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE]; - current_entry = current_entry->Flink; + while (entry) + { + if (entry->Hash == Hash) + { + rcFCB = entry->self; + if (rcFCB->Hash.Hash == Hash) + { + /* compare the long name */ + if (!_wcsicmp(pFileName, rcFCB->PathName)) + { + rcFCB->RefCount++; + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return rcFCB; + } + } + else + { + len = rcFCB->ObjectName - rcFCB->PathName + 1; + if (ObjectName == NULL) + { + ObjectName = wcsrchr(pFileName, L'\\'); + if (ObjectName == NULL) + { + ObjectName = pFileName; + } + else + { + ObjectName++; + } + } + + /* compare the short name and the directory */ + if (!_wcsicmp(ObjectName, rcFCB->ShortName) && !_wcsnicmp(pFileName, rcFCB->PathName, len)) + { + rcFCB->RefCount++; + KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); + return rcFCB; + } + } + } + entry = entry->next; } KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); @@ -169,15 +278,14 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb) fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice); - newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } memset (newCCB, 0, sizeof (VFATCCB)); - fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID | - FO_DIRECT_CACHE_PAGING_READ; + fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; fileObject->SectionObjectPointers = &fcb->SectionObjectPointers; fileObject->FsContext = (PVOID) &fcb->RFCB; fileObject->FsContext2 = newCCB; @@ -213,6 +321,9 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) FCB = vfatNewFCB(L"\\"); memset(FCB->entry.Filename, ' ', 11); + FCB->ShortName[0] = L'\\'; + FCB->ShortName[1] = 0; + FCB->ShortHash.Hash = FCB->Hash.Hash; FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector; FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; if (pVCB->FatInfo.FatType == FAT32) @@ -233,7 +344,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) FCB->entry.FirstCluster = 1; Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector; } - FCB->RefCount = 1; + FCB->RefCount = 2; FCB->dirIndex = 0; FCB->RFCB.FileSize.QuadPart = Size; FCB->RFCB.ValidDataLength.QuadPart = Size; @@ -241,7 +352,6 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) vfatFCBInitializeCacheFromVolume(pVCB, FCB); vfatAddFCBToTable(pVCB, FCB); - vfatGrabFCB(pVCB, FCB); return(FCB); } @@ -265,12 +375,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb, PVFATFCB directoryFCB, PWSTR longName, PFAT_DIR_ENTRY dirEntry, + ULONG startIndex, ULONG dirIndex, PVFATFCB* fileFCB) { PVFATFCB rcFCB; WCHAR pathName [MAX_PATH]; + WCHAR entryName [14]; ULONG Size; + ULONG hash; + if (longName [0] != 0 && wcslen (directoryFCB->PathName) + sizeof(WCHAR) + wcslen (longName) > MAX_PATH) { @@ -281,21 +395,22 @@ vfatMakeFCBFromDirEntry(PVCB vcb, { wcscat (pathName, L"\\"); } + hash = vfatNameHash(0, pathName); + vfatGetDirEntryName (dirEntry, entryName); if (longName [0] != 0) { wcscat (pathName, longName); } else { - WCHAR entryName [MAX_PATH]; - - vfatGetDirEntryName (dirEntry, entryName); wcscat (pathName, entryName); } rcFCB = vfatNewFCB (pathName); memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY)); - - if (vfatFCBIsDirectory(vcb, rcFCB)) + wcscpy(rcFCB->ShortName, entryName); + rcFCB->ShortHash.Hash = vfatNameHash(hash, entryName); + + if (vfatFCBIsDirectory(rcFCB)) { ULONG FirstCluster, CurrentCluster; NTSTATUS Status; @@ -320,14 +435,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb, Size = rcFCB->entry.FileSize; } rcFCB->dirIndex = dirIndex; + rcFCB->startIndex = startIndex; rcFCB->RFCB.FileSize.QuadPart = Size; rcFCB->RFCB.ValidDataLength.QuadPart = Size; rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster); rcFCB->RefCount++; - if (vfatFCBIsDirectory(vcb, rcFCB)) + if (vfatFCBIsDirectory(rcFCB)) { vfatFCBInitializeCacheFromVolume(vcb, rcFCB); } + rcFCB->parentFcb = directoryFCB; vfatAddFCBToTable (vcb, rcFCB); *fileFCB = rcFCB; @@ -342,7 +459,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, NTSTATUS status; PVFATCCB newCCB; - newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (newCCB == NULL) { return STATUS_INSUFFICIENT_RESOURCES; @@ -368,13 +485,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, PWSTR pFileToFind, PVFATFCB * pFoundFCB) { - BOOL finishedScanningDirectory; ULONG directoryIndex; + ULONG startIndex; NTSTATUS status; WCHAR defaultFileName [2]; WCHAR currentLongName [256]; FAT_DIR_ENTRY currentDirEntry; WCHAR currentEntryName [256]; + PVOID Context = NULL; + PVOID Page; assert (pDeviceExt); assert (pDirectoryFCB); @@ -395,30 +514,25 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, } directoryIndex = 0; - finishedScanningDirectory = FALSE; - while (!finishedScanningDirectory) + while (TRUE) { - status = vfatGetNextDirEntry (pDeviceExt, - pDirectoryFCB, - &directoryIndex, - currentLongName, - ¤tDirEntry); + status = vfatGetNextDirEntry(&Context, + &Page, + pDirectoryFCB, + &directoryIndex, + currentLongName, + ¤tDirEntry, + &startIndex); if (status == STATUS_NO_MORE_ENTRIES) { - finishedScanningDirectory = TRUE; - continue; - } - else if (!NT_SUCCESS(status)) - { - return status; + return STATUS_OBJECT_NAME_NOT_FOUND; } DPRINT (" Index:%d longName:%S\n", directoryIndex, currentLongName); - if (!vfatIsDirEntryDeleted (¤tDirEntry) - && !vfatIsDirEntryVolume(¤tDirEntry)) + if (!vfatIsDirEntryVolume(¤tDirEntry)) { if (currentLongName [0] != L'\0' && wstrcmpjoki (currentLongName, pFileToFind)) { @@ -427,8 +541,10 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pDirectoryFCB, currentLongName, ¤tDirEntry, - directoryIndex - 1, + startIndex, + directoryIndex, pFoundFCB); + CcUnpinData(Context); return status; } else @@ -443,12 +559,15 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pDirectoryFCB, currentLongName, ¤tDirEntry, - directoryIndex - 1, + startIndex, + directoryIndex, pFoundFCB); + CcUnpinData(Context); return status; } } } + directoryIndex++; } return STATUS_OBJECT_NAME_NOT_FOUND; @@ -484,11 +603,18 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND; } - else + + currentElement = wcsrchr(pFileName, L'\\'); + wcsncpy(pathName, pFileName, currentElement - pFileName); + pathName[currentElement - pFileName] = L'\0'; + currentElement++; + + FCB = vfatGrabFCBFromTable(pVCB, pathName); + if (FCB == NULL) { - currentElement = pFileName + 1; - wcscpy (pathName, L"\\"); - FCB = vfatOpenRootFCB (pVCB); + currentElement = pFileName + 1; + wcscpy (pathName, L"\\"); + FCB = vfatOpenRootFCB (pVCB); } parentFCB = NULL; @@ -512,7 +638,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, parentFCB = 0; } // fail if element in FCB is not a directory - if (!vfatFCBIsDirectory (pVCB, FCB)) + if (!vfatFCBIsDirectory (FCB)) { DPRINT ("Element in requested path is not a directory\n"); diff --git a/drivers/fs/vfat/finfo.c b/drivers/fs/vfat/finfo.c index 2917a50..cccbfd6 100644 --- a/drivers/fs/vfat/finfo.c +++ b/drivers/fs/vfat/finfo.c @@ -22,22 +22,17 @@ static NTSTATUS VfatGetStandardInformation(PVFATFCB FCB, - PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength) /* * FUNCTION: Retrieve the standard file information */ { - PDEVICE_EXTENSION DeviceExtension; if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION)) return STATUS_BUFFER_OVERFLOW; - DeviceExtension = DeviceObject->DeviceExtension; /* PRECONDITION */ - assert (DeviceExtension != NULL); - assert (DeviceExtension->FatInfo.BytesPerCluster != 0); assert (StandardInfo != NULL); assert (FCB != NULL); @@ -56,8 +51,6 @@ VfatGetStandardInformation(PVFATFCB FCB, static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, - PVFATFCB FCB, - PDEVICE_OBJECT DeviceObject, PFILE_POSITION_INFORMATION PositionInfo) { DPRINT ("FsdSetPositionInformation()\n"); @@ -93,6 +86,45 @@ VfatGetPositionInformation(PFILE_OBJECT FileObject, } static NTSTATUS +VfatSetBasicInformation(PFILE_OBJECT FileObject, + PVFATFCB FCB, + PDEVICE_EXTENSION DeviceExt, + PFILE_BASIC_INFORMATION BasicInfo) +{ + DPRINT("VfatSetBasicInformation()\n"); + + assert (NULL != FileObject); + assert (NULL != FCB); + assert (NULL != DeviceExt); + assert (NULL != BasicInfo); + /* Check volume label bit */ + assert(0 == (FCB->entry.Attrib & 0x08)); + + FsdFileTimeToDosDateTime(&(BasicInfo->CreationTime), + &(FCB->entry.CreationDate), + &(FCB->entry.CreationTime)); + FsdFileTimeToDosDateTime(&(BasicInfo->LastAccessTime), + &(FCB->entry.AccessDate), + NULL); + FsdFileTimeToDosDateTime(&(BasicInfo->LastWriteTime), + &(FCB->entry.UpdateDate), + &(FCB->entry.UpdateTime)); + + FCB->entry.Attrib = (FCB->entry.Attrib & + (FILE_ATTRIBUTE_DIRECTORY | 0x48)) | + (BasicInfo->FileAttributes & + (FILE_ATTRIBUTE_ARCHIVE | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY)); + DPRINT("Setting attributes 0x%02x\n", FCB->entry.Attrib); + + VfatUpdateEntry(DeviceExt, FileObject); + + return(STATUS_SUCCESS); +} + +static NTSTATUS VfatGetBasicInformation(PFILE_OBJECT FileObject, PVFATFCB FCB, PDEVICE_OBJECT DeviceObject, @@ -113,12 +145,19 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject, FsdDosDateTimeToFileTime(FCB->entry.UpdateDate, FCB->entry.UpdateTime, &BasicInfo->LastWriteTime); - FsdDosDateTimeToFileTime(FCB->entry.UpdateDate, - FCB->entry.UpdateTime, - &BasicInfo->ChangeTime); + BasicInfo->ChangeTime = BasicInfo->LastWriteTime; BasicInfo->FileAttributes = FCB->entry.Attrib; - DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes); + /* Synthesize FILE_ATTRIBUTE_NORMAL */ + if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | + FILE_ATTRIBUTE_ARCHIVE | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY))) + { + BasicInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL; + } + DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes); *BufferLength -= sizeof(FILE_BASIC_INFORMATION); return(STATUS_SUCCESS); @@ -154,18 +193,29 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject, } if (DispositionInfo->DoDeleteFile) { - KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); - count = FCB->RefCount; - if (FCB->RefCount > 1) - Status = STATUS_ACCESS_DENIED; + if (MmFlushImageSection (FileObject->SectionObjectPointers, MmFlushForDelete)) + { + KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql); + count = FCB->RefCount; + if (FCB->RefCount > 1) + { + DPRINT1("%d %x\n", FCB->RefCount, CcGetFileObjectFromSectionPtrs(FileObject->SectionObjectPointers)); + Status = STATUS_ACCESS_DENIED; + } + else + { + FCB->Flags |= FCB_DELETE_PENDING; + FileObject->DeletePending = TRUE; + } + KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql); + } else { - FCB->Flags |= FCB_DELETE_PENDING; - FileObject->DeletePending = TRUE; + DPRINT1("MmFlushImageSection returned FALSE\n"); + Status = STATUS_ACCESS_DENIED; } - KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql); DPRINT("RefCount:%d\n", count); - if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB)) + if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB)) { memset (&tmpFcb, 0, sizeof(VFATFCB)); tmpFcb.ObjectName = tmpFcb.PathName; @@ -208,16 +258,13 @@ VfatGetNameInformation(PFILE_OBJECT FileObject, assert (FCB != NULL); NameLength = wcslen(FCB->PathName) * sizeof(WCHAR); - if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength) + if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)) return STATUS_BUFFER_OVERFLOW; NameInfo->FileNameLength = NameLength; - memcpy(NameInfo->FileName, - FCB->PathName, - NameLength + sizeof(WCHAR)); + memcpy(NameInfo->FileName, FCB->PathName, NameLength + sizeof(WCHAR)); - *BufferLength -= - (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)); + *BufferLength -= (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR)); return STATUS_SUCCESS; } @@ -262,9 +309,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb, FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, Fcb->entry.UpdateTime, &NetworkInfo->LastWriteTime); - FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, - Fcb->entry.UpdateTime, - &NetworkInfo->ChangeTime); + NetworkInfo->ChangeTime = NetworkInfo->LastWriteTime; NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize; NetworkInfo->EndOfFile = Fcb->RFCB.FileSize; NetworkInfo->FileAttributes = Fcb->entry.Attrib; @@ -289,7 +334,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, assert (Fcb); NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR); - if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength) + if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR)) return(STATUS_BUFFER_OVERFLOW); /* Basic Information */ @@ -302,9 +347,7 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, Fcb->entry.UpdateTime, &Info->BasicInformation.LastWriteTime); - FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate, - Fcb->entry.UpdateTime, - &Info->BasicInformation.ChangeTime); + Info->BasicInformation.ChangeTime = Info->BasicInformation.LastWriteTime; Info->BasicInformation.FileAttributes = Fcb->entry.Attrib; /* Standard Information */ @@ -335,15 +378,36 @@ VfatGetAllInformation(PFILE_OBJECT FileObject, /* Name Information */ Info->NameInformation.FileNameLength = NameLength; - RtlCopyMemory(Info->NameInformation.FileName, - Fcb->PathName, - NameLength + sizeof(WCHAR)); + RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathName, NameLength + sizeof(WCHAR)); *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR)); return STATUS_SUCCESS; } +VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize) +{ + if (Size > 0) + { + Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, ClusterSize); + } + else + { + Fcb->RFCB.AllocationSize.QuadPart = 0LL; + } + if (!vfatFCBIsDirectory(Fcb)) + { + Fcb->entry.FileSize = Size; + } + Fcb->RFCB.FileSize.QuadPart = Size; + Fcb->RFCB.ValidDataLength.QuadPart = Size; + + if (FileObject->SectionObjectPointers->SharedCacheMap != NULL) + { + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize); + } +} + NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, @@ -380,7 +444,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, Status = NextCluster (DeviceExt, Fcb, FirstCluster, &FirstCluster, TRUE); if (!NT_SUCCESS(Status)) { - DPRINT1("NextCluster failed.\n"); + DPRINT1("NextCluster failed. Status = %x\n", Status); return Status; } if (FirstCluster == 0xffffffff) @@ -390,13 +454,14 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster, ROUND_DOWN(NewSize - 1, ClusterSize), &NCluster, TRUE); - if (NCluster == 0xffffffff) + if (NCluster == 0xffffffff || !NT_SUCCESS(Status)) { /* disk is full */ NCluster = Cluster = FirstCluster; - while (Cluster != 0xffffffff) + Status = STATUS_SUCCESS; + while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1) { - NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE); + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE); WriteCluster (DeviceExt, Cluster, 0); Cluster = NCluster; } @@ -410,67 +475,61 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster, Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize, &Cluster, FALSE); + /* FIXME: Check status */ /* Cluster points now to the last cluster within the chain */ Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster, ROUND_DOWN(NewSize - 1, ClusterSize), &NCluster, TRUE); - if (NCluster == 0xffffffff) + if (NCluster == 0xffffffff || !NT_SUCCESS(Status)) { /* disk is full */ NCluster = Cluster; - NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE); + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE); WriteCluster(DeviceExt, Cluster, 0xffffffff); Cluster = NCluster; - while (Cluster != 0xffffffff) + while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1) { - NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE); - WriteCluster (DeviceExt, Cluster, 0); - Cluster = NCluster; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE); + WriteCluster (DeviceExt, Cluster, 0); + Cluster = NCluster; } return STATUS_DISK_FULL; } } + UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize); } - else if (NewSize <= Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize) + else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart) { - if (NewSize > 0) - { - Status = OffsetToCluster(DeviceExt, Fcb, Cluster, + UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize); + if (NewSize > 0) + { + Status = OffsetToCluster(DeviceExt, Fcb, Cluster, ROUND_DOWN(NewSize - 1, ClusterSize), &Cluster, FALSE); - } - NCluster = Cluster; - Status = NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE); - WriteCluster(DeviceExt, Cluster, 0xffffffff); - Cluster = NCluster; - while (Cluster != 0xffffffff) - { - NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE); - WriteCluster (DeviceExt, Cluster, 0); - Cluster = NCluster; - } - } - if (!vfatFCBIsDirectory(DeviceExt, Fcb)) - { - Fcb->entry.FileSize = NewSize; - } - if (NewSize > 0) - { - Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize - 1, ClusterSize); + NCluster = Cluster; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE); + WriteCluster(DeviceExt, Cluster, 0xffffffff); + Cluster = NCluster; + } + else + { + Fcb->entry.FirstCluster = 0; + Fcb->entry.FirstClusterHigh = 0; + + NCluster = Cluster = FirstCluster; + Status = STATUS_SUCCESS; + } + while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1) + { + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE); + WriteCluster (DeviceExt, Cluster, 0); + Cluster = NCluster; + } } else { - Fcb->RFCB.AllocationSize.QuadPart = 0LL; - Fcb->entry.FirstCluster = 0; - Fcb->entry.FirstClusterHigh = 0; - } - Fcb->RFCB.FileSize.QuadPart = NewSize; - Fcb->RFCB.ValidDataLength.QuadPart = NewSize; - - if (FileObject->SectionObjectPointers->SharedCacheMap != NULL) - { - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize); + UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize); } /* Update the on-disk directory entry */ VfatUpdateEntry(DeviceExt, FileObject); @@ -512,7 +571,6 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext) { case FileStandardInformation: RC = VfatGetStandardInformation(FCB, - IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; @@ -621,8 +679,6 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext) { case FilePositionInformation: RC = VfatSetPositionInformation(IrpContext->FileObject, - FCB, - IrpContext->DeviceObject, SystemBuffer); break; case FileDispositionInformation: @@ -639,6 +695,11 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext) (PLARGE_INTEGER)SystemBuffer); break; case FileBasicInformation: + RC = VfatSetBasicInformation(IrpContext->FileObject, + FCB, + IrpContext->DeviceExt, + SystemBuffer); + break; case FileRenameInformation: RC = STATUS_NOT_IMPLEMENTED; break; diff --git a/drivers/fs/vfat/flush.c b/drivers/fs/vfat/flush.c new file mode 100644 index 0000000..7262598 --- /dev/null +++ b/drivers/fs/vfat/flush.c @@ -0,0 +1,119 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/fs/vfat/flush.c + * PURPOSE: VFAT Filesystem + * PROGRAMMER: Hartmut Birr + */ + +/* INCLUDES *****************************************************************/ + +#include +#include "vfat.h" + +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb) +{ + IO_STATUS_BLOCK IoStatus; + + DPRINT("VfatFlushFile(DeviceExt %x, Fcb %x) for '%S'\n", DeviceExt, Fcb, Fcb->PathName); + + CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus); + if (IoStatus.Status == STATUS_INVALID_PARAMETER) + { + /* FIXME: Caching was possible not initialized */ + IoStatus.Status = STATUS_SUCCESS; + } + return IoStatus.Status; +} + +NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) +{ + PLIST_ENTRY ListEntry; + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; + + DPRINT("VfatFlushVolume(DeviceExt %x, FatFcb %x)\n", DeviceExt, VolumeFcb); + + ListEntry = DeviceExt->FcbListHead.Flink; + while (ListEntry != &DeviceExt->FcbListHead) + { + Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry); + ListEntry = ListEntry->Flink; + ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); + Status = VfatFlushFile(DeviceExt, Fcb); + ExReleaseResourceLite (&Fcb->MainResource); + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushFile failed, status = %x\n", Status); + ReturnStatus = Status; + } + /* FIXME: Stop flushing if this a removable media and the media was removed */ + } + + Ccb = (PVFATCCB) DeviceExt->FATFileObject->FsContext2; + Fcb = Ccb->pFcb; + + ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); + Status = VfatFlushFile(DeviceExt, Fcb); + ExReleaseResourceLite(&DeviceExt->FatResource); + + /* FIXME: Flush the buffers from storage device */ + + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushFile failed, status = %x\n", Status); + ReturnStatus = Status; + } + + return ReturnStatus; +} + +NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext) +{ + NTSTATUS Status; + PVFATFCB Fcb; + PVFATCCB Ccb; + /* + * This request is not allowed on the main device object. + */ + if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) + { + Status = STATUS_INVALID_DEVICE_REQUEST; + goto ByeBye; + } + + Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; + assert(Ccb); + Fcb = Ccb->pFcb; + assert(Fcb); + + if (Fcb->Flags & FCB_IS_VOLUME) + { + ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE); + Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb); + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); + } + else + { + ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); + Status = VfatFlushFile(IrpContext->DeviceExt, Fcb); + ExReleaseResourceLite (&Fcb->MainResource); + } + +ByeBye: + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + + return (Status); +} + +/* EOF */ diff --git a/drivers/fs/vfat/fsctl.c b/drivers/fs/vfat/fsctl.c index 244079e..5d84d45 100644 --- a/drivers/fs/vfat/fsctl.c +++ b/drivers/fs/vfat/fsctl.c @@ -291,7 +291,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } - Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); + Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); if (Ccb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -330,7 +330,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) DbgPrint ("CcRosInitializeFileCache failed\n"); goto ByeBye; } - DeviceExt->LastAvailableCluster = 0; + DeviceExt->LastAvailableCluster = 2; ExInitializeResourceLite(&DeviceExt->DirResource); ExInitializeResourceLite(&DeviceExt->FatResource); @@ -352,6 +352,10 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) VolumeFcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; DeviceExt->VolumeFcb = VolumeFcb; + ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); + InsertHeadList(&VfatGlobalData->VolumeListHead, &DeviceExt->VolumeListEntry); + ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); + /* read serial number */ DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID; @@ -367,9 +371,9 @@ ByeBye: if (DeviceExt && DeviceExt->FATFileObject) ObDereferenceObject (DeviceExt->FATFileObject); if (Fcb) - ExFreePool(Fcb); + vfatDestroyFCB(Fcb); if (Ccb) - ExFreePool(Ccb); + vfatDestroyCCB(Ccb); if (DeviceObject) IoDeleteDevice(DeviceObject); if (VolumeFcb) diff --git a/drivers/fs/vfat/iface.c b/drivers/fs/vfat/iface.c index 9b7aad2..4eeb922 100644 --- a/drivers/fs/vfat/iface.c +++ b/drivers/fs/vfat/iface.c @@ -84,10 +84,21 @@ DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; + DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest; DriverObject->DriverUnload = NULL; + ExInitializeNPagedLookasideList(&VfatGlobalData->FcbLookasideList, + NULL, NULL, 0, sizeof(VFATFCB), TAG_FCB, 0); + ExInitializeNPagedLookasideList(&VfatGlobalData->CcbLookasideList, + NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0); + ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, + NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0); + + ExInitializeResourceLite(&VfatGlobalData->VolumeListLock); + InitializeListHead(&VfatGlobalData->VolumeListHead); IoRegisterFileSystem(DeviceObject); return(STATUS_SUCCESS); } diff --git a/drivers/fs/vfat/makefile b/drivers/fs/vfat/makefile index ad6160d..0cf3999 100644 --- a/drivers/fs/vfat/makefile +++ b/drivers/fs/vfat/makefile @@ -26,7 +26,8 @@ TARGET_OBJECTS = \ volume.o \ misc.o \ fsctl.o \ - ea.o + ea.o \ + flush.o DEP_OBJECTS = $(TARGET_OBJECTS) diff --git a/drivers/fs/vfat/misc.c b/drivers/fs/vfat/misc.c index dd71eb8..b2bd621 100644 --- a/drivers/fs/vfat/misc.c +++ b/drivers/fs/vfat/misc.c @@ -51,8 +51,12 @@ NTSTATUS VfatDispatchRequest ( return VfatQueryVolumeInformation(IrpContext); case IRP_MJ_SET_VOLUME_INFORMATION: return VfatSetVolumeInformation(IrpContext); + case IRP_MJ_LOCK_CONTROL: + return VfatLockControl(IrpContext); case IRP_MJ_CLEANUP: return VfatCleanup(IrpContext); + case IRP_MJ_FLUSH_BUFFERS: + return VfatFlush(IrpContext); default: DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; @@ -62,6 +66,47 @@ NTSTATUS VfatDispatchRequest ( } } +NTSTATUS VfatLockControl( + IN PVFAT_IRP_CONTEXT IrpContext + ) +{ + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status; + + DPRINT("VfatLockControl(IrpContext %x)\n", IrpContext); + + assert(IrpContext); + + Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; + Fcb = Ccb->pFcb; + + if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) + { + Status = STATUS_INVALID_DEVICE_REQUEST; + goto Fail; + } + + if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) + { + Status = STATUS_INVALID_PARAMETER; + goto Fail; + } + + Status = FsRtlProcessFileLock(&Fcb->FileLock, + IrpContext->Irp, + NULL + ); + + VfatFreeIrpContext(IrpContext); + return Status; + +Fail:; + IrpContext->Irp->IoStatus.Status = Status; + IofCompleteRequest(IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + return Status; +} NTSTATUS STDCALL VfatBuildRequest ( IN PDEVICE_OBJECT DeviceObject, @@ -94,7 +139,7 @@ NTSTATUS STDCALL VfatBuildRequest ( VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext) { assert (IrpContext); - ExFreePool(IrpContext); + ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext); } PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) @@ -107,7 +152,7 @@ PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) assert (DeviceObject); assert (Irp); - IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT)); + IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList); if (IrpContext) { RtlZeroMemory(IrpContext, sizeof(IrpContext)); diff --git a/drivers/fs/vfat/rw.c b/drivers/fs/vfat/rw.c index cd63a63..cce9f96 100644 --- a/drivers/fs/vfat/rw.c +++ b/drivers/fs/vfat/rw.c @@ -672,6 +672,17 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext) Status = STATUS_PENDING; goto ByeBye; } + + if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) && + FsRtlAreThereCurrentFileLocks(&Fcb->FileLock)) + { + if (!FsRtlCheckLockForReadAccess(&Fcb->FileLock, IrpContext->Irp)) + { + Status = STATUS_FILE_LOCK_CONFLICT; + goto ByeBye; + } + } + if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) && !(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME))) { @@ -918,6 +929,16 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } } + if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) && + FsRtlAreThereCurrentFileLocks(&Fcb->FileLock)) + { + if (!FsRtlCheckLockForWriteAccess(&Fcb->FileLock, IrpContext->Irp)) + { + Status = STATUS_FILE_LOCK_CONFLICT; + goto ByeBye; + } + } + if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT) && !(Fcb->Flags & FCB_IS_VOLUME)) { if (ByteOffset.u.LowPart + Length > Fcb->RFCB.AllocationSize.u.LowPart) @@ -945,10 +966,6 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } } - if (ByteOffset.QuadPart > OldFileSize.QuadPart) - { - CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); - } if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) && !(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME))) @@ -973,6 +990,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize); } + if (ByteOffset.QuadPart > OldFileSize.QuadPart) + { + CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); + } if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length, 1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer)) { @@ -990,6 +1011,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) // non cached write CHECKPOINT; + if (ByteOffset.QuadPart > OldFileSize.QuadPart) + { + CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); + } Buffer = VfatGetUserBuffer(IrpContext->Irp); if (!Buffer) { @@ -1017,13 +1042,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) &Fcb->entry.UpdateTime); Fcb->entry.AccessDate = Fcb->entry.UpdateDate; // update dates/times and length - if (OldAllocationSize != Fcb->RFCB.AllocationSize.u.LowPart) - { - VfatUpdateEntry (IrpContext->DeviceExt, IrpContext->FileObject); - Fcb->Flags &= ~FCB_UPDATE_DIRENTRY; - } - else - Fcb->Flags |= FCB_UPDATE_DIRENTRY; + VfatUpdateEntry (IrpContext->DeviceExt, IrpContext->FileObject); } } diff --git a/drivers/fs/vfat/shutdown.c b/drivers/fs/vfat/shutdown.c index c4be53e..f709406 100644 --- a/drivers/fs/vfat/shutdown.c +++ b/drivers/fs/vfat/shutdown.c @@ -22,29 +22,43 @@ NTSTATUS STDCALL VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS Status; + PLIST_ENTRY ListEntry; + PDEVICE_EXTENSION DeviceExt; DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp); -#if 0 /* FIXME: block new mount requests */ - - /* FIXME: Traverse list of logical volumes. For each volume: */ - { - /* FIXME: acquire vcb resource exclusively */ - - /* FIXME: Flush logical volume */ - - /* FIXME: send IRP_MJ_SHUTDOWN to each volume */ - - /* FIXME: wait for completion of IRP_MJ_SHUTDOWN */ - - /* FIXME: release vcb resource */ - } - -#endif - - Status = STATUS_SUCCESS; + if (DeviceObject == VfatGlobalData->DeviceObject) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); + ListEntry = VfatGlobalData->VolumeListHead.Flink; + while (ListEntry != &VfatGlobalData->VolumeListHead) + { + DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry); + ListEntry = ListEntry->Flink; + + ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); + Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); + ExReleaseResourceLite(&DeviceExt->DirResource); + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushVolume failed, status = %x\n", Status); + Irp->IoStatus.Status = Status; + } + /* FIXME: Unmount the logical volume */ + + ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); + } + /* FIXME: Free all global acquired resources */ + + Status = Irp->IoStatus.Status; + } + else + { + Status = STATUS_INVALID_DEVICE_REQUEST; + } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; diff --git a/drivers/fs/vfat/string.c b/drivers/fs/vfat/string.c index 9419fdf..66d2698 100644 --- a/drivers/fs/vfat/string.c +++ b/drivers/fs/vfat/string.c @@ -20,102 +20,6 @@ /* FUNCTIONS ****************************************************************/ -void vfat_initstr(wchar_t *wstr, ULONG wsize) -/* - * FUNCTION: Initialize a string for use with a long file name - */ -{ - int i; - wchar_t nc=0; - for(i=0; i + BOOLEAN AlreadyOpened = FALSE; BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart, @@ -73,13 +76,18 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M // Throw data up to GDI callback if(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL) { + DPRINT("MouseClassCallBack() Calling GDI callback at %p\n", ClassDeviceExtension->GDIInformation.CallBack); (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack) (ClassDeviceExtension->PortData - ReadSize, ReadSize); - } + } else { + DPRINT("MouseClassCallBack() NO GDI callback installed\n"); + } ClassDeviceExtension->PortData -= ReadSize; ClassDeviceExtension->InputCount -= ReadSize; ClassDeviceExtension->ReadIsPending = FALSE; + } else { + DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount); } return TRUE; @@ -232,6 +240,8 @@ NTSTATUS STDCALL MouseClassInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, DeviceExtension->GDIInformation = *((PGDI_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer); + DbgPrint("MouseClassInternalDeviceControl() installed GDI callback at %p\n", DeviceExtension->GDIInformation.CallBack); + status = STATUS_SUCCESS; break; diff --git a/drivers/input/psaux/.cvsignore b/drivers/input/psaux/.cvsignore index f61f1c9..c132aad 100644 --- a/drivers/input/psaux/.cvsignore +++ b/drivers/input/psaux/.cvsignore @@ -1,2 +1,4 @@ psaux.coff -psaux.sys.unstripped +*.o +*.sys +*.sym diff --git a/drivers/input/psaux/psaux.c b/drivers/input/psaux/psaux.c index a3e7cfc..3393801 100644 --- a/drivers/input/psaux/psaux.c +++ b/drivers/input/psaux/psaux.c @@ -158,10 +158,12 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) UNICODE_STRING SymlinkName; PDEVICE_EXTENSION DeviceExtension; - if(detect_ps2_port() == TRUE) - { - } else + if (detect_ps2_port() == TRUE) { + DbgPrint("PS2 Port Driver version 0.0.1\n"); + } else { + DbgPrint("PS2 port not found.\n"); return STATUS_UNSUCCESSFUL; + } DriverObject->MajorFunction[IRP_MJ_CREATE] = PS2MouseDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = PS2MouseDispatch; diff --git a/drivers/lib/bzip2/.cvsignore b/drivers/lib/bzip2/.cvsignore new file mode 100644 index 0000000..80ade3d --- /dev/null +++ b/drivers/lib/bzip2/.cvsignore @@ -0,0 +1,5 @@ +unbzip2.sys +unbzip2.nostrip.sys +unbzip2.sym +*.d +*.o \ No newline at end of file diff --git a/drivers/lib/bzip2/Makefile b/drivers/lib/bzip2/Makefile index c933adb..8e845e1 100644 --- a/drivers/lib/bzip2/Makefile +++ b/drivers/lib/bzip2/Makefile @@ -1,18 +1,35 @@ +# $Id$ + PATH_TO_TOP = ../../.. + TARGET_TYPE = export_driver + TARGET_NAME = unbzip2 + TARGET_NORC = yes -TARGET_CFLAGS=-Wall -Winline -Os -fomit-frame-pointer -fno-strength-reduce -DBZ_NO_STDIO -DBZ_DECOMPRESS_ONLY $(BIGFILES) -g +TARGET_CFLAGS = \ + -Wall -Winline -Os -fomit-frame-pointer -fno-strength-reduce \ + -DBZ_NO_STDIO -DBZ_DECOMPRESS_ONLY $(BIGFILES) -g -TARGET_OBJECTS = bzlib.o randtable.o crctable.o decompress.o huffman.o dllmain.o +TARGET_OBJECTS = \ + bzlib.o \ + randtable.o \ + crctable.o \ + decompress.o \ + huffman.o \ + dllmain.o TARGET_GCCLIBS = gcc include $(PATH_TO_TOP)/rules.mak + include $(TOOLS_PATH)/helper.mk test.exe: test.o ../../dk/w32/lib/unbzip2.a $(CC) -s -Os -o test.exe test.o ../../dk/w32/lib/unbzip2.a + test.o: test.c $(CC) -s -Os -c test.c + +# EOF diff --git a/drivers/lib/zlib/.cvsignore b/drivers/lib/zlib/.cvsignore index a438335..14e6faf 100644 --- a/drivers/lib/zlib/.cvsignore +++ b/drivers/lib/zlib/.cvsignore @@ -1 +1,5 @@ +zlib.a +zlib.nostrip.a *.d +*.o +*.sym diff --git a/drivers/lib/zlib/Makefile b/drivers/lib/zlib/Makefile index 0202634..98244e8 100644 --- a/drivers/lib/zlib/Makefile +++ b/drivers/lib/zlib/Makefile @@ -6,6 +6,8 @@ TARGET_TYPE = library TARGET_NAME = zlib +TARGET_NORC = yes + TARGET_CFLAGS = \ -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -Wstrict-prototypes -Wmissing-prototypes diff --git a/drivers/net/afd/.cvsignore b/drivers/net/afd/.cvsignore index 4592925..cbda6a7 100644 --- a/drivers/net/afd/.cvsignore +++ b/drivers/net/afd/.cvsignore @@ -1 +1,4 @@ -afd.coff \ No newline at end of file +*.coff +*.sym +*.sys +*.o diff --git a/lib/crtdll/assert/.cvsignore b/drivers/net/afd/afd/.cvsignore similarity index 100% rename from lib/crtdll/assert/.cvsignore rename to drivers/net/afd/afd/.cvsignore index bd0e3df..d273b98 100644 --- a/lib/crtdll/assert/.cvsignore +++ b/drivers/net/afd/afd/.cvsignore @@ -1,3 +1,3 @@ -*.d *.o *.sym +*.d diff --git a/drivers/net/afd/afd/afd.c b/drivers/net/afd/afd/afd.c index 845272b..742d989 100644 --- a/drivers/net/afd/afd/afd.c +++ b/drivers/net/afd/afd/afd.c @@ -12,7 +12,7 @@ #ifdef DBG /* See debug.h for debug/trace constants */ -DWORD DebugTraceLevel = MIN_TRACE; +DWORD DebugTraceLevel = MID_TRACE; //DWORD DebugTraceLevel = DEBUG_ULTRA; #endif /* DBG */ diff --git a/drivers/net/dd/ne2000/.cvsignore b/drivers/net/dd/ne2000/.cvsignore index 51ffd22..dad625c 100644 --- a/drivers/net/dd/ne2000/.cvsignore +++ b/drivers/net/dd/ne2000/.cvsignore @@ -1,4 +1,7 @@ base.tmp junk.tmp +temp.exp ne2000.coff -temp.exp \ No newline at end of file +*.sym +*.o +*.sys diff --git a/drivers/net/dd/ne2000/ne2000/.cvsignore b/drivers/net/dd/ne2000/ne2000/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/dd/ne2000/ne2000/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/ndis/.cvsignore b/drivers/net/ndis/.cvsignore index dea5140..942ff9d 100644 --- a/drivers/net/ndis/.cvsignore +++ b/drivers/net/ndis/.cvsignore @@ -3,3 +3,4 @@ ndis.coff *.d *.o *.sym +*.sys diff --git a/drivers/net/ndis/ndis/.cvsignore b/drivers/net/ndis/ndis/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/ndis/ndis/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/npf/.cvsignore b/drivers/net/npf/.cvsignore new file mode 100644 index 0000000..d7687d4 --- /dev/null +++ b/drivers/net/npf/.cvsignore @@ -0,0 +1,5 @@ +*.coff +*.d +*.o +*.sym +*.sys diff --git a/drivers/net/npf/Makefile b/drivers/net/npf/Makefile new file mode 100644 index 0000000..4d66ad3 --- /dev/null +++ b/drivers/net/npf/Makefile @@ -0,0 +1,38 @@ +# $Id$ + +PATH_TO_TOP = ../../.. + +#TARGET_TYPE = export_driver +TARGET_TYPE = driver + +TARGET_NAME = npf + +#TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -I$(PATH_TO_TOP)/ntoskrnl/include + +TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -DUSE_KLOCKS -I$(PATH_TO_TOP)/ntoskrnl/include + +TARGET_DDKLIBS = ndis.a + +TARGET_OBJECTS = \ + packet.o \ + openclos.o \ + read.o \ + write.o \ + dump.o \ + jitter.o \ + win_bpf_filter.o \ + tme.o \ + count_packets.o \ + win_bpf_filter_init.o \ + tcp_session.o \ + memory_t.o \ + time_calls.o \ + functions.o \ + bucket_lookup.o \ + normal_lookup.o + +TARGET_PATH = . + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/drivers/net/npf/bucket_lookup.c b/drivers/net/npf/bucket_lookup.c new file mode 100644 index 0000000..e2c5fde --- /dev/null +++ b/drivers/net/npf/bucket_lookup.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#include "bucket_lookup.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + + + +/* the key is represented by the initial and final value */ +/* of the bucket. At the moment bucket_lookup is able to */ +/* manage values of 16, 32 bits. */ +uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 value; + uint32 i,j; + int found=-1; + uint32 blocks; + uint32 block_size; + uint8 *temp; + if ((data->key_len!=1)&& /*16 bit value*/ + (data->key_len!=2)) /*32 bit value*/ + return TME_ERROR; + + /*32 bit values*/ + blocks=data->filled_blocks-1; + block_size=data->block_size; + i=blocks/2; /*relative shift*/ + j=i; + temp=data->shared_memory_base_address+block_size; + + if (data->key_len==2) + { + value=SW_ULONG_AT(key,0); + + if((valueSW_ULONG_AT(temp+block_size*(blocks-1),4))) + { + uint32 *key32=(uint32*) key; + key32[0]=key32[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + while(found==-1) /* search routine */ + { + i=(i==1)? 1:i>>1; + if (SW_ULONG_AT(temp+block_size*j,0)>value) + if (SW_ULONG_AT(temp+block_size*(j-1),4)value) + found=-2; + else + j+=i; + else found=j; + } + if (found<0) + { + uint32 *key32=(uint32*) key; + key32[0]=key32[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + data->last_found=data->lut_base_address+found*sizeof(RECORD); + + COPY_MEMORY(key,temp+block_size*found,8); + + GET_TIME((struct timeval *)(temp+block_size*found+8),time_ref); + + return TME_TRUE; + } + else + { + value=SW_USHORT_AT(key,0); + + if((valueSW_USHORT_AT(temp+block_size*(blocks-1),2))) + { + uint16 *key16=(uint16*) key; + key16[0]=key16[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + while(found==-1) /* search routine */ + { + i=(i==1)? 1:i>>1; + if (SW_USHORT_AT(temp+block_size*j,0)>value) + if (SW_USHORT_AT(temp+block_size*(j-1),2)value) + found=-2; + else + j+=i; + else found=j; + } + + if (found<0) + { + uint16 *key16=(uint16*) key; + key16[0]=key16[1]=0; + + GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref); + + data->last_found=NULL; + return TME_FALSE; + } + + data->last_found=data->lut_base_address+found*sizeof(RECORD); + + GET_TIME((struct timeval *)(temp+block_size*found+4),time_ref); + + COPY_MEMORY(key,temp+block_size*found,4); + + return TME_TRUE; + } + +} + +uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + RECORD *records=(RECORD*)data->lut_base_address; + + if ((data->key_len!=1)&& /*16 bit value*/ + (data->key_len!=2)) /*32 bit value*/ + return TME_ERROR; + + if(data->key_len==2) + { + uint32 start,stop; + uint8 *tmp; + + start=SW_ULONG_AT(key,0); + stop=SW_ULONG_AT(key,4); + + if (start>stop) + return TME_ERROR; + if (data->filled_entries>0) + { + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0); + /*check if it is coherent with the previous block*/ + if (SW_ULONG_AT(tmp,4)>=start) + return TME_ERROR; + } + + if (data->filled_blocks==data->shared_memory_blocks) + return TME_ERROR; + + if (data->filled_entries==data->lut_entries) + return TME_ERROR; + + tmp=data->shared_memory_base_address+data->block_size*data->filled_blocks; + + COPY_MEMORY(tmp,key,8); + + SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer); + SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec); + + GET_TIME((struct timeval *)(tmp+8),time_ref); + + data->filled_blocks++; + data->filled_entries++; + + return TME_TRUE; + } + else + { + uint16 start,stop; + uint8 *tmp; + + start=SW_USHORT_AT(key,0); + stop=SW_USHORT_AT(key,2); + + if (start>stop) + return TME_ERROR; + if (data->filled_entries>0) + { + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0); + /*check if it is coherent with the previous block*/ + if (SW_USHORT_AT(tmp,2)>=start) + return TME_ERROR; + } + + if (data->filled_blocks==data->shared_memory_blocks) + return TME_ERROR; + + if (data->filled_entries==data->lut_entries) + return TME_ERROR; + + tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries].block,0); + + COPY_MEMORY(tmp,key,4); + + SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer); + SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec); + + GET_TIME((struct timeval *)(tmp+4),time_ref); + + data->filled_blocks++; + data->filled_entries++; + + return TME_TRUE; + } +} \ No newline at end of file diff --git a/drivers/net/npf/bucket_lookup.h b/drivers/net/npf/bucket_lookup.h new file mode 100644 index 0000000..512d637 --- /dev/null +++ b/drivers/net/npf/bucket_lookup.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __bucket_lookup +#define __bucket_lookup +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define BUCKET_LOOKUP_INSERT 0x00000011 +uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define BUCKET_LOOKUP 0x00000010 +uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); + +#endif \ No newline at end of file diff --git a/drivers/net/npf/count_packets.c b/drivers/net/npf/count_packets.c new file mode 100644 index 0000000..71aa61f --- /dev/null +++ b/drivers/net/npf/count_packets.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#include "count_packets.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + + + +uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data) +{ + + c_p_data *counters=(c_p_data*)(block+data->key_len*4); + + counters->bytes+=pkt_size; + counters->packets++; + + return TME_SUCCESS; + +} diff --git a/drivers/net/npf/count_packets.h b/drivers/net/npf/count_packets.h new file mode 100644 index 0000000..819b5b5 --- /dev/null +++ b/drivers/net/npf/count_packets.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __count_packets +#define __count_packets + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +typedef struct __c_p_data +{ + struct timeval timestamp; + uint64 packets; + uint64 bytes; +} + c_p_data; + +#define COUNT_PACKETS 0x00000000 +uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); + +#endif + diff --git a/drivers/net/npf/debug.h b/drivers/net/npf/debug.h new file mode 100644 index 0000000..7461b8b --- /dev/null +++ b/drivers/net/npf/debug.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __DEBUG_INCLUDE +#define __DEBUG_INCLUDE + + +#if DBG + +#define IF_PACKETDEBUG(f) if (PacketDebugFlag & (f)) +extern ULONG PacketDebugFlag; + +#define PACKET_DEBUG_LOUD 0x00000001 // debugging info +#define PACKET_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info + +#define PACKET_DEBUG_INIT 0x00000100 // init debugging info + +// +// Macro for deciding whether to dump lots of debugging information. +// + +#define IF_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_LOUD ) { A } +#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { A } +#define IF_INIT_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { A } + +#else + +#define IF_LOUD(A) +#define IF_VERY_LOUD(A) +#define IF_INIT_LOUD(A) + +#endif + +#endif /*#define __DEBUG_INCLUDE*/ diff --git a/drivers/net/npf/dump.c b/drivers/net/npf/dump.c new file mode 100644 index 0000000..1f1b754 --- /dev/null +++ b/drivers/net/npf/dump.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#else +#include +#include +//#define PsGetCurrentProcess() IoGetCurrentProcess() +#define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread())) +#endif + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" + +//------------------------------------------------------------------- + +NTSTATUS +NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append) +{ + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + OBJECT_ATTRIBUTES ObjectAttributes; + PWCHAR PathPrefix; + USHORT PathLen; + UNICODE_STRING FullFileName; + ULONG FullFileNameLength; + PDEVICE_OBJECT fsdDevice; + + FILE_STANDARD_INFORMATION StandardInfo; + + IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");) + + if(fileName->Buffer[0] == L'\\' && + fileName->Buffer[1] == L'?' && + fileName->Buffer[2] == L'?' && + fileName->Buffer[3] == L'\\' + ){ + PathLen = 0; + } + else{ + PathPrefix = L"\\??\\"; + PathLen = 8; + } + + // Insert the correct path prefix. + FullFileNameLength = PathLen + fileName->MaximumLength; + +#define NPF_TAG_FILENAME TAG('0', 'D', 'W', 'A') + FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, + FullFileNameLength, + NPF_TAG_FILENAME); + + if (FullFileName.Buffer == NULL) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + return ntStatus; + } + + FullFileName.Length = PathLen; + FullFileName.MaximumLength = (USHORT)FullFileNameLength; + + if(PathLen) + RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen); + + RtlAppendUnicodeStringToString (&FullFileName, fileName); + + IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);) + + InitializeObjectAttributes ( &ObjectAttributes, + &FullFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL ); + + // Create the dump file + ntStatus = ZwCreateFile( &Open->DumpFileHandle, + SYNCHRONIZE | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatus, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + (Append)?FILE_OPEN_IF:FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0 ); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);) + + ExFreePool(FullFileName.Buffer); + Open->DumpFileHandle=NULL; + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + ExFreePool(FullFileName.Buffer); + + ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle, + FILE_WRITE_ACCESS, +#ifndef __GNUC__ + *IoFileObjectType, +#else + IoFileObjectType, +#endif + KernelMode, + (PVOID)&Open->DumpFileObject, + 0); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject); + + IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);) + + return ntStatus; +} + +//------------------------------------------------------------------- + +NTSTATUS +NPF_StartDump(POPEN_INSTANCE Open) +{ + NTSTATUS ntStatus; + struct packet_file_header hdr; + IO_STATUS_BLOCK IoStatus; + NDIS_REQUEST pRequest; + ULONG MediaType; + OBJECT_ATTRIBUTES ObjectAttributes; + + IF_LOUD(DbgPrint("NPF: StartDump.\n");) + + // Init the file header + hdr.magic = TCPDUMP_MAGIC; + hdr.version_major = PCAP_VERSION_MAJOR; + hdr.version_minor = PCAP_VERSION_MINOR; + hdr.thiszone = 0; /*Currently not set*/ + hdr.snaplen = 1514; + hdr.sigfigs = 0; + + // Detect the medium type + switch (Open->Medium){ + + case NdisMediumWan: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMedium802_3: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMediumFddi: + hdr.linktype = DLT_FDDI; + break; + + case NdisMedium802_5: + hdr.linktype = DLT_IEEE802; + break; + + case NdisMediumArcnet878_2: + hdr.linktype = DLT_ARCNET; + break; + + case NdisMediumAtm: + hdr.linktype = DLT_ATM_RFC1483; + break; + + default: + hdr.linktype = DLT_EN10MB; + } + + // Write the header. + // We can use ZwWriteFile because we are in the context of the application + ntStatus = ZwWriteFile(Open->DumpFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + &hdr, + sizeof(hdr), + NULL, + NULL ); + + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + ntStatus = STATUS_NO_SUCH_FILE; + return ntStatus; + } + + Open->DumpOffset.QuadPart=24; + + ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + (ACCESS_MASK)0L, + 0, + 0, + (PKSTART_ROUTINE)NPF_DumpThread, + Open); + + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + return ntStatus; + } + ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + NULL, + KernelMode, + (PVOID*)&Open->DumpThreadObject, + 0); + if ( !NT_SUCCESS( ntStatus ) ) + { + IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) + + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + + return ntStatus; + } + + return ntStatus; + +} + +//------------------------------------------------------------------- +// Dump Thread +//------------------------------------------------------------------- + +VOID NPF_DumpThread(POPEN_INSTANCE Open) +{ + ULONG FrozenNic; + + IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%0x\n",Open);) + + while(TRUE){ + + // Wait until some packets arrive or the timeout expires + NdisWaitEvent(&Open->DumpEvent, 5000); + + IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");) + + if(Open->DumpLimitReached || + Open->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too + // small for any capture. In both cases it is better to end the dump + + IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");) + IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);) + + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + NdisResetEvent(&Open->DumpEvent); + + // Write the content of the buffer to the file + if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){ + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + } + +} + +//------------------------------------------------------------------- + +NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open) +{ + UINT Thead; + UINT Ttail; + UINT TLastByte; + PUCHAR CurrBuff; + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL lMdl; + UINT SizeToDump; + + + Thead=Open->Bhead; + Ttail=Open->Btail; + TLastByte=Open->BLastByte; + + IF_LOUD(DbgPrint("NPF: NPF_SaveCurrentBuffer.\n");) + + // Get the address of the buffer + CurrBuff=Open->Buffer; + // + // Fill the application buffer + // + if( Ttail < Thead ) + { + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(TRUE){ + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = TLastByte-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != TLastByte-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(TLastByte-Thead); + Open->BLastByte=Ttail; + Open->Bhead=0; + } + + if( Ttail > Thead ){ + + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(Thead + SizeToDump < Ttail){ + + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = Ttail-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != Ttail-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(Ttail-Thead); + Open->Bhead=Ttail; + + } + + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- + +NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){ + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL WriteMdl; + PUCHAR VMBuff; + UINT VMBufLen; + + + IF_LOUD(DbgPrint("NPF: NPF_CloseDumpFile.\n");) + IF_LOUD(DbgPrint("Dumpoffset=%d\n",Open->DumpOffset.QuadPart);) + +DbgPrint("1\n"); + // Consistency check + if(Open->DumpFileHandle == NULL) + return STATUS_UNSUCCESSFUL; + +DbgPrint("2\n"); + ZwClose( Open->DumpFileHandle ); + + ObDereferenceObject(Open->DumpFileObject); +/* + if(Open->DumpLimitReached == TRUE) + // Limit already reached: don't save the rest of the buffer. + return STATUS_SUCCESS; +*/ +DbgPrint("3\n"); + + NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE); + + // Flush the buffer to file + NPF_SaveCurrentBuffer(Open); + + // Close The file + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + + Open->DumpFileHandle = NULL; + + ObDereferenceObject(Open->DumpFileObject); + + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------- + +#ifndef __GNUC__ +static NTSTATUS +#else +NTSTATUS STDCALL +#endif +PacketDumpCompletion(PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context) +{ + + // Copy the status information back into the "user" IOSB + *Irp->UserIosb = Irp->IoStatus; + + // Wake up the mainline code + KeSetEvent(Irp->UserEvent, 0, FALSE); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +//------------------------------------------------------------------- + +VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock) +{ + PIRP irp; + KEVENT event; + PIO_STACK_LOCATION ioStackLocation; + PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject); + NTSTATUS Status; + + // Set up the event we'll use + KeInitializeEvent(&event, SynchronizationEvent, FALSE); + + // Allocate and build the IRP we'll be sending to the FSD + irp = IoAllocateIrp(fsdDevice->StackSize, FALSE); + + if (!irp) { + // Allocation failed, presumably due to memory allocation failure + IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES; + IoStatusBlock->Information = 0; + + return; + } + + irp->MdlAddress = Mdl; + irp->UserEvent = &event; + irp->UserIosb = IoStatusBlock; + irp->Tail.Overlay.Thread = PsGetCurrentThread(); + irp->Tail.Overlay.OriginalFileObject= FileObject; + irp->RequestorMode = KernelMode; + + // Indicate that this is a WRITE operation + irp->Flags = IRP_WRITE_OPERATION; + + // Set up the next I/O stack location + ioStackLocation = IoGetNextIrpStackLocation(irp); + ioStackLocation->MajorFunction = IRP_MJ_WRITE; + ioStackLocation->MinorFunction = 0; + ioStackLocation->DeviceObject = fsdDevice; + ioStackLocation->FileObject = FileObject; + IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE); + ioStackLocation->Parameters.Write.Length = Length; + ioStackLocation->Parameters.Write.ByteOffset = *Offset; + + + // Send it on. Ignore the return code + (void) IoCallDriver(fsdDevice, irp); + + // Wait for the I/O to complete. + KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); + + // Free the IRP now that we are done with it + IoFreeIrp(irp); + + return; +} diff --git a/drivers/net/npf/functions.c b/drivers/net/npf/functions.c new file mode 100644 index 0000000..04c7e4b --- /dev/null +++ b/drivers/net/npf/functions.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#include "functions.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#include +#else +#include +#include +#include +#endif + +#endif + + + +lut_fcn lut_fcn_mapper(uint32 index) +{ + + switch (index) + { + case NORMAL_LUT_W_INSERT: + return (lut_fcn) normal_lut_w_insert; + + case NORMAL_LUT_WO_INSERT: + return (lut_fcn) normal_lut_wo_insert; + + case BUCKET_LOOKUP: + return (lut_fcn) bucket_lookup; + + case BUCKET_LOOKUP_INSERT: + return (lut_fcn) bucket_lookup_insert; + + default: + return NULL; + } + + return NULL; + +} + +exec_fcn exec_fcn_mapper(uint32 index) +{ + switch (index) + { + case COUNT_PACKETS: + return (exec_fcn) count_packets; + + case TCP_SESSION: + return (exec_fcn) tcp_session; + default: + return NULL; + } + + return NULL; +} diff --git a/drivers/net/npf/functions.h b/drivers/net/npf/functions.h new file mode 100644 index 0000000..d25c679 --- /dev/null +++ b/drivers/net/npf/functions.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __FUNCTIONS +#define __FUNCTIONS + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif +/*function mappers */ + +lut_fcn lut_fcn_mapper(uint32 index); +exec_fcn exec_fcn_mapper(uint32 index); + +/* lookup functions */ + +#ifdef WIN32 +#include "bucket_lookup.h" +#include "normal_lookup.h" +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +/* execution functions */ + +#ifdef WIN32 +#include "count_packets.h" +#include "tcp_session.h" +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +#endif \ No newline at end of file diff --git a/drivers/net/npf/jitter.c b/drivers/net/npf/jitter.c new file mode 100644 index 0000000..2be1cf9 --- /dev/null +++ b/drivers/net/npf/jitter.c @@ -0,0 +1,681 @@ +/* + * Copyright (c) 2002 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#else +#include +#include +#endif + +#include "packet.h" +#include "win_bpf.h" + +emit_func emitm; + +// +// emit routine to update the jump table +// +void emit_lenght(binary_stream *stream, ULONG value, UINT len) +{ + (stream->refs)[stream->bpf_pc]+=len; + stream->cur_ip+=len; +} + +// +// emit routine to output the actual binary code +// +void emit_code(binary_stream *stream, ULONG value, UINT len) +{ + + switch (len){ + + case 1: + stream->ibuf[stream->cur_ip]=(UCHAR)value; + stream->cur_ip++; + break; + + case 2: + *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value; + stream->cur_ip+=2; + break; + + case 4: + *((ULONG*)(stream->ibuf+stream->cur_ip))=value; + stream->cur_ip+=4; + break; + + default:; + + } + + return; + +} + +// +// Function that does the real stuff +// +BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem) +{ + struct bpf_insn *ins; + UINT i, pass; + binary_stream stream; + + + // Allocate the reference table for the jumps +#ifdef NTKERNEL +#define NPF_TAG_REFTABLE TAG('0', 'J', 'W', 'A') + stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), NPF_TAG_REFTABLE); +#else + stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT)); +#endif + if(stream.refs==NULL) + { + return NULL; + } + + // Reset the reference table + for(i=0; i< nins + 1; i++) + stream.refs[i]=0; + + stream.cur_ip=0; + stream.bpf_pc=0; + + // the first pass will emit the lengths of the instructions + // to create the reference table + emitm=emit_lenght; + + for(pass=0;;){ + + ins = prog; + + /* create the procedure header */ + PUSH(EBP) + MOVrd(EBP,ESP) + PUSH(EBX) + PUSH(ECX) + PUSH(EDX) + PUSH(ESI) + PUSH(EDI) + MOVodd(EBX, EBP, 8) + + for(i=0;icode) { + + default: + + return NULL; + + case BPF_RET|BPF_K: + + MOVid(EAX,ins->k) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_RET|BPF_A: + + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_LD|BPF_W|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) //this can be optimized with xor eax,eax + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_ABS: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LD|BPF_W|BPF_LEN: + + MOVodd(EAX, EBP, 0xc) + + break; + + case BPF_LDX|BPF_W|BPF_LEN: + + MOVodd(EDX, EBP, 0xc) + + break; + + case BPF_LD|BPF_W|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LDX|BPF_MSH|BPF_B: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EDX,0) + MOVobb(DL,EBX,ECX) + ANDib(DL, 0xf) + SHLib(EDX, 2) + + break; + + case BPF_LD|BPF_IMM: + + MOVid(EAX,ins->k) + + break; + + case BPF_LDX|BPF_IMM: + + MOVid(EDX,ins->k) + + break; + + case BPF_LD|BPF_MEM: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EAX, ECX, ESI) + + break; + + case BPF_LDX|BPF_MEM: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EDX, ECX, ESI) + + break; + + case BPF_ST: + + // XXX: this command and the following could be optimized if the previous + // instruction was already of this type + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EAX) + + break; + + case BPF_STX: + + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EDX) + break; + + case BPF_JMP|BPF_JA: + + JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JGT|BPF_K: + + CMPid(EAX, ins->k) + JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; + + case BPF_JMP|BPF_JGE|BPF_K: + + CMPid(EAX, ins->k) + JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JEQ|BPF_K: + + CMPid(EAX, ins->k) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JSET|BPF_K: + + MOVrd(ECX,EAX) + ANDid(ECX,ins->k) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JGT|BPF_X: + + CMPrd(EAX, EDX) + JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; + + case BPF_JMP|BPF_JGE|BPF_X: + + CMPrd(EAX, EDX) + JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JEQ|BPF_X: + + CMPrd(EAX, EDX) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_JMP|BPF_JSET|BPF_X: + + MOVrd(ECX,EAX) + ANDrd(ECX,EDX) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + + break; + + case BPF_ALU|BPF_ADD|BPF_X: + + ADDrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_SUB|BPF_X: + + SUBrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_MUL|BPF_X: + + MOVrd(ECX,EDX) + MULrd(EDX) + MOVrd(EDX,ECX) + break; + + case BPF_ALU|BPF_DIV|BPF_X: + + CMPid(EDX, 0) + JNEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVrd(ECX,EDX) + MOVid(EDX,0) + DIVrd(ECX) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_AND|BPF_X: + + ANDrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_OR|BPF_X: + + ORrd(EAX,EDX) + + break; + + case BPF_ALU|BPF_LSH|BPF_X: + + MOVrd(ECX,EDX) + SHL_CLrb(EAX) + + break; + + case BPF_ALU|BPF_RSH|BPF_X: + + MOVrd(ECX,EDX) + SHR_CLrb(EAX) + + break; + + case BPF_ALU|BPF_ADD|BPF_K: + + ADD_EAXi(ins->k) + + break; + + case BPF_ALU|BPF_SUB|BPF_K: + + SUB_EAXi(ins->k) + + break; + + case BPF_ALU|BPF_MUL|BPF_K: + + MOVrd(ECX,EDX) + MOVid(EDX,ins->k) + MULrd(EDX) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_DIV|BPF_K: + + MOVrd(ECX,EDX) + MOVid(EDX,0) + MOVid(ESI,ins->k) + DIVrd(ESI) + MOVrd(EDX,ECX) + + break; + + case BPF_ALU|BPF_AND|BPF_K: + + ANDid(EAX, ins->k) + + break; + + case BPF_ALU|BPF_OR|BPF_K: + + ORid(EAX, ins->k) + + break; + + case BPF_ALU|BPF_LSH|BPF_K: + + SHLib(EAX, (ins->k) & 255) + + break; + + case BPF_ALU|BPF_RSH|BPF_K: + + SHRib(EAX, (ins->k) & 255) + + break; + + case BPF_ALU|BPF_NEG: + + NEGd(EAX) + + break; + + case BPF_MISC|BPF_TAX: + + MOVrd(EDX,EAX) + + break; + + case BPF_MISC|BPF_TXA: + + MOVrd(EAX,EDX) + + break; + + + + } + + ins++; + } + + pass++; + if(pass == 2) break; + +#ifdef NTKERNEL +#define NPF_TAG_STREAMBUF TAG('1', 'J', 'W', 'A') + stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, NPF_TAG_STREAMBUF); +#else + stream.ibuf=(CHAR*)malloc(stream.cur_ip); +#endif + if(stream.ibuf==NULL) + { +#ifdef NTKERNEL + ExFreePool(stream.refs); +#else + free(stream.refs); +#endif + return NULL; + } + + // modify the reference table to contain the offsets and not the lengths of the instructions + for(i=1; i< nins + 1; i++) + stream.refs[i]+=stream.refs[i-1]; + + // Reset the counters + stream.cur_ip=0; + stream.bpf_pc=0; + // the second pass creates the actual code + emitm=emit_code; + + } + + // the reference table is needed only during compilation, now we can free it +#ifdef NTKERNEL + ExFreePool(stream.refs); +#else + free(stream.refs); +#endif + return (BPF_filter_function)stream.ibuf; + +} + + +JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins) +{ + JIT_BPF_Filter *Filter; + + + // Allocate the filter structure +#ifdef NTKERNEL +#define NPF_TAG_FILTSTRUCT TAG('2', 'J', 'W', 'A') + Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), NPF_TAG_FILTSTRUCT); +#else + Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter)); +#endif + if(Filter==NULL) + { + return NULL; + } + + // Allocate the filter's memory +#ifdef NTKERNEL +#define NPF_TAG_FILTMEM TAG('3', 'J', 'W', 'A') + Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), NPF_TAG_FILTMEM); +#else + Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT)); +#endif + if(Filter->mem==NULL) + { +#ifdef NTKERNEL + ExFreePool(Filter); +#else + free(Filter); +#endif + return NULL; + } + + // Create the binary + if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL) + { +#ifdef NTKERNEL + ExFreePool(Filter->mem); + ExFreePool(Filter); +#else + free(Filter->mem); + free(Filter); + + return NULL; +#endif + } + + return Filter; + +} + +////////////////////////////////////////////////////////////// + +void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter){ + +#ifdef NTKERNEL + ExFreePool(Filter->mem); + ExFreePool(Filter->Function); + ExFreePool(Filter); +#else + free(Filter->mem); + free(Filter->Function); + free(Filter); +#endif + +} diff --git a/drivers/net/npf/jitter.h b/drivers/net/npf/jitter.h new file mode 100644 index 0000000..de4e609 --- /dev/null +++ b/drivers/net/npf/jitter.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2002 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** @ingroup NPF + * @{ + */ + +/** @defgroup NPF_include NPF structures and definitions + * @{ + */ + +// +// Registers +// +#define EAX 0 +#define ECX 1 +#define EDX 2 +#define EBX 3 +#define ESP 4 +#define EBP 5 +#define ESI 6 +#define EDI 7 + +#define AX 0 +#define CX 1 +#define DX 2 +#define BX 3 +#define SP 4 +#define BP 5 +#define SI 6 +#define DI 7 + +#define AL 0 +#define CL 1 +#define DL 2 +#define BL 3 + +/*! \brief A stream of X86 binary code.*/ +typedef struct binary_stream{ + INT cur_ip; ///< Current X86 instruction pointer. + INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter. + PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code. + PUINT refs; ///< Jumps reference table. +}binary_stream; + + +/*! \brief Prototype of a filtering function created by the jitter. + + The syntax and the meaning of the parameters is analogous to the one of bpf_filter(). Notice that the filter + is not among the parameters, because it is hardwired in the function. +*/ +typedef UINT (*BPF_filter_function)( binary_stream *, ULONG, UINT); + +/*! \brief Prototype of the emit functions. + + Different emit functions are used to create the reference table and to generate the actual filtering code. + This allows to have simpler instruction macros. + The first parameter is the stream that will receive the data. The secon one is a variable containing + the data, the third one is the length, that can be 1,2 or 4 since it is possible to emit a byte, a short + or a work at a time. +*/ +typedef void (*emit_func)(binary_stream *stream, ULONG value, UINT n); + +/*! \brief Structure describing a x86 filtering program created by the jitter.*/ +typedef struct JIT_BPF_Filter{ + BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function. + PINT mem; +} +JIT_BPF_Filter; + + + + +/**************************/ +/* X86 INSTRUCTION MACROS */ +/**************************/ + +/// mov r32,i32 +#define MOVid(r32, i32) \ + emitm(&stream, 11 << 4 | 1 << 3 | r32 & 0x7, 1); emitm(&stream, i32, 4); + +/// mov dr32,sr32 +#define MOVrd(dr32, sr32) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// mov dr32,sr32[off] +#define MOVodd(dr32, sr32, off) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\ + emitm(&stream, off, 1); + +/// mov dr32,sr32[or32] +#define MOVobd(dr32, sr32, or32) \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov dr16,sr32[or32] +#define MOVobw(dr32, sr32, or32) \ + emitm(&stream, 0x66, 1); \ + emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov dr8,sr32[or32] +#define MOVobb(dr8, sr32, or32) \ + emitm(&stream, 0x8a, 1); \ + emitm(&stream, (dr8 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1); + +/// mov [dr32][or32],sr32 +#define MOVomd(dr32, or32, sr32) \ + emitm(&stream, 0x89, 1); \ + emitm(&stream, (sr32 & 0x7) << 3 | 4 , 1);\ + emitm(&stream, (or32 & 0x7) << 3 | (dr32 & 0x7) , 1); + +/// bswap dr32 +#define BSWAP(dr32) \ + emitm(&stream, 0xf, 1); \ + emitm(&stream, 0x19 << 3 | dr32 , 1); + +/// xchg al,ah +#define SWAP_AX() \ + emitm(&stream, 0x86, 1); \ + emitm(&stream, 0xc4 , 1); + +/// push r32 +#define PUSH(r32) \ + emitm(&stream, 5 << 4 | 0 << 3 | r32 & 0x7, 1); + +/// pop r32 +#define POP(r32) \ + emitm(&stream, 5 << 4 | 1 << 3 | r32 & 0x7, 1); + +/// ret +#define RET() \ + emitm(&stream, 12 << 4 | 0 << 3 | 3, 1); + +/// add dr32,sr32 +#define ADDrd(dr32, sr32) \ + emitm(&stream, 0x03, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1); + +/// add eax,i32 +#define ADD_EAXi(i32) \ + emitm(&stream, 0x05, 1);\ + emitm(&stream, i32, 4); + +/// add r32,i32 +#define ADDid(r32, i32) \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 24 << 3 | r32, 1);\ + emitm(&stream, i32, 4); + +/// add r32,i8 +#define ADDib(r32, i8) \ + emitm(&stream, 0x83, 1);\ + emitm(&stream, 24 << 3 | r32, 1);\ + emitm(&stream, i8, 1); + +/// sub dr32,sr32 +#define SUBrd(dr32, sr32) \ + emitm(&stream, 0x2b, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1); + +/// sub eax,i32 +#define SUB_EAXi(i32) \ + emitm(&stream, 0x2d, 1);\ + emitm(&stream, i32, 4); + +/// mul r32 +#define MULrd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 7 << 5 | (r32 & 0x7), 1); + +/// div r32 +#define DIVrd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 15 << 4 | (r32 & 0x7), 1); + +/// and r8,i8 +#define ANDib(r8, i8) \ + emitm(&stream, 0x80, 1);\ + emitm(&stream, 7 << 5 | r8, 1);\ + emitm(&stream, i8, 1); + +/// and r32,i32 +#define ANDid(r32, i32) \ + if (r32 == EAX){ \ + emitm(&stream, 0x25, 1);\ + emitm(&stream, i32, 4);}\ + else{ \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 7 << 5 | r32, 1);\ + emitm(&stream, i32, 4);} + +/// and dr32,sr32 +#define ANDrd(dr32, sr32) \ + emitm(&stream, 0x23, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// or dr32,sr32 +#define ORrd(dr32, sr32) \ + emitm(&stream, 0x0b, 1);\ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// or r32,i32 +#define ORid(r32, i32) \ + if (r32 == EAX){ \ + emitm(&stream, 0x0d, 1);\ + emitm(&stream, i32, 4);}\ + else{ \ + emitm(&stream, 0x81, 1);\ + emitm(&stream, 25 << 3 | r32, 1);\ + emitm(&stream, i32, 4);} + +/// shl r32,i8 +#define SHLib(r32, i8) \ + emitm(&stream, 0xc1, 1);\ + emitm(&stream, 7 << 5 | r32 & 0x7, 1);\ + emitm(&stream, i8, 1); + +/// shl dr32,cl +#define SHL_CLrb(dr32) \ + emitm(&stream, 0xd3, 1);\ + emitm(&stream, 7 << 5 | dr32 & 0x7, 1); + +/// shr r32,i8 +#define SHRib(r32, i8) \ + emitm(&stream, 0xc1, 1);\ + emitm(&stream, 29 << 3 | r32 & 0x7, 1);\ + emitm(&stream, i8, 1); + +/// shr dr32,cl +#define SHR_CLrb(dr32) \ + emitm(&stream, 0xd3, 1);\ + emitm(&stream, 29 << 3 | dr32 & 0x7, 1); + +/// neg r32 +#define NEGd(r32) \ + emitm(&stream, 0xf7, 1);\ + emitm(&stream, 27 << 3 | r32 & 0x7, 1); + +/// cmp dr32,sr32[off] +#define CMPodd(dr32, sr32, off) \ + emitm(&stream, 3 << 4 | 3 | 1 << 3, 1); \ + emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\ + emitm(&stream, off, 1); + +/// cmp dr32,sr32 +#define CMPrd(dr32, sr32) \ + emitm(&stream, 0x3b, 1); \ + emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1); + +/// cmp dr32,i32 +#define CMPid(dr32, i32) \ + if (dr32 == EAX){ \ + emitm(&stream, 0x3d, 1); \ + emitm(&stream, i32, 4);} \ + else{ \ + emitm(&stream, 0x81, 1); \ + emitm(&stream, 0x1f << 3 | (dr32 & 0x7), 1);\ + emitm(&stream, i32, 4);} + +/// jne off32 +#define JNEb(off8) \ + emitm(&stream, 0x75, 1);\ + emitm(&stream, off8, 1); + +/// je off32 +#define JE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x84, 1);\ + emitm(&stream, off32, 4); + +/// jle off32 +#define JLE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8e, 1);\ + emitm(&stream, off32, 4); + +/// jle off8 +#define JLEb(off8) \ + emitm(&stream, 0x7e, 1);\ + emitm(&stream, off8, 1); + +/// ja off32 +#define JA(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x87, 1);\ + emitm(&stream, off32, 4); + +/// jae off32 +#define JAE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x83, 1);\ + emitm(&stream, off32, 4); + +/// jg off32 +#define JG(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8f, 1);\ + emitm(&stream, off32, 4); + +/// jge off32 +#define JGE(off32) \ + emitm(&stream, 0x0f, 1);\ + emitm(&stream, 0x8d, 1);\ + emitm(&stream, off32, 4); + +/// jmp off32 +#define JMP(off32) \ + emitm(&stream, 0xe9, 1);\ + emitm(&stream, off32, 4); + +/** + * @} + */ + +/** + * @} + */ + +/**************************/ +/* Prototypes */ +/**************************/ + +/** @ingroup NPF + * @{ + */ + +/** @defgroup NPF_code NPF functions + * @{ + */ + +/*! + \brief BPF jitter, builds an x86 function from a BPF program. + \param fp The BPF pseudo-assembly filter that will be translated into x86 code. + \param nins Number of instructions of the input filter. + \return The JIT_BPF_Filter structure containing the x86 filtering binary. + + BPF_jitter allocates the buffers for the new native filter and then translates the program pointed by fp + calling BPFtoX86(). +*/ +JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins); + +/*! + \brief Translates a set of BPF instructions in a set of x86 ones. + \param ins Pointer to the BPF instructions that will be translated into x86 code. + \param nins Number of instructions to translate. + \param mem Memory used by the x86 function to emulate the RAM of the BPF pseudo processor. + \return The x86 filtering function. + + This function does the hard work for the JIT compilation. It takes a group of BPF pseudo instructions and + through the instruction macros defined in jitter.h it is able to create an function directly executable + by NPF. +*/ +BPF_filter_function BPFtoX86(struct bpf_insn *ins, UINT nins, INT *mem); +/*! + \brief Deletes a filtering function that was previously created by BPF_jitter(). + \param Filter The filter to destroy. + + This function frees the variuos buffers (code, memory, etc.) associated with a filtering function. +*/ +void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter); + +/** + * @} + */ + +/** + * @} + */ diff --git a/drivers/net/npf/memory_t.c b/drivers/net/npf/memory_t.c new file mode 100644 index 0000000..361082c --- /dev/null +++ b/drivers/net/npf/memory_t.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "tme.h" +#include "memory_t.h" + +#ifdef _USE_SW_FUNCS_ + +int32 SW_LONG_AT(void *b, uint32 c) +{ + return ((int32)*((uint8 *)b+c)<<24| + (int32)*((uint8 *)b+c+1)<<16| + (int32)*((uint8 *)b+c+2)<<8| + (int32)*((uint8 *)b+c+3)<<0); +} + +uint32 SW_ULONG_AT(void *b, uint32 c) +{ + return ((uint32)*((uint8 *)b+c)<<24| + (uint32)*((uint8 *)b+c+1)<<16| + (uint32)*((uint8 *)b+c+2)<<8| + (uint32)*((uint8 *)b+c+3)<<0); +} + +int16 SW_SHORT_AT(void *b, uint32 os) +{ + return ((int16) + ((int16)*((uint8 *)b+os+0)<<8| + (int16)*((uint8 *)b+os+1)<<0)); +} + +uint16 SW_USHORT_AT(void *b, uint32 os) +{ + return ((uint16) + ((uint16)*((uint8 *)b+os+0)<<8| + (uint16)*((uint8 *)b+os+1)<<0)); +} + +VOID SW_ULONG_ASSIGN(void *dst, uint32 src) +{ + *((uint8*)dst+0)=*((uint8*)&src+3); + *((uint8*)dst+1)=*((uint8*)&src+2); + *((uint8*)dst+2)=*((uint8*)&src+1); + *((uint8*)dst+3)=*((uint8*)&src+0); + +} + +#endif /*_USE_SW_FUNCS_*/ + +void assert(void* assert, const char* file, int line, void* msg) { }; diff --git a/drivers/net/npf/memory_t.h b/drivers/net/npf/memory_t.h new file mode 100644 index 0000000..57f24e7 --- /dev/null +++ b/drivers/net/npf/memory_t.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __memory_t +#define __memory_t + +#define uint8 UCHAR +#define int8 CHAR +#define uint16 USHORT +#define int16 SHORT +#define uint32 ULONG +#define int32 LONG +#define uint64 ULONGLONG +#define int64 LONGLONG + +/*memory type*/ +typedef struct __MEM_TYPE +{ + uint8 *buffer; + uint32 size; +} MEM_TYPE, *PMEM_TYPE; + +#define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset)) + +#define ULONG_AT(base,offset) (*(uint32*)((uint8*)base+(uint32)offset)) + +#define SHORT_AT(base,offset) (*(int16*)((uint8*)base+(uint32)offset)) + +#define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset)) + +#ifdef __GNUC__ +#define __inline inline +#define _USE_SW_FUNCS_ +#endif + +#ifdef _USE_SW_FUNCS_ + +inline int32 SW_LONG_AT(void *b, uint32 c); +inline uint32 SW_ULONG_AT(void *b, uint32 c); +inline int16 SW_SHORT_AT(void *b, uint32 os); +inline uint16 SW_USHORT_AT(void *b, uint32 os); +inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src); + +#else /*_USE_SW_FUNCS_*/ + +__inline int32 SW_LONG_AT(void *b, uint32 c) +{ + return ((int32)*((uint8 *)b+c)<<24| + (int32)*((uint8 *)b+c+1)<<16| + (int32)*((uint8 *)b+c+2)<<8| + (int32)*((uint8 *)b+c+3)<<0); +} + +__inline uint32 SW_ULONG_AT(void *b, uint32 c) +{ + return ((uint32)*((uint8 *)b+c)<<24| + (uint32)*((uint8 *)b+c+1)<<16| + (uint32)*((uint8 *)b+c+2)<<8| + (uint32)*((uint8 *)b+c+3)<<0); +} + +__inline int16 SW_SHORT_AT(void *b, uint32 os) +{ + return ((int16) + ((int16)*((uint8 *)b+os+0)<<8| + (int16)*((uint8 *)b+os+1)<<0)); +} + +__inline uint16 SW_USHORT_AT(void *b, uint32 os) +{ + return ((uint16) + ((uint16)*((uint8 *)b+os+0)<<8| + (uint16)*((uint8 *)b+os+1)<<0)); +} + +__inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src) +{ + *((uint8*)dst+0)=*((uint8*)&src+3); + *((uint8*)dst+1)=*((uint8*)&src+2); + *((uint8*)dst+2)=*((uint8*)&src+1); + *((uint8*)dst+3)=*((uint8*)&src+0); + +} + +#endif /*_USE_SW_FUNCS_*/ + +#ifdef WIN_NT_DRIVER + +#define ALLOCATE_MEMORY(dest,type,amount) \ + (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); +#define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ + { \ + (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \ + if ((dest)!=NULL) \ + RtlZeroMemory((dest),sizeof(type)*(amount)); \ + } + +#define FREE_MEMORY(dest) ExFreePool(dest); +#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); +#define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount); + +#endif /*WIN_NT_DRIVER*/ + + +#endif + diff --git a/drivers/net/npf/normal_lookup.c b/drivers/net/npf/normal_lookup.c new file mode 100644 index 0000000..ea6442f --- /dev/null +++ b/drivers/net/npf/normal_lookup.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#include "normal_lookup.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + + +/* lookup in the table, seen as an hash */ +/* if not found, inserts an element */ +/* returns TME_TRUE if the entry is found or created, */ +/* returns TME_FALSE if no more blocks are available */ +uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 i; + uint32 tocs=0; + uint32 *key32=(uint32*) key; + uint32 shrinked_key=0; + uint32 index; + RECORD *records=(RECORD*)data->lut_base_address; + uint8 *offset; + uint32 key_len=data->key_len; + /*the key is shrinked into a 32-bit value */ + for (i=0; ilut_entries; + + while (tocs<=data->filled_entries) + { + + if (records[index].block==0) + { /*creation of a new entry*/ + + if (data->filled_blocks==data->shared_memory_blocks) + { + /*no more free blocks*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + } + + /*offset=absolute pointer to the block associated*/ + /*with the newly created entry*/ + offset=data->shared_memory_base_address+ + data->block_size*data->filled_blocks; + + /*copy the key in the block*/ + COPY_MEMORY(offset,key32,key_len*4); + GET_TIME((struct timeval *)(offset+4*key_len),time_ref); + /*assign the block relative offset to the entry, in NBO*/ + SW_ULONG_ASSIGN(&records[index].block,offset-mem_ex->buffer); + + data->filled_blocks++; + + /*assign the exec function ID to the entry, in NBO*/ + SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); + data->filled_entries++; + + data->last_found=(uint8*)&records[index]; + + return TME_TRUE; + } + /*offset contains the absolute pointer to the block*/ + /*associated with the current entry */ + offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0); + + for (i=0; (ilast_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + /* wrong entry, rehashing */ + if (IS_DELETABLE(offset+key_len*4,data)) + { + ZERO_MEMORY(offset,data->block_size); + COPY_MEMORY(offset,key32,key_len*4); + SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); + GET_TIME((struct timeval*)(offset+key_len*4),time_ref); + data->last_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + index=(index+data->rehashing_value) % data->lut_entries; + tocs++; + } + } + } + + /* nothing found, last found= out of lut */ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + +} + +/* lookup in the table, seen as an hash */ +/* if not found, returns out of count entry index */ +/* returns TME_TRUE if the entry is found */ +/* returns TME_FALSE if the entry is not found */ +uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) +{ + uint32 i; + uint32 tocs=0; + uint32 *key32=(uint32*) key; + uint32 shrinked_key=0; + uint32 index; + RECORD *records=(RECORD*)data->lut_base_address; + uint8 *offset; + uint32 key_len=data->key_len; + /*the key is shrinked into a 32-bit value */ + for (i=0; ilut_entries; + + while (tocs<=data->filled_entries) + { + + if (records[index].block==0) + { /*out of table, insertion is not allowed*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + } + /*offset contains the absolute pointer to the block*/ + /*associated with the current entry */ + + offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0); + + for (i=0; (ilast_found=(uint8*)&records[index]; + return TME_TRUE; + } + else + { + /*wrong entry, rehashing*/ + index=(index+data->rehashing_value) % data->lut_entries; + tocs++; + } + } + + /*nothing found, last found= out of lut*/ + GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); + data->last_found=NULL; + return TME_FALSE; + +} diff --git a/drivers/net/npf/normal_lookup.h b/drivers/net/npf/normal_lookup.h new file mode 100644 index 0000000..69e21ce --- /dev/null +++ b/drivers/net/npf/normal_lookup.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __normal_lookup +#define __normal_lookup + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define NORMAL_LUT_W_INSERT 0x00000000 +uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define NORMAL_LUT_WO_INSERT 0x00000001 +uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); +#define DUMMY_INSERT 1234 + +#endif \ No newline at end of file diff --git a/drivers/net/npf/npf.def b/drivers/net/npf/npf.def new file mode 100644 index 0000000..3517ee3 --- /dev/null +++ b/drivers/net/npf/npf.def @@ -0,0 +1,8 @@ +; packet capture driver - ReactOS Operating System + +LIBRARY PACKET.SYS + +EXPORTS +DriverEntry@8 + +; EOF diff --git a/drivers/net/npf/npf.edf b/drivers/net/npf/npf.edf new file mode 100644 index 0000000..11994e4 --- /dev/null +++ b/drivers/net/npf/npf.edf @@ -0,0 +1,8 @@ +; PACKET.SYS - PACKET protocol driver + +LIBRARY packet.sys + +EXPORTS +DriverEntry=DriverEntry@8 + +; EOF diff --git a/drivers/net/npf/npf.rc b/drivers/net/npf/npf.rc new file mode 100644 index 0000000..47f2b3d --- /dev/null +++ b/drivers/net/npf/npf.rc @@ -0,0 +1,47 @@ +//#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,0,0,13 + PRODUCTVERSION 3,0,0,13 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x3L + FILESUBTYPE 0x7L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Netgroup Packet Filter Driver\0" + VALUE "CompanyName", "Politecnico di Torino\0" + VALUE "FileDescription", "NPF Driver - TME extensions\0" + VALUE "FileVersion", "3, 0, 0, 13\0" + VALUE "InternalName", "NPF + TME \0" + VALUE "LegalCopyright", "Copyright © 2002\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "NPF.RC\0" + VALUE "PrivateBuild", "REACTOS PRIVATE BUILD\0" + VALUE "ProductName", "NPF Driver\0" + VALUE "ProductVersion", "3, 0, 0, 13\0" + VALUE "SpecialBuild", "Beta testing use only\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +///////////////////////////////////////////////////////////////////////////// + + diff --git a/drivers/net/npf/ntddpack.h b/drivers/net/npf/ntddpack.h new file mode 100644 index 0000000..a855138 --- /dev/null +++ b/drivers/net/npf/ntddpack.h @@ -0,0 +1,30 @@ +#ifndef __NTDDPACKET +#define __NTDDPACKET 1 + +#ifdef _MSC_VER +#include "devioctl.h" +/*#include */ +#else +#endif + +struct _PACKET_OID_DATA { + ULONG Oid; + ULONG Length; + UCHAR Data[1]; +}; + +typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; + +/*#include */ +#define FILE_DEVICE_PROTOCOL 0x8000 +#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) + +#endif diff --git a/drivers/net/npf/openclos.c b/drivers/net/npf/openclos.c new file mode 100644 index 0000000..bdb5b1a --- /dev/null +++ b/drivers/net/npf/openclos.c @@ -0,0 +1,683 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#else +#include +#include +#endif +#include "debug.h" +#include "packet.h" + +static NDIS_MEDIUM MediumArray[] = { + NdisMedium802_3, + NdisMediumWan, + NdisMediumFddi, + NdisMediumArcnet878_2, + NdisMediumAtm, + NdisMedium802_5 +}; + +#define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0]) + +ULONG NamedEventsCounter=0; + +//Itoa. Replaces the buggy RtlIntegerToUnicodeString +void PacketItoa(UINT n,PUCHAR buf){ +int i; + + for(i=0;i<20;i+=2){ + buf[18-i]=(n%10)+48; + buf[19-i]=0; + n/=10; + } + +} + +/// Global start time. Used as an absolute reference for timestamp conversion. +struct time_conv G_Start_Time = { + 0, + {0, 0}, +}; + +UINT n_Opened_Instances = 0; + +NDIS_SPIN_LOCK Opened_Instances_Lock; + +//------------------------------------------------------------------- + +NTSTATUS STDCALL +NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +{ + + PDEVICE_EXTENSION DeviceExtension; + + POPEN_INSTANCE Open; + + PIO_STACK_LOCATION IrpSp; + + NDIS_STATUS Status; + NDIS_STATUS ErrorStatus; + UINT i; + PUCHAR tpointer; + PLIST_ENTRY PacketListEntry; + PCHAR EvName; + + IF_LOUD(DbgPrint("NPF: OpenAdapter\n");) + + DeviceExtension = DeviceObject->DeviceExtension; + + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + // allocate some memory for the open structure +#define NPF_TAG_OPENSTRUCT TAG('0', 'O', 'W', 'A') + Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), NPF_TAG_OPENSTRUCT); + + + if (Open==NULL) { + // no memory + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( + Open, + sizeof(OPEN_INSTANCE) + ); + + +#define NPF_TAG_EVNAME TAG('1', 'O', 'W', 'A') + EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), NPF_TAG_EVNAME); + + if (EvName==NULL) { + // no memory + ExFreePool(Open); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // Save or open here + IrpSp->FileObject->FsContext=Open; + + Open->DeviceExtension=DeviceExtension; + + + // Save the Irp here for the completeion routine to retrieve + Open->OpenCloseIrp=Irp; + + // Allocate a packet pool for our xmit and receive packets + NdisAllocatePacketPool( + &Status, + &Open->PacketPool, + TRANSMIT_PACKETS, + sizeof(PACKET_RESERVED)); + + + if (Status != NDIS_STATUS_SUCCESS) { + + IF_LOUD(DbgPrint("NPF: Failed to allocate packet pool\n");) + + ExFreePool(Open); + ExFreePool(EvName); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + + RtlCopyBytes(EvName,L"\\BaseNamedObjects\\NPF0000000000",sizeof(L"\\BaseNamedObjects\\NPF0000000000")); + + //Create the string containing the name of the read event + RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName); + + PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21)); + + InterlockedIncrement(&NamedEventsCounter); + + IF_LOUD(DbgPrint("\nCreated the named event for the read; name=%ws, counter=%d\n", Open->ReadEventName.Buffer,NamedEventsCounter-1);) + + //allocate the event objects + Open->ReadEvent=IoCreateNotificationEvent(&Open->ReadEventName,&Open->ReadEventHandle); + if(Open->ReadEvent==NULL){ + ExFreePool(Open); + ExFreePool(EvName); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + KeInitializeEvent(Open->ReadEvent, NotificationEvent, FALSE); + KeClearEvent(Open->ReadEvent); + NdisInitializeEvent(&Open->WriteEvent); + NdisInitializeEvent(&Open->IOEvent); + NdisInitializeEvent(&Open->DumpEvent); + NdisInitializeEvent(&Open->IOEvent); + NdisAllocateSpinLock(&Open->machine_lock); + + + // list to hold irp's want to reset the adapter + InitializeListHead(&Open->ResetIrpList); + + + // Initialize the request list + KeInitializeSpinLock(&Open->RequestSpinLock); + InitializeListHead(&Open->RequestList); + + // Initializes the extended memory of the NPF machine +#define NPF_TAG_MACHINE TAG('2', 'O', 'W', 'A') + Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, NPF_TAG_MACHINE); + if((Open->mem_ex.buffer) == NULL) + { + // no memory + ExFreePool(Open); + ExFreePool(EvName); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Open->mem_ex.size = DEFAULT_MEM_EX_SIZE; + RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE); + + // + // Initialize the open instance + // + Open->BufSize = 0; + Open->Buffer = NULL; + Open->Bhead = 0; + Open->Btail = 0; + (INT)Open->BLastByte = -1; + Open->Dropped = 0; //reset the dropped packets counter + Open->Received = 0; //reset the received packets counter + Open->Accepted = 0; //reset the accepted packets counter + Open->bpfprogram = NULL; //reset the filter + Open->mode = MODE_CAPT; + Open->Nbytes.QuadPart = 0; + Open->Npackets.QuadPart = 0; + Open->Nwrites = 1; + Open->Multiple_Write_Counter = 0; + Open->MinToCopy = 0; + Open->TimeOut.QuadPart = (LONGLONG)1; + Open->Bound = TRUE; + Open->DumpFileName.Buffer = NULL; + Open->DumpFileHandle = NULL; + Open->tme.active = TME_NONE_ACTIVE; + Open->DumpLimitReached = FALSE; + Open->MaxFrameSize = 0; + + //allocate the spinlock for the statistic counters + NdisAllocateSpinLock(&Open->CountersLock); + + //allocate the spinlock for the buffer pointers + NdisAllocateSpinLock(&Open->BufLock); + + // + // link up the request stored in our open block + // + for (i=0;iRequestList, + &Open->Requests[i].ListElement, + &Open->RequestSpinLock); + + } + + + IoMarkIrpPending(Irp); + + // + // Try to open the MAC + // + IF_LOUD(DbgPrint("NPF: Openinig the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);) + + NdisOpenAdapter( + &Status, + &ErrorStatus, + &Open->AdapterHandle, + &Open->Medium, + MediumArray, + NUM_NDIS_MEDIA, + DeviceExtension->NdisProtocolHandle, + Open, + &DeviceExtension->AdapterName, + 0, + NULL); + + IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);) + + if (Status != NDIS_STATUS_PENDING) + { + NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS); + } + + return(STATUS_PENDING); +} + +//------------------------------------------------------------------- + +VOID NPF_OpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus) +{ + + PIRP Irp; + POPEN_INSTANCE Open; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST MaxSizeReq; + NDIS_STATUS ReqStatus; + + + IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + // + // get the open irp + // + Irp=Open->OpenCloseIrp; + + if (Status != NDIS_STATUS_SUCCESS) { + + IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");) + + NdisFreePacketPool(Open->PacketPool); + + //free mem_ex + Open->mem_ex.size = 0; + if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); + + ExFreePool(Open->ReadEventName.Buffer); + + ZwClose(Open->ReadEventHandle); + + + ExFreePool(Open); + } + else { + NdisAcquireSpinLock(&Opened_Instances_Lock); + n_Opened_Instances++; + NdisReleaseSpinLock(&Opened_Instances_Lock); + + IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) + + // Get the absolute value of the system boot time. + // This is used for timestamp conversion. + TIME_SYNCHRONIZE(&G_Start_Time); + + // Extract a request from the list of free ones + RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock); + + if (RequestListEntry == NULL) + { + + Open->MaxFrameSize = 1514; // Assume Ethernet + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return; + } + + MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); + MaxSizeReq->Irp = Irp; + MaxSizeReq->Internal = TRUE; + + + MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; + + + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4; + + // submit the request + NdisRequest( + &ReqStatus, + Open->AdapterHandle, + &MaxSizeReq->Request); + + + if (ReqStatus != NDIS_STATUS_PENDING) { + NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus); + } + + return; + + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return; + +} + +//------------------------------------------------------------------- + +NTSTATUS STDCALL +NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + + POPEN_INSTANCE Open; + NDIS_STATUS Status; + PIO_STACK_LOCATION IrpSp; + LARGE_INTEGER ThreadDelay; + + IF_LOUD(DbgPrint("NPF: CloseAdapter\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open=IrpSp->FileObject->FsContext; + + // Reset the buffer size. This tells the dump thread to stop. + Open->BufSize = 0; + + if( Open->Bound == FALSE){ + + NdisWaitEvent(&Open->IOEvent,10000); + + // Free the filter if it's present + if(Open->bpfprogram != NULL) + ExFreePool(Open->bpfprogram); + + // Free the jitted filter if it's present + if(Open->Filter != NULL) + BPF_Destroy_JIT_Filter(Open->Filter); + + //free the buffer + Open->BufSize=0; + if(Open->Buffer != NULL)ExFreePool(Open->Buffer); + + //free mem_ex + Open->mem_ex.size = 0; + if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); + + NdisFreePacketPool(Open->PacketPool); + + // Free the string with the name of the dump file + if(Open->DumpFileName.Buffer!=NULL) + ExFreePool(Open->DumpFileName.Buffer); + + ExFreePool(Open->ReadEventName.Buffer); + ExFreePool(Open); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); + } + + // Unfreeze the consumer + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + KeSetEvent(Open->ReadEvent,0,FALSE); + + // Save the IRP + Open->OpenCloseIrp = Irp; + + IoMarkIrpPending(Irp); + + // If this instance is in dump mode, complete the dump and close the file + if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){ + NTSTATUS wres; + + ThreadDelay.QuadPart = -50000000; + // Wait the completion of the thread + wres = KeWaitForSingleObject(Open->DumpThreadObject, + UserRequest, + KernelMode, + TRUE, + &ThreadDelay); + + ObDereferenceObject(Open->DumpThreadObject); + + + // Flush and close the dump file + NPF_CloseDumpFile(Open); + } + + // Destroy the read Event + ZwClose(Open->ReadEventHandle); + + // Close the adapter + NdisCloseAdapter( + &Status, + Open->AdapterHandle + ); + + if (Status != NDIS_STATUS_PENDING) { + + NPF_CloseAdapterComplete( + Open, + Status + ); + return STATUS_SUCCESS; + + } + + return(STATUS_PENDING); +} + +//------------------------------------------------------------------- + +VOID +NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) +{ + POPEN_INSTANCE Open; + PIRP Irp; + + IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + // free the allocated structures only if the instance is still bound to the adapter + if(Open->Bound == TRUE){ + + // Free the filter if it's present + if(Open->bpfprogram != NULL) + ExFreePool(Open->bpfprogram); + + // Free the jitted filter if it's present + if(Open->Filter != NULL) + BPF_Destroy_JIT_Filter(Open->Filter); + + //free the buffer + Open->BufSize = 0; + if(Open->Buffer!=NULL)ExFreePool(Open->Buffer); + + //free mem_ex + Open->mem_ex.size = 0; + if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); + + NdisFreePacketPool(Open->PacketPool); + + Irp=Open->OpenCloseIrp; + + // Free the string with the name of the dump file + if(Open->DumpFileName.Buffer!=NULL) + ExFreePool(Open->DumpFileName.Buffer); + + ExFreePool(Open->ReadEventName.Buffer); + ExFreePool(Open); + + // Complete the request only if the instance is still bound to the adapter + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + NdisSetEvent(&Open->IOEvent); + + // Decrease the counter of open instances + NdisAcquireSpinLock(&Opened_Instances_Lock); + n_Opened_Instances--; + NdisReleaseSpinLock(&Opened_Instances_Lock); + + IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) + + if(n_Opened_Instances == 0){ + // Force a synchronization at the next NPF_Open(). + // This hopefully avoids the synchronization issues caused by hibernation or standby. + TIME_DESYNCHRONIZE(&G_Start_Time); + } + + return; + +} +//------------------------------------------------------------------- + +#ifdef NDIS50 +NDIS_STATUS +NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) +{ + IF_LOUD(DbgPrint("NPF: PowerChange\n");) + + TIME_DESYNCHRONIZE(&G_Start_Time); + + TIME_SYNCHRONIZE(&G_Start_Time); + + return STATUS_SUCCESS; +} +#endif + +//------------------------------------------------------------------- + +VOID +NPF_BindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindContext, + IN PNDIS_STRING DeviceName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 + ) +{ + IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");) +} + +//------------------------------------------------------------------- + +VOID +NPF_UnbindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext + ) +{ + POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext; + NDIS_STATUS lStatus; + + IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");) + + // Reset the buffer size. This tells the dump thread to stop. + Open->BufSize=0; + + NdisResetEvent(&Open->IOEvent); + + // This open instance is no more bound to the adapter, set Bound to False + InterlockedExchange( (PLONG) &Open->Bound, FALSE ); + + // Awake a possible pending read on this instance + if(Open->mode & MODE_DUMP) + NdisSetEvent(&Open->DumpEvent); + else + KeSetEvent(Open->ReadEvent,0,FALSE); + + // If this instance is in dump mode, complete the dump and close the file + if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) + NPF_CloseDumpFile(Open); + + // Destroy the read Event + ZwClose(Open->ReadEventHandle); + + // close the adapter + NdisCloseAdapter( + &lStatus, + Open->AdapterHandle + ); + + if (lStatus != NDIS_STATUS_PENDING) { + + NPF_CloseAdapterComplete( + Open, + lStatus + ); + + *Status = NDIS_STATUS_SUCCESS; + return; + + } + + *Status = NDIS_STATUS_SUCCESS; + return; +} + +//------------------------------------------------------------------- + +VOID +NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) + +{ + POPEN_INSTANCE Open; + PIRP Irp; + + PLIST_ENTRY ResetListEntry; + + IF_LOUD(DbgPrint("NPF: PacketResetComplte\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + + // + // remove the reset IRP from the list + // + ResetListEntry=ExInterlockedRemoveHeadList( + &Open->ResetIrpList, + &Open->RequestSpinLock + ); + +#if DBG + if (ResetListEntry == NULL) { + DbgBreakPoint(); + return; + } +#endif + + Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + IF_LOUD(DbgPrint("NPF: PacketResetComplte exit\n");) + + return; + +} diff --git a/drivers/net/npf/packet.c b/drivers/net/npf/packet.c new file mode 100644 index 0000000..17acc0b --- /dev/null +++ b/drivers/net/npf/packet.c @@ -0,0 +1,1388 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#else +#include +#include +#endif + +#include "ntddpack.h" + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" +#include "win_bpf_filter_init.h" + +#include "tme.h" + +#if DBG +// Declare the global debug flag for this driver. +//ULONG PacketDebugFlag = PACKET_DEBUG_LOUD; +ULONG PacketDebugFlag = PACKET_DEBUG_LOUD + PACKET_DEBUG_VERY_LOUD + PACKET_DEBUG_INIT; + +#endif + +PDEVICE_EXTENSION GlobalDeviceExtension; + +//////////////////////////////////////////////////////////////////////////////// +#define ROBERTS_PATCH +#ifdef ROBERTS_PATCH + +#define NDIS_STRING_CONST(x) {sizeof(L##x)-2, sizeof(L##x), L##x} + +//void __moddi3(void) {} +//void __divdi3(void) {} + +#endif // ROBERTS_PATCH +//////////////////////////////////////////////////////////////////////////////// +// +// Global strings +// +NDIS_STRING NPF_Prefix = NDIS_STRING_CONST("NPF_"); +NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\"); +NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\"); +NDIS_STRING tcpLinkageKeyName = NDIS_STRING_CONST("\\Registry\\Machine\\System" + L"\\CurrentControlSet\\Services\\Tcpip\\Linkage"); +NDIS_STRING AdapterListKey = NDIS_STRING_CONST("\\Registry\\Machine\\System" + L"\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"); +NDIS_STRING bindValueName = NDIS_STRING_CONST("Bind"); + + +/// Global variable that points to the names of the bound adapters +WCHAR* bindP = NULL; + +extern struct time_conv G_Start_Time; // from openclos.c + +extern NDIS_SPIN_LOCK Opened_Instances_Lock; + +// +// Packet Driver's entry routine. +// +NTSTATUS +#ifdef __GNUC__ +STDCALL +#endif +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + + NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; + UNICODE_STRING MacDriverName; + UNICODE_STRING UnicodeDeviceName; + PDEVICE_OBJECT DeviceObject = NULL; + PDEVICE_EXTENSION DeviceExtension = NULL; + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ErrorCode = STATUS_SUCCESS; + NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); + ULONG DevicesCreated=0; + PWSTR BindString; + PWSTR ExportString; + PWSTR BindStringSave; + PWSTR ExportStringSave; + NDIS_HANDLE NdisProtocolHandle; + WCHAR* bindT; + PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP; + UNICODE_STRING macName; + + // This driver at the moment works only on single processor machines + if(NdisSystemProcessorCount() != 1){ + return STATUS_IMAGE_MP_UP_MISMATCH; + } + + IF_LOUD(DbgPrint("Packet: DriverEntry\n");) + + RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + +#ifdef NDIS50 + ProtocolChar.MajorNdisVersion = 5; +#else + ProtocolChar.MajorNdisVersion = 3; +#endif + ProtocolChar.MinorNdisVersion = 0; +#ifndef __GNUC__ + ProtocolChar.Reserved = 0; +#else + ProtocolChar.u1.Reserved = 0; +#endif + ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete; + ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete; +#ifndef __GNUC__ + ProtocolChar.SendCompleteHandler = NPF_SendComplete; + ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete; +#else + ProtocolChar.u2.SendCompleteHandler = NPF_SendComplete; + ProtocolChar.u3.TransferDataCompleteHandler = NPF_TransferDataComplete; +#endif + ProtocolChar.ResetCompleteHandler = NPF_ResetComplete; + ProtocolChar.RequestCompleteHandler = NPF_RequestComplete; +#ifndef __GNUC__ + ProtocolChar.ReceiveHandler = NPF_tap; +#else + ProtocolChar.u4.ReceiveHandler = NPF_tap; +#endif + ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete; + ProtocolChar.StatusHandler = NPF_Status; + ProtocolChar.StatusCompleteHandler = NPF_StatusComplete; +#ifdef NDIS50 + ProtocolChar.BindAdapterHandler = NPF_BindAdapter; + ProtocolChar.UnbindAdapterHandler = NPF_UnbindAdapter; + ProtocolChar.PnPEventHandler = NPF_PowerChange; + ProtocolChar.ReceivePacketHandler = NULL; +#endif + ProtocolChar.Name = ProtoName; + + NdisRegisterProtocol( + &Status, + &NdisProtocolHandle, + &ProtocolChar, + sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + + if (Status != NDIS_STATUS_SUCCESS) { + + IF_LOUD(DbgPrint("NPF: Failed to register protocol with NDIS\n");) + + return Status; + + } + + NdisAllocateSpinLock(&Opened_Instances_Lock); + + // Set up the device driver entry points. + DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_Open; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = NPF_Close; + DriverObject->MajorFunction[IRP_MJ_READ] = NPF_Read; + DriverObject->MajorFunction[IRP_MJ_WRITE] = NPF_Write; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl; + DriverObject->DriverUnload = NPF_Unload; + +/* + // Get the name of the Packet driver and the name of the NIC driver + // to bind to from the registry + Status=NPF_ReadRegistry( + &BindString, + &ExportString, + RegistryPath + ); + + if (Status != STATUS_SUCCESS) { + + IF_LOUD(DbgPrint("Trying dynamic binding\n");) + */ + bindP = getAdaptersList(); + + if (bindP == NULL) { + IF_LOUD(DbgPrint("Adapters not found in the registry, try to copy the bindings of TCP-IP.\n");) + + tcpBindingsP = getTcpBindings(); + + if (tcpBindingsP == NULL){ + IF_LOUD(DbgPrint("TCP-IP not found, quitting.\n");) + goto RegistryError; + } + + bindP = (WCHAR*)tcpBindingsP; + bindT = (WCHAR*)(tcpBindingsP->Data); + } else { + bindT = bindP; + } + + for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) { + RtlInitUnicodeString(&macName, bindT); + createDevice(DriverObject, &macName, NdisProtocolHandle); + } + + return STATUS_SUCCESS; +/* + } + BindStringSave = BindString; + ExportStringSave = ExportString; + // + // create a device object for each entry + // + while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) { + // + // Create a counted unicode string for both null terminated strings + // + RtlInitUnicodeString( + &MacDriverName, + BindString); + RtlInitUnicodeString( + &UnicodeDeviceName, + ExportString); + // + // Advance to the next string of the MULTI_SZ string + // + BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); + ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); + IF_LOUD(DbgPrint("NPF: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);) + // + // Create the device object + // + Status = IoCreateDevice( + DriverObject, + sizeof(DEVICE_EXTENSION), + &UnicodeDeviceName, + FILE_DEVICE_PROTOCOL, + 0, + FALSE, + &DeviceObject); + if (Status != STATUS_SUCCESS) { + IF_LOUD(DbgPrint("NPF: IoCreateDevice() failed:\n");) + break; + } + DevicesCreated++; + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; + DeviceExtension->DeviceObject = DeviceObject; + // + // Save the the name of the MAC driver to open in the Device Extension + // + DeviceExtension->AdapterName=MacDriverName; + if (DevicesCreated == 1) { + DeviceExtension->BindString = NULL; + DeviceExtension->ExportString = NULL; + } + DeviceExtension->NdisProtocolHandle=NdisProtocolHandle; + } + if (DevicesCreated > 0) { + // + // Managed to create at least one device. + // + IF_LOUD(DbgPrint("NPF: Managed to create at least one device.\n");) + return STATUS_SUCCESS; + } + ExFreePool(BindStringSave); + ExFreePool(ExportStringSave); + */ + +RegistryError: + IF_LOUD(DbgPrint("NPF: RegistryError: calling NdisDeregisterProtocol()\n");) + NdisDeregisterProtocol( + &Status, + NdisProtocolHandle + ); + + Status=STATUS_UNSUCCESSFUL; + + return(Status); + +} + +//------------------------------------------------------------------- + +PWCHAR getAdaptersList(void) +{ + PKEY_VALUE_PARTIAL_INFORMATION result = NULL; + OBJECT_ATTRIBUTES objAttrs; + NTSTATUS status; + HANDLE keyHandle; + UINT BufPos=0; + +#define NPF_TAG_DEVICENAME TAG('0', 'P', 'W', 'A') + PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, NPF_TAG_DEVICENAME); + + if (DeviceNames == NULL) { + IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");) + return NULL; + } + + InitializeObjectAttributes(&objAttrs, &AdapterListKey, + OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs); + if (!NT_SUCCESS(status)) { + + //IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, AdapterListKey.Buffer);) + + } else { //OK + ULONG resultLength; + KEY_VALUE_PARTIAL_INFORMATION valueInfo; + CHAR AdapInfo[1024]; + UINT i=0; + + IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%x\n",DeviceNames);) + + // Scan the list of the devices + while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS) { + WCHAR ExportKeyName [512]; + PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; + UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"); + PWCHAR LinkageKeyPrefix = L"\\Linkage"; + UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage"); + NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export"); + PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo; + UNICODE_STRING AdapterKeyName; + HANDLE ExportKeyHandle; + KEY_VALUE_PARTIAL_INFORMATION valueInfo; + ULONG resultLength; + + RtlCopyMemory(ExportKeyName, + ExportKeyPrefix, + ExportKeyPrefixSize); + + RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize, + tInfo->Name, + tInfo->NameLength+2); + + RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength, + LinkageKeyPrefix, + LinkageKeyPrefixSize); + + IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);) + + RtlInitUnicodeString(&AdapterKeyName, ExportKeyName); + + InitializeObjectAttributes(&objAttrs, &AdapterKeyName, + OBJ_CASE_INSENSITIVE, NULL, NULL); + + status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs); + + if (!NT_SUCCESS(status)) { + DbgPrint("OpenKey Failed, %d!\n",status); + i++; + continue; + } + + status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, + KeyValuePartialInformation, &valueInfo, + sizeof(valueInfo), &resultLength); + + if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) + } else { // We know how big it needs to be. + ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); +#define NPF_TAG_KEYVALUE TAG('1', 'P', 'W', 'A') + PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE); + if (valueInfoP != NULL) { + status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, + KeyValuePartialInformation, + valueInfoP, + valueInfoLength, &resultLength); + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("Status of %x querying key value\n", status);) + } else { + IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);) + RtlCopyMemory((PCHAR)DeviceNames+BufPos, + valueInfoP->Data, + valueInfoP->DataLength); + BufPos+=valueInfoP->DataLength-2; + } + + ExFreePool(valueInfoP); + } else { + IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");) + } + + } + + // terminate the buffer + DeviceNames[BufPos/2]=0; + DeviceNames[BufPos/2+1]=0; + + ZwClose (ExportKeyHandle); + i++; + + } + + ZwClose (keyHandle); + + } + if(BufPos==0){ + ExFreePool(DeviceNames); + return NULL; + } + return DeviceNames; +} + +//------------------------------------------------------------------- + +PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void) +{ + PKEY_VALUE_PARTIAL_INFORMATION result = NULL; + OBJECT_ATTRIBUTES objAttrs; + NTSTATUS status; + HANDLE keyHandle; + + InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName, + OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs); + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + } else { + ULONG resultLength; + KEY_VALUE_PARTIAL_INFORMATION valueInfo; + + IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);) + + status = ZwQueryValueKey(keyHandle, &bindValueName, + KeyValuePartialInformation, &valueInfo, + sizeof(valueInfo), &resultLength); + if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) + } else { // We know how big it needs to be. + ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); +#define NPF_TAG_KEYVALUE2 TAG('2', 'P', 'W', 'A') + PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = + (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE2); + + if (valueInfoP != NULL) { + status = ZwQueryValueKey(keyHandle, &bindValueName, + KeyValuePartialInformation, + valueInfoP, + valueInfoLength, &resultLength); + + if (!NT_SUCCESS(status)) { + IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);) + } + else if (valueInfoLength != resultLength) { + IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u " + "but previous len = %u\n", + resultLength, valueInfoLength);) + } + else if (valueInfoP->Type != REG_MULTI_SZ) { + IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n", + valueInfoP->Type);) + } + else { // It's OK +#if DBG + ULONG i; + WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]); + IF_LOUD(DbgPrint("\n\nBind value:\n");) + for (i = 0; *dataP != UNICODE_NULL; i++) { + UNICODE_STRING macName; + RtlInitUnicodeString(&macName, dataP); + IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);) + dataP += + (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR); + } +#endif // DBG + result = valueInfoP; + } + } + } + ZwClose(keyHandle); + } + return result; +} + +//------------------------------------------------------------------- + +BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP, + IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle) +{ + NTSTATUS status; + PDEVICE_OBJECT devObjP; + UNICODE_STRING deviceName; + UNICODE_STRING deviceSymLink; + + IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer);); + if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, + devicePrefix.Length) < devicePrefix.Length) { + return FALSE; + } + + deviceName.Length = 0; + deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL)); +#define NPF_TAG_DEVICENAMEBUF TAG('3', 'P', 'W', 'A') + deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, NPF_TAG_DEVICENAMEBUF); + + if (deviceName.Buffer == NULL) + return FALSE; + + deviceSymLink.Length = 0; + deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length + + symbolicLinkPrefix.Length + + NPF_Prefix.Length + + sizeof(UNICODE_NULL)); + +#define NPF_TAG_SYMLINKBUF TAG('3', 'P', 'W', 'A') + deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, NPF_TAG_SYMLINKBUF); + + if (deviceSymLink.Buffer == NULL) + { + ExFreePool(deviceName.Buffer); + return FALSE; + } + + RtlAppendUnicodeStringToString(&deviceName, &devicePrefix); + RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix); + RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer + + devicePrefix.Length / sizeof(WCHAR)); + + RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix); + RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix); + RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer + + devicePrefix.Length / sizeof(WCHAR)); + + IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);) + + status = IoCreateDevice(adriverObjectP, + sizeof(PDEVICE_EXTENSION), + &deviceName, + FILE_DEVICE_TRANSPORT, + 0, + FALSE, + &devObjP); + + if (NT_SUCCESS(status)) { + PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension; + + IF_LOUD(DbgPrint("Device created successfully\n");); + + devObjP->Flags |= DO_DIRECT_IO; + RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer); + devExtP->NdisProtocolHandle=aProtoHandle; + + IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer);); + + if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) { + IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer);); + + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + devExtP->ExportString = NULL; + + return FALSE; + } + + IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer);); + + devExtP->ExportString = deviceSymLink.Buffer; + + ExFreePool(deviceName.Buffer); + + return TRUE; + } + + else + { + IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status);); + + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + return FALSE; + } +} + +//------------------------------------------------------------------- + +VOID STDCALL +NPF_Unload(IN PDRIVER_OBJECT DriverObject) +{ + PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT OldDeviceObject; + PDEVICE_EXTENSION DeviceExtension; + + NDIS_HANDLE NdisProtocolHandle; + NDIS_STATUS Status; + + NDIS_STRING SymLink; + + IF_LOUD(DbgPrint("NPF: Unload\n");); + + DeviceObject = DriverObject->DeviceObject; + + while (DeviceObject != NULL) { + OldDeviceObject=DeviceObject; + + DeviceObject=DeviceObject->NextDevice; + + DeviceExtension = OldDeviceObject->DeviceExtension; + + NdisProtocolHandle=DeviceExtension->NdisProtocolHandle; + + IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n", + DeviceExtension->AdapterName.Buffer, + NdisProtocolHandle, + DeviceObject, + OldDeviceObject);); + + if (DeviceExtension->ExportString) + { + RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString); + + IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer);); + + IoDeleteSymbolicLink(&SymLink); + ExFreePool(DeviceExtension->ExportString); + } + + IoDeleteDevice(OldDeviceObject); + } + + NdisDeregisterProtocol( + &Status, + NdisProtocolHandle + ); + + // Free the adapters names + ExFreePool( bindP ); +} + +//------------------------------------------------------------------- + +NTSTATUS STDCALL +NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST pRequest; + ULONG FunctionCode; + NDIS_STATUS Status; + PLIST_ENTRY PacketListEntry; + UINT i; + PUCHAR tpointer; + ULONG dim,timeout; + PUCHAR prog; + PPACKET_OID_DATA OidData; + int *StatsBuf; + PNDIS_PACKET pPacket; + ULONG mode; + PWSTR DumpNameBuff; + PUCHAR TmpBPFProgram; + INT WriteRes; + BOOLEAN SyncWrite = FALSE; + struct bpf_insn *initprogram; + ULONG insns; + ULONG cnt; + BOOLEAN IsExtendedFilter=FALSE; + + IF_LOUD(DbgPrint("NPF: IoControl\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; + Open=IrpSp->FileObject->FsContext; + + Irp->IoStatus.Status = STATUS_SUCCESS; + + IF_LOUD(DbgPrint("NPF: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);) + + + switch (FunctionCode){ + + case BIOCGSTATS: //function to get the capture stats + + if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){ + EXIT_FAILURE(0); + } + + *(((PUINT)Irp->UserBuffer)+3) = Open->Accepted; + *(((PUINT)Irp->UserBuffer)) = Open->Received; + *(((PUINT)Irp->UserBuffer)+1) = Open->Dropped; + *(((PUINT)Irp->UserBuffer)+2) = 0; // Not yet supported + + EXIT_SUCCESS(4*sizeof(INT)); + + break; + + case BIOCGEVNAME: //function to get the name of the event associated with the current instance + + if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){ + EXIT_FAILURE(0); + } + + RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26); + + EXIT_SUCCESS(26); + + break; + + case BIOCSENDPACKETSSYNC: + + SyncWrite = TRUE; + + case BIOCSENDPACKETSNOSYNC: + + WriteRes = NPF_BufferedWrite(Irp, + (PUCHAR)Irp->AssociatedIrp.SystemBuffer, + IrpSp->Parameters.DeviceIoControl.InputBufferLength, + SyncWrite); + + if( WriteRes != -1) + { + EXIT_SUCCESS(WriteRes); + } + + EXIT_FAILURE(WriteRes); + + break; + + case BIOCSETF: + + // Free the previous buffer if it was present + if(Open->bpfprogram!=NULL){ + TmpBPFProgram=Open->bpfprogram; + Open->bpfprogram = NULL; + ExFreePool(TmpBPFProgram); + } + + if (Open->Filter!=NULL) + { + JIT_BPF_Filter *OldFilter=Open->Filter; + Open->Filter=NULL; + BPF_Destroy_JIT_Filter(OldFilter); + } + + // Get the pointer to the new program + prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer; + + if(prog==NULL){ + IF_LOUD(DbgPrint("0001");) + + EXIT_FAILURE(0); + } + + insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn); + + //count the number of operative instructions + for (cnt=0;(cntmem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK) + { + + IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");) + + EXIT_FAILURE(0); + } + } + + //the NPF processor has been initialized, we have to validate the operative instructions + insns=cnt; + + if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0) + { + IF_LOUD(DbgPrint("Error validating program");) + //FIXME: the machine has been initialized(?), but the operative code is wrong. + //we have to reset the machine! + //something like: reallocate the mem_ex, and reset the tme_core + EXIT_FAILURE(0); + } + + // Allocate the memory to contain the new filter program + // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers() +#define NPF_TAG_BPFPROG TAG('4', 'P', 'W', 'A') + TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), NPF_TAG_BPFPROG); + if (TmpBPFProgram==NULL){ + IF_LOUD(DbgPrint("Error - No memory for filter");) + // no memory + EXIT_FAILURE(0); + } + + //copy the program in the new buffer + RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn)); + Open->bpfprogram=TmpBPFProgram; + + // Create the new JIT filter function + if(!IsExtendedFilter) + if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL) { + IF_LOUD(DbgPrint("Error jittering filter");) + EXIT_FAILURE(0); + } + + //return + Open->Bhead = 0; + Open->Btail = 0; + (INT)Open->BLastByte = -1; + Open->Received = 0; + Open->Dropped = 0; + Open->Accepted = 0; + + EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength); + + break; + + case BIOCSMODE: //set the capture mode + + mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer); + + if(mode == MODE_CAPT){ + Open->mode=MODE_CAPT; + + EXIT_SUCCESS(0); + } + else if (mode==MODE_MON){ + Open->mode=MODE_MON; + + EXIT_SUCCESS(0); + } + else{ + if(mode & MODE_STAT){ + Open->mode = MODE_STAT; + Open->Nbytes.QuadPart=0; + Open->Npackets.QuadPart=0; + + if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000; + + } + + if(mode & MODE_DUMP){ + + Open->mode |= MODE_DUMP; + Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000; + + } + EXIT_SUCCESS(0); + } + + EXIT_FAILURE(0); + + break; + + case BIOCSETDUMPFILENAME: + + if(Open->mode & MODE_DUMP) + { + + // Close current dump file + if(Open->DumpFileHandle != NULL){ + NPF_CloseDumpFile(Open); + Open->DumpFileHandle = NULL; + } + + if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){ + EXIT_FAILURE(0); + } + + // Allocate the buffer that will contain the string +#define NPF_TAG_DUMPNAMEBUF TAG('5', 'P', 'W', 'A') + DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, NPF_TAG_DUMPNAMEBUF); + if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){ + IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");) + EXIT_FAILURE(0); + } + + // Copy the buffer + RtlCopyBytes((PVOID)DumpNameBuff, + Irp->AssociatedIrp.SystemBuffer, + IrpSp->Parameters.DeviceIoControl.InputBufferLength); + + // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system + ((SHORT*)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0; + + // Create the unicode string + RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff); + + IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n", + Open->DumpFileName.Buffer, + IrpSp->Parameters.DeviceIoControl.InputBufferLength);) + + // Try to create the file + if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) && + NT_SUCCESS( NPF_StartDump(Open))){ + + EXIT_SUCCESS(0); + } + } + + EXIT_FAILURE(0); + + break; + + case BIOCSETDUMPLIMITS: + + Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer; + Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1); + + IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);) + + EXIT_SUCCESS(0); + + break; + + case BIOCISDUMPENDED: + if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4){ + EXIT_FAILURE(0); + } + + *((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0; + + EXIT_SUCCESS(4); + + break; + + case BIOCSETBUFFERSIZE: + + // Get the number of bytes to allocate + dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + // Free the old buffer + tpointer = Open->Buffer; + if(tpointer != NULL){ + Open->BufSize = 0; + Open->Buffer = NULL; + ExFreePool(tpointer); + } + // Allocate the new buffer + if(dim!=0){ +#define NPF_TAG_TPOINTER TAG('6', 'P', 'W', 'A') + tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, NPF_TAG_TPOINTER); + if (tpointer==NULL) { + // no memory + Open->BufSize = 0; + Open->Buffer = NULL; + EXIT_FAILURE(0); + } + } + else + tpointer = NULL; + + Open->Buffer = tpointer; + Open->Bhead = 0; + Open->Btail = 0; + (INT)Open->BLastByte = -1; + + Open->BufSize = (UINT)dim; + EXIT_SUCCESS(dim); + + break; + + case BIOCSRTIMEOUT: //set the timeout on the read calls + + timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + if((int)timeout==-1) + Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE; + else { + Open->TimeOut.QuadPart=(LONGLONG)timeout; + Open->TimeOut.QuadPart*=10000; + Open->TimeOut.QuadPart=-Open->TimeOut.QuadPart; + } + + //IF_LOUD(DbgPrint("NPF: read timeout set to %d:%d\n",Open->TimeOut.HighPart,Open->TimeOut.LowPart);) + EXIT_SUCCESS(timeout); + + break; + + case BIOCSWRITEREP: //set the writes repetition number + + Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + EXIT_SUCCESS(Open->Nwrites); + + break; + + case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application + + Open->MinToCopy = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + + EXIT_SUCCESS(Open->MinToCopy); + + break; + + case IOCTL_PROTOCOL_RESET: + + IF_LOUD(DbgPrint("NPF: IoControl - Reset request\n");) + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_SUCCESS; + + ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock); + NdisReset(&Status,Open->AdapterHandle); + if (Status != NDIS_STATUS_PENDING) { + IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");) + NPF_ResetComplete(Open,Status); + } + + break; + + + case BIOCSETOID: + case BIOCQUERYOID: + + // Extract a request from the list of free ones + RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock); + if (RequestListEntry == NULL) + { + EXIT_FAILURE(0); + } + + pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement); + pRequest->Irp=Irp; + pRequest->Internal = FALSE; + + + // + // See if it is an Ndis request + // + OidData=Irp->AssociatedIrp.SystemBuffer; + + if (((FunctionCode == BIOCSETOID) || (FunctionCode == BIOCQUERYOID)) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) { + + IF_LOUD(DbgPrint("NPF: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);) + + // + // The buffer is valid + // + if (FunctionCode == BIOCSETOID){ + + pRequest->Request.RequestType=NdisRequestSetInformation; + pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid; + + pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length; + } else{ + pRequest->Request.RequestType=NdisRequestQueryInformation; + pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid; + + pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length; + + } + + NdisResetEvent(&Open->IOEvent); + // + // submit the request + // + NdisRequest( + &Status, + Open->AdapterHandle, + &pRequest->Request + ); + + } else { + // + // buffer too small + // + Status=NDIS_STATUS_FAILURE; + pRequest->Request.DATA.SET_INFORMATION.BytesRead=0; + pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0; + + } + + if (Status != NDIS_STATUS_PENDING) { + IF_LOUD(DbgPrint("NPF: Calling RequestCompleteHandler\n");) + + NPF_RequestComplete(Open, &pRequest->Request, Status); + return Status; + + } + + NdisWaitEvent(&Open->IOEvent, 5000); + + return(Open->IOStatus); + + break; + + + default: + + EXIT_FAILURE(0); + } + + return Status; +} + +//------------------------------------------------------------------- + +VOID +NPF_RequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST NdisRequest, + IN NDIS_STATUS Status + ) + +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PIRP Irp; + PINTERNAL_REQUEST pRequest; + UINT FunctionCode; + KIRQL OldIrq; + + PPACKET_OID_DATA OidData; + + IF_LOUD(DbgPrint("NPF: RequestComplete\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); + Irp=pRequest->Irp; + + if(pRequest->Internal == TRUE){ + + // Put the request in the list of the free ones + ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock); + + if(Status != NDIS_STATUS_SUCCESS) + Open->MaxFrameSize = 1514; // Assume Ethernet + + // We always return success, because the adapter has been already opened + Irp->IoStatus.Status = NDIS_STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return; + } + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; + + OidData=Irp->AssociatedIrp.SystemBuffer; + + if (FunctionCode == BIOCSETOID) { + + OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead; + + } else { + + if (FunctionCode == BIOCQUERYOID) { + + OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten; + + IF_LOUD(DbgPrint("RequestComplete: BytesWritten=%d\n",pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten);) + } + + } + + Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength; + + IF_LOUD(DbgPrint("RequestComplete: BytesReturned=%d\n",IrpSp->Parameters.DeviceIoControl.InputBufferLength);) + + ExInterlockedInsertTailList( + &Open->RequestList, + &pRequest->ListElement, + &Open->RequestSpinLock); + + Irp->IoStatus.Status = Status; + + Open->IOStatus = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // Unlock the caller + NdisSetEvent(&Open->IOEvent); + + return; + + +} + +//------------------------------------------------------------------- + +VOID +NPF_Status( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ) + +{ + + IF_LOUD(DbgPrint("NPF: Status Indication\n");) + + return; + +} + +//------------------------------------------------------------------- + +VOID +NPF_StatusComplete( + IN NDIS_HANDLE ProtocolBindingContext + ) + +{ + + IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");) + + return; + +} + +//------------------------------------------------------------------- + +NTSTATUS +NPF_ReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath + ) + +{ + NTSTATUS Status; + + RTL_QUERY_REGISTRY_TABLE ParamTable[4]; + + PWSTR Bind = L"Bind"; + PWSTR Export = L"Export"; + PWSTR Parameters = L"Parameters"; + PWSTR Linkage = L"Linkage"; + + PWCHAR Path; + +#define NPF_TAG_PATH TAG('7', 'P', 'W', 'A') + Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), NPF_TAG_PATH); + + if (Path == NULL) { + IF_LOUD(DbgPrint("\nPacketReadRegistry: returing STATUS_INSUFFICIENT_RESOURCES\n");) + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( + Path, + RegistryPath->Length+sizeof(WCHAR) + ); + + RtlCopyMemory( + Path, + RegistryPath->Buffer, + RegistryPath->Length + ); + + IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);) + + RtlZeroMemory( + ParamTable, + sizeof(ParamTable) + ); + + + + // + // change to the linkage key + // + //ParamTable[0].QueryRoutine = NULL; + ParamTable[0].QueryRoutine = NPF_QueryRegistryRoutine; + ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; + ParamTable[0].Name = Linkage; + + + // + // Get the name of the mac driver we should bind to + // + + ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine; + ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED | + RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[1].Name = Bind; + ParamTable[1].EntryContext = (PVOID)MacDriverName; + ParamTable[1].DefaultType = REG_MULTI_SZ; + + // + // Get the name that we should use for the driver object + // + + ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine; + ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | + RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[2].Name = Export; + ParamTable[2].EntryContext = (PVOID)PacketDriverName; + ParamTable[2].DefaultType = REG_MULTI_SZ; + + + Status=RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + Path, + ParamTable, + NULL, + NULL + ); + + if (Status != STATUS_SUCCESS) { + // insert hard coded parameters here while registry on ROS is not working... + IF_LOUD(DbgPrint("PacketReadRegistry() RtlQueryRegistryValues failed - returing fixed parameters\n");) + + *MacDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR)); + //memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR)); + memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR)); + + *PacketDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR)); + memcpy(*PacketDriverName, L"\\Device\\NPF_ne2000", 19 * sizeof(WCHAR)); + Status = STATUS_SUCCESS; + + } + + ExFreePool(Path); + return Status; +} + +//------------------------------------------------------------------- + +NTSTATUS STDCALL +NPF_QueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ) + +{ + + PUCHAR Buffer; + + IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");) + + if (ValueType != REG_MULTI_SZ) { + + return STATUS_OBJECT_NAME_NOT_FOUND; + + } + +#define NPF_TAG_REGBUF TAG('8', 'P', 'W', 'A') + Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, NPF_TAG_REGBUF); + + if (Buffer==NULL) { + + return STATUS_INSUFFICIENT_RESOURCES; + + } + + RtlCopyMemory( + Buffer, + ValueData, + ValueLength + ); + + *((PUCHAR *)EntryContext)=Buffer; + + return STATUS_SUCCESS; + +} diff --git a/drivers/net/npf/packet.h b/drivers/net/npf/packet.h new file mode 100644 index 0000000..062a790 --- /dev/null +++ b/drivers/net/npf/packet.h @@ -0,0 +1,959 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** @ingroup NPF + * @{ + */ + +/** @defgroup NPF_include NPF structures and definitions + * @{ + */ + +#ifndef __PACKET_INCLUDE______ +#define __PACKET_INCLUDE______ + +#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls + +#ifdef __GNUC__ +#undef EXIT_SUCCESS +#undef EXIT_FAILURE +#define UNICODE_NULL ((WCHAR)0) // winnt +#include "win_bpf.h" +#include +#endif + +#include "jitter.h" +#include "tme.h" + +#define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests. + +#define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size. +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next + ///< even multiple of Packet_ALIGNMENT. + + +/***************************/ +/* IOCTLs */ +/***************************/ + +/*! + \brief IOCTL code: set kernel buffer size. + + This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF. + When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one + and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently + buffered packets are lost. +*/ +#define BIOCSETBUFFERSIZE 9592 + +/*! + \brief IOCTL code: set packet filtering program. + + This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the + bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE, + the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the + OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to + every incoming packet. This command also empties the circular buffer used by current instance + to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter. +*/ +#define BIOCSETF 9030 + +/*! + \brief IOCTL code: get the capture stats + + This command returns to the application the number of packets received and the number of packets dropped by + an instance of the driver. +*/ +#define BIOCGSTATS 9031 + +/*! + \brief IOCTL code: set the read timeout + + This command sets the maximum timeout after which a read is released, also if no data packets were received. +*/ +#define BIOCSRTIMEOUT 7416 + +/*! + \brief IOCTL code: set working mode + + This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the + buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for + statistical mode or #MODE_DUMP for dump mode. +*/ +#define BIOCSMODE 7412 + +/*! + \brief IOCTL code: set number of physical repetions of every packet written by the app + + Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites + member, and is used to implement the 'multiple write' feature of the driver. +*/ +#define BIOCSWRITEREP 7413 + +/*! + \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call + + This command sets the OPEN_INSTANCE::MinToCopy member. +*/ +#define BIOCSMINTOCOPY 7414 + +/*! + \brief IOCTL code: set an OID value + + This IOCTL is used to perform an OID set operation on the NIC driver. +*/ +#define BIOCSETOID 2147483648UL + +/*! + \brief IOCTL code: get an OID value + + This IOCTL is used to perform an OID get operation on the NIC driver. +*/ +#define BIOCQUERYOID 2147483652UL + +/*! + \brief IOCTL code: set the name of a the file used by kernel dump mode + + This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance. + The dump thread uses it to copy the content of the circular buffer to file. + If a file was already opened, the driver closes it before opening the new one. +*/ +#define BIOCSETDUMPFILENAME 9029 + +/*! + \brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer + + Command used by the application to retrieve the name of the global event associated with a NPF instance. + The event is signaled by the driver when the kernel buffer contains enough data for a transfer. +*/ +#define BIOCGEVNAME 7415 + +/*! + \brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps. + + Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by + a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as + possible. The NPF_BufferedWrite() function is invoked to send the packets. +*/ +#define BIOCSENDPACKETSNOSYNC 9032 + +/*! + \brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps. + + Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by + a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets + are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each + packet. NPF_BufferedWrite() function is invoked to send the packets. +*/ +#define BIOCSENDPACKETSSYNC 9033 + +/*! + \brief IOCTL code: Set the dump file limits. + + This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the + driver works in dump mode. +*/ +#define BIOCSETDUMPLIMITS 9034 + +/*! + \brief IOCTL code: Get the status of the kernel dump process. + + This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS + (amount of bytes or number of packets) has been reached. +*/ +#define BIOCISDUMPENDED 7411 + +// Working modes +#define MODE_CAPT 0x0 ///< Capture working mode +#define MODE_STAT 0x1 ///< Statistical working mode +#define MODE_MON 0x2 ///< Kernel monitoring mode +#define MODE_DUMP 0x10 ///< Kernel dump working mode + + +#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately. + + +// The following definitions are used to provide compatibility +// of the dump files with the ones of libpcap +#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. + +/*! + \brief Header of a libpcap dump file. + + Used when a driver instance is set in dump mode to create a libpcap-compatible file. +*/ +struct packet_file_header +{ + UINT magic; ///< Libpcap magic number + USHORT version_major; ///< Libpcap major version + USHORT version_minor; ///< Libpcap minor version + UINT thiszone; ///< Gmt to local correction + UINT sigfigs; ///< Accuracy of timestamps + UINT snaplen; ///< Length of the max saved portion of each packet + UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details. +}; + +/*! + \brief Header associated to a packet in the driver's buffer when the driver is in dump mode. + Similar to the bpf_hdr structure, but simpler. +*/ +struct sf_pkthdr { + struct timeval ts; ///< time stamp + UINT caplen; ///< Length of captured portion. The captured portion can be different from + ///< the original packet, because it is possible (with a proper filter) to + ///< instruct the driver to capture only a portion of the packets. + UINT len; ///< Length of the original packet (off wire). +}; + +/*! + \brief Stores an OID request. + + This structure is used by the driver to perform OID query or set operations on the underlying NIC driver. + The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level + applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure. + This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and + maintaining information about the IRPs to complete. +*/ +typedef struct _INTERNAL_REQUEST { + LIST_ENTRY ListElement; ///< Used to handle lists of requests. + PIRP Irp; ///< Irp that performed the request + BOOLEAN Internal; ///< True if the request is for internal use of npf.sys. False if the request is performed by the user through an IOCTL. + NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest(). +} INTERNAL_REQUEST, *PINTERNAL_REQUEST; + +/*! + \brief Contains a NDIS packet. + + The driver uses this structure to wrap a NDIS_PACKET structure. + This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and + maintaining information about the IRPs to complete. +*/ +typedef struct _PACKET_RESERVED { + LIST_ENTRY ListElement; ///< Used to handle lists of packets. + PIRP Irp; ///< Irp that performed the request + PMDL pMdl; ///< MDL mapping the buffer of the packet. + BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed + ///< after a call to NdisSend(). +} PACKET_RESERVED, *PPACKET_RESERVED; + +#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED + +/*! + \brief Port device extension. + + Structure containing some data relative to every adapter on which NPF is bound. +*/ +typedef struct _DEVICE_EXTENSION { + NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF. + NDIS_STRING AdapterName; ///< Name of the adapter. + PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use + ///< to open this adapter through WinPcap. +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +/*! + \brief Contains the state of a running instance of the NPF driver. + + This is the most important structure of NPF: it is used by almost all the functions of the driver. An + _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access + to the driver. +*/ +typedef struct _OPEN_INSTANCE +{ + PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which + ///< the instance is bound. + NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance. + UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the + ///< documentation of NdisOpenAdapter in the MS DDK for details. + NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver. + PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the + ///< callbacks of NDIS. + KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests. + LIST_ENTRY RequestList; ///< List of pending OID requests. + LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests. + INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request. + PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory. + PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait. + HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait. + UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait. + ///< The event is created with a name, so it can be used at user level to know when it + ///< is possible to access the driver without being blocked. This fiels stores the name + ///< that and is used by the BIOCGEVNAME IOCTL call. + INT Received; ///< Number of packets received by current instance from its opening, i.e. number of + ///< packet received by the network adapter since the beginning of the + ///< capture/monitoring/dump session. + INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet + ///< is dropped if there is no more space to store it in the circular buffer that the + ///< driver associates to current instance. + INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet + ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the + ///< ones that reach the application. + PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver. + ///< This code is used only in particular situations (for example when the packet received + ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations + ///< the filtering routine created by the JIT compiler and pointed by the next field + ///< is used. See \ref NPF for details on the filtering process. + JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter. + ///< See BPF_jitter() for details. + PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the + ///< data that will be passed to the application. See \ref NPF for details. + UINT Bhead; ///< Head of the circular buffer. + UINT Btail; ///< Tail of the circular buffer. + UINT BufSize; ///< Size of the circular buffer. + UINT BLastByte; ///< Position of the last valid byte in the circular buffer. + PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet. + ///< Used by NdisTransferData(). + NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables. + UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the + ///< BIOCSMINTOCOPY IOCTL. + LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is + ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL. + + int mode; ///< Working mode of the driver. See PacketSetMode() for details. + LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode. + LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode. + NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters. + UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an + ///< explanation + UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated. + NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process. + NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS. + NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application. + BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be + ///< FALSE if a Plug and Play adapter has been removed or disabled by the user. + HANDLE DumpFileHandle; ///< Handle of the file used in dump mode. + PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode. + PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode. + HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk. + NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode. + LARGE_INTEGER DumpOffset; ///< Current offset in the dump file. + UNICODE_STRING DumpFileName; ///< String containing the name of the dump file. + UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it + ///< will be closed. A value of 0 means unlimited size. + UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of + ///< packets is reached the dump will be closed. A value of 0 means unlimited number of + ///< packets. + BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is + ///< reached. + MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor + TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor + NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer + UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the + ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite(). +} OPEN_INSTANCE, *POPEN_INSTANCE; + + +#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number + ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets. + + +/// Macro used in the I/O routines to return the control to user-mode with a success status. +#define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\ + Irp->IoStatus.Status = STATUS_SUCCESS;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_SUCCESS;\ + +/// Macro used in the I/O routines to return the control to user-mode with a failure status. +#define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_UNSUCCESSFUL;\ + +/** + * @} + */ + + +/***************************/ +/* Prototypes */ +/***************************/ + +/** @defgroup NPF_code NPF functions + * @{ + */ + + +/*! + \brief The initialization routine of the driver. + \param DriverObject The driver object of NPF created by the system. + \param RegistryPath The registry path containing the keys related to the driver. + \return A string containing a list of network adapters. + + DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called + by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver, + performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O + callbacks, creates the devices, defines NPF as a protocol inside NDIS. +*/ +//NTSTATUS +//DriverEntry( +// IN PDRIVER_OBJECT DriverObject, +// IN PUNICODE_STRING RegistryPath +// ); + +/*! + \brief Returns the list of the MACs available on the system. + \return A string containing a list of network adapters. + + The list of adapters is retrieved from the + SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key. + NPF tries to create its bindings from this list. In this way it is possible to be loaded + and unloaded dynamically without passing from the control panel. +*/ +PWCHAR getAdaptersList(VOID); + +/*! + \brief Returns the MACs that bind to TCP/IP. + \return Pointer to the registry key containing the list of adapters on which TCP/IP is bound. + + If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function. +*/ +PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID); + +/*! + \brief Creates a device for a given MAC. + \param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF. + \param amacNameP The name of the network interface that the device will point. + \param aProtoHandle NDIS protocol handle of NPF. + \return If the function succeeds, the return value is nonzero. + + NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains + information about the original device. In this way, when the user opens the new device, NPF will be able to + determine the correct adapter to use. +*/ +BOOLEAN createDevice( + IN OUT PDRIVER_OBJECT adriverObjectP, + IN PUNICODE_STRING amacNameP, + NDIS_HANDLE aProtoHandle); + +/*! + \brief Opens a new instance of the driver. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS when a new instance of the driver is opened, i.e. when a user application + performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects + and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the + adapter with a call to NdisOpenAdapter. +*/ +NTSTATUS STDCALL +NPF_Open( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +/*! + \brief Ends the opening of an adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the opening operation performed by NDIS. + \param OpenErrorStatus not used by NPF. + + Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC + driver has finished an open operation that was previously started by NPF_Open(). +*/ +VOID +NPF_OpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus + ); + +/*! + \brief Closes an instance of the driver. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called when a running instance of the driver is closed by the user with a CloseHandle(). + It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the + instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter. +*/ +NTSTATUS STDCALL +NPF_Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +/*! + \brief Ends the closing of an adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the close operation performed by NDIS. + + Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC + driver has finished a close operation that was previously started by NPF_Close(). +*/ +VOID +NPF_CloseAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + +/*! + \brief Callback invoked by NDIS when a packet arrives from the network. + \param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies + the NPF instance to which the packets are destined. + \param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request. + This value must be used when the packet is transferred from the NIC driver with NdisTransferData(). + \param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet. + \param HeaderBufferSize Size in bytes of the header. + \param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's + data available to NPF. This value does not necessarily coincide with the actual size of the packet, + since only a portion can be available at this time. The remaining portion can be obtained with the + NdisTransferData() NDIS function. + \param LookaheadBufferSize Size in bytes of the lookahead buffer. + \param PacketSize Total size of the incoming packet, excluded the header. + \return The status of the operation. See ntstatus.h in the DDK. + + NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of + the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in + statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function, + along with the filtering ones, that is executed for every incoming packet, therefore it is carefully + optimized. +*/ +NDIS_STATUS +NPF_tap( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +/*! + \brief Ends the transfer of a packet. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Packet Pointer to the NDIS_PACKET structure that received the packet data. + \param Status Status of the transfer operation. + \param BytesTransferred Amount of bytes transferred. + + Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC + driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer. +*/ +VOID +NPF_TransferDataComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status, + IN UINT BytesTransferred + ); + +/*! + \brief Callback function that signals the end of a packet reception. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + + does nothing in NPF +*/ +VOID +NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext); + +/*! + \brief Handles the IOCTL calls. + \param DeviceObject Pointer to the device object utilized by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands + using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF. + The following commands are recognized: + - #BIOCSETBUFFERSIZE + - #BIOCSETF + - #BIOCGSTATS + - #BIOCSRTIMEOUT + - #BIOCSMODE + - #BIOCSWRITEREP + - #BIOCSMINTOCOPY + - #BIOCSETOID + - #BIOCQUERYOID + - #BIOCSETDUMPFILENAME + - #BIOCGEVNAME + - #BIOCSENDPACKETSSYNC + - #BIOCSENDPACKETSNOSYNC +*/ +NTSTATUS STDCALL +NPF_IoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + + +/*! + \brief Ends an OID request. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param pRequest Pointer to the completed OID request. + \param Status Status of the operation. + + Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_IoControl(). +*/ +VOID +NPF_RequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST pRequest, + IN NDIS_STATUS Status + ); + +/*! + \brief Writes a raw packet to the network. + \param DeviceObject Pointer to the device object on which the user wrote the packet. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must + be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and + delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure + associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the + packet can be sent for performance reasons. +*/ +NTSTATUS STDCALL +NPF_Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + + +/*! + \brief Writes a buffer of raw packets to the network. + \param Irp Pointer to the IRP containing the user request. + \param UserBuff Pointer to the buffer containing the packets to send. + \param UserBuffSize Size of the buffer with the packets. + \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an + error occurred during the send. The error can be caused by an adapter problem or by an + inconsistent/bogus user buffer. + + This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL. + The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a + sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function. + When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function. + This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision + of some microseconds (depending on the precision of the performance counter of the machine). + If Sync is false, the timestamps are ignored and the packets are sent as fat as possible. +*/ + +INT NPF_BufferedWrite(IN PIRP Irp, + IN PCHAR UserBuff, + IN ULONG UserBuffSize, + BOOLEAN sync); + +/*! + \brief Ends a send operation. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param pRequest Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet. + \param Status Status of the operation. + + Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_Write(). +*/ +VOID +NPF_SendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ); + +/*! + \brief Ends a reset of the adapter. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. + \param Status Status of the operation. + + Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC + driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET + command. +*/ +VOID +NPF_ResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + +/*! + \brief Callback for NDIS StatusHandler. Not used by NPF +*/ +VOID +NPF_Status( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ); + + +/*! + \brief Callback for NDIS StatusCompleteHandler. Not used by NPF +*/ +VOID +NPF_StatusComplete(IN NDIS_HANDLE ProtocolBindingContext); + +/*! + \brief Function called by the OS when NPF is unloaded. + \param DriverObject The driver object of NPF created by the system. + + This is the last function executed when the driver is unloaded from the system. It frees global resources, + delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF + service (from control panel or with a console 'net stop npf'). +*/ +VOID STDCALL +NPF_Unload(IN PDRIVER_OBJECT DriverObject); + + +/*! + \brief Function that serves the user's reads. + \param DeviceObject Pointer to the device used by the user. + \param Irp Pointer to the IRP containing the user request. + \return The status of the operation. See ntstatus.h in the DDK. + + This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the + kernel buffer to the user buffer associated with Irp. + First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance. + - If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes, + NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the + user is not blocking. + - If the buffer contains less than MinToCopy bytes, the application's request isn't + satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net + or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field. + - If the instance is in statistical mode or in dump mode, the application's request is blocked until the + timeout kept in OPEN_INSTANCE::TimeOut expires. +*/ +NTSTATUS STDCALL +NPF_Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +/*! + \brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel. + + Normally not used in recent versions of NPF. +*/ +NTSTATUS +NPF_ReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath + ); + +/*! + \brief Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver + is manually installed via the control panel. + + Normally not used in recent versions of NPF. +*/ +NTSTATUS STDCALL +NPF_QueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ); + +/*! + \brief Callback for NDIS BindAdapterHandler. Not used by NPF. + + Function called by NDIS when a new adapter is installed on the machine With Plug and Play. +*/ +VOID NPF_BindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE BindContext, + IN PNDIS_STRING DeviceName, + IN PVOID SystemSpecific1, + IN PVOID SystemSpecific2 + ); + +/*! + \brief Callback for NDIS UnbindAdapterHandler. + \param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation. + \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance. + \param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the opration. + + Function called by NDIS when a new adapter is removed from the machine without shutting it down. + NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures + associated with it. It also releases the waiting user-level app and closes the dump thread if the instance + is in dump mode. +*/ +VOID +NPF_UnbindAdapter( + OUT PNDIS_STATUS Status, + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE UnbindContext + ); + +/*! + \brief Validates a filtering program arriving from the user-level app. + \param f The filter. + \param len Its length, in pseudo instructions. + \param mem_ex_size The length of the extended memory, used to validate LD/ST to that memory + \return true if f is a valid filter program.. + + The kernel needs to be able to verify an application's filter code. Otherwise, a bogus program could easily + crash the system. + This function returns true if f is a valid filter program. The constraints are that each jump be forward and + to a valid code. The code must terminate with either an accept or reject. +*/ +int bpf_validate(struct bpf_insn *f,int len, uint32 mem_ex_size); + +/*! + \brief The filtering pseudo-machine interpreter. + \param pc The filter. + \param p Pointer to a memory buffer containing the packet on which the filter will be executed. + \param wirelen Original length of the packet. + \param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM + has not yet finished), bpf_filter can be executed on a portion of the packet. + \param mem_ex The extended memory. + \param tme The virtualization of the TME co-processor + \param time_ref Data structure needed by the TME co-processor to timestamp data + \return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that + the whole packet must be kept. + + \note this function is not used in normal situations, because the jitter creates a native filtering function + that is faster than the interpreter. +*/ +UINT bpf_filter(register struct bpf_insn *pc, + register UCHAR *p, + UINT wirelen, + register UINT buflen, + PMEM_TYPE mem_ex, + PTME_CORE tme, + struct time_conv *time_ref); + +/*! + \brief The filtering pseudo-machine interpreter with two buffers. This function is slower than bpf_filter(), + but works correctly also if the MAC header and the data of the packet are in two different buffers. + \param pc The filter. + \param p Pointer to a memory buffer containing the MAC header of the packet. + \param pd Pointer to a memory buffer containing the data of the packet. + \param wirelen Original length of the packet. + \param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM + has not yet finished), bpf_filter can be executed on a portion of the packet. + \param mem_ex The extended memory. + \param tme The virtualization of the TME co-processor + \param time_ref Data structure needed by the TME co-processor to timestamp data + \return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that + the whole packet must be kept. + + This function is used when NDIS passes the packet to NPF_tap() in two buffers instaed than in a single one. +*/ +UINT bpf_filter_with_2_buffers(register struct bpf_insn *pc, + register UCHAR *p, + register UCHAR *pd, + register int headersize, + UINT wirelen, + register UINT buflen, + PMEM_TYPE mem_ex, + PTME_CORE tme, + struct time_conv *time_ref); + +/*! + \brief Creates the file that will receive the packets when the driver is in dump mode. + \param Open The NPF instance that opens the file. + \param fileName Pointer to a UNICODE string containing the name of the file. + \param append Boolean value that specifies if the data must be appended to the file. + \return The status of the operation. See ntstatus.h in the DDK. +*/ +NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append); + +/*! + \brief Starts dump to file. + \param Open The NPF instance that opens the file. + \return The status of the operation. See ntstatus.h in the DDK. + + This function performs two operations. First, it writes the libpcap header at the beginning of the file. + Second, it starts the thread that asynchronously dumps the network data to the file. +*/ +NTSTATUS NPF_StartDump(POPEN_INSTANCE Open); + +/*! + \brief The dump thread. + \param Open The NPF instance that creates the thread. + + This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower + priority than the TAP. +*/ +VOID NPF_DumpThread(POPEN_INSTANCE Open); + +/*! + \brief Saves the content of the packet buffer to the file associated with current instance. + \param Open The NPF instance that creates the thread. + + Used by NPF_DumpThread() and NPF_CloseDumpFile(). +*/ +NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open); + +/*! + \brief Writes a block of packets on the dump file. + \param FileObject The file object that will receive the packets. + \param Offset The offset in the file where the packets will be put. + \param Length The amount of bytes to write. + \param Mdl MDL mapping the memory buffer that will be written to disk. + \param IoStatusBlock Used by the function to return the status of the operation. + \return The status of the operation. See ntstatus.h in the DDK. + + NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion + of the NPF circular buffer to disk. This function is used by NPF_DumpThread(). +*/ +VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock); + + + +/*! + \brief Closes the dump file associated with an instance of the driver. + \param Open The NPF instance that closes the file. + \return The status of the operation. See ntstatus.h in the DDK. +*/ +NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open); + +/*! + \brief Returns the amount of bytes present in the packet buffer. + \param Open The NPF instance that closes the file. +*/ +UINT GetBuffOccupation(POPEN_INSTANCE Open); + +/*! + \brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change. + + \param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig + events. + \param pNetPnPEvent Pointer to the PnP event + + If there is a power state change, the driver is forced to resynchronize the global timer. + This hopefully avoids the synchronization issues caused by hibernation or standby. + This function is excluded from the NT4 driver, where PnP is not supported +*/ +#ifdef NDIS50 +NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent); +#endif + +/** + * @} + */ + +/** + * @} + */ + +#endif /*main ifndef/define*/ diff --git a/drivers/net/npf/read.c b/drivers/net/npf/read.c new file mode 100644 index 0000000..7541744 --- /dev/null +++ b/drivers/net/npf/read.c @@ -0,0 +1,680 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include +#include +#include +#include +#else +#include +#include + +#define NdisMoveMappedMemory(Destination,Source,Length) RtlCopyMemory(Destination,Source,Length) +#define NdisZeroMappedMemory(Destination,Length) RtlZeroMemory(Destination,Length) +#define NdisReinitializePacket(Packet) \ +{ \ + (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \ + (Packet)->Private.ValidCounts = FALSE; \ +} + + +#endif + +#include "debug.h" +#include "packet.h" +#include "win_bpf.h" + +#include "tme.h" +#include "time_calls.h" + +extern struct time_conv G_Start_Time; // from openclos.c + +//------------------------------------------------------------------- + +UINT GetBuffOccupation(POPEN_INSTANCE Open) +{ + UINT Occupation; + + NdisAcquireSpinLock( &Open->BufLock ); + + if(Open->Btail >= Open->Bhead) Occupation = Open->Btail-Open->Bhead; + else Occupation = Open->BLastByte-Open->Bhead+Open->Btail; + + NdisReleaseSpinLock( &Open->BufLock ); + + return Occupation; +} + +//------------------------------------------------------------------- + +void PacketMoveMem(PVOID Destination, PVOID Source, ULONG Length, UINT *Bhead) +{ +ULONG WordLength; +UINT n,i,NBlocks; + + WordLength=Length>>2; + NBlocks=WordLength>>8; + + for(n=0;nFileObject->FsContext; + + if( Open->Bound == FALSE ){ + // The Network adapter was removed. + EXIT_FAILURE(0); + } + + if( Open->mode & MODE_DUMP && Open->DumpFileHandle == NULL ){ + // this instance is in dump mode, but the dump file has still not been opened + EXIT_FAILURE(0); + } + + //See if the buffer is full enough to be copied + if( GetBuffOccupation(Open) <= Open->MinToCopy || Open->mode & MODE_DUMP ) + { + //wait until some packets arrive or the timeout expires + if(Open->TimeOut.QuadPart != (LONGLONG)IMMEDIATE) + KeWaitForSingleObject(Open->ReadEvent, + UserRequest, + KernelMode, + TRUE, + (Open->TimeOut.QuadPart == (LONGLONG)0)? NULL: &(Open->TimeOut)); + + KeClearEvent(Open->ReadEvent); + + if(Open->mode & MODE_STAT){ //this capture instance is in statistics mode + CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); + + //fill the bpf header for this packet + header=(struct bpf_hdr*)CurrBuff; + GET_TIME(&header->bh_tstamp,&G_Start_Time); + + if(Open->mode & MODE_DUMP){ + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+16)=Open->DumpOffset.QuadPart; + header->bh_caplen=24; + header->bh_datalen=24; + Irp->IoStatus.Information = 24 + sizeof(struct bpf_hdr); + } + else{ + header->bh_caplen=16; + header->bh_datalen=16; + header->bh_hdrlen=sizeof(struct bpf_hdr); + Irp->IoStatus.Information = 16 + sizeof(struct bpf_hdr); + } + + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets.QuadPart; + *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes.QuadPart; + + //reset the countetrs + NdisAcquireSpinLock( &Open->CountersLock ); + Open->Npackets.QuadPart=0; + Open->Nbytes.QuadPart=0; + NdisReleaseSpinLock( &Open->CountersLock ); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + + if(Open->mode==MODE_MON) //this capture instance is in monitor mode + { + PTME_DATA data; + ULONG cnt; + ULONG block_size; + PUCHAR tmp; + + UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress); + + if ((!IS_VALIDATED(Open->tme.validated_blocks,Open->tme.active_read))||(IrpSp->Parameters.Read.Lengthbh_tstamp,&G_Start_Time); + + + header->bh_hdrlen=sizeof(struct bpf_hdr); + + + //moves user memory pointer + UserPointer+=sizeof(struct bpf_hdr); + + //calculus of data to be copied + //if the user buffer is smaller than data to be copied, + //only some data will be copied + data=&Open->tme.block_data[Open->tme.active_read]; + + if (data->last_read.tv_sec!=0) + data->last_read=header->bh_tstamp; + + + bytecopy=data->block_size*data->filled_blocks; + + if ((IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))Parameters.Read.Length-sizeof(struct bpf_hdr))/ data->block_size; + else + bytecopy=data->filled_blocks; + + tmp=data->shared_memory_base_address; + block_size=data->block_size; + + for (cnt=0;cntmachine_lock); + RtlCopyMemory(UserPointer,tmp,block_size); + NdisReleaseSpinLock(&Open->machine_lock); + tmp+=block_size; + UserPointer+=block_size; + } + + bytecopy*=block_size; + + header->bh_caplen=bytecopy; + header->bh_datalen=header->bh_caplen; + + EXIT_SUCCESS(bytecopy+sizeof(struct bpf_hdr)); + } + + if (Open->Bhead == Open->Btail || Open->mode & MODE_DUMP) + // The timeout has expired, but the buffer is still empty (or the packets must be written to file). + // We must awake the application, returning an empty buffer. + { + EXIT_SUCCESS(0); + } + + } + + // + // The buffer if full enough to be copied, + // + NdisAcquireSpinLock( &Open->BufLock ); + + Thead = Open->Bhead; + Ttail = Open->Btail; + TLastByte = Open->BLastByte; + + //get the address of the buffer + CurrBuff=Open->Buffer; + + NdisReleaseSpinLock( &Open->BufLock ); + + Input_Buffer_Length=IrpSp->Parameters.Read.Length; + packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); + + + // + //fill the application buffer + // + if(Ttail > Thead){ //first of all see if it we can copy all the buffer in one time + if((Ttail-Thead)ReadEvent); + + PacketMoveMem(packp,CurrBuff+Thead,Ttail-Thead,&(Open->Bhead)); + EXIT_SUCCESS(Ttail-Thead); + } + } + else if((TLastByte - Thead) < Input_Buffer_Length){ + PacketMoveMem(packp, CurrBuff+Thead, TLastByte - Thead, &(Open->Bhead)); + + NdisAcquireSpinLock( &Open->BufLock ); + + Open->BLastByte = Open->Btail; + Open->Bhead = 0; + + NdisReleaseSpinLock( &Open->BufLock ); + + EXIT_SUCCESS(TLastByte-Thead); + } + + //the buffer must be scannned to determine the number of bytes to copy + SizeToCopy = 0; + while(TRUE){ + if(Thead + SizeToCopy == Ttail) + break; + + if(Thead + SizeToCopy == TLastByte && TLastByte != Ttail){ + + PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead)); + // Reset the buffer + NdisAcquireSpinLock( &Open->BufLock ); + (INT)Open->BLastByte = -1; + Open->Bhead = 0; + NdisReleaseSpinLock( &Open->BufLock ); + + EXIT_SUCCESS(SizeToCopy); + } + + // Get the size of the next packet in the buffer + PktLen = ((struct bpf_hdr*)(CurrBuff + Thead + SizeToCopy))->bh_caplen + sizeof(struct bpf_hdr); + + // The length is aligned to 32-bit boundary + PktLen = Packet_WORDALIGN(PktLen); + + if(SizeToCopy + PktLen > Input_Buffer_Length) + break; + + SizeToCopy += PktLen; + } + + PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead)); + EXIT_SUCCESS(SizeToCopy); + +} + +//------------------------------------------------------------------- + +NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer,IN UINT HeaderBufferSize,IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize,IN UINT PacketSize) +{ + POPEN_INSTANCE Open; + PNDIS_PACKET pPacketb; + ULONG SizeToTransfer; + NDIS_STATUS Status; + UINT BytesTransfered; + ULONG BufferLength; + PMDL pMdl; + LARGE_INTEGER CapTime; + LARGE_INTEGER TimeFreq; + struct bpf_hdr *header; + PUCHAR CurrBuff; + UINT Thead; + UINT Ttail; + UINT TLastByte; + UINT fres; + UINT maxbufspace; + USHORT NPFHdrSize; + UINT BufOccupation; + BOOLEAN ResetBuff = FALSE; + + IF_VERY_LOUD(DbgPrint("NPF: tap\n");) + IF_VERY_LOUD(DbgPrint("HeaderBufferSize=%d, LookAheadBuffer=%d, LookaheadBufferSize=%d, PacketSize=%d\n", + HeaderBufferSize, + LookAheadBuffer, + LookaheadBufferSize, + PacketSize);) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + Open->Received++; // Number of packets received by filter ++ + + BufOccupation = GetBuffOccupation(Open); // Get the full buffer space + + if(((Open->mode&MODE_CAPT)||(Open->mode&MODE_DUMP)) && Open->BufSize - BufOccupation < PacketSize+HeaderBufferSize+sizeof(struct bpf_hdr)){ + // Heuristic that drops the packet also if it possibly fits in the buffer. + // It allows to avoid filtering in critical situations when CPU is very important. + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + + NdisAcquireSpinLock(&Open->machine_lock); + + // + //Check if the lookahead buffer follows the mac header. + //If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is + //executed on the packet. + //Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or + //things like this) bpf_filter_with_2_buffers() is executed. + // + if((UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize) + fres=bpf_filter_with_2_buffers((struct bpf_insn*)(Open->bpfprogram), + HeaderBuffer, + LookAheadBuffer, + HeaderBufferSize, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize, + &Open->mem_ex, + &Open->tme, + &G_Start_Time); + + + else + if(Open->Filter != NULL) + { + if (Open->bpfprogram != NULL) + { + fres=Open->Filter->Function(HeaderBuffer, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize); + + // Restore the stack. + // I ignore the reason, but this instruction is needed only at kernel level +#ifndef __GNUC__ + _asm add esp,12 +#else + asm("add $0x12,%esp;"); +#endif + } + else + fres = -1; + } + else + fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram), + HeaderBuffer, + PacketSize+HeaderBufferSize, + LookaheadBufferSize+HeaderBufferSize, + &Open->mem_ex, + &Open->tme, + &G_Start_Time); + + NdisReleaseSpinLock(&Open->machine_lock); + + if(Open->mode==MODE_MON) + // we are in monitor mode + { + if (fres==1) + KeSetEvent(Open->ReadEvent,0,FALSE); + return NDIS_STATUS_NOT_ACCEPTED; + + } + + if(fres==0) + // Packet not accepted by the filter, ignore it. + return NDIS_STATUS_NOT_ACCEPTED; + + //if the filter returns -1 the whole packet must be accepted + if(fres==-1 || fres > PacketSize+HeaderBufferSize)fres=PacketSize+HeaderBufferSize; + + if(Open->mode & MODE_STAT){ + // we are in statistics mode + NdisAcquireSpinLock( &Open->CountersLock ); + + Open->Npackets.QuadPart++; + + if(PacketSize+HeaderBufferSize<60) + Open->Nbytes.QuadPart+=60; + else + Open->Nbytes.QuadPart+=PacketSize+HeaderBufferSize; + // add preamble+SFD+FCS to the packet + // these values must be considered because are not part of the packet received from NDIS + Open->Nbytes.QuadPart+=12; + + NdisReleaseSpinLock( &Open->CountersLock ); + + if(!(Open->mode & MODE_DUMP)){ + return NDIS_STATUS_NOT_ACCEPTED; + } + } + + if(Open->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED; + + if(Open->mode & MODE_DUMP && Open->MaxDumpPacks && (UINT)Open->Accepted > Open->MaxDumpPacks){ + // Reached the max number of packets to save in the dump file. Discard the packet and stop the dump thread. + Open->DumpLimitReached = TRUE; // This stops the thread + // Awake the dump thread + NdisSetEvent(&Open->DumpEvent); + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return NDIS_STATUS_NOT_ACCEPTED; + } + + // Calculate the correct size for the header associated with the packet + NPFHdrSize=(Open->mode==MODE_CAPT)? sizeof(struct bpf_hdr): sizeof(struct sf_pkthdr); + + NdisAcquireSpinLock( &Open->BufLock ); + + Thead=Open->Bhead; + Ttail=Open->Btail; + TLastByte = Open->BLastByte; + + NdisReleaseSpinLock( &Open->BufLock ); + + maxbufspace=Packet_WORDALIGN(fres+NPFHdrSize); + + if(Ttail+maxbufspace >= Open->BufSize){ + if(Thead <= maxbufspace) + { + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + else{ + Ttail=0; + ResetBuff = TRUE; + } + } + + if (Thead > Ttail && (Thead-Ttail) <= maxbufspace) + { + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + + CurrBuff=Open->Buffer+Ttail; + + if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize) + { + // Allocate an MDL to map the portion of the buffer following the header + pMdl=IoAllocateMdl(CurrBuff+HeaderBufferSize+LookaheadBufferSize+NPFHdrSize, + maxbufspace, + FALSE, + FALSE, + NULL); + + if (pMdl == NULL) + { + // Unable to map the memory: packet lost + IF_LOUD(DbgPrint("NPF: Read-Failed to allocate Mdl\n");) + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + MmBuildMdlForNonPagedPool(pMdl); + + //allocate the packet from NDIS + NdisAllocatePacket(&Status, &pPacketb, Open->PacketPool); + if (Status != NDIS_STATUS_SUCCESS) + { + IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");) + IoFreeMdl(pMdl); + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + //link the buffer to the packet + NdisChainBufferAtFront(pPacketb,pMdl); + + BufferLength=fres-HeaderBufferSize; + //Find out how much to transfer + SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength; + + //copy the ethernet header into buffer + NdisMoveMappedMemory((CurrBuff)+NPFHdrSize,HeaderBuffer,HeaderBufferSize); + + //Copy the look ahead buffer + if(LookaheadBufferSize) + { + NdisMoveMappedMemory((CurrBuff) + NPFHdrSize + HeaderBufferSize, + LookAheadBuffer, + (SizeToTransfer < LookaheadBufferSize)? SizeToTransfer : LookaheadBufferSize ); + + SizeToTransfer = (SizeToTransfer > LookaheadBufferSize)? + SizeToTransfer - LookaheadBufferSize : 0; + } + + Open->TransferMdl=pMdl; + + if(SizeToTransfer) + { + //Call the Mac to transfer the packet + NdisTransferData(&Status, + Open->AdapterHandle, + MacReceiveContext, + LookaheadBufferSize, + SizeToTransfer, + pPacketb, + &BytesTransfered); + } + else{ + BytesTransfered = 0; + } + + } + else + { + // The whole packet is in the lookahead buffer, we can avoid the call to NdisTransferData. + // This allows us to avoid the allocation of the MDL and the NDIS packet as well + RtlCopyMemory((CurrBuff) + NPFHdrSize, + HeaderBuffer, + HeaderBufferSize + LookaheadBufferSize); + + BytesTransfered = 0; + + Open->TransferMdl = NULL; + Status = NDIS_STATUS_SUCCESS; + } + + if (Status != NDIS_STATUS_FAILURE) + { + + Open->Accepted++; // Increase the accepted packets counter + + if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) ) + fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize; + + // + // Build the header + // + header=(struct bpf_hdr*)CurrBuff; + GET_TIME(&header->bh_tstamp,&G_Start_Time); + header->bh_caplen=fres; + header->bh_datalen=PacketSize+HeaderBufferSize; + if(Open->mode==MODE_CAPT){ + header->bh_hdrlen=NPFHdrSize; + // Don't align if the packet goes to disk + Ttail+=Packet_WORDALIGN(fres + NPFHdrSize); + } + else + Ttail+=fres+NPFHdrSize; + + //update the buffer + NdisAcquireSpinLock( &Open->BufLock ); + + if(ResetBuff){ + Open->BLastByte = Open->Btail; + } + Open->Btail=Ttail; + + NdisReleaseSpinLock( &Open->BufLock ); + } + + if (Status != NDIS_STATUS_PENDING){ + + if( Open->TransferMdl != NULL) + // Complete the request and free the buffers + NPF_TransferDataComplete(Open,pPacketb,Status,fres); + else{ + // Unfreeze the consumer + if(GetBuffOccupation(Open)>Open->MinToCopy){ + if(Open->mode & MODE_DUMP){ + NdisSetEvent(&Open->DumpEvent); + } + else + KeSetEvent(Open->ReadEvent,0,FALSE); + } + + } + } + + return NDIS_STATUS_SUCCESS; + +} + +//------------------------------------------------------------------- + +VOID NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status,IN UINT BytesTransfered) +{ + POPEN_INSTANCE Open; + + IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + IoFreeMdl(Open->TransferMdl); + //recylcle the packet + NdisReinitializePacket(pPacket); + //Put the packet on the free queue + NdisFreePacket(pPacket); + // Unfreeze the consumer + if(GetBuffOccupation(Open)>Open->MinToCopy){ + if(Open->mode & MODE_DUMP){ + NdisSetEvent(&Open->DumpEvent); + } + else + KeSetEvent(Open->ReadEvent,0,FALSE); + } + return; +} + +//------------------------------------------------------------------- + +VOID NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext) +{ + IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");) + return; +} diff --git a/drivers/net/npf/resource.h b/drivers/net/npf/resource.h new file mode 100644 index 0000000..d704eca --- /dev/null +++ b/drivers/net/npf/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by NPF.RC +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/drivers/net/npf/tcp_session.c b/drivers/net/npf/tcp_session.c new file mode 100644 index 0000000..4eb6410 --- /dev/null +++ b/drivers/net/npf/tcp_session.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#include "tcp_session.h" +#endif + +#ifdef __FreeBSD + +#ifdef _KERNEL +#include +#include +#else +#include +#include +#endif + +#endif + +uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data) + +{ + + uint32 next_status; + uint32 direction=ULONG_AT(mem_data,12); + uint8 flags=mem_ex->buffer[25]; + tcp_data *session=(tcp_data*)(block+data->key_len*4); + + session->last_timestamp=session->timestamp_block; + session->timestamp_block.tv_sec=0x7fffffff; + + if (direction==session->direction) + { + session->pkts_cln_to_srv++; + session->bytes_cln_to_srv+=pkt_size; + } + else + { + session->pkts_srv_to_cln++; + session->bytes_srv_to_cln+=pkt_size; + } + /* we use only thes four flags, we don't need PSH or URG */ + flags&=(ACK|FIN|SYN|RST); + + switch (session->status) + { + case ERROR_TCP: + next_status=ERROR_TCP; + break; + + case UNKNOWN: + if (flags==SYN) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=0) + { + + next_status=ERROR_TCP; + break; + } + next_status=SYN_RCV; + session->syn_timestamp=session->last_timestamp; + + session->direction=direction; + session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16); + } + else + next_status=UNKNOWN; + break; + + case SYN_RCV: + if ((flags&RST)&&(direction!=session->direction)) + { + next_status=CLOSED_RST; + break; + } + if ((flags==SYN)&&(direction==session->direction)) + { /* two syns... */ + next_status=SYN_RCV; + session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16); + break; + } + + if ((flags==(SYN|ACK))&&(direction!=session->direction)) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_cln+1) + { + next_status=ERROR_TCP; + break; + } + next_status=SYN_ACK_RCV; + + session->syn_ack_timestamp=session->last_timestamp; + + session->seq_n_0_srv=SW_ULONG_AT(mem_ex->buffer,16); + session->ack_cln=session->seq_n_0_cln+1; + } + else + { + next_status=ERROR_TCP; + } + break; + + case SYN_ACK_RCV: + if ((flags&ACK)&&(flags&RST)&&(direction==session->direction)) + { + next_status=CLOSED_RST; + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,20); + break; + } + + if ((flags==ACK)&&(!(flags&(SYN|FIN|RST)))&&(direction==session->direction)) + { + if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_srv+1) + { + next_status=ERROR_TCP; + break; + } + next_status=ESTABLISHED; + session->ack_srv=session->seq_n_0_srv+1; + break; + } + if ((flags&ACK)&&(flags&SYN)&&(direction!=session->direction)) + { + next_status=SYN_ACK_RCV; + break; + } + + next_status=ERROR_TCP; + break; + + case ESTABLISHED: + if (flags&SYN) + { + if ((flags&ACK)&& + (direction!=session->direction)&& + ((session->ack_cln-SW_ULONG_AT(mem_ex->buffer,20))direction)&& + (SW_ULONG_AT(mem_ex->buffer,16)==session->seq_n_0_cln)&& + (ULONG_AT(mem_ex->buffer,20)==0) + ) + { /* syn duplicato */ + next_status=ESTABLISHED; + break; + } + + next_status=ERROR_TCP; + break; + } + if (flags&ACK) + if (direction==session->direction) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (new_ack-session->ack_srvack_srv=new_ack; + } + else + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (new_ack-session->ack_clnack_cln=new_ack; + } + if (flags&RST) + { + next_status=CLOSED_RST; + break; + } + if (flags&FIN) + if (direction==session->direction) + { /* an hack to make all things work */ + session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16); + next_status=FIN_CLN_RCV; + break; + } + else + { + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16); + next_status=FIN_SRV_RCV; + break; + } + next_status=ESTABLISHED; + break; + + case CLOSED_RST: + next_status=CLOSED_RST; + break; + + case FIN_SRV_RCV: + if (flags&SYN) + { + next_status=ERROR_TCP; + break; + } + + next_status=FIN_SRV_RCV; + + if (flags&ACK) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (direction!=session->direction) + if ((new_ack-session->ack_cln)ack_cln=new_ack; + } + + if (flags&RST) + next_status=CLOSED_RST; + else + if ((flags&FIN)&&(direction==session->direction)) + { + session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16); + next_status=CLOSED_FIN; + } + + break; + + case FIN_CLN_RCV: + if (flags&SYN) + { + next_status=ERROR_TCP; + break; + } + + next_status=FIN_CLN_RCV; + + if (flags&ACK) + { + uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20); + if (direction==session->direction) + if (new_ack-session->ack_srvack_srv=new_ack; + } + + if (flags&RST) + next_status=CLOSED_RST; + else + if ((flags&FIN)&&(direction!=session->direction)) + { + session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16); + next_status=CLOSED_FIN; + } + + break; + + case CLOSED_FIN: + next_status=CLOSED_FIN; + break; + default: + next_status=ERROR_TCP; + + } + + session->status=next_status; + + if ((next_status==CLOSED_FIN)||(next_status==UNKNOWN)||(next_status==CLOSED_RST)||(next_status==ERROR_TCP)) + session->timestamp_block=session->last_timestamp; + + return TME_SUCCESS; +} \ No newline at end of file diff --git a/drivers/net/npf/tcp_session.h b/drivers/net/npf/tcp_session.h new file mode 100644 index 0000000..6262e79 --- /dev/null +++ b/drivers/net/npf/tcp_session.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __tcp_session +#define __tcp_session + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +#define UNKNOWN 0 +#define SYN_RCV 1 +#define SYN_ACK_RCV 2 +#define ESTABLISHED 3 +#define CLOSED_RST 4 +#define FIN_CLN_RCV 5 +#define FIN_SRV_RCV 6 +#define CLOSED_FIN 7 +#define ERROR_TCP 8 +#define FIRST_IS_CLN 0 +#define FIRST_IS_SRV 0xffffffff +#define FIN_CLN 1 +#define FIN_SRV 2 + +#define MAX_WINDOW 65536 + +typedef struct __tcp_data +{ + struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/ + struct timeval syn_timestamp; + struct timeval last_timestamp; + struct timeval syn_ack_timestamp; + uint32 direction; + uint32 seq_n_0_srv; + uint32 seq_n_0_cln; + uint32 ack_srv; /* acknowledge of (data sent by server) */ + uint32 ack_cln; /* acknowledge of (data sent by client) */ + uint32 status; + uint32 pkts_cln_to_srv; + uint32 pkts_srv_to_cln; + uint32 bytes_srv_to_cln; + uint32 bytes_cln_to_srv; + uint32 close_state; +} + tcp_data; + +#define FIN 1 +#define SYN 2 +#define RST 4 +#define PSH 8 +#define ACK 16 +#define URG 32 + +#define TCP_SESSION 0x00000800 +uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); + +#endif \ No newline at end of file diff --git a/drivers/net/npf/time_calls.c b/drivers/net/npf/time_calls.c new file mode 100644 index 0000000..0e42697 --- /dev/null +++ b/drivers/net/npf/time_calls.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "tme.h" +#include "win_bpf.h" +#include "time_calls.h" + + +void TIME_DESYNCHRONIZE(struct time_conv *data) +{ + data->reference = 0; + data->start.tv_sec = 0; + data->start.tv_usec = 0; +} + +#ifdef KQPC_TS + +/* KeQueryPerformanceCounter TimeStamps */ + +VOID TIME_SYNCHRONIZE(struct time_conv *data) +{ + struct timeval tmp; + LARGE_INTEGER SystemTime; + LARGE_INTEGER i; + ULONG tmp2; + LARGE_INTEGER TimeFreq,PTime; + + if (data->reference!=0) + return; + + // get the absolute value of the system boot time. + PTime=KeQueryPerformanceCounter(&TimeFreq); + KeQuerySystemTime(&SystemTime); +#ifndef __GNUC__ + tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600); + tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10); + tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart); + tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); +#else + // TODO FIXME: +#endif + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + data->reference=1; +} + +void FORCE_TIME(struct timeval *src, struct time_conv *dest) +{ + dest->start=*src; +} + +void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + LARGE_INTEGER PTime, TimeFreq; + LONG tmp; + + PTime=KeQueryPerformanceCounter(&TimeFreq); +#ifndef __GNUC__ + tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart); + dst->tv_sec=data->start.tv_sec+tmp; + dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); +#else + // TODO FIXME: +#endif + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } +} + +#else /*KQPC_TS*/ + +/*RDTSC timestamps*/ + +/* callers must be at IRQL=PASSIVE_LEVEL */ +VOID TIME_SYNCHRONIZE(struct time_conv *data) +{ + struct timeval tmp; + LARGE_INTEGER system_time; + ULONGLONG curr_ticks; + KIRQL old; + LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; + ULONGLONG start_ticks,stop_ticks; + ULONGLONG delta,delta2; + KEVENT event; + LARGE_INTEGER i; + ULONGLONG reference; + + if (data->reference!=0) + return; + + KeInitializeEvent(&event,NotificationEvent,FALSE); + i.QuadPart=-3500000; + KeRaiseIrql(HIGH_LEVEL,&old); + start_kqpc=KeQueryPerformanceCounter(&start_freq); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, start_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(start_ticks): ); +#endif + KeLowerIrql(old); + KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); + KeRaiseIrql(HIGH_LEVEL,&old); + stop_kqpc=KeQueryPerformanceCounter(&stop_freq); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, stop_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(stop_ticks): ); +#endif + KeLowerIrql(old); + delta=stop_ticks-start_ticks; + delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; + if (delta>10000000000) { + delta/=16; + delta2/=16; + } + reference=delta*(start_freq.QuadPart)/delta2; + data->reference=reference/1000; + if (reference%1000>500) + data->reference++; + data->reference*=1000; + reference=data->reference; + KeQuerySystemTime(&system_time); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, curr_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(curr_ticks): ); +#endif + tmp.tv_sec=-(LONG)(curr_ticks/reference); + tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); + system_time.QuadPart-=116444736000000000; + tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); + tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) +} + +void FORCE_TIME(struct timeval *src, struct time_conv *dest) +{ + dest->start=*src; +} + +void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + ULONGLONG tmp; +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, tmp + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(tmp): ); +#endif + if (data->reference==0) { + return; + } + dst->tv_sec=(LONG)(tmp/data->reference); + dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); + dst->tv_sec+=data->start.tv_sec; + dst->tv_usec+=data->start.tv_usec; + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } +} + +#endif /*KQPC_TS*/ diff --git a/drivers/net/npf/time_calls.h b/drivers/net/npf/time_calls.h new file mode 100644 index 0000000..04731cf --- /dev/null +++ b/drivers/net/npf/time_calls.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _time_calls +#define _time_calls + +#ifdef WIN_NT_DRIVER + +#include "debug.h" + +/*! + \brief A microsecond precise timestamp. + + included in the sf_pkthdr or the bpf_hdr that NPF associates with every packet. +*/ + +struct timeval { + long tv_sec; ///< seconds + long tv_usec; ///< microseconds +}; + +#endif /*WIN_NT_DRIVER*/ + +struct time_conv { + ULONGLONG reference; + struct timeval start; +}; + +#ifdef __GNUC__ + +void TIME_DESYNCHRONIZE(struct time_conv *data); +VOID TIME_SYNCHRONIZE(struct time_conv *data); +void FORCE_TIME(struct timeval *src, struct time_conv *dest); +void GET_TIME(struct timeval *dst, struct time_conv *data); + +#else /* __GNUC__ */ + +#ifdef WIN_NT_DRIVER + +__inline void TIME_DESYNCHRONIZE(struct time_conv *data) +{ + data->reference = 0; + data->start.tv_sec = 0; + data->start.tv_usec = 0; +} + +#ifdef KQPC_TS + +/* KeQueryPerformanceCounter TimeStamps */ + +__inline VOID TIME_SYNCHRONIZE(struct time_conv *data) +{ + struct timeval tmp; + LARGE_INTEGER SystemTime; + LARGE_INTEGER i; + ULONG tmp2; + LARGE_INTEGER TimeFreq,PTime; + + if (data->reference!=0) + return; + + // get the absolute value of the system boot time. + PTime=KeQueryPerformanceCounter(&TimeFreq); + KeQuerySystemTime(&SystemTime); + tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600); + tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10); + tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart); + tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + data->reference=1; +} + +__inline void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + LARGE_INTEGER PTime, TimeFreq; + LONG tmp; + + PTime=KeQueryPerformanceCounter(&TimeFreq); + tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart); + dst->tv_sec=data->start.tv_sec+tmp; + dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } +} + +__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) +{ + dest->start=*src; +} + +#else + +/*RDTSC timestamps*/ + +/* callers must be at IRQL=PASSIVE_LEVEL */ +__inline VOID TIME_SYNCHRONIZE(struct time_conv *data) +{ + struct timeval tmp; + LARGE_INTEGER system_time; + ULONGLONG curr_ticks; + KIRQL old; + LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; + ULONGLONG start_ticks,stop_ticks; + ULONGLONG delta,delta2; + KEVENT event; + LARGE_INTEGER i; + ULONGLONG reference; + + if (data->reference!=0) + return; + + KeInitializeEvent(&event,NotificationEvent,FALSE); + i.QuadPart=-3500000; + KeRaiseIrql(HIGH_LEVEL,&old); + start_kqpc=KeQueryPerformanceCounter(&start_freq); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, start_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else +#endif + KeLowerIrql(old); + KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); + KeRaiseIrql(HIGH_LEVEL,&old); + stop_kqpc=KeQueryPerformanceCounter(&stop_freq); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, stop_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else +#endif + KeLowerIrql(old); + delta=stop_ticks-start_ticks; + delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; + if (delta>10000000000) { + delta/=16; + delta2/=16; + } + reference=delta*(start_freq.QuadPart)/delta2; + data->reference=reference/1000; + if (reference%1000>500) + data->reference++; + data->reference*=1000; + reference=data->reference; + KeQuerySystemTime(&system_time); +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, curr_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else +#endif + tmp.tv_sec=-(LONG)(curr_ticks/reference); + tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); + system_time.QuadPart-=116444736000000000; + tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); + tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) +} + +__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) +{ + dest->start=*src; +} + +__inline void GET_TIME(struct timeval *dst, struct time_conv *data) +{ + ULONGLONG tmp; +#ifndef __GNUC__ + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, tmp + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } +#else +#endif + if (data->reference==0) { + return; + } + dst->tv_sec=(LONG)(tmp/data->reference); + dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); + dst->tv_sec+=data->start.tv_sec; + dst->tv_usec+=data->start.tv_usec; + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } +} + +#endif /*KQPC_TS*/ + +#endif /*WIN_NT_DRIVER*/ + +#endif /* __GNUC__ */ + +#endif /*_time_calls*/ diff --git a/drivers/net/npf/tme.c b/drivers/net/npf/tme.c new file mode 100644 index 0000000..87ed7dc --- /dev/null +++ b/drivers/net/npf/tme.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ +#include +#endif + +/* resizes extended memory */ +uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex) +{ + uint8 *tmp; + + if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0)) + return TME_ERROR; /* awfully never reached!!!! */ + + tmp=mem_ex->buffer; + mem_ex->buffer=NULL; + FREE_MEMORY(tmp); + + ALLOCATE_MEMORY(tmp,uint8,size); + if (tmp==NULL) + return TME_ERROR; /* no memory */ + + mem_ex->size=size; + mem_ex->buffer=tmp; + return TME_SUCCESS; + +} + +/* activates a block of the TME */ +uint32 set_active_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active=block; + tme->working=block; + return TME_SUCCESS; + +} + +/* simply inserts default values in a TME block */ +/* it DOESN'T initialize the block in the core!! */ +/* FIXME default values are defined at compile time, */ +/* it will be useful to store them in the registry */ +uint32 init_tme_block(TME_CORE *tme, uint32 block) +{ + + TME_DATA *data; + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&(tme->block_data[block]); + tme->working=block; + + ZERO_MEMORY(data,sizeof(TME_DATA)); + + /* entries in LUT */ + data->lut_entries=TME_LUT_ENTRIES_DEFAULT; + /* blocks */ + data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT; + /* block size */ + data->block_size=TME_BLOCK_SIZE_DEFAULT; + /* lookup function */ + data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT); + /* rehashing value */ + data->rehashing_value=TME_REHASHING_VALUE_DEFAULT; + /* out lut function */ + data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT; + /* default function */ + data->default_exec=TME_DEFAULT_EXEC_DEFAULT; + /* extra segment size */ + data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT; + + + data->enable_deletion=FALSE; + data->last_read.tv_sec=0; + data->last_read.tv_usec=0; + return TME_SUCCESS; + +} +/* it validates a TME block and */ +/* (on OK) inserts the block in the core */ +uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset) +{ + uint32 required_memory; + uint8 *base=mem_ex_offset+mem_ex->buffer; + TME_DATA *data; + + /* FIXME soluzione un po' posticcia... */ + if (mem_ex_offset==0) + return TME_ERROR; + + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&tme->block_data[block]; + + if (data->lut_entries==0) + return TME_ERROR; + + if (data->key_len==0) + return TME_ERROR; + + if (data->shared_memory_blocks==0) + return TME_ERROR; + + if (data->block_size==0) + return TME_ERROR; + + /* checks if the lookup function is valid */ + if (data->lookup_code==NULL) + return TME_ERROR; + + /* checks if the out lut exec function is valid */ + if (exec_fcn_mapper(data->out_lut_exec)==NULL) + return TME_ERROR; + + /* checks if the default exec function is valid */ + if (exec_fcn_mapper(data->default_exec)==NULL) + return TME_ERROR; + + /* let's calculate memory needed */ + required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/ + required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/ + required_memory+=data->extra_segment_size; /*extra segment*/ + + if (required_memory>(mem_ex->size-mem_ex_offset)) + return TME_ERROR; /*not enough memory*/ + + /* the TME block can be initialized */ + ZERO_MEMORY(base,required_memory); + + data->lut_base_address=base; + + data->shared_memory_base_address= + data->lut_base_address+ + data->lut_entries*sizeof(RECORD); + + data->extra_segment_base_address= + data->shared_memory_base_address+ + data->block_size*data->shared_memory_blocks; + data->filled_blocks=1; + VALIDATE(tme->validated_blocks,block); + tme->active=block; + tme->working=block; + return TME_SUCCESS; +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref) +{ + if (tme->active==TME_NONE_ACTIVE) + return TME_FALSE; + + return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref); +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset) +{ + + exec_fcn tmp; + TME_DATA *data; + uint8 *block; + uint8 *mem_data; + + if (tme->active==TME_NONE_ACTIVE) + return TME_ERROR; + + data=&tme->block_data[tme->active]; + + if (data->last_found==NULL) + { /*out lut exec */ + tmp=exec_fcn_mapper(data->out_lut_exec); + block=data->shared_memory_base_address; + } + else + { /*checks if last_found is valid */ + if ((data->last_foundlut_base_address)||(data->last_found>=data->shared_memory_base_address)) + return TME_ERROR; + else + { + tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0)); + if (tmp==NULL) + return TME_ERROR; + block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer; + if ((blockshared_memory_base_address)||(block>=data->extra_segment_base_address)) + return TME_ERROR; + } + } + + if (offset>=mem_ex->size) + return TME_ERROR; + + mem_data=mem_ex->buffer+offset; + + return tmp(block,pkt_size,data,mem_ex,mem_data); +} + +/*resets all the TME core*/ +uint32 reset_tme(TME_CORE *tme) +{ + if (tme==NULL) + return TME_ERROR; + ZERO_MEMORY(tme, sizeof(TME_CORE)); + return TME_SUCCESS; +} + +/* returns a register value of the active TME block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval) +{ + switch(rgstr) + { + case TME_LUT_ENTRIES: + *rval=data->lut_entries; + return TME_SUCCESS; + case TME_MAX_FILL_STATE: + *rval=data->max_fill_state; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + *rval=data->rehashing_value; + return TME_SUCCESS; + case TME_KEY_LEN: + *rval=data->key_len; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + *rval=data->shared_memory_blocks; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + *rval=data->filled_entries; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + *rval=data->block_size; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + *rval=data->extra_segment_size; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + *rval=data->filled_blocks; + return TME_SUCCESS; + case TME_DEFAULT_EXEC: + *rval=data->default_exec; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + *rval=data->out_lut_exec; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BASE_ADDRESS: + *rval=data->shared_memory_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LUT_BASE_ADDRESS: + *rval=data->lut_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_BASE_ADDRESS: + *rval=data->extra_segment_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LAST_FOUND_BLOCK: + if (data->last_found==NULL) + *rval=0; + else + *rval=data->last_found-mem_ex->buffer; + return TME_SUCCESS; + + default: + return TME_ERROR; + } +} + +/* sets a register value in the active block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init) +{ /* very very very dangerous!!!!!!!!!!! */ + lut_fcn tmp; + switch(rgstr) + { + case TME_MAX_FILL_STATE: + data->max_fill_state=value; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + data->rehashing_value=value; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + data->filled_entries=value; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + if (value<=data->shared_memory_blocks) + { + data->filled_blocks=value; + return TME_SUCCESS; + } + else + return TME_ERROR; + case TME_DEFAULT_EXEC: + data->default_exec=value; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + data->out_lut_exec=value; + return TME_SUCCESS; + case TME_LOOKUP_CODE: + tmp=lut_fcn_mapper(value); + if (tmp==NULL) + return TME_ERROR; + else + data->lookup_code=tmp; + return TME_SUCCESS; + default: + break; + } + + if (init) + switch (rgstr) + { + + case TME_LUT_ENTRIES: + data->lut_entries=value; + return TME_SUCCESS; + case TME_KEY_LEN: + data->key_len=value; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + data->shared_memory_blocks=value; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + data->block_size=value; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + data->extra_segment_size=value; + return TME_SUCCESS; + default: + return TME_ERROR; + } + else + return TME_ERROR; + +} + +/* chooses the TME block for read */ +uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active_read=block; + return TME_SUCCESS; + +} + +/* chooses if the autodeletion must be used */ +uint32 set_autodeletion(TME_DATA *data, uint32 value) +{ + if (value==0) /* no autodeletion */ + data->enable_deletion=FALSE; + else + data->enable_deletion=TRUE; + + return TME_SUCCESS; +} \ No newline at end of file diff --git a/drivers/net/npf/tme.h b/drivers/net/npf/tme.h new file mode 100644 index 0000000..4140f9f --- /dev/null +++ b/drivers/net/npf/tme.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __tme_include_ +#define __tme_include_ + +#ifdef WIN_NT_DRIVER + +#include "ntddk.h" +#include "memory_t.h" +#include "time_calls.h" +#endif /*WIN_NT_DRIVER*/ + +#ifdef WIN32 +#include "memory_t.h" +#include "time_calls.h" +#endif /*WIN32*/ + + + +#ifdef __FreeBSD__ + +#ifdef _KERNEL +#include +#else +#include +#endif + +#endif + +/* error codes */ +#define TME_ERROR 0 +#define TME_SUCCESS 1 +#define TME_TRUE 2 +#define TME_FALSE 3 + +/* some constants */ +#define DEFAULT_MEM_EX_SIZE 65536 +#define MAX_TME_DATA_BLOCKS 4 +#define TME_NONE_ACTIVE 0xffffffff +#define DELTA_READ 2 /* secs */ + +#define TME_LUT_ENTRIES 0x00000000 +#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */ +#define TME_REHASHING_VALUE 0x00000002 +#define TME_KEY_LEN 0x00000003 +#define TME_SHARED_MEMORY_BLOCKS 0x00000004 +#define TME_FILLED_ENTRIES 0x00000005 +#define TME_BLOCK_SIZE 0x00000006 +#define TME_EXTRA_SEGMENT_SIZE 0x00000007 +#define TME_LOOKUP_CODE 0x00000008 +#define TME_OUT_LUT_EXEC 0x00000009 +#define TME_FILLED_BLOCKS 0x0000000a +#define TME_DEFAULT_EXEC 0x0000000b +#define TME_LUT_BASE_ADDRESS 0x0000000c +#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d +#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e +#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */ +#define TME_LAST_FOUND_BLOCK 0x00000010 +/* TME default values */ +#define TME_LUT_ENTRIES_DEFAULT 32007 +#define TME_REHASHING_VALUE_DEFAULT 1 +#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000 +#define TME_BLOCK_SIZE_DEFAULT 64 +#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0 +#define TME_LOOKUP_CODE_DEFAULT 0 +#define TME_OUT_LUT_EXEC_DEFAULT 0 +#define TME_DEFAULT_EXEC_DEFAULT 0 +#define TME_MAX_FILL_STATE_DEFAULT 15000 + +#define IS_VALIDATED(src,index) (src&(1<tv_sec=0x7fffffff; + +/* TME callback prototypes */ +#ifndef __GNUC__ +typedef uint32 (*lut_fcn)(uint8 *key, struct __TME_DATA *data,MEM_TYPE *mem_ex, struct time_conv *time_ref ); +typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, struct __TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); +#else +typedef uint32 (*lut_fcn)(uint8 *key, void *data,MEM_TYPE *mem_ex, struct time_conv *time_ref ); +typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, void *data, MEM_TYPE *mem_ex, uint8 *mem_data); +#endif + +/* DO NOT MODIFY THIS STRUCTURE!!!! GV */ +typedef struct __RECORD + +{ + uint32 block; + uint32 exec_fcn; +} + RECORD, *PRECORD; + +/* TME data registers */ +struct __TME_DATA +{ + uint32 lut_entries; + uint32 max_fill_state; + uint32 rehashing_value; + uint32 key_len; + uint32 shared_memory_blocks; + uint32 filled_entries; + uint32 block_size; + uint32 extra_segment_size; + uint32 filled_blocks; + lut_fcn lookup_code; + uint32 default_exec; + uint32 out_lut_exec; + uint8 *lut_base_address; + uint8 *shared_memory_base_address; + uint8 *extra_segment_base_address; + struct timeval last_read; + uint32 enable_deletion; + uint8 *last_found; +}; + +typedef struct __TME_DATA TME_DATA,*PTME_DATA; + + + +/* TME core */ +typedef struct __TME_CORE +{ + uint32 working; + uint32 active; + uint32 validated_blocks; + TME_DATA block_data[MAX_TME_DATA_BLOCKS]; + uint32 active_read; + +} TME_CORE, *PTME_CORE; + +static __inline int32 IS_DELETABLE(void *timestamp, TME_DATA *data) +{ + struct timeval *ts=(struct timeval*)timestamp; + + if (data->enable_deletion==FALSE) + return FALSE; + if (data->filled_entriesmax_fill_state) + return FALSE; + if ((ts->tv_sec+DELTA_READ)last_read.tv_sec) + return TRUE; + return FALSE; +} + +/* functions to manage TME */ +uint32 init_tme_block(TME_CORE *tme, uint32 block); +uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset); +uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref); +uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size,uint32 offset); +uint32 set_active_tme_block(TME_CORE *tme, uint32 block); +uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex); +uint32 reset_tme(TME_CORE *tme); +uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval); +uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init); +uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block); +uint32 set_autodeletion(TME_DATA *data, uint32 value); + +/* function mappers */ +lut_fcn lut_fcn_mapper(uint32 index); +exec_fcn exec_fcn_mapper(uint32 index); + +#endif \ No newline at end of file diff --git a/drivers/net/npf/valid_insns.h b/drivers/net/npf/valid_insns.h new file mode 100644 index 0000000..20b115d --- /dev/null +++ b/drivers/net/npf/valid_insns.h @@ -0,0 +1,73 @@ +u_short valid_instructions[]= + { + BPF_RET|BPF_K, + BPF_RET|BPF_A, + BPF_LD|BPF_IMM, + BPF_LDX|BPF_IMM, + BPF_LD|BPF_MEM, + BPF_LDX|BPF_MEM, + BPF_LD|BPF_MEM_EX_IMM|BPF_B, + BPF_LD|BPF_MEM_EX_IMM|BPF_H, + BPF_LD|BPF_MEM_EX_IMM|BPF_W, + BPF_LD|BPF_MEM_EX_IND|BPF_B, + BPF_LD|BPF_MEM_EX_IND|BPF_H, + BPF_LD|BPF_MEM_EX_IND|BPF_W, + BPF_LD|BPF_W|BPF_ABS, + BPF_LD|BPF_H|BPF_ABS, + BPF_LD|BPF_B|BPF_ABS, + BPF_LDX|BPF_W|BPF_ABS, + BPF_LDX|BPF_H|BPF_ABS, + BPF_LDX|BPF_B|BPF_ABS, + BPF_LD|BPF_W|BPF_LEN, + BPF_LDX|BPF_W|BPF_LEN, + BPF_LD|BPF_W|BPF_IND, + BPF_LD|BPF_H|BPF_IND, + BPF_LD|BPF_B|BPF_IND, + BPF_LDX|BPF_MSH|BPF_B, + BPF_ST, + BPF_STX, + BPF_ST|BPF_MEM_EX_IMM|BPF_B, + BPF_STX|BPF_MEM_EX_IMM|BPF_B, + BPF_ST|BPF_MEM_EX_IMM|BPF_W, + BPF_STX|BPF_MEM_EX_IMM|BPF_W, + BPF_ST|BPF_MEM_EX_IMM|BPF_H, + BPF_STX|BPF_MEM_EX_IMM|BPF_H, + BPF_ST|BPF_MEM_EX_IND|BPF_B, + BPF_ST|BPF_MEM_EX_IND|BPF_W, + BPF_ST|BPF_MEM_EX_IND|BPF_H, + BPF_JMP|BPF_JA, + BPF_JMP|BPF_JGT|BPF_K, + BPF_JMP|BPF_JGE|BPF_K, + BPF_JMP|BPF_JEQ|BPF_K, + BPF_JMP|BPF_JSET|BPF_K, + BPF_JMP|BPF_JGT|BPF_X, + BPF_JMP|BPF_JGE|BPF_X, + BPF_JMP|BPF_JEQ|BPF_X, + BPF_JMP|BPF_JSET|BPF_X, + BPF_ALU|BPF_ADD|BPF_X, + BPF_ALU|BPF_SUB|BPF_X, + BPF_ALU|BPF_MUL|BPF_X, + BPF_ALU|BPF_DIV|BPF_X, + BPF_ALU|BPF_AND|BPF_X, + BPF_ALU|BPF_OR|BPF_X, + BPF_ALU|BPF_LSH|BPF_X, + BPF_ALU|BPF_RSH|BPF_X, + BPF_ALU|BPF_ADD|BPF_K, + BPF_ALU|BPF_SUB|BPF_K, + BPF_ALU|BPF_MUL|BPF_K, + BPF_ALU|BPF_DIV|BPF_K, + BPF_ALU|BPF_AND|BPF_K, + BPF_ALU|BPF_OR|BPF_K, + BPF_ALU|BPF_LSH|BPF_K, + BPF_ALU|BPF_RSH|BPF_K, + BPF_ALU|BPF_NEG, + BPF_MISC|BPF_TAX, + BPF_MISC|BPF_TXA, + BPF_MISC|BPF_TME|BPF_LOOKUP, + BPF_MISC|BPF_TME|BPF_EXECUTE, + BPF_MISC|BPF_TME|BPF_SET_ACTIVE, + BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE, + BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE + }; + +#define VALID_INSTRUCTIONS_LEN (sizeof(valid_instructions)/sizeof(u_short)) diff --git a/drivers/net/npf/win_bpf.h b/drivers/net/npf/win_bpf.h new file mode 100644 index 0000000..7dc5f14 --- /dev/null +++ b/drivers/net/npf/win_bpf.h @@ -0,0 +1,325 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * @(#) $Header$ (LBL) + */ + +#ifndef BPF_MAJOR_VERSION + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +typedef UCHAR u_char; +typedef USHORT u_short; +typedef ULONG u_int; +typedef LONG bpf_int32; +typedef ULONG bpf_u_int32; +typedef ULONG u_int32; + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x8000 +#define BPF_MINBUFSIZE 32 + +#include "time_calls.h" + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_int32 k; +}; + +/* + * Structure for BIOCSETF. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * Struct returned by BIOCGSTATS. + */ +struct bpf_stat { + u_int bs_recv; /* number of packets received */ + u_int bs_drop; /* number of packets dropped */ +}; + +/* + * Struct return by BIOCVERSION. This represents the version number of + * the filter language described by the instruction encodings below. + * bpf understands a program iff kernel_major == filter_major && + * kernel_minor >= filter_minor, that is, if the value returned by the + * running kernel has the same major number and a minor number equal + * equal to or less than the filter being downloaded. Otherwise, the + * results are undefined, meaning an error may be returned or packets + * may be accepted haphazardly. + * It has nothing to do with the source code version. + */ +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +/* Current version number of filter architecture. */ +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + + +/* + * Structure prepended to each packet. + */ +struct bpf_hdr { + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; + +/* + * Data-link level type codes. + */ + +/* + * These are the types that are the same on all platforms; on other + * platforms, a should be supplied that defines the additional + * DLT_* codes appropriately for that platform (the BSDs, for example, + * should not just pick up this version of "bpf.h"; they should also define + * the additional DLT_* codes used by their kernels, as well as the values + * defined here - and, if the values they use for particular DLT_ types + * differ from those here, they should use their values, not the ones + * here). + */ +#define DLT_NULL 0 /* no link-layer encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are values from the traditional libpcap "bpf.h". + * Ports of this to particular platforms should replace these definitions + * with the ones appropriate to that platform, if the values are + * different on that platform. + */ +#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ +#define DLT_RAW 12 /* raw IP */ + +/* + * These are values from BSD/OS's "bpf.h". + * These are not the same as the values from the traditional libpcap + * "bpf.h"; however, these values shouldn't be generated by any + * OS other than BSD/OS, so the correct values to use here are the + * BSD/OS values. + * + * Platforms that have already assigned these values to other + * DLT_ codes, however, should give these codes the values + * from that platform, so that programs that use these codes will + * continue to compile - even though they won't correctly read + * files of these types. + */ +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * This value is defined by NetBSD; other platforms should refrain from + * using it for other purposes, so that NetBSD savefiles with a link + * type of 50 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +/* + * Reserved for future use. + * Do not pick other numerical value for these unless you have also + * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c", + * which will arrange that capture files for these DLT_ types have + * the same "network" value on all platforms, regardless of what + * value is chosen for their DLT_ type (thus allowing captures made + * on one platform to be read on other platforms, even if the two + * platforms don't use the same numerical values for all DLT_ types). + */ +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * Values between 106 and 107 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 for any purpose. + */ +#define DLT_LOOP 108 + +/* + * Values between 109 and 112 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * The instruction encodings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* TME instructions */ +#define BPF_TME 0x08 + +#define BPF_LOOKUP 0x90 +#define BPF_EXECUTE 0xa0 +#define BPF_INIT 0xb0 +#define BPF_VALIDATE 0xc0 +#define BPF_SET_ACTIVE 0xd0 +#define BPF_RESET 0xe0 +#define BPF_SET_MEMORY 0x80 +#define BPF_GET_REGISTER_VALUE 0x70 +#define BPF_SET_REGISTER_VALUE 0x60 +#define BPF_SET_WORKING 0x50 +#define BPF_SET_ACTIVE_READ 0x40 +#define BPF_SET_AUTODELETION 0x30 +#define BPF_SEPARATION 0xff + +#define BPF_MEM_EX_IMM 0xc0 +#define BPF_MEM_EX_IND 0xe0 +/*used for ST */ +#define BPF_MEM_EX 0xc0 + + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#endif diff --git a/drivers/net/npf/win_bpf_filter.c b/drivers/net/npf/win_bpf_filter.c new file mode 100644 index 0000000..76dee6e --- /dev/null +++ b/drivers/net/npf/win_bpf_filter.c @@ -0,0 +1,961 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * + * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + + @(#)bpf.c 7.5 (Berkeley) 7/15/91 +*/ + +#include "tme.h" +#include "win_bpf.h" + +#include "debug.h" + +#include "valid_insns.h" + +#define EXTRACT_SHORT(p)\ + ((u_short)\ + ((u_short)*((u_char *)p+0)<<8|\ + (u_short)*((u_char *)p+1)<<0)) +#define EXTRACT_LONG(p)\ + ((u_int32)*((u_char *)p+0)<<24|\ + (u_int32)*((u_char *)p+1)<<16|\ + (u_int32)*((u_char *)p+2)<<8|\ + (u_int32)*((u_char *)p+3)<<0) + + +u_int bpf_filter(pc, p, wirelen, buflen,mem_ex,tme,time_ref) + register struct bpf_insn *pc; + register u_char *p; + u_int wirelen; + register u_int buflen; + PMEM_TYPE mem_ex; + PTME_CORE tme; + struct time_conv *time_ref; + +{ + register u_int32 A, X; + register int k; + u_int32 j,tmp; + u_short tmp2; + + int32 mem[BPF_MEMWORDS]; + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + A = p[k]; + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + X = (p[pc->k] & 0xf) << 2; + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + +/* LD NO PACKET INSTRUCTIONS */ + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + A = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + X = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]); + continue; +/* END LD NO PACKET INSTRUCTIONS */ + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + +/* STORE INSTRUCTIONS */ + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=A; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=X; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)X; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=A; + *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2); + continue; +/* END STORE INSTRUCTIONS */ + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + +/* TME INSTRUCTIONS */ + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR) + return 0; + continue; +/* END TME INSTRUCTIONS */ + + } + } +} + +//------------------------------------------------------------------- + +u_int bpf_filter_with_2_buffers(pc, p, pd, headersize, wirelen, buflen, mem_ex,tme,time_ref) + register struct bpf_insn *pc; + register u_char *p; + register u_char *pd; + register int headersize; + u_int wirelen; + register u_int buflen; + PMEM_TYPE mem_ex; + PTME_CORE tme; + struct time_conv *time_ref; +{ + register u_int32 A, X; + register int k; + int32 mem[BPF_MEMWORDS]; + u_int32 j,tmp; + u_short tmp2; + + if (pc == 0) + /* + * No filter means accept all. + */ + return (u_int)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + + return 0; + + case BPF_RET|BPF_K: + return (u_int)pc->k; + + case BPF_RET|BPF_A: + return (u_int)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int32) > buflen) { + return 0; + } + + if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]); + else if(k + 2 == headersize){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k == headersize-1){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k == headersize){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + + if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]); + else if(k == headersize){ + A=(u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(kk; + if (k + sizeof(int32) > buflen) { + return 0; + } + + if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]); + else if(k + (int)sizeof(int32) == headersize+2){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)p+k+2)<<8| + (u_int32)*((u_char *)pd+k-headersize); + } + else if(k + (int)sizeof(int32) == headersize+3){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)p+k+1)<<16| + (u_int32)*((u_char *)pd+k-headersize)<<8| + (u_int32)*((u_char *)pd+k-headersize+1); + } + else if(k + (int)sizeof(int32) == headersize+4){ + A=(u_int32)*((u_char *)p+k)<<24| + (u_int32)*((u_char *)pd+k-headersize+1)<<16| + (u_int32)*((u_char *)pd+k-headersize+2)<<8| + (u_int32)*((u_char *)pd+k-headersize+3); + } + A = EXTRACT_LONG(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short) > buflen) { + return 0; + } + + if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]); + else if(k == headersize){ + A=(u_short)*((u_char *)p+k)<<8| + (u_short)*((u_char *)pd+k-headersize); + } + A = EXTRACT_SHORT(&pd[k-headersize]); + + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if ((int)k >= (int)buflen) { + return 0; + } + + if(kk; + if ((int)k >= (int)buflen) { + return 0; + } + + if((pc->k)k] & 0xf) << 2; + else X = (pd[(pc->k)-headersize] & 0xf) << 2; + + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + +/* LD NO PACKET INSTRUCTIONS */ + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + A = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + X = EXTRACT_LONG(&mem_ex->buffer[pc->k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]); + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]); + continue; +/* END LD NO PACKET INSTRUCTIONS */ + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + +/* STORE INSTRUCTIONS */ + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=A; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=X; + *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16)X; + *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=A; + *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp); + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16)A; + *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2); + continue; +/* END STORE INSTRUCTIONS */ + + + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int)A = -((int)A); + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + +/* TME INSTRUCTIONS */ + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR) + return 0; + continue; +/* END TME INSTRUCTIONS */ + + } + } +} + +int32 +bpf_validate(f, len,mem_ex_size) + struct bpf_insn *f; + int32 len; + uint32 mem_ex_size; +{ + register int32 i,j; + register struct bpf_insn *p; + int32 flag; + + for (i = 0; i < len; ++i) { + /* + * Check that that jumps are forward, and within + * the code block. + */ + + p = &f[i]; + + IF_LOUD(DbgPrint("Validating program");) + + flag=0; + for(j=0;jcode==valid_instructions[j]) + flag=1; + if (flag==0) + return 0; + + IF_LOUD(DbgPrint("Validating program: no unknown instructions");) + + if (BPF_CLASS(p->code) == BPF_JMP) { + register int32 from = i + 1; + + if (BPF_OP(p->code) == BPF_JA) { + if (from + p->k >= len) + return 0; + } + else if (from + p->jt >= len || from + p->jf >= len) + return 0; + } + + IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");) + + /* + * Check that memory operations use valid addresses. + */ + if (((BPF_CLASS(p->code) == BPF_ST && ((p->code &BPF_MEM_EX_IMM)!=BPF_MEM_EX_IMM && (p->code &BPF_MEM_EX_IND)!=BPF_MEM_EX_IND)) || + (BPF_CLASS(p->code) == BPF_LD && + (p->code & 0xe0) == BPF_MEM)) && + (p->k >= BPF_MEMWORDS || p->k < 0)) + return 0; + + IF_LOUD(DbgPrint("Validating program: no wrong ST/LD memory locations");) + + /* + * Check if key stores use valid addresses + */ + if (BPF_CLASS(p->code) == BPF_ST && (p->code &BPF_MEM_EX_IMM)==BPF_MEM_EX_IMM) + switch (BPF_SIZE(p->code)) + { + case BPF_W: if (p->k<0 || p->k+3>=(int32)mem_ex_size) return 0; + case BPF_H: if (p->k<0 || p->k+1>=(int32)mem_ex_size) return 0; + case BPF_B: if (p->k<0 || p->k>=(int32)mem_ex_size) return 0; + } + + IF_LOUD(DbgPrint("Validating program: no wrong ST/LD mem_ex locations");) + + /* + * Check for constant division by 0. + */ + if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) + return 0; + } + return BPF_CLASS(f[len - 1].code) == BPF_RET; +} \ No newline at end of file diff --git a/drivers/net/npf/win_bpf_filter_init.c b/drivers/net/npf/win_bpf_filter_init.c new file mode 100644 index 0000000..51fb5d4 --- /dev/null +++ b/drivers/net/npf/win_bpf_filter_init.c @@ -0,0 +1,689 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * + * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "tme.h" +#include "win_bpf.h" + +/* + * Initialize the filter machine + */ +uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref) +{ + register uint32 A, X; + int32 mem[BPF_MEMWORDS]; + register int32 k; + uint32 *tmp; + uint16 *tmp2; + uint32 j; + if (pc == 0) + /* + * No filter means accept all. + */ + return (uint32)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + return 0; + +/* RET INSTRUCTIONS */ + case BPF_RET|BPF_K: + return (uint32)pc->k; + + case BPF_RET|BPF_A: + return (uint32)A; +/* END RET INSTRUCTIONS */ + +/* LD NO PACKET INSTRUCTIONS */ + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + tmp2=(uint16*)&mem_ex->buffer[k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + tmp=(uint32*)&mem_ex->buffer[k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; +/* END LD NO PACKET INSTRUCTIONS */ + +/* STORE INSTRUCTIONS */ + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, X + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, X + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k+X]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k+X]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; +/* END STORE INSTRUCTIONS */ + +/* JUMP INSTRUCTIONS */ + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; +/* END JUMP INSTRUCTIONS */ + +/* ARITHMETIC INSTRUCTIONS */ + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int32)A = -((int32)A); + continue; +/* ARITHMETIC INSTRUCTIONS */ + +/* MISC INSTRUCTIONS */ + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; +/* END MISC INSTRUCTIONS */ + +/* TME INSTRUCTIONS */ + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_INIT: + if (init_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_VALIDATE: + if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_MEMORY: + if (init_extended_memory(pc->k,mem_ex)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + case BPF_MISC|BPF_TME|BPF_SET_WORKING: + if ((pc->k<0)||(pc->k>=MAX_TME_DATA_BLOCKS)) + return 0; + tme->working=pc->k; + continue; + + + + case BPF_MISC|BPF_TME|BPF_RESET: + if (reset_tme(tme)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION: + set_autodeletion(&tme->block_data[tme->working],pc->k); + continue; + +/* END TME INSTRUCTIONS */ + + } + } +} + diff --git a/drivers/net/npf/win_bpf_filter_init.h b/drivers/net/npf/win_bpf_filter_init.h new file mode 100644 index 0000000..8b06af7 --- /dev/null +++ b/drivers/net/npf/win_bpf_filter_init.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef __FILTER_INIT +#define __FILTER_INIT + +#include "tme.h" + +#define INIT_OK 1 +#define INIT_ERROR 0 + +uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref); + +#endif \ No newline at end of file diff --git a/drivers/net/npf/write.c b/drivers/net/npf/write.c new file mode 100644 index 0000000..c3c5eb5 --- /dev/null +++ b/drivers/net/npf/write.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 1999, 2000 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef _MSC_VER +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#else +#include +#include +#define NdisReinitializePacket(Packet) \ +{ \ + (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \ + (Packet)->Private.ValidCounts = FALSE; \ +} + +#endif + +#include "debug.h" +#include "packet.h" + + +//------------------------------------------------------------------- + +NTSTATUS STDCALL +NPF_Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) + +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + UINT i; + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("NPF_Write\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + + Open=IrpSp->FileObject->FsContext; + + IF_LOUD(DbgPrint("Max frame size = %d\n", Open->MaxFrameSize);) + + + if(IrpSp->Parameters.Write.Length == 0 || // Check that the buffer provided by the user is not empty + Open->MaxFrameSize == 0 || // Check that the MaxFrameSize is correctly initialized + IrpSp->Parameters.Write.Length > Open->MaxFrameSize) // Check that the fame size is smaller that the MTU + { + IF_LOUD(DbgPrint("frame size out of range, send aborted\n");) + + Irp->IoStatus.Status = NDIS_STATUS_SUCCESS; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + return NDIS_STATUS_SUCCESS; + } + + + IoMarkIrpPending(Irp); + + Open->Multiple_Write_Counter=Open->Nwrites; + + NdisResetEvent(&Open->WriteEvent); + + + for(i=0;iNwrites;i++){ + + // Try to get a packet from our list of free ones + NdisAllocatePacket( + &Status, + &pPacket, + Open->PacketPool + ); + + if (Status != NDIS_STATUS_SUCCESS) { + + // No free packets + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // The packet has a buffer that needs not to be freed after every single write + RESERVED(pPacket)->FreeBufAfterWrite = FALSE; + + // Save the IRP associated with the packet + RESERVED(pPacket)->Irp=Irp; + + // Attach the writes buffer to the packet + NdisChainBufferAtFront(pPacket,Irp->MdlAddress); + + // Call the MAC + NdisSend( + &Status, + Open->AdapterHandle, + pPacket); + + if (Status != NDIS_STATUS_PENDING) { + // The send didn't pend so call the completion handler now + NPF_SendComplete( + Open, + pPacket, + Status + ); + + } + + if(i%100==99){ + NdisWaitEvent(&Open->WriteEvent,1000); + NdisResetEvent(&Open->WriteEvent); + } + } + + return(STATUS_PENDING); + +} + + +//------------------------------------------------------------------- + +INT +NPF_BufferedWrite( + IN PIRP Irp, + IN PCHAR UserBuff, + IN ULONG UserBuffSize, + BOOLEAN Sync) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + UINT i; + NDIS_STATUS Status; + LARGE_INTEGER StartTicks, CurTicks, TargetTicks; + LARGE_INTEGER TimeFreq; + struct timeval BufStartTime; + struct sf_pkthdr *winpcap_hdr; + PMDL TmpMdl; + PCHAR CurPos; + PCHAR EndOfUserBuff = UserBuff + UserBuffSize; + + IF_LOUD(DbgPrint("NPF: BufferedWrite, UserBuff=%x, Size=%u\n", UserBuff, UserBuffSize);) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open=IrpSp->FileObject->FsContext; + + // Security check on the length of the user buffer + if(UserBuff==0) + { + return 0; + } + + // Check that the MaxFrameSize is correctly initialized + if(Open->MaxFrameSize == 0) + { + IF_LOUD(DbgPrint("BufferedWrite: Open->MaxFrameSize not initialized, probably because of a problem in the OID query\n");) + + return 0; + } + + + // Start from the first packet + winpcap_hdr = (struct sf_pkthdr*)UserBuff; + + // Retrieve the time references + StartTicks = KeQueryPerformanceCounter(&TimeFreq); + BufStartTime.tv_sec = winpcap_hdr->ts.tv_sec; + BufStartTime.tv_usec = winpcap_hdr->ts.tv_usec; + + // Chech the consistency of the user buffer + if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct sf_pkthdr) > EndOfUserBuff ) + { + IF_LOUD(DbgPrint("Buffered Write: bogus packet buffer\n");) + + return -1; + } + + // Save the current time stamp counter + CurTicks = KeQueryPerformanceCounter(NULL); + + // Main loop: send the buffer to the wire + while( TRUE ){ + + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > Open->MaxFrameSize) + { + // Malformed header + IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed or bogus user buffer, aborting write.\n");) + + return -1; + } + + // Allocate an MDL to map the packet data + TmpMdl=IoAllocateMdl((PCHAR)winpcap_hdr + sizeof(struct sf_pkthdr), + winpcap_hdr->caplen, + FALSE, + FALSE, + NULL); + + if (TmpMdl == NULL) + { + // Unable to map the memory: packet lost + IF_LOUD(DbgPrint("NPF_BufferedWrite: unable to allocate the MDL.\n");) + + return -1; + } + + MmBuildMdlForNonPagedPool(TmpMdl); // XXX can this line be removed? + + // Allocate a packet from our free list + NdisAllocatePacket( &Status, &pPacket, Open->PacketPool); + + if (Status != NDIS_STATUS_SUCCESS) { + // No free packets + IF_LOUD(DbgPrint("NPF_BufferedWrite: no more free packets, returning.\n");) + + return (PCHAR)winpcap_hdr - UserBuff; + } + + // The packet has a buffer that needs to be freed after every single write + RESERVED(pPacket)->FreeBufAfterWrite = TRUE; + + // Attach the MDL to the packet + NdisChainBufferAtFront(pPacket,TmpMdl); + + // Call the MAC + NdisSend( &Status, Open->AdapterHandle, pPacket); + + if (Status != NDIS_STATUS_PENDING) { + // The send didn't pend so call the completion handler now + NPF_SendComplete( + Open, + pPacket, + Status + ); + } + + // Step to the next packet in the buffer + (PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct sf_pkthdr); + + // Check if the end of the user buffer has been reached + if( (PCHAR)winpcap_hdr >= EndOfUserBuff ) + { + IF_LOUD(DbgPrint("NPF_BufferedWrite: End of buffer.\n");) + + return (PCHAR)winpcap_hdr - UserBuff; + } + + if( Sync ){ + + // Release the application if it has been blocked for approximately more than 1 seconds + if( winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec > 1 ) + { + IF_LOUD(DbgPrint("NPF_BufferedWrite: timestamp elapsed, returning.\n");) + + return (PCHAR)winpcap_hdr - UserBuff; + } + +#ifndef __GNUC__ + // Calculate the time interval to wait before sending the next packet + TargetTicks.QuadPart = StartTicks.QuadPart + + (LONGLONG)((winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec) * 1000000 + + winpcap_hdr->ts.tv_usec - BufStartTime.tv_usec) * + (TimeFreq.QuadPart) / 1000000; + + // Wait until the time interval has elapsed + while( CurTicks.QuadPart <= TargetTicks.QuadPart ) + CurTicks = KeQueryPerformanceCounter(NULL); +#else +#endif + } + + } + + return (PCHAR)winpcap_hdr - UserBuff; + +} + + +//------------------------------------------------------------------- + +VOID +NPF_SendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ) + +{ + PIRP Irp; + PIO_STACK_LOCATION irpSp; + POPEN_INSTANCE Open; + PMDL TmpMdl; + + IF_LOUD(DbgPrint("NPF: SendComplete, BindingContext=%d\n",ProtocolBindingContext);) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + if( RESERVED(pPacket)->FreeBufAfterWrite ){ + // Free the MDL associated with the packet + NdisUnchainBufferAtFront(pPacket, &TmpMdl); + IoFreeMdl(TmpMdl); + } + else{ + if((Open->Nwrites - Open->Multiple_Write_Counter) %100 == 99) + NdisSetEvent(&Open->WriteEvent); + + Open->Multiple_Write_Counter--; + } + + // recyle the packet + NdisReinitializePacket(pPacket); + + // Put the packet back on the free list + NdisFreePacket(pPacket); + + if( !(RESERVED(pPacket)->FreeBufAfterWrite) ){ + if(Open->Multiple_Write_Counter==0){ + // Release the buffer and awake the application + NdisUnchainBufferAtFront(pPacket, &TmpMdl); + + Irp=RESERVED(pPacket)->Irp; + irpSp = IoGetCurrentIrpStackLocation(Irp); + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = irpSp->Parameters.Write.Length; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + } + } + + return; +} + + +#ifdef __GNUC__ +/* +__divdi3() +{ + //_alldiv(); +} + +//_allmul(); +//_allrem(); + +*/ +#endif diff --git a/drivers/net/packet/Makefile b/drivers/net/packet/Makefile index 30fc7e2..24b4fe2 100644 --- a/drivers/net/packet/Makefile +++ b/drivers/net/packet/Makefile @@ -7,7 +7,9 @@ TARGET_TYPE = driver TARGET_NAME = packet -TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS +#TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -I$(PATH_TO_TOP)/ntoskrnl/include + +TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -DUSE_KLOCKS -I$(PATH_TO_TOP)/ntoskrnl/include TARGET_OBJECTS = \ packet.o \ diff --git a/drivers/net/packet/bucket_lookup.h b/drivers/net/packet/bucket_lookup.h index ffe4523..512d637 100644 --- a/drivers/net/packet/bucket_lookup.h +++ b/drivers/net/packet/bucket_lookup.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -35,9 +35,9 @@ #endif -#define BUCKET_LOOKUP_INSERT 0x00000011 +#define BUCKET_LOOKUP_INSERT 0x00000011 uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); -#define BUCKET_LOOKUP 0x00000010 +#define BUCKET_LOOKUP 0x00000010 uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); #endif \ No newline at end of file diff --git a/drivers/net/packet/count_packets.h b/drivers/net/packet/count_packets.h index 0599964..819b5b5 100644 --- a/drivers/net/packet/count_packets.h +++ b/drivers/net/packet/count_packets.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -38,13 +38,13 @@ typedef struct __c_p_data { - struct timeval timestamp; - uint64 packets; - uint64 bytes; + struct timeval timestamp; + uint64 packets; + uint64 bytes; } - c_p_data; + c_p_data; -#define COUNT_PACKETS 0x00000000 +#define COUNT_PACKETS 0x00000000 uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); #endif diff --git a/drivers/net/packet/debug.h b/drivers/net/packet/debug.h index 9fcd26b..7461b8b 100644 --- a/drivers/net/packet/debug.h +++ b/drivers/net/packet/debug.h @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2000 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions diff --git a/drivers/net/packet/dump.c b/drivers/net/packet/dump.c index e7c40fb..99f916b 100644 --- a/drivers/net/packet/dump.c +++ b/drivers/net/packet/dump.c @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2000 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -27,6 +27,8 @@ #else #include #include +//#define PsGetCurrentProcess() IoGetCurrentProcess() +#define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread())) #endif #include "debug.h" @@ -38,232 +40,229 @@ NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append) { - NTSTATUS ntStatus; - IO_STATUS_BLOCK IoStatus; - OBJECT_ATTRIBUTES ObjectAttributes; - PWCHAR PathPrefix; - USHORT PathLen; - UNICODE_STRING FullFileName; - ULONG FullFileNameLength; - PDEVICE_OBJECT fsdDevice; - - FILE_STANDARD_INFORMATION StandardInfo; - + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + OBJECT_ATTRIBUTES ObjectAttributes; + PWCHAR PathPrefix; + USHORT PathLen; + UNICODE_STRING FullFileName; + ULONG FullFileNameLength; + PDEVICE_OBJECT fsdDevice; + + FILE_STANDARD_INFORMATION StandardInfo; + IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");) - if(fileName->Buffer[0] == L'\\' && - fileName->Buffer[1] == L'?' && - fileName->Buffer[2] == L'?' && - fileName->Buffer[3] == L'\\' - ){ - PathLen = 0; - } - else{ - PathPrefix = L"\\??\\"; - PathLen = 8; - } - - // Insert the correct path prefix. - FullFileNameLength = PathLen + fileName->MaximumLength; - - FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, - FullFileNameLength, - '0DWA'); - - if (FullFileName.Buffer == NULL) { - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - return ntStatus; - } - - FullFileName.Length = PathLen; - FullFileName.MaximumLength = (USHORT)FullFileNameLength; - - if(PathLen) - RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen); - - RtlAppendUnicodeStringToString (&FullFileName, fileName); - - IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);) - - InitializeObjectAttributes ( &ObjectAttributes, - &FullFileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL ); - - // Create the dump file - ntStatus = ZwCreateFile( &Open->DumpFileHandle, - SYNCHRONIZE | FILE_WRITE_DATA, - &ObjectAttributes, - &IoStatus, - NULL, - FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, - (Append)?FILE_OPEN_IF:FILE_SUPERSEDE, - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0 ); + if(fileName->Buffer[0] == L'\\' && + fileName->Buffer[1] == L'?' && + fileName->Buffer[2] == L'?' && + fileName->Buffer[3] == L'\\' + ){ + PathLen = 0; + } + else{ + PathPrefix = L"\\??\\"; + PathLen = 8; + } + + // Insert the correct path prefix. + FullFileNameLength = PathLen + fileName->MaximumLength; + +#define NPF_TAG_FILENAME TAG('0', 'D', 'W', 'A') + FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, + FullFileNameLength, + NPF_TAG_FILENAME); + + if (FullFileName.Buffer == NULL) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + return ntStatus; + } + + FullFileName.Length = PathLen; + FullFileName.MaximumLength = (USHORT)FullFileNameLength; + + if(PathLen) + RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen); + + RtlAppendUnicodeStringToString (&FullFileName, fileName); + + IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);) + + InitializeObjectAttributes ( &ObjectAttributes, + &FullFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL ); + + // Create the dump file + ntStatus = ZwCreateFile( &Open->DumpFileHandle, + SYNCHRONIZE | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatus, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + (Append)?FILE_OPEN_IF:FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0 ); if ( !NT_SUCCESS( ntStatus ) ) { IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);) - + ExFreePool(FullFileName.Buffer); - Open->DumpFileHandle=NULL; + Open->DumpFileHandle=NULL; ntStatus = STATUS_NO_SUCH_FILE; return ntStatus; } - - ExFreePool(FullFileName.Buffer); - - ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle, - FILE_WRITE_ACCESS, + + ExFreePool(FullFileName.Buffer); + + ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle, + FILE_WRITE_ACCESS, #ifndef __GNUC__ - *IoFileObjectType, + *IoFileObjectType, #else - IoFileObjectType, + IoFileObjectType, #endif - KernelMode, - &Open->DumpFileObject, - 0); - + KernelMode, + (PVOID)&Open->DumpFileObject, + 0); + if ( !NT_SUCCESS( ntStatus ) ) { IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);) - - ZwClose( Open->DumpFileHandle ); - Open->DumpFileHandle=NULL; - + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + ntStatus = STATUS_NO_SUCH_FILE; return ntStatus; } - + fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject); - IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);) + IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);) - return ntStatus; -} + return ntStatus; +} //------------------------------------------------------------------- NTSTATUS NPF_StartDump(POPEN_INSTANCE Open) { - NTSTATUS ntStatus; - struct packet_file_header hdr; - IO_STATUS_BLOCK IoStatus; + NTSTATUS ntStatus; + struct packet_file_header hdr; + IO_STATUS_BLOCK IoStatus; NDIS_REQUEST pRequest; - ULONG MediaType; - OBJECT_ATTRIBUTES ObjectAttributes; + ULONG MediaType; + OBJECT_ATTRIBUTES ObjectAttributes; IF_LOUD(DbgPrint("NPF: StartDump.\n");) - // Init the file header - hdr.magic = TCPDUMP_MAGIC; - hdr.version_major = PCAP_VERSION_MAJOR; - hdr.version_minor = PCAP_VERSION_MINOR; - hdr.thiszone = 0; /*Currently not set*/ - hdr.snaplen = 1514; - hdr.sigfigs = 0; - - // Detect the medium type - switch (Open->Medium){ - - case NdisMediumWan: - hdr.linktype = DLT_EN10MB; - break; - - case NdisMedium802_3: - hdr.linktype = DLT_EN10MB; - break; - - case NdisMediumFddi: - hdr.linktype = DLT_FDDI; - break; - - case NdisMedium802_5: - hdr.linktype = DLT_IEEE802; - break; - - case NdisMediumArcnet878_2: - hdr.linktype = DLT_ARCNET; - break; - - case NdisMediumAtm: - hdr.linktype = DLT_ATM_RFC1483; - break; - - default: - hdr.linktype = DLT_EN10MB; - } - - // Write the header. - // We can use ZwWriteFile because we are in the context of the application - ntStatus = ZwWriteFile(Open->DumpFileHandle, - NULL, - NULL, - NULL, - &IoStatus, - &hdr, - sizeof(hdr), - NULL, - NULL ); - - + // Init the file header + hdr.magic = TCPDUMP_MAGIC; + hdr.version_major = PCAP_VERSION_MAJOR; + hdr.version_minor = PCAP_VERSION_MINOR; + hdr.thiszone = 0; /*Currently not set*/ + hdr.snaplen = 1514; + hdr.sigfigs = 0; + + // Detect the medium type + switch (Open->Medium){ + + case NdisMediumWan: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMedium802_3: + hdr.linktype = DLT_EN10MB; + break; + + case NdisMediumFddi: + hdr.linktype = DLT_FDDI; + break; + + case NdisMedium802_5: + hdr.linktype = DLT_IEEE802; + break; + + case NdisMediumArcnet878_2: + hdr.linktype = DLT_ARCNET; + break; + + case NdisMediumAtm: + hdr.linktype = DLT_ATM_RFC1483; + break; + + default: + hdr.linktype = DLT_EN10MB; + } + + // Write the header. + // We can use ZwWriteFile because we are in the context of the application + ntStatus = ZwWriteFile(Open->DumpFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + &hdr, + sizeof(hdr), + NULL, + NULL ); + + if ( !NT_SUCCESS( ntStatus ) ) { IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);) - - ZwClose( Open->DumpFileHandle ); - Open->DumpFileHandle=NULL; - + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; + ntStatus = STATUS_NO_SUCH_FILE; return ntStatus; } - Open->DumpOffset.QuadPart=24; - - ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle, - THREAD_ALL_ACCESS, - (ACCESS_MASK)0L, - 0, - 0, - NPF_DumpThread, - Open); - + Open->DumpOffset.QuadPart=24; + + ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + (ACCESS_MASK)0L, + 0, + 0, + (PKSTART_ROUTINE)NPF_DumpThread, + Open); + if ( !NT_SUCCESS( ntStatus ) ) { IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) - - ZwClose( Open->DumpFileHandle ); - Open->DumpFileHandle=NULL; + + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; return ntStatus; } -#ifndef __GNUC__ - ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle, - THREAD_ALL_ACCESS, - NULL, - KernelMode, - &Open->DumpThreadObject, - 0); -#else -#endif + ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle, + THREAD_ALL_ACCESS, + NULL, + KernelMode, + &Open->DumpThreadObject, + 0); if ( !NT_SUCCESS( ntStatus ) ) { IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);) - - ObDereferenceObject(Open->DumpFileObject); - ZwClose( Open->DumpFileHandle ); - Open->DumpFileHandle=NULL; + + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + Open->DumpFileHandle=NULL; return ntStatus; } - - - return ntStatus; - + + return ntStatus; + } //------------------------------------------------------------------- @@ -272,245 +271,250 @@ NPF_StartDump(POPEN_INSTANCE Open) VOID NPF_DumpThread(POPEN_INSTANCE Open) { - ULONG FrozenNic; + ULONG FrozenNic; IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%0x\n",Open);) - while(TRUE){ - - // Wait until some packets arrive or the timeout expires - NdisWaitEvent(&Open->DumpEvent, 5000); - - IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");) - - if(Open->DumpLimitReached || - Open->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too - // small for any capture. In both cases it is better to end the dump - - IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");) - IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);) - - PsTerminateSystemThread(STATUS_SUCCESS); - return; - } - - NdisResetEvent(&Open->DumpEvent); - - // Write the content of the buffer to the file - if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){ - PsTerminateSystemThread(STATUS_SUCCESS); - return; - } - - } - + while(TRUE){ + + // Wait until some packets arrive or the timeout expires + NdisWaitEvent(&Open->DumpEvent, 5000); + + IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");) + + if(Open->DumpLimitReached || + Open->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too + // small for any capture. In both cases it is better to end the dump + + IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");) + IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);) + + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + NdisResetEvent(&Open->DumpEvent); + + // Write the content of the buffer to the file + if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){ + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + + } + } //------------------------------------------------------------------- NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open) { - UINT Thead; - UINT Ttail; - UINT TLastByte; - PUCHAR CurrBuff; - NTSTATUS ntStatus; - IO_STATUS_BLOCK IoStatus; - PMDL lMdl; - UINT SizeToDump; - - - Thead=Open->Bhead; - Ttail=Open->Btail; - TLastByte=Open->BLastByte; - + UINT Thead; + UINT Ttail; + UINT TLastByte; + PUCHAR CurrBuff; + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL lMdl; + UINT SizeToDump; + + + Thead=Open->Bhead; + Ttail=Open->Btail; + TLastByte=Open->BLastByte; + IF_LOUD(DbgPrint("NPF: NPF_SaveCurrentBuffer.\n");) - // Get the address of the buffer - CurrBuff=Open->Buffer; - // - // Fill the application buffer - // - if( Ttail < Thead ) - { - if(Open->MaxDumpBytes && - (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) - { - // Size limit reached - UINT PktLen; - - SizeToDump = 0; - - // Scan the buffer to detect the exact amount of data to save - while(TRUE){ - PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); - - if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) - break; - - SizeToDump += PktLen; - } - - } - else - SizeToDump = TLastByte-Thead; - - lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); - if (lMdl == NULL) - { - // No memory: stop dump - IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) - return STATUS_UNSUCCESSFUL; - } - - MmBuildMdlForNonPagedPool(lMdl); - - // Write to disk - NPF_WriteDumpFile(Open->DumpFileObject, - &Open->DumpOffset, - SizeToDump, - lMdl, - &IoStatus); - - IoFreeMdl(lMdl); - - if(!NT_SUCCESS(IoStatus.Status)){ - // Error - return STATUS_UNSUCCESSFUL; - } - - if(SizeToDump != TLastByte-Thead){ - // Size limit reached. - Open->DumpLimitReached = TRUE; - - // Awake the application - KeSetEvent(Open->ReadEvent,0,FALSE); - - return STATUS_UNSUCCESSFUL; - } - - // Update the packet buffer - Open->DumpOffset.QuadPart+=(TLastByte-Thead); - Open->BLastByte=Ttail; - Open->Bhead=0; - } - - if( Ttail > Thead ){ - - if(Open->MaxDumpBytes && - (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) - { - // Size limit reached - UINT PktLen; - - SizeToDump = 0; - - // Scan the buffer to detect the exact amount of data to save - while(Thead + SizeToDump < Ttail){ - - PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); - - if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) - break; - - SizeToDump += PktLen; - } - - } - else - SizeToDump = Ttail-Thead; - - lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); - if (lMdl == NULL) - { - // No memory: stop dump - IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) - return STATUS_UNSUCCESSFUL; - } - - MmBuildMdlForNonPagedPool(lMdl); - - // Write to disk - NPF_WriteDumpFile(Open->DumpFileObject, - &Open->DumpOffset, - SizeToDump, - lMdl, - &IoStatus); - - IoFreeMdl(lMdl); - - if(!NT_SUCCESS(IoStatus.Status)){ - // Error - return STATUS_UNSUCCESSFUL; - } - - if(SizeToDump != Ttail-Thead){ - // Size limit reached. - Open->DumpLimitReached = TRUE; - - // Awake the application - KeSetEvent(Open->ReadEvent,0,FALSE); - - return STATUS_UNSUCCESSFUL; - } - - // Update the packet buffer - Open->DumpOffset.QuadPart+=(Ttail-Thead); - Open->Bhead=Ttail; - - } - - return STATUS_SUCCESS; + // Get the address of the buffer + CurrBuff=Open->Buffer; + // + // Fill the application buffer + // + if( Ttail < Thead ) + { + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(TRUE){ + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = TLastByte-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != TLastByte-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(TLastByte-Thead); + Open->BLastByte=Ttail; + Open->Bhead=0; + } + + if( Ttail > Thead ){ + + if(Open->MaxDumpBytes && + (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes) + { + // Size limit reached + UINT PktLen; + + SizeToDump = 0; + + // Scan the buffer to detect the exact amount of data to save + while(Thead + SizeToDump < Ttail){ + + PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr); + + if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes) + break; + + SizeToDump += PktLen; + } + + } + else + SizeToDump = Ttail-Thead; + + lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL); + if (lMdl == NULL) + { + // No memory: stop dump + IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");) + return STATUS_UNSUCCESSFUL; + } + + MmBuildMdlForNonPagedPool(lMdl); + + // Write to disk + NPF_WriteDumpFile(Open->DumpFileObject, + &Open->DumpOffset, + SizeToDump, + lMdl, + &IoStatus); + + IoFreeMdl(lMdl); + + if(!NT_SUCCESS(IoStatus.Status)){ + // Error + return STATUS_UNSUCCESSFUL; + } + + if(SizeToDump != Ttail-Thead){ + // Size limit reached. + Open->DumpLimitReached = TRUE; + + // Awake the application + KeSetEvent(Open->ReadEvent,0,FALSE); + + return STATUS_UNSUCCESSFUL; + } + + // Update the packet buffer + Open->DumpOffset.QuadPart+=(Ttail-Thead); + Open->Bhead=Ttail; + + } + + return STATUS_SUCCESS; } //------------------------------------------------------------------- NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){ - NTSTATUS ntStatus; - IO_STATUS_BLOCK IoStatus; - PMDL WriteMdl; - PUCHAR VMBuff; - UINT VMBufLen; + NTSTATUS ntStatus; + IO_STATUS_BLOCK IoStatus; + PMDL WriteMdl; + PUCHAR VMBuff; + UINT VMBufLen; IF_LOUD(DbgPrint("NPF: NPF_CloseDumpFile.\n");) IF_LOUD(DbgPrint("Dumpoffset=%d\n",Open->DumpOffset.QuadPart);) DbgPrint("1\n"); - // Consistency check - if(Open->DumpFileHandle == NULL) - return STATUS_UNSUCCESSFUL; + // Consistency check + if(Open->DumpFileHandle == NULL) + return STATUS_UNSUCCESSFUL; DbgPrint("2\n"); - ZwClose( Open->DumpFileHandle ); + ZwClose( Open->DumpFileHandle ); - ObDereferenceObject(Open->DumpFileObject); + ObDereferenceObject(Open->DumpFileObject); /* - if(Open->DumpLimitReached == TRUE) - // Limit already reached: don't save the rest of the buffer. - return STATUS_SUCCESS; + if(Open->DumpLimitReached == TRUE) + // Limit already reached: don't save the rest of the buffer. + return STATUS_SUCCESS; */ DbgPrint("3\n"); - NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE); + NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE); - // Flush the buffer to file - NPF_SaveCurrentBuffer(Open); + // Flush the buffer to file + NPF_SaveCurrentBuffer(Open); - // Close The file - ObDereferenceObject(Open->DumpFileObject); - ZwClose( Open->DumpFileHandle ); - - Open->DumpFileHandle = NULL; + // Close The file + ObDereferenceObject(Open->DumpFileObject); + ZwClose( Open->DumpFileHandle ); + + Open->DumpFileHandle = NULL; - ObDereferenceObject(Open->DumpFileObject); + ObDereferenceObject(Open->DumpFileObject); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } //------------------------------------------------------------------- -static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject, +#ifndef __GNUC__ +static NTSTATUS +#else +NTSTATUS STDCALL +#endif +PacketDumpCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { @@ -527,10 +531,10 @@ static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject, //------------------------------------------------------------------- VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, - PLARGE_INTEGER Offset, - ULONG Length, - PMDL Mdl, - PIO_STATUS_BLOCK IoStatusBlock) + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock) { PIRP irp; KEVENT event; @@ -549,33 +553,33 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES; IoStatusBlock->Information = 0; - return; + return; } - + irp->MdlAddress = Mdl; irp->UserEvent = &event; irp->UserIosb = IoStatusBlock; irp->Tail.Overlay.Thread = PsGetCurrentThread(); - irp->Tail.Overlay.OriginalFileObject= FileObject; + irp->Tail.Overlay.OriginalFileObject= FileObject; irp->RequestorMode = KernelMode; - + // Indicate that this is a WRITE operation - irp->Flags = IRP_WRITE_OPERATION; - + irp->Flags = IRP_WRITE_OPERATION; + // Set up the next I/O stack location ioStackLocation = IoGetNextIrpStackLocation(irp); ioStackLocation->MajorFunction = IRP_MJ_WRITE; ioStackLocation->MinorFunction = 0; ioStackLocation->DeviceObject = fsdDevice; ioStackLocation->FileObject = FileObject; - IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE); - ioStackLocation->Parameters.Write.Length = Length; + IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE); + ioStackLocation->Parameters.Write.Length = Length; ioStackLocation->Parameters.Write.ByteOffset = *Offset; - + // Send it on. Ignore the return code (void) IoCallDriver(fsdDevice, irp); - + // Wait for the I/O to complete. KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); @@ -583,5 +587,4 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, IoFreeIrp(irp); return; - } diff --git a/drivers/net/packet/functions.h b/drivers/net/packet/functions.h index 91f242a..d25c679 100644 --- a/drivers/net/packet/functions.h +++ b/drivers/net/packet/functions.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions diff --git a/drivers/net/packet/jitter.c b/drivers/net/packet/jitter.c index 4a71a7c..2be1cf9 100644 --- a/drivers/net/packet/jitter.c +++ b/drivers/net/packet/jitter.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2002 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -39,8 +39,8 @@ emit_func emitm; // void emit_lenght(binary_stream *stream, ULONG value, UINT len) { - (stream->refs)[stream->bpf_pc]+=len; - stream->cur_ip+=len; + (stream->refs)[stream->bpf_pc]+=len; + stream->cur_ip+=len; } // @@ -48,29 +48,29 @@ void emit_lenght(binary_stream *stream, ULONG value, UINT len) // void emit_code(binary_stream *stream, ULONG value, UINT len) { - - switch (len){ + + switch (len){ - case 1: - stream->ibuf[stream->cur_ip]=(UCHAR)value; - stream->cur_ip++; - break; + case 1: + stream->ibuf[stream->cur_ip]=(UCHAR)value; + stream->cur_ip++; + break; - case 2: - *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value; - stream->cur_ip+=2; - break; + case 2: + *((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value; + stream->cur_ip+=2; + break; - case 4: - *((ULONG*)(stream->ibuf+stream->cur_ip))=value; - stream->cur_ip+=4; - break; + case 4: + *((ULONG*)(stream->ibuf+stream->cur_ip))=value; + stream->cur_ip+=4; + break; - default:; - - } + default:; + + } - return; + return; } @@ -79,599 +79,603 @@ void emit_code(binary_stream *stream, ULONG value, UINT len) // BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem) { - struct bpf_insn *ins; - UINT i, pass; - binary_stream stream; + struct bpf_insn *ins; + UINT i, pass; + binary_stream stream; - // Allocate the reference table for the jumps + // Allocate the reference table for the jumps #ifdef NTKERNEL - stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), '0JWA'); +#define NPF_TAG_REFTABLE TAG('0', 'J', 'W', 'A') + stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), NPF_TAG_REFTABLE); #else - stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT)); + stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT)); #endif - if(stream.refs==NULL) - { - return NULL; - } - - // Reset the reference table - for(i=0; i< nins + 1; i++) - stream.refs[i]=0; - - stream.cur_ip=0; - stream.bpf_pc=0; - - // the first pass will emit the lengths of the instructions - // to create the reference table - emitm=emit_lenght; - - for(pass=0;;){ - - ins = prog; - - /* create the procedure header */ - PUSH(EBP) - MOVrd(EBP,ESP) - PUSH(EBX) - PUSH(ECX) - PUSH(EDX) - PUSH(ESI) - PUSH(EDI) - MOVodd(EBX, EBP, 8) - - for(i=0;icode) { - - default: - - return NULL; - - case BPF_RET|BPF_K: - - MOVid(EAX,ins->k) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - RET() - - break; - - - case BPF_RET|BPF_A: - - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - RET() - - break; - - - case BPF_LD|BPF_W|BPF_ABS: - - MOVid(ECX,ins->k) - MOVrd(ESI,ECX) - ADDib(ECX,sizeof(INT)) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) //this can be optimized with xor eax,eax - RET() - MOVobd(EAX, EBX, ESI) - BSWAP(EAX) - - break; - - case BPF_LD|BPF_H|BPF_ABS: - - MOVid(ECX,ins->k) - MOVrd(ESI,ECX) - ADDib(ECX,sizeof(SHORT)) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVid(EAX,0) - MOVobw(AX, EBX, ESI) - SWAP_AX() - - break; - - case BPF_LD|BPF_B|BPF_ABS: - - MOVid(ECX,ins->k) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVid(EAX,0) - MOVobb(AL,EBX,ECX) - - break; - - case BPF_LD|BPF_W|BPF_LEN: - - MOVodd(EAX, EBP, 0xc) - - break; - - case BPF_LDX|BPF_W|BPF_LEN: - - MOVodd(EDX, EBP, 0xc) - - break; - - case BPF_LD|BPF_W|BPF_IND: - - MOVid(ECX,ins->k) - ADDrd(ECX,EDX) - MOVrd(ESI,ECX) - ADDib(ECX,sizeof(INT)) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVobd(EAX, EBX, ESI) - BSWAP(EAX) - - break; - - case BPF_LD|BPF_H|BPF_IND: - - MOVid(ECX,ins->k) - ADDrd(ECX,EDX) - MOVrd(ESI,ECX) - ADDib(ECX,sizeof(SHORT)) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVid(EAX,0) - MOVobw(AX, EBX, ESI) - SWAP_AX() - - break; - - case BPF_LD|BPF_B|BPF_IND: - - MOVid(ECX,ins->k) - ADDrd(ECX,EDX) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVid(EAX,0) - MOVobb(AL,EBX,ECX) - - break; - - case BPF_LDX|BPF_MSH|BPF_B: - - MOVid(ECX,ins->k) - CMPodd(ECX, EBP, 0x10) - JLEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVid(EDX,0) - MOVobb(DL,EBX,ECX) - ANDib(DL, 0xf) - SHLib(EDX, 2) - - break; + if(stream.refs==NULL) + { + return NULL; + } + + // Reset the reference table + for(i=0; i< nins + 1; i++) + stream.refs[i]=0; + + stream.cur_ip=0; + stream.bpf_pc=0; + + // the first pass will emit the lengths of the instructions + // to create the reference table + emitm=emit_lenght; + + for(pass=0;;){ + + ins = prog; + + /* create the procedure header */ + PUSH(EBP) + MOVrd(EBP,ESP) + PUSH(EBX) + PUSH(ECX) + PUSH(EDX) + PUSH(ESI) + PUSH(EDI) + MOVodd(EBX, EBP, 8) + + for(i=0;icode) { + + default: + + return NULL; + + case BPF_RET|BPF_K: + + MOVid(EAX,ins->k) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_RET|BPF_A: + + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + RET() + + break; + + + case BPF_LD|BPF_W|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) //this can be optimized with xor eax,eax + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_ABS: + + MOVid(ECX,ins->k) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_ABS: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LD|BPF_W|BPF_LEN: + + MOVodd(EAX, EBP, 0xc) + + break; + + case BPF_LDX|BPF_W|BPF_LEN: + + MOVodd(EDX, EBP, 0xc) + + break; + + case BPF_LD|BPF_W|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(INT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVobd(EAX, EBX, ESI) + BSWAP(EAX) + + break; + + case BPF_LD|BPF_H|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + MOVrd(ESI,ECX) + ADDib(ECX,sizeof(SHORT)) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobw(AX, EBX, ESI) + SWAP_AX() + + break; + + case BPF_LD|BPF_B|BPF_IND: + + MOVid(ECX,ins->k) + ADDrd(ECX,EDX) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EAX,0) + MOVobb(AL,EBX,ECX) + + break; + + case BPF_LDX|BPF_MSH|BPF_B: + + MOVid(ECX,ins->k) + CMPodd(ECX, EBP, 0x10) + JLEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVid(EDX,0) + MOVobb(DL,EBX,ECX) + ANDib(DL, 0xf) + SHLib(EDX, 2) + + break; - case BPF_LD|BPF_IMM: + case BPF_LD|BPF_IMM: - MOVid(EAX,ins->k) + MOVid(EAX,ins->k) - break; + break; - case BPF_LDX|BPF_IMM: - - MOVid(EDX,ins->k) + case BPF_LDX|BPF_IMM: + + MOVid(EDX,ins->k) - break; + break; - case BPF_LD|BPF_MEM: + case BPF_LD|BPF_MEM: - MOVid(ECX,(INT)mem) - MOVid(ESI,ins->k*4) - MOVobd(EAX, ECX, ESI) + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EAX, ECX, ESI) - break; + break; - case BPF_LDX|BPF_MEM: + case BPF_LDX|BPF_MEM: - MOVid(ECX,(INT)mem) - MOVid(ESI,ins->k*4) - MOVobd(EDX, ECX, ESI) + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVobd(EDX, ECX, ESI) - break; + break; - case BPF_ST: + case BPF_ST: - // XXX: this command and the following could be optimized if the previous - // instruction was already of this type - MOVid(ECX,(INT)mem) - MOVid(ESI,ins->k*4) - MOVomd(ECX, ESI, EAX) + // XXX: this command and the following could be optimized if the previous + // instruction was already of this type + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EAX) - break; + break; - case BPF_STX: + case BPF_STX: - MOVid(ECX,(INT)mem) - MOVid(ESI,ins->k*4) - MOVomd(ECX, ESI, EDX) - break; + MOVid(ECX,(INT)mem) + MOVid(ESI,ins->k*4) + MOVomd(ECX, ESI, EDX) + break; - case BPF_JMP|BPF_JA: + case BPF_JMP|BPF_JA: - JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc]) + JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JGT|BPF_K: + case BPF_JMP|BPF_JGT|BPF_K: - CMPid(EAX, ins->k) - JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + CMPid(EAX, ins->k) + JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; - case BPF_JMP|BPF_JGE|BPF_K: + case BPF_JMP|BPF_JGE|BPF_K: - CMPid(EAX, ins->k) - JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + CMPid(EAX, ins->k) + JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JEQ|BPF_K: + case BPF_JMP|BPF_JEQ|BPF_K: - CMPid(EAX, ins->k) - JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + CMPid(EAX, ins->k) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JSET|BPF_K: + case BPF_JMP|BPF_JSET|BPF_K: - MOVrd(ECX,EAX) - ANDid(ECX,ins->k) - JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + MOVrd(ECX,EAX) + ANDid(ECX,ins->k) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JGT|BPF_X: + case BPF_JMP|BPF_JGT|BPF_X: - CMPrd(EAX, EDX) - JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + CMPrd(EAX, EDX) + JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + break; - case BPF_JMP|BPF_JGE|BPF_X: + case BPF_JMP|BPF_JGE|BPF_X: - CMPrd(EAX, EDX) - JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + CMPrd(EAX, EDX) + JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JEQ|BPF_X: + case BPF_JMP|BPF_JEQ|BPF_X: - CMPrd(EAX, EDX) - JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) + CMPrd(EAX, EDX) + JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]) - break; + break; - case BPF_JMP|BPF_JSET|BPF_X: + case BPF_JMP|BPF_JSET|BPF_X: - MOVrd(ECX,EAX) - ANDrd(ECX,EDX) - JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) - JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) - - break; + MOVrd(ECX,EAX) + ANDrd(ECX,EDX) + JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5) + JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]) + + break; - case BPF_ALU|BPF_ADD|BPF_X: + case BPF_ALU|BPF_ADD|BPF_X: - ADDrd(EAX,EDX) - - break; + ADDrd(EAX,EDX) + + break; - case BPF_ALU|BPF_SUB|BPF_X: + case BPF_ALU|BPF_SUB|BPF_X: - SUBrd(EAX,EDX) + SUBrd(EAX,EDX) - break; + break; - case BPF_ALU|BPF_MUL|BPF_X: + case BPF_ALU|BPF_MUL|BPF_X: - MOVrd(ECX,EDX) - MULrd(EDX) - MOVrd(EDX,ECX) - break; + MOVrd(ECX,EDX) + MULrd(EDX) + MOVrd(EDX,ECX) + break; - case BPF_ALU|BPF_DIV|BPF_X: + case BPF_ALU|BPF_DIV|BPF_X: - CMPid(EDX, 0) - JNEb(12) - POP(EDI) - POP(ESI) - POP(EDX) - POP(ECX) - POP(EBX) - POP(EBP) - MOVid(EAX,0) - RET() - MOVrd(ECX,EDX) - MOVid(EDX,0) - DIVrd(ECX) - MOVrd(EDX,ECX) + CMPid(EDX, 0) + JNEb(12) + POP(EDI) + POP(ESI) + POP(EDX) + POP(ECX) + POP(EBX) + POP(EBP) + MOVid(EAX,0) + RET() + MOVrd(ECX,EDX) + MOVid(EDX,0) + DIVrd(ECX) + MOVrd(EDX,ECX) - break; + break; - case BPF_ALU|BPF_AND|BPF_X: + case BPF_ALU|BPF_AND|BPF_X: - ANDrd(EAX,EDX) - - break; + ANDrd(EAX,EDX) + + break; - case BPF_ALU|BPF_OR|BPF_X: + case BPF_ALU|BPF_OR|BPF_X: - ORrd(EAX,EDX) + ORrd(EAX,EDX) - break; + break; - case BPF_ALU|BPF_LSH|BPF_X: + case BPF_ALU|BPF_LSH|BPF_X: - MOVrd(ECX,EDX) - SHL_CLrb(EAX) + MOVrd(ECX,EDX) + SHL_CLrb(EAX) - break; + break; - case BPF_ALU|BPF_RSH|BPF_X: + case BPF_ALU|BPF_RSH|BPF_X: - MOVrd(ECX,EDX) - SHR_CLrb(EAX) + MOVrd(ECX,EDX) + SHR_CLrb(EAX) - break; + break; - case BPF_ALU|BPF_ADD|BPF_K: + case BPF_ALU|BPF_ADD|BPF_K: - ADD_EAXi(ins->k) + ADD_EAXi(ins->k) - break; + break; - case BPF_ALU|BPF_SUB|BPF_K: + case BPF_ALU|BPF_SUB|BPF_K: - SUB_EAXi(ins->k) - - break; + SUB_EAXi(ins->k) + + break; - case BPF_ALU|BPF_MUL|BPF_K: + case BPF_ALU|BPF_MUL|BPF_K: - MOVrd(ECX,EDX) - MOVid(EDX,ins->k) - MULrd(EDX) - MOVrd(EDX,ECX) + MOVrd(ECX,EDX) + MOVid(EDX,ins->k) + MULrd(EDX) + MOVrd(EDX,ECX) - break; + break; - case BPF_ALU|BPF_DIV|BPF_K: + case BPF_ALU|BPF_DIV|BPF_K: - MOVrd(ECX,EDX) - MOVid(EDX,0) - MOVid(ESI,ins->k) - DIVrd(ESI) - MOVrd(EDX,ECX) + MOVrd(ECX,EDX) + MOVid(EDX,0) + MOVid(ESI,ins->k) + DIVrd(ESI) + MOVrd(EDX,ECX) - break; + break; - case BPF_ALU|BPF_AND|BPF_K: + case BPF_ALU|BPF_AND|BPF_K: - ANDid(EAX, ins->k) + ANDid(EAX, ins->k) - break; + break; - case BPF_ALU|BPF_OR|BPF_K: + case BPF_ALU|BPF_OR|BPF_K: - ORid(EAX, ins->k) - - break; + ORid(EAX, ins->k) + + break; - case BPF_ALU|BPF_LSH|BPF_K: + case BPF_ALU|BPF_LSH|BPF_K: - SHLib(EAX, (ins->k) & 255) + SHLib(EAX, (ins->k) & 255) - break; + break; - case BPF_ALU|BPF_RSH|BPF_K: + case BPF_ALU|BPF_RSH|BPF_K: - SHRib(EAX, (ins->k) & 255) + SHRib(EAX, (ins->k) & 255) - break; + break; - case BPF_ALU|BPF_NEG: + case BPF_ALU|BPF_NEG: - NEGd(EAX) + NEGd(EAX) - break; + break; - case BPF_MISC|BPF_TAX: + case BPF_MISC|BPF_TAX: - MOVrd(EDX,EAX) + MOVrd(EDX,EAX) - break; + break; - case BPF_MISC|BPF_TXA: + case BPF_MISC|BPF_TXA: - MOVrd(EAX,EDX) + MOVrd(EAX,EDX) - break; + break; - } - - ins++; - } + } + + ins++; + } - pass++; - if(pass == 2) break; - + pass++; + if(pass == 2) break; + #ifdef NTKERNEL - stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, '1JWA'); +#define NPF_TAG_STREAMBUF TAG('1', 'J', 'W', 'A') + stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, NPF_TAG_STREAMBUF); #else - stream.ibuf=(CHAR*)malloc(stream.cur_ip); + stream.ibuf=(CHAR*)malloc(stream.cur_ip); #endif - if(stream.ibuf==NULL) - { + if(stream.ibuf==NULL) + { #ifdef NTKERNEL - ExFreePool(stream.refs); + ExFreePool(stream.refs); #else - free(stream.refs); + free(stream.refs); #endif - return NULL; - } - - // modify the reference table to contain the offsets and not the lengths of the instructions - for(i=1; i< nins + 1; i++) - stream.refs[i]+=stream.refs[i-1]; - - // Reset the counters - stream.cur_ip=0; - stream.bpf_pc=0; - // the second pass creates the actual code - emitm=emit_code; - - } - - // the reference table is needed only during compilation, now we can free it + return NULL; + } + + // modify the reference table to contain the offsets and not the lengths of the instructions + for(i=1; i< nins + 1; i++) + stream.refs[i]+=stream.refs[i-1]; + + // Reset the counters + stream.cur_ip=0; + stream.bpf_pc=0; + // the second pass creates the actual code + emitm=emit_code; + + } + + // the reference table is needed only during compilation, now we can free it #ifdef NTKERNEL - ExFreePool(stream.refs); + ExFreePool(stream.refs); #else - free(stream.refs); + free(stream.refs); #endif - return (BPF_filter_function)stream.ibuf; + return (BPF_filter_function)stream.ibuf; } JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins) { - JIT_BPF_Filter *Filter; + JIT_BPF_Filter *Filter; - // Allocate the filter structure + // Allocate the filter structure #ifdef NTKERNEL - Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), '2JWA'); +#define NPF_TAG_FILTSTRUCT TAG('2', 'J', 'W', 'A') + Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), NPF_TAG_FILTSTRUCT); #else - Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter)); + Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter)); #endif - if(Filter==NULL) - { - return NULL; - } + if(Filter==NULL) + { + return NULL; + } - // Allocate the filter's memory + // Allocate the filter's memory #ifdef NTKERNEL - Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), '3JWA'); +#define NPF_TAG_FILTMEM TAG('3', 'J', 'W', 'A') + Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), NPF_TAG_FILTMEM); #else - Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT)); + Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT)); #endif - if(Filter->mem==NULL) - { + if(Filter->mem==NULL) + { #ifdef NTKERNEL - ExFreePool(Filter); + ExFreePool(Filter); #else - free(Filter); + free(Filter); #endif - return NULL; - } + return NULL; + } - // Create the binary - if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL) - { + // Create the binary + if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL) + { #ifdef NTKERNEL - ExFreePool(Filter->mem); - ExFreePool(Filter); + ExFreePool(Filter->mem); + ExFreePool(Filter); #else - free(Filter->mem); - free(Filter); + free(Filter->mem); + free(Filter); - return NULL; + return NULL; #endif - } + } - return Filter; + return Filter; } ////////////////////////////////////////////////////////////// void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter){ - + #ifdef NTKERNEL - ExFreePool(Filter->mem); - ExFreePool(Filter->Function); - ExFreePool(Filter); + ExFreePool(Filter->mem); + ExFreePool(Filter->Function); + ExFreePool(Filter); #else - free(Filter->mem); - free(Filter->Function); - free(Filter); + free(Filter->mem); + free(Filter->Function); + free(Filter); #endif } diff --git a/drivers/net/packet/jitter.h b/drivers/net/packet/jitter.h index 4f9c7fd..de4e609 100644 --- a/drivers/net/packet/jitter.h +++ b/drivers/net/packet/jitter.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2002 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -55,10 +55,10 @@ /*! \brief A stream of X86 binary code.*/ typedef struct binary_stream{ - INT cur_ip; ///< Current X86 instruction pointer. - INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter. - PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code. - PUINT refs; ///< Jumps reference table. + INT cur_ip; ///< Current X86 instruction pointer. + INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter. + PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code. + PUINT refs; ///< Jumps reference table. }binary_stream; @@ -81,8 +81,8 @@ typedef void (*emit_func)(binary_stream *stream, ULONG value, UINT n); /*! \brief Structure describing a x86 filtering program created by the jitter.*/ typedef struct JIT_BPF_Filter{ - BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function. - PINT mem; + BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function. + PINT mem; } JIT_BPF_Filter; @@ -373,7 +373,7 @@ JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins); through the instruction macros defined in jitter.h it is able to create an function directly executable by NPF. */ -BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem); +BPF_filter_function BPFtoX86(struct bpf_insn *ins, UINT nins, INT *mem); /*! \brief Deletes a filtering function that was previously created by BPF_jitter(). \param Filter The filter to destroy. diff --git a/drivers/net/packet/memory_t.c b/drivers/net/packet/memory_t.c index 2a02998..361082c 100644 --- a/drivers/net/packet/memory_t.c +++ b/drivers/net/packet/memory_t.c @@ -22,6 +22,7 @@ #include "tme.h" #include "memory_t.h" +#ifdef _USE_SW_FUNCS_ int32 SW_LONG_AT(void *b, uint32 c) { @@ -62,4 +63,6 @@ VOID SW_ULONG_ASSIGN(void *dst, uint32 src) } +#endif /*_USE_SW_FUNCS_*/ + void assert(void* assert, const char* file, int line, void* msg) { }; diff --git a/drivers/net/packet/memory_t.h b/drivers/net/packet/memory_t.h index 0ecd90b..57f24e7 100644 --- a/drivers/net/packet/memory_t.h +++ b/drivers/net/packet/memory_t.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -22,20 +22,20 @@ #ifndef __memory_t #define __memory_t -#define uint8 UCHAR -#define int8 CHAR -#define uint16 USHORT -#define int16 SHORT -#define uint32 ULONG -#define int32 LONG -#define uint64 ULONGLONG -#define int64 LONGLONG +#define uint8 UCHAR +#define int8 CHAR +#define uint16 USHORT +#define int16 SHORT +#define uint32 ULONG +#define int32 LONG +#define uint64 ULONGLONG +#define int64 LONGLONG /*memory type*/ typedef struct __MEM_TYPE { - uint8 *buffer; - uint32 size; + uint8 *buffer; + uint32 size; } MEM_TYPE, *PMEM_TYPE; #define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset)) @@ -47,66 +47,71 @@ typedef struct __MEM_TYPE #define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset)) #ifdef __GNUC__ +#define __inline inline +#define _USE_SW_FUNCS_ +#endif -int32 SW_LONG_AT(void *b, uint32 c); -uint32 SW_ULONG_AT(void *b, uint32 c); -int16 SW_SHORT_AT(void *b, uint32 os); -uint16 SW_USHORT_AT(void *b, uint32 os); -VOID SW_ULONG_ASSIGN(void *dst, uint32 src); +#ifdef _USE_SW_FUNCS_ -#else /* __GNUC__ */ +inline int32 SW_LONG_AT(void *b, uint32 c); +inline uint32 SW_ULONG_AT(void *b, uint32 c); +inline int16 SW_SHORT_AT(void *b, uint32 os); +inline uint16 SW_USHORT_AT(void *b, uint32 os); +inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src); + +#else /*_USE_SW_FUNCS_*/ __inline int32 SW_LONG_AT(void *b, uint32 c) { - return ((int32)*((uint8 *)b+c)<<24| - (int32)*((uint8 *)b+c+1)<<16| - (int32)*((uint8 *)b+c+2)<<8| - (int32)*((uint8 *)b+c+3)<<0); + return ((int32)*((uint8 *)b+c)<<24| + (int32)*((uint8 *)b+c+1)<<16| + (int32)*((uint8 *)b+c+2)<<8| + (int32)*((uint8 *)b+c+3)<<0); } __inline uint32 SW_ULONG_AT(void *b, uint32 c) { - return ((uint32)*((uint8 *)b+c)<<24| - (uint32)*((uint8 *)b+c+1)<<16| - (uint32)*((uint8 *)b+c+2)<<8| - (uint32)*((uint8 *)b+c+3)<<0); + return ((uint32)*((uint8 *)b+c)<<24| + (uint32)*((uint8 *)b+c+1)<<16| + (uint32)*((uint8 *)b+c+2)<<8| + (uint32)*((uint8 *)b+c+3)<<0); } __inline int16 SW_SHORT_AT(void *b, uint32 os) { - return ((int16) - ((int16)*((uint8 *)b+os+0)<<8| - (int16)*((uint8 *)b+os+1)<<0)); + return ((int16) + ((int16)*((uint8 *)b+os+0)<<8| + (int16)*((uint8 *)b+os+1)<<0)); } __inline uint16 SW_USHORT_AT(void *b, uint32 os) { - return ((uint16) - ((uint16)*((uint8 *)b+os+0)<<8| - (uint16)*((uint8 *)b+os+1)<<0)); + return ((uint16) + ((uint16)*((uint8 *)b+os+0)<<8| + (uint16)*((uint8 *)b+os+1)<<0)); } __inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src) { - *((uint8*)dst+0)=*((uint8*)&src+3); - *((uint8*)dst+1)=*((uint8*)&src+2); - *((uint8*)dst+2)=*((uint8*)&src+1); - *((uint8*)dst+3)=*((uint8*)&src+0); + *((uint8*)dst+0)=*((uint8*)&src+3); + *((uint8*)dst+1)=*((uint8*)&src+2); + *((uint8*)dst+2)=*((uint8*)&src+1); + *((uint8*)dst+3)=*((uint8*)&src+0); } -#endif /* __GNUC__ */ +#endif /*_USE_SW_FUNCS_*/ #ifdef WIN_NT_DRIVER #define ALLOCATE_MEMORY(dest,type,amount) \ - (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); + (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); #define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ - { \ - (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \ - if ((dest)!=NULL) \ - RtlZeroMemory((dest),sizeof(type)*(amount)); \ - } + { \ + (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \ + if ((dest)!=NULL) \ + RtlZeroMemory((dest),sizeof(type)*(amount)); \ + } #define FREE_MEMORY(dest) ExFreePool(dest); #define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); diff --git a/drivers/net/packet/normal_lookup.h b/drivers/net/packet/normal_lookup.h index c88d890..69e21ce 100644 --- a/drivers/net/packet/normal_lookup.h +++ b/drivers/net/packet/normal_lookup.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -36,10 +36,10 @@ #endif -#define NORMAL_LUT_W_INSERT 0x00000000 +#define NORMAL_LUT_W_INSERT 0x00000000 uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); -#define NORMAL_LUT_WO_INSERT 0x00000001 +#define NORMAL_LUT_WO_INSERT 0x00000001 uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); -#define DUMMY_INSERT 1234 +#define DUMMY_INSERT 1234 #endif \ No newline at end of file diff --git a/drivers/net/packet/ntddpack.h b/drivers/net/packet/ntddpack.h index a868cc7..a855138 100644 --- a/drivers/net/packet/ntddpack.h +++ b/drivers/net/packet/ntddpack.h @@ -11,7 +11,7 @@ struct _PACKET_OID_DATA { ULONG Oid; ULONG Length; UCHAR Data[1]; -}; +}; typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; diff --git a/drivers/net/packet/openclos.c b/drivers/net/packet/openclos.c index 6c857a8..902afd0 100644 --- a/drivers/net/packet/openclos.c +++ b/drivers/net/packet/openclos.c @@ -67,8 +67,7 @@ NDIS_SPIN_LOCK Opened_Instances_Lock; //------------------------------------------------------------------- -NTSTATUS -NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PDEVICE_EXTENSION DeviceExtension; @@ -84,7 +83,6 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) PLIST_ENTRY PacketListEntry; PCHAR EvName; - IF_LOUD(DbgPrint("NPF: OpenAdapter\n");) DeviceExtension = DeviceObject->DeviceExtension; @@ -93,7 +91,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) IrpSp = IoGetCurrentIrpStackLocation(Irp); // allocate some memory for the open structure - Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA'); +#define NPF_TAG_OPENSTRUCT TAG('0', 'O', 'W', 'A') + Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), NPF_TAG_OPENSTRUCT); if (Open==NULL) { @@ -109,7 +108,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) ); - EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), '1OWA'); +#define NPF_TAG_EVNAME TAG('1', 'O', 'W', 'A') + EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), NPF_TAG_EVNAME); if (EvName==NULL) { // no memory @@ -187,7 +187,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) InitializeListHead(&Open->RequestList); // Initializes the extended memory of the NPF machine - Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA'); +#define NPF_TAG_MACHINE TAG('2', 'O', 'W', 'A') + Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, NPF_TAG_MACHINE); if((Open->mem_ex.buffer) == NULL) { // no memory @@ -208,7 +209,7 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) Open->Buffer = NULL; Open->Bhead = 0; Open->Btail = 0; - Open->BLastByte = 0; + (INT)Open->BLastByte = -1; Open->Dropped = 0; //reset the dropped packets counter Open->Received = 0; //reset the received packets counter Open->Accepted = 0; //reset the accepted packets counter @@ -225,6 +226,7 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) Open->DumpFileHandle = NULL; Open->tme.active = TME_NONE_ACTIVE; Open->DumpLimitReached = FALSE; + Open->MaxFrameSize = 0; //allocate the spinlock for the statistic counters NdisAllocateSpinLock(&Open->CountersLock); @@ -282,8 +284,12 @@ VOID NPF_OpenAdapterComplete( IN NDIS_STATUS OpenErrorStatus) { - PIRP Irp; - POPEN_INSTANCE Open; + PIRP Irp; + POPEN_INSTANCE Open; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST MaxSizeReq; + NDIS_STATUS ReqStatus; + IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");) @@ -306,6 +312,9 @@ VOID NPF_OpenAdapterComplete( ExFreePool(Open->ReadEventName.Buffer); + ZwClose(Open->ReadEventHandle); + + ExFreePool(Open); } else { @@ -318,6 +327,47 @@ VOID NPF_OpenAdapterComplete( // Get the absolute value of the system boot time. // This is used for timestamp conversion. TIME_SYNCHRONIZE(&G_Start_Time); + + // Extract a request from the list of free ones + RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock); + + if (RequestListEntry == NULL) + { + + Open->MaxFrameSize = 1514; // Assume Ethernet + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return; + } + + MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); + MaxSizeReq->Irp = Irp; + MaxSizeReq->Internal = TRUE; + + + MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; + + + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize; + MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4; + + // submit the request + NdisRequest( + &ReqStatus, + Open->AdapterHandle, + &MaxSizeReq->Request); + + + if (ReqStatus != NDIS_STATUS_PENDING) { + NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus); + } + + return; + } Irp->IoStatus.Status = Status; @@ -397,7 +447,6 @@ NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) // If this instance is in dump mode, complete the dump and close the file if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){ -#ifndef __GNUC__ NTSTATUS wres; ThreadDelay.QuadPart = -50000000; @@ -413,7 +462,6 @@ NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) // Flush and close the dump file NPF_CloseDumpFile(Open); -#endif } // Destroy the read Event diff --git a/drivers/net/packet/packet.c b/drivers/net/packet/packet.c index 1891a8a..dc063f5 100644 --- a/drivers/net/packet/packet.c +++ b/drivers/net/packet/packet.c @@ -82,6 +82,9 @@ extern NDIS_SPIN_LOCK Opened_Instances_Lock; // Packet Driver's entry routine. // NTSTATUS +#ifdef __GNUC__ +STDCALL +#endif DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath @@ -111,7 +114,7 @@ DriverEntry( return STATUS_IMAGE_MP_UP_MISMATCH; } - IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");) + IF_LOUD(DbgPrint("Packet: DriverEntry\n");) RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); @@ -123,17 +126,24 @@ DriverEntry( ProtocolChar.MinorNdisVersion = 0; #ifndef __GNUC__ ProtocolChar.Reserved = 0; +#else + ProtocolChar.u1.Reserved = 0; #endif ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete; ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete; #ifndef __GNUC__ ProtocolChar.SendCompleteHandler = NPF_SendComplete; ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete; +#else + ProtocolChar.u2.SendCompleteHandler = NPF_SendComplete; + ProtocolChar.u3.TransferDataCompleteHandler = NPF_TransferDataComplete; #endif ProtocolChar.ResetCompleteHandler = NPF_ResetComplete; ProtocolChar.RequestCompleteHandler = NPF_RequestComplete; #ifndef __GNUC__ ProtocolChar.ReceiveHandler = NPF_tap; +#else + ProtocolChar.u4.ReceiveHandler = NPF_tap; #endif ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete; ProtocolChar.StatusHandler = NPF_Status; @@ -170,6 +180,7 @@ DriverEntry( DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl; DriverObject->DriverUnload = NPF_Unload; +/* // Get the name of the Packet driver and the name of the NIC driver // to bind to from the registry Status=NPF_ReadRegistry( @@ -181,7 +192,7 @@ DriverEntry( if (Status != STATUS_SUCCESS) { IF_LOUD(DbgPrint("Trying dynamic binding\n");) - + */ bindP = getAdaptersList(); if (bindP == NULL) { @@ -198,7 +209,6 @@ DriverEntry( bindT = (WCHAR*)(tcpBindingsP->Data); } else { bindT = bindP; - } for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) { @@ -207,13 +217,10 @@ DriverEntry( } return STATUS_SUCCESS; - +/* } - BindStringSave = BindString; ExportStringSave = ExportString; - - // // create a device object for each entry // @@ -223,23 +230,16 @@ DriverEntry( // RtlInitUnicodeString( &MacDriverName, - BindString - ); - + BindString); RtlInitUnicodeString( &UnicodeDeviceName, - ExportString - ); - + ExportString); // // Advance to the next string of the MULTI_SZ string // BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); - ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); - IF_LOUD(DbgPrint("NPF: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);) - // // Create the device object // @@ -250,40 +250,25 @@ DriverEntry( FILE_DEVICE_PROTOCOL, 0, FALSE, - &DeviceObject - ); - + &DeviceObject); if (Status != STATUS_SUCCESS) { IF_LOUD(DbgPrint("NPF: IoCreateDevice() failed:\n");) - break; } - DevicesCreated++; - - DeviceObject->Flags |= DO_DIRECT_IO; DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; DeviceExtension->DeviceObject = DeviceObject; - // // Save the the name of the MAC driver to open in the Device Extension // - DeviceExtension->AdapterName=MacDriverName; - if (DevicesCreated == 1) { - DeviceExtension->BindString = NULL; DeviceExtension->ExportString = NULL; } - - DeviceExtension->NdisProtocolHandle=NdisProtocolHandle; - - } - if (DevicesCreated > 0) { // // Managed to create at least one device. @@ -291,11 +276,9 @@ DriverEntry( IF_LOUD(DbgPrint("NPF: Managed to create at least one device.\n");) return STATUS_SUCCESS; } - - - ExFreePool(BindStringSave); ExFreePool(ExportStringSave); + */ RegistryError: IF_LOUD(DbgPrint("NPF: RegistryError: calling NdisDeregisterProtocol()\n");) @@ -320,7 +303,8 @@ PWCHAR getAdaptersList(void) HANDLE keyHandle; UINT BufPos=0; - PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, '0PWA'); +#define NPF_TAG_DEVICENAME TAG('0', 'P', 'W', 'A') + PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, NPF_TAG_DEVICENAME); if (DeviceNames == NULL) { IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");) @@ -331,7 +315,10 @@ PWCHAR getAdaptersList(void) OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs); if (!NT_SUCCESS(status)) { - IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + + //IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);) + IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, AdapterListKey.Buffer);) + } else { //OK ULONG resultLength; KEY_VALUE_PARTIAL_INFORMATION valueInfo; @@ -389,7 +376,8 @@ PWCHAR getAdaptersList(void) IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) } else { // We know how big it needs to be. ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); - PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, '1PWA'); +#define NPF_TAG_KEYVALUE TAG('1', 'P', 'W', 'A') + PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE); if (valueInfoP != NULL) { status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, KeyValuePartialInformation, @@ -458,8 +446,9 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void) IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);) } else { // We know how big it needs to be. ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); +#define NPF_TAG_KEYVALUE2 TAG('2', 'P', 'W', 'A') PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = - (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, '2PWA'); + (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE2); if (valueInfoP != NULL) { status = ZwQueryValueKey(keyHandle, &bindValueName, @@ -506,54 +495,100 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void) BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP, IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle) { - NTSTATUS status; - PDEVICE_OBJECT devObjP; - UNICODE_STRING deviceName; - BOOLEAN result = FALSE; + NTSTATUS status; + PDEVICE_OBJECT devObjP; + UNICODE_STRING deviceName; + UNICODE_STRING deviceSymLink; - IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer);) - if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, + IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer);); + if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, devicePrefix.Length) < devicePrefix.Length) { - return result; - } + return FALSE; + } - deviceName.Length = 0; - deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL)); - deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA'); + deviceName.Length = 0; + deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL)); +#define NPF_TAG_DEVICENAMEBUF TAG('3', 'P', 'W', 'A') + deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, NPF_TAG_DEVICENAMEBUF); - if (deviceName.Buffer != NULL) { + if (deviceName.Buffer == NULL) + return FALSE; + + deviceSymLink.Length = 0; + deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length + + symbolicLinkPrefix.Length + + NPF_Prefix.Length + + sizeof(UNICODE_NULL)); + +#define NPF_TAG_SYMLINKBUF TAG('3', 'P', 'W', 'A') + deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, NPF_TAG_SYMLINKBUF); + + if (deviceSymLink.Buffer == NULL) + { + ExFreePool(deviceName.Buffer); + return FALSE; + } + RtlAppendUnicodeStringToString(&deviceName, &devicePrefix); RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix); RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer + devicePrefix.Length / sizeof(WCHAR)); - IF_LOUD(DbgPrint("\n\nDevice name: %ws\n", deviceName.Buffer);) + RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix); + RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix); + RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer + + devicePrefix.Length / sizeof(WCHAR)); + + IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);) - status = IoCreateDevice(adriverObjectP, sizeof(PDEVICE_EXTENSION), - &deviceName, FILE_DEVICE_TRANSPORT, 0, FALSE, - &devObjP); + status = IoCreateDevice(adriverObjectP, + sizeof(PDEVICE_EXTENSION), + &deviceName, + FILE_DEVICE_TRANSPORT, + 0, + FALSE, + &devObjP); if (NT_SUCCESS(status)) { - PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension; + PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension; - IF_LOUD(DbgPrint("\n\nDevice created succesfully\n");) + IF_LOUD(DbgPrint("Device created successfully\n");); - devObjP->Flags |= DO_DIRECT_IO; - - devExtP->DeviceObject = devObjP; - RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer); - devExtP->BindString = NULL; - devExtP->ExportString = NULL; - devExtP->NdisProtocolHandle=aProtoHandle; + devObjP->Flags |= DO_DIRECT_IO; + RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer); + devExtP->NdisProtocolHandle=aProtoHandle; + + IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer);); + + if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) { + IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer);); + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + devExtP->ExportString = NULL; + + return FALSE; } - else IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status);); + IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer);); - ExFreePool(deviceName.Buffer); - } + devExtP->ExportString = deviceSymLink.Buffer; + + ExFreePool(deviceName.Buffer); + + return TRUE; + } - return result; + else + { + IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status);); + + ExFreePool(deviceName.Buffer); + ExFreePool(deviceSymLink.Buffer); + + return FALSE; + } } //------------------------------------------------------------------- @@ -561,7 +596,6 @@ BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP, VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject) { - PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT OldDeviceObject; PDEVICE_EXTENSION DeviceExtension; @@ -569,27 +603,38 @@ NPF_Unload(IN PDRIVER_OBJECT DriverObject) NDIS_HANDLE NdisProtocolHandle; NDIS_STATUS Status; - IF_LOUD(DbgPrint("NPF: Unload\n");) + NDIS_STRING SymLink; + IF_LOUD(DbgPrint("NPF: Unload\n");); DeviceObject = DriverObject->DeviceObject; while (DeviceObject != NULL) { - DeviceExtension = DeviceObject->DeviceExtension; - - NdisProtocolHandle=DeviceExtension->NdisProtocolHandle; OldDeviceObject=DeviceObject; DeviceObject=DeviceObject->NextDevice; + DeviceExtension = OldDeviceObject->DeviceExtension; + + NdisProtocolHandle=DeviceExtension->NdisProtocolHandle; + IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n", DeviceExtension->AdapterName.Buffer, NdisProtocolHandle, DeviceObject, - OldDeviceObject);) + OldDeviceObject);); + + if (DeviceExtension->ExportString) + { + RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString); + IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer);); + + IoDeleteSymbolicLink(&SymLink); + ExFreePool(DeviceExtension->ExportString); + } + IoDeleteDevice(OldDeviceObject); - } NdisDeregisterProtocol( @@ -599,7 +644,6 @@ NPF_Unload(IN PDRIVER_OBJECT DriverObject) // Free the adapters names ExFreePool( bindP ); - } //------------------------------------------------------------------- @@ -754,7 +798,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) // Allocate the memory to contain the new filter program // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers() - TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA'); +#define NPF_TAG_BPFPROG TAG('4', 'P', 'W', 'A') + TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), NPF_TAG_BPFPROG); if (TmpBPFProgram==NULL){ IF_LOUD(DbgPrint("Error - No memory for filter");) // no memory @@ -766,11 +811,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) Open->bpfprogram=TmpBPFProgram; // Create the new JIT filter function - if(!IsExtendedFilter) - if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) - == NULL) - { + if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL) { IF_LOUD(DbgPrint("Error jittering filter");) EXIT_FAILURE(0); } @@ -778,9 +820,10 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) //return Open->Bhead = 0; Open->Btail = 0; - Open->BLastByte = 0; + (INT)Open->BLastByte = -1; Open->Received = 0; Open->Dropped = 0; + Open->Accepted = 0; EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength); @@ -839,7 +882,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) } // Allocate the buffer that will contain the string - DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA'); +#define NPF_TAG_DUMPNAMEBUF TAG('5', 'P', 'W', 'A') + DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, NPF_TAG_DUMPNAMEBUF); if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){ IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");) EXIT_FAILURE(0); @@ -908,7 +952,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) } // Allocate the new buffer if(dim!=0){ - tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA'); +#define NPF_TAG_TPOINTER TAG('6', 'P', 'W', 'A') + tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, NPF_TAG_TPOINTER); if (tpointer==NULL) { // no memory Open->BufSize = 0; @@ -922,7 +967,7 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) Open->Buffer = tpointer; Open->Bhead = 0; Open->Btail = 0; - Open->BLastByte = 0; + (INT)Open->BLastByte = -1; Open->BufSize = (UINT)dim; EXIT_SUCCESS(dim); @@ -990,6 +1035,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement); pRequest->Irp=Irp; + pRequest->Internal = FALSE; + // // See if it is an Ndis request @@ -1094,11 +1141,18 @@ NPF_RequestComplete( pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); Irp=pRequest->Irp; - if(Irp == NULL){ + if(pRequest->Internal == TRUE){ // Put the request in the list of the free ones ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock); + if(Status != NDIS_STATUS_SUCCESS) + Open->MaxFrameSize = 1514; // Assume Ethernet + + // We always return success, because the adapter has been already opened + Irp->IoStatus.Status = NDIS_STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return; } @@ -1138,7 +1192,7 @@ NPF_RequestComplete( IoCompleteRequest(Irp, IO_NO_INCREMENT); - // Unlock the IOCTL call + // Unlock the caller NdisSetEvent(&Open->IOEvent); return; @@ -1200,7 +1254,8 @@ NPF_ReadRegistry( PWCHAR Path; - Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA'); +#define NPF_TAG_PATH TAG('7', 'P', 'W', 'A') + Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), NPF_TAG_PATH); if (Path == NULL) { IF_LOUD(DbgPrint("\nPacketReadRegistry: returing STATUS_INSUFFICIENT_RESOURCES\n");) @@ -1311,7 +1366,8 @@ NPF_QueryRegistryRoutine( } - Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA'); +#define NPF_TAG_REGBUF TAG('8', 'P', 'W', 'A') + Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, NPF_TAG_REGBUF); if (Buffer==NULL) { diff --git a/drivers/net/packet/packet.h b/drivers/net/packet/packet.h index 18dfcb1..a3582cc 100644 --- a/drivers/net/packet/packet.h +++ b/drivers/net/packet/packet.h @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2000 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -30,11 +30,15 @@ #ifndef __PACKET_INCLUDE______ #define __PACKET_INCLUDE______ -#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls +#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls +#ifdef __GNUC__ +#undef EXIT_SUCCESS +#undef EXIT_FAILURE #define UNICODE_NULL ((WCHAR)0) // winnt - #include "win_bpf.h" +#include +#endif #include "jitter.h" #include "tme.h" @@ -42,8 +46,10 @@ #define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests. #define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size. -#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next - ///< even multiple of Packet_ALIGNMENT. +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next + ///< even multiple of Packet_ALIGNMENT. + + /***************************/ /* IOCTLs */ /***************************/ @@ -56,7 +62,7 @@ and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently buffered packets are lost. */ -#define BIOCSETBUFFERSIZE 9592 +#define BIOCSETBUFFERSIZE 9592 /*! \brief IOCTL code: set packet filtering program. @@ -68,7 +74,7 @@ every incoming packet. This command also empties the circular buffer used by current instance to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter. */ -#define BIOCSETF 9030 +#define BIOCSETF 9030 /*! \brief IOCTL code: get the capture stats @@ -83,7 +89,7 @@ This command sets the maximum timeout after which a read is released, also if no data packets were received. */ -#define BIOCSRTIMEOUT 7416 +#define BIOCSRTIMEOUT 7416 /*! \brief IOCTL code: set working mode @@ -92,7 +98,7 @@ buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for statistical mode or #MODE_DUMP for dump mode. */ -#define BIOCSMODE 7412 +#define BIOCSMODE 7412 /*! \brief IOCTL code: set number of physical repetions of every packet written by the app @@ -100,28 +106,28 @@ Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites member, and is used to implement the 'multiple write' feature of the driver. */ -#define BIOCSWRITEREP 7413 +#define BIOCSWRITEREP 7413 /*! \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call This command sets the OPEN_INSTANCE::MinToCopy member. */ -#define BIOCSMINTOCOPY 7414 +#define BIOCSMINTOCOPY 7414 /*! \brief IOCTL code: set an OID value This IOCTL is used to perform an OID set operation on the NIC driver. */ -#define BIOCSETOID 2147483648 +#define BIOCSETOID 2147483648 /*! \brief IOCTL code: get an OID value This IOCTL is used to perform an OID get operation on the NIC driver. */ -#define BIOCQUERYOID 2147483652 +#define BIOCQUERYOID 2147483652 /*! \brief IOCTL code: set the name of a the file used by kernel dump mode @@ -176,20 +182,20 @@ #define BIOCISDUMPENDED 7411 // Working modes -#define MODE_CAPT 0x0 ///< Capture working mode -#define MODE_STAT 0x1 ///< Statistical working mode -#define MODE_MON 0x2 ///< Kernel monitoring mode -#define MODE_DUMP 0x10 ///< Kernel dump working mode +#define MODE_CAPT 0x0 ///< Capture working mode +#define MODE_STAT 0x1 ///< Statistical working mode +#define MODE_MON 0x2 ///< Kernel monitoring mode +#define MODE_DUMP 0x10 ///< Kernel dump working mode -#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately. +#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately. // The following definitions are used to provide compatibility // of the dump files with the ones of libpcap -#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file. -#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. -#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. +#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. +#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file. /*! \brief Header of a libpcap dump file. @@ -198,13 +204,13 @@ */ struct packet_file_header { - UINT magic; ///< Libpcap magic number - USHORT version_major; ///< Libpcap major version - USHORT version_minor; ///< Libpcap minor version - UINT thiszone; ///< Gmt to local correction - UINT sigfigs; ///< Accuracy of timestamps - UINT snaplen; ///< Length of the max saved portion of each packet - UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details. + UINT magic; ///< Libpcap magic number + USHORT version_major; ///< Libpcap major version + USHORT version_minor; ///< Libpcap minor version + UINT thiszone; ///< Gmt to local correction + UINT sigfigs; ///< Accuracy of timestamps + UINT snaplen; ///< Length of the max saved portion of each packet + UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details. }; /*! @@ -212,11 +218,11 @@ struct packet_file_header Similar to the bpf_hdr structure, but simpler. */ struct sf_pkthdr { - struct timeval ts; ///< time stamp - UINT caplen; ///< Length of captured portion. The captured portion can be different from - ///< the original packet, because it is possible (with a proper filter) to - ///< instruct the driver to capture only a portion of the packets. - UINT len; ///< Length of the original packet (off wire). + struct timeval ts; ///< time stamp + UINT caplen; ///< Length of captured portion. The captured portion can be different from + ///< the original packet, because it is possible (with a proper filter) to + ///< instruct the driver to capture only a portion of the packets. + UINT len; ///< Length of the original packet (off wire). }; /*! @@ -229,9 +235,10 @@ struct sf_pkthdr { maintaining information about the IRPs to complete. */ typedef struct _INTERNAL_REQUEST { - LIST_ENTRY ListElement; ///< Used to handle lists of requests. - PIRP Irp; ///< Irp that performed the request - NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest(). + LIST_ENTRY ListElement; ///< Used to handle lists of requests. + PIRP Irp; ///< Irp that performed the request + BOOLEAN Internal; ///< True if the request is for internal use of npf.sys. False if the request is performed by the user through an IOCTL. + NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest(). } INTERNAL_REQUEST, *PINTERNAL_REQUEST; /*! @@ -242,11 +249,11 @@ typedef struct _INTERNAL_REQUEST { maintaining information about the IRPs to complete. */ typedef struct _PACKET_RESERVED { - LIST_ENTRY ListElement; ///< Used to handle lists of packets. - PIRP Irp; ///< Irp that performed the request - PMDL pMdl; ///< MDL mapping the buffer of the packet. - BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed - ///< after a call to NdisSend(). + LIST_ENTRY ListElement; ///< Used to handle lists of packets. + PIRP Irp; ///< Irp that performed the request + PMDL pMdl; ///< MDL mapping the buffer of the packet. + BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed + ///< after a call to NdisSend(). } PACKET_RESERVED, *PPACKET_RESERVED; #define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED @@ -257,12 +264,10 @@ typedef struct _PACKET_RESERVED { Structure containing some data relative to every adapter on which NPF is bound. */ typedef struct _DEVICE_EXTENSION { - PDEVICE_OBJECT DeviceObject; ///< Adapter's device. - NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF. - NDIS_STRING AdapterName; ///< Name of the adapter. - PWSTR BindString; ///< Original device name of the adapter. - PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use - ///< to open this adapter through WinPcap. + NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF. + NDIS_STRING AdapterName; ///< Name of the adapter. + PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use + ///< to open this adapter through WinPcap. } DEVICE_EXTENSION, *PDEVICE_EXTENSION; /*! @@ -274,106 +279,104 @@ typedef struct _DEVICE_EXTENSION { */ typedef struct _OPEN_INSTANCE { - PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which - ///< the instance is bound. - NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance. - UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the - ///< documentation of NdisOpenAdapter in the MS DDK for details. - NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver. - PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the - ///< callbacks of NDIS. - KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests. - LIST_ENTRY RequestList; ///< List of pending OID requests. - LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests. + PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which + ///< the instance is bound. + NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance. + UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the + ///< documentation of NdisOpenAdapter in the MS DDK for details. + NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver. + PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the + ///< callbacks of NDIS. + KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests. + LIST_ENTRY RequestList; ///< List of pending OID requests. + LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests. INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request. - PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory. - PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait. - HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait. - UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait. - ///< The event is created with a name, so it can be used at user level to know when it - ///< is possible to access the driver without being blocked. This fiels stores the name - ///< that and is used by the BIOCGEVNAME IOCTL call. - INT Received; ///< Number of packets received by current instance from its opening, i.e. number of - ///< packet received by the network adapter since the beginning of the - ///< capture/monitoring/dump session. - INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet - ///< is dropped if there is no more space to store it in the circular buffer that the - ///< driver associates to current instance. - INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet - ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the - ///< ones that reach the application. - PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver. - ///< This code is used only in particular situations (for example when the packet received - ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations - ///< the filtering routine created by the JIT compiler and pointed by the next field - ///< is used. See \ref NPF for details on the filtering process. - JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter. - ///< See BPF_jitter() for details. - PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the - ///< data that will be passed to the application. See \ref NPF for details. - UINT Bhead; ///< Head of the circular buffer. - UINT Btail; ///< Tail of the circular buffer. - UINT BufSize; ///< Size of the circular buffer. - UINT BLastByte; ///< Position of the last valid byte in the circular buffer. - PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet. - ///< Used by NdisTransferData(). - NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables. - UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the - ///< BIOCSMINTOCOPY IOCTL. - LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is - ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL. - - int mode; ///< Working mode of the driver. See PacketSetMode() for details. - LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode. - LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode. - NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters. - UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an - ///< explanation - UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated. - NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process. - NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS. - NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application. - BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be - ///< FALSE if a Plug and Play adapter has been removed or disabled by the user. - HANDLE DumpFileHandle; ///< Handle of the file used in dump mode. - PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode. -// PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode. - HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk. - NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode. - LARGE_INTEGER DumpOffset; ///< Current offset in the dump file. - UNICODE_STRING DumpFileName; ///< String containing the name of the dump file. - UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it - ///< will be closed. A value of 0 means unlimited size. - UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of - ///< packets is reached the dump will be closed. A value of 0 means unlimited number of - ///< packets. - BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is - ///< reached. - MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor - TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor - NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer + PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory. + PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait. + HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait. + UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait. + ///< The event is created with a name, so it can be used at user level to know when it + ///< is possible to access the driver without being blocked. This fiels stores the name + ///< that and is used by the BIOCGEVNAME IOCTL call. + INT Received; ///< Number of packets received by current instance from its opening, i.e. number of + ///< packet received by the network adapter since the beginning of the + ///< capture/monitoring/dump session. + INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet + ///< is dropped if there is no more space to store it in the circular buffer that the + ///< driver associates to current instance. + INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet + ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the + ///< ones that reach the application. + PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver. + ///< This code is used only in particular situations (for example when the packet received + ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations + ///< the filtering routine created by the JIT compiler and pointed by the next field + ///< is used. See \ref NPF for details on the filtering process. + JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter. + ///< See BPF_jitter() for details. + PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the + ///< data that will be passed to the application. See \ref NPF for details. + UINT Bhead; ///< Head of the circular buffer. + UINT Btail; ///< Tail of the circular buffer. + UINT BufSize; ///< Size of the circular buffer. + UINT BLastByte; ///< Position of the last valid byte in the circular buffer. + PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet. + ///< Used by NdisTransferData(). + NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables. + UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the + ///< BIOCSMINTOCOPY IOCTL. + LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is + ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL. + + int mode; ///< Working mode of the driver. See PacketSetMode() for details. + LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode. + LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode. + NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters. + UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an + ///< explanation + UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated. + NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process. + NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS. + NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application. + BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be + ///< FALSE if a Plug and Play adapter has been removed or disabled by the user. + HANDLE DumpFileHandle; ///< Handle of the file used in dump mode. + PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode. + PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode. + HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk. + NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode. + LARGE_INTEGER DumpOffset; ///< Current offset in the dump file. + UNICODE_STRING DumpFileName; ///< String containing the name of the dump file. + UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it + ///< will be closed. A value of 0 means unlimited size. + UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of + ///< packets is reached the dump will be closed. A value of 0 means unlimited number of + ///< packets. + BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is + ///< reached. + MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor + TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor + NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer + UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the + ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite(). } OPEN_INSTANCE, *POPEN_INSTANCE; -#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number - ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets. +#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number + ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets. -#ifdef __GNUC__ -#undef EXIT_SUCCESS -#undef EXIT_FAILURE -#endif /// Macro used in the I/O routines to return the control to user-mode with a success status. #define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\ -Irp->IoStatus.Status = STATUS_SUCCESS;\ -IoCompleteRequest(Irp, IO_NO_INCREMENT);\ -return STATUS_SUCCESS;\ + Irp->IoStatus.Status = STATUS_SUCCESS;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_SUCCESS;\ /// Macro used in the I/O routines to return the control to user-mode with a failure status. #define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\ -Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\ -IoCompleteRequest(Irp, IO_NO_INCREMENT);\ -return STATUS_UNSUCCESSFUL;\ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\ + IoCompleteRequest(Irp, IO_NO_INCREMENT);\ + return STATUS_UNSUCCESSFUL;\ /** * @} @@ -400,11 +403,11 @@ return STATUS_UNSUCCESSFUL;\ performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O callbacks, creates the devices, defines NPF as a protocol inside NDIS. */ -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); +//NTSTATUS +//DriverEntry( +// IN PDRIVER_OBJECT DriverObject, +// IN PUNICODE_STRING RegistryPath +// ); /*! \brief Returns the list of the MACs available on the system. @@ -437,9 +440,9 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID); determine the correct adapter to use. */ BOOLEAN createDevice( - IN OUT PDRIVER_OBJECT adriverObjectP, - IN PUNICODE_STRING amacNameP, - NDIS_HANDLE aProtoHandle); + IN OUT PDRIVER_OBJECT adriverObjectP, + IN PUNICODE_STRING amacNameP, + NDIS_HANDLE aProtoHandle); /*! \brief Opens a new instance of the driver. @@ -584,8 +587,8 @@ NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext); - #BIOCQUERYOID - #BIOCSETDUMPFILENAME - #BIOCGEVNAME - - #BIOCSENDPACKETSSYNC - - #BIOCSENDPACKETSNOSYNC + - #BIOCSENDPACKETSSYNC + - #BIOCSENDPACKETSNOSYNC */ NTSTATUS NPF_IoControl( @@ -624,9 +627,9 @@ NPF_RequestComplete( */ NTSTATUS NPF_Write( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); /*! @@ -636,7 +639,7 @@ NPF_Write( \param UserBuffSize Size of the buffer with the packets. \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an error occurred during the send. The error can be caused by an adapter problem or by an - inconsistent/bogus user buffer. + inconsistent/bogus user buffer. This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL. The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a @@ -648,9 +651,9 @@ NPF_Write( */ INT NPF_BufferedWrite(IN PIRP Irp, - IN PCHAR UserBuff, - IN ULONG UserBuffSize, - BOOLEAN sync); + IN PCHAR UserBuff, + IN ULONG UserBuffSize, + BOOLEAN sync); /*! \brief Ends a send operation. @@ -827,12 +830,12 @@ int bpf_validate(struct bpf_insn *f,int len, uint32 mem_ex_size); that is faster than the interpreter. */ UINT bpf_filter(register struct bpf_insn *pc, - register UCHAR *p, - UINT wirelen, - register UINT buflen, - PMEM_TYPE mem_ex, - PTME_CORE tme, - struct time_conv *time_ref); + register UCHAR *p, + UINT wirelen, + register UINT buflen, + PMEM_TYPE mem_ex, + PTME_CORE tme, + struct time_conv *time_ref); /*! \brief The filtering pseudo-machine interpreter with two buffers. This function is slower than bpf_filter(), @@ -852,14 +855,14 @@ UINT bpf_filter(register struct bpf_insn *pc, This function is used when NDIS passes the packet to NPF_tap() in two buffers instaed than in a single one. */ UINT bpf_filter_with_2_buffers(register struct bpf_insn *pc, - register UCHAR *p, - register UCHAR *pd, - register int headersize, - UINT wirelen, - register UINT buflen, - PMEM_TYPE mem_ex, - PTME_CORE tme, - struct time_conv *time_ref); + register UCHAR *p, + register UCHAR *pd, + register int headersize, + UINT wirelen, + register UINT buflen, + PMEM_TYPE mem_ex, + PTME_CORE tme, + struct time_conv *time_ref); /*! \brief Creates the file that will receive the packets when the driver is in dump mode. @@ -910,10 +913,10 @@ NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open); of the NPF circular buffer to disk. This function is used by NPF_DumpThread(). */ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject, - PLARGE_INTEGER Offset, - ULONG Length, - PMDL Mdl, - PIO_STATUS_BLOCK IoStatusBlock); + PLARGE_INTEGER Offset, + ULONG Length, + PMDL Mdl, + PIO_STATUS_BLOCK IoStatusBlock); @@ -954,4 +957,3 @@ NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_E */ #endif /*main ifndef/define*/ - diff --git a/drivers/net/packet/read.c b/drivers/net/packet/read.c index fc82870..e456f1a 100644 --- a/drivers/net/packet/read.c +++ b/drivers/net/packet/read.c @@ -27,6 +27,16 @@ #else #include #include + +#define NdisMoveMappedMemory(Destination,Source,Length) RtlCopyMemory(Destination,Source,Length) +#define NdisZeroMappedMemory(Destination,Length) RtlZeroMemory(Destination,Length) +#define NdisReinitializePacket(Packet) \ +{ \ + (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \ + (Packet)->Private.ValidCounts = FALSE; \ +} + + #endif #include "debug.h" @@ -92,20 +102,19 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) POPEN_INSTANCE Open; PIO_STACK_LOCATION IrpSp; PUCHAR packp; - UINT i; ULONG Input_Buffer_Length; UINT Thead; UINT Ttail; UINT TLastByte; PUCHAR CurrBuff; - UINT cplen; - UINT CpStart; LARGE_INTEGER CapTime; LARGE_INTEGER TimeFreq; struct bpf_hdr *header; KIRQL Irql; PUCHAR UserPointer; ULONG bytecopy; + UINT SizeToCopy; + UINT PktLen; IF_LOUD(DbgPrint("NPF: Read\n");) @@ -255,7 +264,7 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) NdisReleaseSpinLock( &Open->BufLock ); Input_Buffer_Length=IrpSp->Parameters.Read.Length; - packp=(PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress); + packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); // @@ -283,47 +292,38 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) } //the buffer must be scannned to determine the number of bytes to copy - CpStart=Thead; - i=0; + SizeToCopy = 0; while(TRUE){ - if(Thead == Ttail)break; + if(Thead + SizeToCopy == Ttail) + break; - if(Thead == TLastByte){ - // Copy the portion between thead and TLastByte - PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); - packp+=(Thead-CpStart); + if(Thead + SizeToCopy == TLastByte && TLastByte != Ttail){ + PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead)); + // Reset the buffer NdisAcquireSpinLock( &Open->BufLock ); - - Open->BLastByte = Open->Btail; - Open->Bhead = 0; - + (INT)Open->BLastByte = -1; + Open->Bhead = 0; NdisReleaseSpinLock( &Open->BufLock ); - Thead=0; - CpStart=0; + EXIT_SUCCESS(SizeToCopy); } - cplen=((struct bpf_hdr*)(CurrBuff+Thead))->bh_caplen+sizeof(struct bpf_hdr); - if((i+cplen > Input_Buffer_Length)){//no more space in the application's buffer - PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); + // Get the size of the next packet in the buffer + PktLen = ((struct bpf_hdr*)(CurrBuff + Thead + SizeToCopy))->bh_caplen + sizeof(struct bpf_hdr); - EXIT_SUCCESS(i); - } - cplen=Packet_WORDALIGN(cplen); - i+=cplen; - Thead+=cplen; + // The length is aligned to 32-bit boundary + PktLen = Packet_WORDALIGN(PktLen); + + if(SizeToCopy + PktLen > Input_Buffer_Length) + break; + + SizeToCopy += PktLen; } - - KeResetEvent(Open->ReadEvent); - - PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); - - Open->Bhead=Thead; - - - EXIT_SUCCESS(i); + PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead)); + EXIT_SUCCESS(SizeToCopy); + } //------------------------------------------------------------------- @@ -350,8 +350,14 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec UINT maxbufspace; USHORT NPFHdrSize; UINT BufOccupation; + BOOLEAN ResetBuff = FALSE; IF_VERY_LOUD(DbgPrint("NPF: tap\n");) + IF_VERY_LOUD(DbgPrint("HeaderBufferSize=%d, LookAheadBuffer=%d, LookaheadBufferSize=%d, PacketSize=%d\n", + HeaderBufferSize, + LookAheadBuffer, + LookaheadBufferSize, + PacketSize);) Open= (POPEN_INSTANCE)ProtocolBindingContext; @@ -401,6 +407,7 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec #ifndef __GNUC__ _asm add esp,12 #else + asm("add $0x12,%esp;"); #endif } else @@ -489,9 +496,16 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec } else{ Ttail=0; + ResetBuff = TRUE; } } + if (Thead > Ttail && (Thead-Ttail) <= maxbufspace) + { + Open->Dropped++; + return NDIS_STATUS_NOT_ACCEPTED; + } + CurrBuff=Open->Buffer+Ttail; if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize) @@ -568,15 +582,17 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec HeaderBuffer, HeaderBufferSize + LookaheadBufferSize); + BytesTransfered = 0; + Open->TransferMdl = NULL; Status = NDIS_STATUS_SUCCESS; } - Open->Accepted++; // Increase the accepted packets counter - if (Status != NDIS_STATUS_FAILURE) { + Open->Accepted++; // Increase the accepted packets counter + if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) ) fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize; @@ -596,12 +612,12 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec Ttail+=fres+NPFHdrSize; //update the buffer - if(Ttail > Thead)TLastByte = Ttail; - NdisAcquireSpinLock( &Open->BufLock ); + if(ResetBuff){ + Open->BLastByte = Open->Btail; + } Open->Btail=Ttail; - Open->BLastByte=TLastByte; NdisReleaseSpinLock( &Open->BufLock ); } diff --git a/drivers/net/packet/tcp_session.h b/drivers/net/packet/tcp_session.h index 7b0fe91..6262e79 100644 --- a/drivers/net/packet/tcp_session.h +++ b/drivers/net/packet/tcp_session.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -36,50 +36,50 @@ #endif -#define UNKNOWN 0 -#define SYN_RCV 1 -#define SYN_ACK_RCV 2 -#define ESTABLISHED 3 -#define CLOSED_RST 4 -#define FIN_CLN_RCV 5 -#define FIN_SRV_RCV 6 -#define CLOSED_FIN 7 -#define ERROR_TCP 8 -#define FIRST_IS_CLN 0 -#define FIRST_IS_SRV 0xffffffff -#define FIN_CLN 1 -#define FIN_SRV 2 +#define UNKNOWN 0 +#define SYN_RCV 1 +#define SYN_ACK_RCV 2 +#define ESTABLISHED 3 +#define CLOSED_RST 4 +#define FIN_CLN_RCV 5 +#define FIN_SRV_RCV 6 +#define CLOSED_FIN 7 +#define ERROR_TCP 8 +#define FIRST_IS_CLN 0 +#define FIRST_IS_SRV 0xffffffff +#define FIN_CLN 1 +#define FIN_SRV 2 #define MAX_WINDOW 65536 typedef struct __tcp_data { - struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/ - struct timeval syn_timestamp; - struct timeval last_timestamp; - struct timeval syn_ack_timestamp; - uint32 direction; - uint32 seq_n_0_srv; - uint32 seq_n_0_cln; - uint32 ack_srv; /* acknowledge of (data sent by server) */ - uint32 ack_cln; /* acknowledge of (data sent by client) */ - uint32 status; - uint32 pkts_cln_to_srv; - uint32 pkts_srv_to_cln; - uint32 bytes_srv_to_cln; - uint32 bytes_cln_to_srv; - uint32 close_state; + struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/ + struct timeval syn_timestamp; + struct timeval last_timestamp; + struct timeval syn_ack_timestamp; + uint32 direction; + uint32 seq_n_0_srv; + uint32 seq_n_0_cln; + uint32 ack_srv; /* acknowledge of (data sent by server) */ + uint32 ack_cln; /* acknowledge of (data sent by client) */ + uint32 status; + uint32 pkts_cln_to_srv; + uint32 pkts_srv_to_cln; + uint32 bytes_srv_to_cln; + uint32 bytes_cln_to_srv; + uint32 close_state; } - tcp_data; + tcp_data; -#define FIN 1 -#define SYN 2 -#define RST 4 -#define PSH 8 -#define ACK 16 -#define URG 32 +#define FIN 1 +#define SYN 2 +#define RST 4 +#define PSH 8 +#define ACK 16 +#define URG 32 -#define TCP_SESSION 0x00000800 +#define TCP_SESSION 0x00000800 uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); #endif \ No newline at end of file diff --git a/drivers/net/packet/time_calls.c b/drivers/net/packet/time_calls.c index 66f18b7..0e42697 100644 --- a/drivers/net/packet/time_calls.c +++ b/drivers/net/packet/time_calls.c @@ -26,11 +26,9 @@ void TIME_DESYNCHRONIZE(struct time_conv *data) { -#ifndef __GNUC__ data->reference = 0; data->start.tv_sec = 0; data->start.tv_usec = 0; -#endif } #ifdef KQPC_TS @@ -39,7 +37,6 @@ void TIME_DESYNCHRONIZE(struct time_conv *data) VOID TIME_SYNCHRONIZE(struct time_conv *data) { -#ifndef __GNUC__ struct timeval tmp; LARGE_INTEGER SystemTime; LARGE_INTEGER i; @@ -52,17 +49,20 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data) // get the absolute value of the system boot time. PTime=KeQueryPerformanceCounter(&TimeFreq); KeQuerySystemTime(&SystemTime); +#ifndef __GNUC__ tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600); tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10); tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart); tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); +#else + // TODO FIXME: +#endif if (tmp.tv_usec<0) { tmp.tv_sec--; tmp.tv_usec+=1000000; } data->start=tmp; data->reference=1; -#endif } void FORCE_TIME(struct timeval *src, struct time_conv *dest) @@ -72,29 +72,30 @@ void FORCE_TIME(struct timeval *src, struct time_conv *dest) void GET_TIME(struct timeval *dst, struct time_conv *data) { -#ifndef __GNUC__ LARGE_INTEGER PTime, TimeFreq; LONG tmp; PTime=KeQueryPerformanceCounter(&TimeFreq); +#ifndef __GNUC__ tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart); dst->tv_sec=data->start.tv_sec+tmp; dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); +#else + // TODO FIXME: +#endif if (dst->tv_usec>=1000000) { dst->tv_sec++; dst->tv_usec-=1000000; } -#endif } -#else +#else /*KQPC_TS*/ /*RDTSC timestamps*/ /* callers must be at IRQL=PASSIVE_LEVEL */ VOID TIME_SYNCHRONIZE(struct time_conv *data) { -#ifndef __GNUC__ struct timeval tmp; LARGE_INTEGER system_time; ULONGLONG curr_ticks; @@ -128,6 +129,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data) pop eax } #else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(start_ticks): ); #endif KeLowerIrql(old); KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); @@ -148,6 +160,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data) pop eax } #else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(stop_ticks): ); #endif KeLowerIrql(old); delta=stop_ticks-start_ticks; @@ -178,6 +201,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data) pop eax } #else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(curr_ticks): ); #endif tmp.tv_sec=-(LONG)(curr_ticks/reference); tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); @@ -190,8 +224,6 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data) } data->start=tmp; IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) -#else -#endif } void FORCE_TIME(struct timeval *src, struct time_conv *dest) @@ -201,7 +233,6 @@ void FORCE_TIME(struct timeval *src, struct time_conv *dest) void GET_TIME(struct timeval *dst, struct time_conv *data) { -#ifndef __GNUC__ ULONGLONG tmp; #ifndef __GNUC__ __asm @@ -218,6 +249,17 @@ void GET_TIME(struct timeval *dst, struct time_conv *data) pop eax } #else + asm("push %%eax;" + "push %%edx;" + "push %%ecx;" + "rdtsc;" + "lea %0,%%ecx;" + "mov %%edx,(%%ecx+4);" + "mov %%eax,(%%ecx);" + "pop %%ecx;" + "pop %%edx;" + "pop %%eax;" + :"=c"(tmp): ); #endif if (data->reference==0) { return; @@ -230,7 +272,6 @@ void GET_TIME(struct timeval *dst, struct time_conv *data) dst->tv_sec++; dst->tv_usec-=1000000; } -#endif } #endif /*KQPC_TS*/ diff --git a/drivers/net/packet/time_calls.h b/drivers/net/packet/time_calls.h index 2355d45..04731cf 100644 --- a/drivers/net/packet/time_calls.h +++ b/drivers/net/packet/time_calls.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -40,8 +40,8 @@ struct timeval { #endif /*WIN_NT_DRIVER*/ struct time_conv { - ULONGLONG reference; - struct timeval start; + ULONGLONG reference; + struct timeval start; }; #ifdef __GNUC__ @@ -57,9 +57,9 @@ void GET_TIME(struct timeval *dst, struct time_conv *data); __inline void TIME_DESYNCHRONIZE(struct time_conv *data) { - data->reference = 0; - data->start.tv_sec = 0; - data->start.tv_usec = 0; + data->reference = 0; + data->start.tv_sec = 0; + data->start.tv_usec = 0; } #ifdef KQPC_TS @@ -68,48 +68,48 @@ __inline void TIME_DESYNCHRONIZE(struct time_conv *data) __inline VOID TIME_SYNCHRONIZE(struct time_conv *data) { - struct timeval tmp; - LARGE_INTEGER SystemTime; - LARGE_INTEGER i; - ULONG tmp2; - LARGE_INTEGER TimeFreq,PTime; + struct timeval tmp; + LARGE_INTEGER SystemTime; + LARGE_INTEGER i; + ULONG tmp2; + LARGE_INTEGER TimeFreq,PTime; - if (data->reference!=0) - return; - - // get the absolute value of the system boot time. - PTime=KeQueryPerformanceCounter(&TimeFreq); - KeQuerySystemTime(&SystemTime); - tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600); - tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10); - tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart); - tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); - if (tmp.tv_usec<0) { - tmp.tv_sec--; - tmp.tv_usec+=1000000; - } - data->start=tmp; - data->reference=1; + if (data->reference!=0) + return; + + // get the absolute value of the system boot time. + PTime=KeQueryPerformanceCounter(&TimeFreq); + KeQuerySystemTime(&SystemTime); + tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600); + tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10); + tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart); + tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + data->reference=1; } -__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) +__inline void GET_TIME(struct timeval *dst, struct time_conv *data) { - dest->start=*src; + LARGE_INTEGER PTime, TimeFreq; + LONG tmp; + + PTime=KeQueryPerformanceCounter(&TimeFreq); + tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart); + dst->tv_sec=data->start.tv_sec+tmp; + dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } } -__inline void GET_TIME(struct timeval *dst, struct time_conv *data) +__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) { - LARGE_INTEGER PTime, TimeFreq; - LONG tmp; - - PTime=KeQueryPerformanceCounter(&TimeFreq); - tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart); - dst->tv_sec=data->start.tv_sec+tmp; - dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); - if (dst->tv_usec>=1000000) { - dst->tv_sec++; - dst->tv_usec-=1000000; - } + dest->start=*src; } #else @@ -119,138 +119,138 @@ __inline void GET_TIME(struct timeval *dst, struct time_conv *data) /* callers must be at IRQL=PASSIVE_LEVEL */ __inline VOID TIME_SYNCHRONIZE(struct time_conv *data) { - struct timeval tmp; - LARGE_INTEGER system_time; - ULONGLONG curr_ticks; - KIRQL old; - LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; - ULONGLONG start_ticks,stop_ticks; - ULONGLONG delta,delta2; - KEVENT event; - LARGE_INTEGER i; - ULONGLONG reference; + struct timeval tmp; + LARGE_INTEGER system_time; + ULONGLONG curr_ticks; + KIRQL old; + LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; + ULONGLONG start_ticks,stop_ticks; + ULONGLONG delta,delta2; + KEVENT event; + LARGE_INTEGER i; + ULONGLONG reference; - if (data->reference!=0) - return; - - KeInitializeEvent(&event,NotificationEvent,FALSE); - i.QuadPart=-3500000; - KeRaiseIrql(HIGH_LEVEL,&old); - start_kqpc=KeQueryPerformanceCounter(&start_freq); + if (data->reference!=0) + return; + + KeInitializeEvent(&event,NotificationEvent,FALSE); + i.QuadPart=-3500000; + KeRaiseIrql(HIGH_LEVEL,&old); + start_kqpc=KeQueryPerformanceCounter(&start_freq); #ifndef __GNUC__ - __asm - { - push eax - push edx - push ecx - rdtsc - lea ecx, start_ticks - mov [ecx+4], edx - mov [ecx], eax - pop ecx - pop edx - pop eax - } + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, start_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } #else #endif - KeLowerIrql(old); + KeLowerIrql(old); KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); - KeRaiseIrql(HIGH_LEVEL,&old); - stop_kqpc=KeQueryPerformanceCounter(&stop_freq); + KeRaiseIrql(HIGH_LEVEL,&old); + stop_kqpc=KeQueryPerformanceCounter(&stop_freq); #ifndef __GNUC__ - __asm - { - push eax - push edx - push ecx - rdtsc - lea ecx, stop_ticks - mov [ecx+4], edx - mov [ecx], eax - pop ecx - pop edx - pop eax - } + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, stop_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } #else #endif - KeLowerIrql(old); - delta=stop_ticks-start_ticks; - delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; - if (delta>10000000000) { - delta/=16; - delta2/=16; - } - reference=delta*(start_freq.QuadPart)/delta2; - data->reference=reference/1000; - if (reference%1000>500) - data->reference++; - data->reference*=1000; - reference=data->reference; - KeQuerySystemTime(&system_time); + KeLowerIrql(old); + delta=stop_ticks-start_ticks; + delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; + if (delta>10000000000) { + delta/=16; + delta2/=16; + } + reference=delta*(start_freq.QuadPart)/delta2; + data->reference=reference/1000; + if (reference%1000>500) + data->reference++; + data->reference*=1000; + reference=data->reference; + KeQuerySystemTime(&system_time); #ifndef __GNUC__ - __asm - { - push eax - push edx - push ecx - rdtsc - lea ecx, curr_ticks - mov [ecx+4], edx - mov [ecx], eax - pop ecx - pop edx - pop eax - } + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, curr_ticks + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } #else #endif - tmp.tv_sec=-(LONG)(curr_ticks/reference); - tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); - system_time.QuadPart-=116444736000000000; - tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); - tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); - if (tmp.tv_usec<0) { - tmp.tv_sec--; - tmp.tv_usec+=1000000; - } - data->start=tmp; - IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) + tmp.tv_sec=-(LONG)(curr_ticks/reference); + tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); + system_time.QuadPart-=116444736000000000; + tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); + tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); + if (tmp.tv_usec<0) { + tmp.tv_sec--; + tmp.tv_usec+=1000000; + } + data->start=tmp; + IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);) } __inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) { - dest->start=*src; + dest->start=*src; } __inline void GET_TIME(struct timeval *dst, struct time_conv *data) { - ULONGLONG tmp; + ULONGLONG tmp; #ifndef __GNUC__ - __asm - { - push eax - push edx - push ecx - rdtsc - lea ecx, tmp - mov [ecx+4], edx - mov [ecx], eax - pop ecx - pop edx - pop eax - } + __asm + { + push eax + push edx + push ecx + rdtsc + lea ecx, tmp + mov [ecx+4], edx + mov [ecx], eax + pop ecx + pop edx + pop eax + } #else #endif - if (data->reference==0) { - return; - } - dst->tv_sec=(LONG)(tmp/data->reference); - dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); - dst->tv_sec+=data->start.tv_sec; - dst->tv_usec+=data->start.tv_usec; - if (dst->tv_usec>=1000000) { - dst->tv_sec++; - dst->tv_usec-=1000000; - } + if (data->reference==0) { + return; + } + dst->tv_sec=(LONG)(tmp/data->reference); + dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); + dst->tv_sec+=data->start.tv_sec; + dst->tv_usec+=data->start.tv_usec; + if (dst->tv_usec>=1000000) { + dst->tv_sec++; + dst->tv_usec-=1000000; + } } #endif /*KQPC_TS*/ diff --git a/drivers/net/packet/tme.h b/drivers/net/packet/tme.h index f6916f9..4140f9f 100644 --- a/drivers/net/packet/tme.h +++ b/drivers/net/packet/tme.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -47,44 +47,44 @@ #endif /* error codes */ -#define TME_ERROR 0 -#define TME_SUCCESS 1 -#define TME_TRUE 2 -#define TME_FALSE 3 +#define TME_ERROR 0 +#define TME_SUCCESS 1 +#define TME_TRUE 2 +#define TME_FALSE 3 /* some constants */ -#define DEFAULT_MEM_EX_SIZE 65536 -#define MAX_TME_DATA_BLOCKS 4 -#define TME_NONE_ACTIVE 0xffffffff -#define DELTA_READ 2 /* secs */ - -#define TME_LUT_ENTRIES 0x00000000 -#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */ -#define TME_REHASHING_VALUE 0x00000002 -#define TME_KEY_LEN 0x00000003 -#define TME_SHARED_MEMORY_BLOCKS 0x00000004 -#define TME_FILLED_ENTRIES 0x00000005 -#define TME_BLOCK_SIZE 0x00000006 -#define TME_EXTRA_SEGMENT_SIZE 0x00000007 -#define TME_LOOKUP_CODE 0x00000008 -#define TME_OUT_LUT_EXEC 0x00000009 -#define TME_FILLED_BLOCKS 0x0000000a -#define TME_DEFAULT_EXEC 0x0000000b -#define TME_LUT_BASE_ADDRESS 0x0000000c -#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d -#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e -#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */ -#define TME_LAST_FOUND_BLOCK 0x00000010 +#define DEFAULT_MEM_EX_SIZE 65536 +#define MAX_TME_DATA_BLOCKS 4 +#define TME_NONE_ACTIVE 0xffffffff +#define DELTA_READ 2 /* secs */ + +#define TME_LUT_ENTRIES 0x00000000 +#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */ +#define TME_REHASHING_VALUE 0x00000002 +#define TME_KEY_LEN 0x00000003 +#define TME_SHARED_MEMORY_BLOCKS 0x00000004 +#define TME_FILLED_ENTRIES 0x00000005 +#define TME_BLOCK_SIZE 0x00000006 +#define TME_EXTRA_SEGMENT_SIZE 0x00000007 +#define TME_LOOKUP_CODE 0x00000008 +#define TME_OUT_LUT_EXEC 0x00000009 +#define TME_FILLED_BLOCKS 0x0000000a +#define TME_DEFAULT_EXEC 0x0000000b +#define TME_LUT_BASE_ADDRESS 0x0000000c +#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d +#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e +#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */ +#define TME_LAST_FOUND_BLOCK 0x00000010 /* TME default values */ -#define TME_LUT_ENTRIES_DEFAULT 32007 -#define TME_REHASHING_VALUE_DEFAULT 1 -#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000 -#define TME_BLOCK_SIZE_DEFAULT 64 -#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0 -#define TME_LOOKUP_CODE_DEFAULT 0 -#define TME_OUT_LUT_EXEC_DEFAULT 0 -#define TME_DEFAULT_EXEC_DEFAULT 0 -#define TME_MAX_FILL_STATE_DEFAULT 15000 +#define TME_LUT_ENTRIES_DEFAULT 32007 +#define TME_REHASHING_VALUE_DEFAULT 1 +#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000 +#define TME_BLOCK_SIZE_DEFAULT 64 +#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0 +#define TME_LOOKUP_CODE_DEFAULT 0 +#define TME_OUT_LUT_EXEC_DEFAULT 0 +#define TME_DEFAULT_EXEC_DEFAULT 0 +#define TME_MAX_FILL_STATE_DEFAULT 15000 #define IS_VALIDATED(src,index) (src&(1<enable_deletion==FALSE) - return FALSE; - if (data->filled_entriesmax_fill_state) - return FALSE; - if ((ts->tv_sec+DELTA_READ)last_read.tv_sec) - return TRUE; - return FALSE; + struct timeval *ts=(struct timeval*)timestamp; + + if (data->enable_deletion==FALSE) + return FALSE; + if (data->filled_entriesmax_fill_state) + return FALSE; + if ((ts->tv_sec+DELTA_READ)last_read.tv_sec) + return TRUE; + return FALSE; } /* functions to manage TME */ diff --git a/drivers/net/packet/win_bpf.h b/drivers/net/packet/win_bpf.h index c0f9b51..7dc5f14 100644 --- a/drivers/net/packet/win_bpf.h +++ b/drivers/net/packet/win_bpf.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed @@ -45,12 +45,12 @@ /* BSD style release date */ #define BPF_RELEASE 199606 -typedef UCHAR u_char; -typedef USHORT u_short; -typedef ULONG u_int; -typedef LONG bpf_int32; -typedef ULONG bpf_u_int32; -typedef ULONG u_int32; +typedef UCHAR u_char; +typedef USHORT u_short; +typedef ULONG u_int; +typedef LONG bpf_int32; +typedef ULONG bpf_u_int32; +typedef ULONG u_int32; #define BPF_MAXINSNS 512 #define BPF_MAXBUFSIZE 0x8000 @@ -62,26 +62,26 @@ typedef ULONG u_int32; * The instruction data structure. */ struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_int32 k; + u_short code; + u_char jt; + u_char jf; + bpf_int32 k; }; /* * Structure for BIOCSETF. */ struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; + u_int bf_len; + struct bpf_insn *bf_insns; }; /* * Struct returned by BIOCGSTATS. */ struct bpf_stat { - u_int bs_recv; /* number of packets received */ - u_int bs_drop; /* number of packets dropped */ + u_int bs_recv; /* number of packets received */ + u_int bs_drop; /* number of packets dropped */ }; /* @@ -96,8 +96,8 @@ struct bpf_stat { * It has nothing to do with the source code version. */ struct bpf_version { - u_short bv_major; - u_short bv_minor; + u_short bv_major; + u_short bv_minor; }; /* Current version number of filter architecture. */ #define BPF_MAJOR_VERSION 1 @@ -108,11 +108,11 @@ struct bpf_version { * Structure prepended to each packet. */ struct bpf_hdr { - struct timeval bh_tstamp; /* time stamp */ - bpf_u_int32 bh_caplen; /* length of captured portion */ - bpf_u_int32 bh_datalen; /* original length of packet */ - u_short bh_hdrlen; /* length of bpf header (this struct - plus alignment padding) */ + struct timeval bh_tstamp; /* time stamp */ + bpf_u_int32 bh_caplen; /* length of captured portion */ + bpf_u_int32 bh_datalen; /* original length of packet */ + u_short bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ }; /* @@ -129,17 +129,17 @@ struct bpf_hdr { * differ from those here, they should use their values, not the ones * here). */ -#define DLT_NULL 0 /* no link-layer encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* IEEE 802 Networks */ -#define DLT_ARCNET 7 /* ARCNET */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ +#define DLT_NULL 0 /* no link-layer encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ /* * These are values from the traditional libpcap "bpf.h". @@ -147,8 +147,8 @@ struct bpf_hdr { * with the ones appropriate to that platform, if the values are * different on that platform. */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_RAW 12 /* raw IP */ +#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ +#define DLT_RAW 12 /* raw IP */ /* * These are values from BSD/OS's "bpf.h". @@ -163,17 +163,17 @@ struct bpf_hdr { * continue to compile - even though they won't correctly read * files of these types. */ -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * This value is defined by NetBSD; other platforms should refrain from * using it for other purposes, so that NetBSD savefiles with a link * type of 50 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ /* * This value was defined by libpcap 0.5; platforms that have defined @@ -189,8 +189,8 @@ struct bpf_hdr { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC /* * Reserved for future use. @@ -202,7 +202,7 @@ struct bpf_hdr { * on one platform to be read on other platforms, even if the two * platforms don't use the same numerical values for all DLT_ types). */ -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * Values between 106 and 107 are used in capture file headers as @@ -219,7 +219,7 @@ struct bpf_hdr { * define DLT_LOOP as 12 in its version, as per the comment above - * and should not use 108 for any purpose. */ -#define DLT_LOOP 108 +#define DLT_LOOP 108 /* * Values between 109 and 112 are used in capture file headers as @@ -230,85 +230,85 @@ struct bpf_hdr { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 +#define DLT_LINUX_SLL 113 /* * The instruction encodings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 /* misc */ #define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 /* TME instructions */ -#define BPF_TME 0x08 - -#define BPF_LOOKUP 0x90 -#define BPF_EXECUTE 0xa0 -#define BPF_INIT 0xb0 -#define BPF_VALIDATE 0xc0 -#define BPF_SET_ACTIVE 0xd0 -#define BPF_RESET 0xe0 -#define BPF_SET_MEMORY 0x80 -#define BPF_GET_REGISTER_VALUE 0x70 -#define BPF_SET_REGISTER_VALUE 0x60 -#define BPF_SET_WORKING 0x50 -#define BPF_SET_ACTIVE_READ 0x40 -#define BPF_SET_AUTODELETION 0x30 -#define BPF_SEPARATION 0xff - -#define BPF_MEM_EX_IMM 0xc0 -#define BPF_MEM_EX_IND 0xe0 +#define BPF_TME 0x08 + +#define BPF_LOOKUP 0x90 +#define BPF_EXECUTE 0xa0 +#define BPF_INIT 0xb0 +#define BPF_VALIDATE 0xc0 +#define BPF_SET_ACTIVE 0xd0 +#define BPF_RESET 0xe0 +#define BPF_SET_MEMORY 0x80 +#define BPF_GET_REGISTER_VALUE 0x70 +#define BPF_SET_REGISTER_VALUE 0x60 +#define BPF_SET_WORKING 0x50 +#define BPF_SET_ACTIVE_READ 0x40 +#define BPF_SET_AUTODELETION 0x30 +#define BPF_SEPARATION 0xff + +#define BPF_MEM_EX_IMM 0xc0 +#define BPF_MEM_EX_IND 0xe0 /*used for ST */ -#define BPF_MEM_EX 0xc0 +#define BPF_MEM_EX 0xc0 /* diff --git a/drivers/net/packet/win_bpf_filter_init.c b/drivers/net/packet/win_bpf_filter_init.c index 96e7e4c..51fb5d4 100644 --- a/drivers/net/packet/win_bpf_filter_init.c +++ b/drivers/net/packet/win_bpf_filter_init.c @@ -135,6 +135,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); #endif continue; @@ -154,6 +164,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); #endif continue; @@ -172,6 +192,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); #endif continue; @@ -190,6 +220,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); #endif continue; @@ -221,6 +261,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); #endif continue; @@ -243,6 +293,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); #endif continue; /* END LD NO PACKET INSTRUCTIONS */ @@ -279,6 +339,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); #endif continue; @@ -297,6 +367,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); #endif continue; @@ -315,6 +395,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); #endif continue; @@ -333,6 +423,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); #endif continue; @@ -354,6 +454,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); #endif continue; @@ -372,6 +482,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE pop eax } #else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); #endif continue; /* END STORE INSTRUCTIONS */ diff --git a/drivers/net/packet/win_bpf_filter_init.h b/drivers/net/packet/win_bpf_filter_init.h index 23e7a9f..8b06af7 100644 --- a/drivers/net/packet/win_bpf_filter_init.h +++ b/drivers/net/packet/win_bpf_filter_init.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2001 - * Politecnico di Torino. All rights reserved. + * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions @@ -23,8 +23,8 @@ #include "tme.h" -#define INIT_OK 1 -#define INIT_ERROR 0 +#define INIT_OK 1 +#define INIT_ERROR 0 uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref); diff --git a/drivers/net/packet/write.c b/drivers/net/packet/write.c index f12818f..0db9e01 100644 --- a/drivers/net/packet/write.c +++ b/drivers/net/packet/write.c @@ -27,6 +27,12 @@ #else #include #include +#define NdisReinitializePacket(Packet) \ +{ \ + (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \ + (Packet)->Private.ValidCounts = FALSE; \ +} + #endif #include "debug.h" @@ -34,8 +40,8 @@ //------------------------------------------------------------------- + NTSTATUS -//STDCALL NPF_Write( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp @@ -48,17 +54,22 @@ NPF_Write( UINT i; NDIS_STATUS Status; - - IF_LOUD(DbgPrint("Packet: SendAdapter\n");) + IF_LOUD(DbgPrint("NPF_Write\n");) IrpSp = IoGetCurrentIrpStackLocation(Irp); Open=IrpSp->FileObject->FsContext; - // Check the length of the packet to avoid to use an empty packet - if(IrpSp->Parameters.Write.Length==0) + IF_LOUD(DbgPrint("Max frame size = %d\n", Open->MaxFrameSize);) + + + if(IrpSp->Parameters.Write.Length == 0 || // Check that the buffer provided by the user is not empty + Open->MaxFrameSize == 0 || // Check that the MaxFrameSize is correctly initialized + IrpSp->Parameters.Write.Length > Open->MaxFrameSize) // Check that the fame size is smaller that the MTU { + IF_LOUD(DbgPrint("frame size out of range, send aborted\n");) + Irp->IoStatus.Status = NDIS_STATUS_SUCCESS; IoCompleteRequest (Irp, IO_NO_INCREMENT); return NDIS_STATUS_SUCCESS; @@ -159,6 +170,15 @@ NPF_BufferedWrite( return 0; } + // Check that the MaxFrameSize is correctly initialized + if(Open->MaxFrameSize == 0) + { + IF_LOUD(DbgPrint("BufferedWrite: Open->MaxFrameSize not initialized, probably because of a problem in the OID query\n");) + + return 0; + } + + // Start from the first packet winpcap_hdr = (struct sf_pkthdr*)UserBuff; @@ -181,10 +201,10 @@ NPF_BufferedWrite( // Main loop: send the buffer to the wire while( TRUE ){ - if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536) + if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > Open->MaxFrameSize) { // Malformed header - IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed user buffer, aborting write.\n");) + IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed or bogus user buffer, aborting write.\n");) return -1; } @@ -247,7 +267,6 @@ NPF_BufferedWrite( if( Sync ){ -#if 0 // Release the application if it has been blocked for approximately more than 1 seconds if( winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec > 1 ) { @@ -256,17 +275,18 @@ NPF_BufferedWrite( return (PCHAR)winpcap_hdr - UserBuff; } +#ifndef __GNUC__ // Calculate the time interval to wait before sending the next packet - TargetTicks.QuadPart = StartTicks.QuadPart + + TargetTicks.QuadPart = StartTicks.QuadPart + (LONGLONG)((winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec) * 1000000 + winpcap_hdr->ts.tv_usec - BufStartTime.tv_usec) * (TimeFreq.QuadPart) / 1000000; - + // Wait until the time interval has elapsed while( CurTicks.QuadPart <= TargetTicks.QuadPart ) CurTicks = KeQueryPerformanceCounter(NULL); +#else #endif - } } @@ -330,3 +350,17 @@ NPF_SendComplete( return; } + + +#ifdef __GNUC__ +/* +__divdi3() +{ + //_alldiv(); +} + +//_allmul(); +//_allrem(); + +*/ +#endif diff --git a/drivers/net/tcpip/.cvsignore b/drivers/net/tcpip/.cvsignore index 48a5fe0..4921815 100644 --- a/drivers/net/tcpip/.cvsignore +++ b/drivers/net/tcpip/.cvsignore @@ -3,3 +3,4 @@ tcpip.coff *.d *.o *.sym +*.sys diff --git a/drivers/net/tcpip/datalink/.cvsignore b/drivers/net/tcpip/datalink/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/datalink/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tcpip/include/linux.h b/drivers/net/tcpip/include/linux.h new file mode 100755 index 0000000..86db7ae --- /dev/null +++ b/drivers/net/tcpip/include/linux.h @@ -0,0 +1,1876 @@ +#ifndef _LINUX_TYPES_H +#define _LINUX_TYPES_H + +#include + +#ifndef NULL +#define NULL (void*)0 +#endif + +typedef struct page { + int x; +} mem_map_t; + + + + + + + + + + + + + +/* i386 */ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* DMA addresses come in generic and 64-bit flavours. */ + +#ifdef CONFIG_HIGHMEM64G +typedef u64 dma_addr_t; +#else +typedef u32 dma_addr_t; +#endif +typedef u64 dma64_addr_t; + + + +/* + * This allows for 1024 file descriptors: if NR_OPEN is ever grown + * beyond that you'll have to change this too. But 1024 fd's seem to be + * enough even for such "real" unices like OSF/1, so hopefully this is + * one limit that doesn't have to be changed [again]. + * + * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in + * (and thus ) - but this is a more logical + * place for them. Solved by having dummy defines in . + */ + +/* + * Those macros may have been defined in . But we always + * use the ones here. + */ +#undef __NFDBITS +#define __NFDBITS (8 * sizeof(unsigned long)) + +#undef __FD_SETSIZE +#define __FD_SETSIZE 1024 + +#undef __FDSET_LONGS +#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS) + +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) + +#undef __FDMASK +#define __FDMASK(d) (1UL << ((d) % __NFDBITS)) + +typedef struct { + unsigned long fds_bits [__FDSET_LONGS]; +} __kernel_fd_set; + +/* Type of a signal handler. */ +typedef void (*__kernel_sighandler_t)(int); + +/* Type of a SYSV IPC key. */ +typedef int __kernel_key_t; + + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + + +#ifndef __KERNEL_STRICT_NAMES + +typedef __kernel_fd_set fd_set; +typedef __kernel_dev_t dev_t; +typedef __kernel_ino_t ino_t; +typedef __kernel_mode_t mode_t; +typedef __kernel_nlink_t nlink_t; +typedef __kernel_off_t off_t; +typedef __kernel_pid_t pid_t; +typedef __kernel_daddr_t daddr_t; +typedef __kernel_key_t key_t; +typedef __kernel_suseconds_t suseconds_t; + +#ifdef __KERNEL__ +typedef __kernel_uid32_t uid_t; +typedef __kernel_gid32_t gid_t; +typedef __kernel_uid16_t uid16_t; +typedef __kernel_gid16_t gid16_t; + +#ifdef CONFIG_UID16 +/* This is defined by include/asm-{arch}/posix_types.h */ +typedef __kernel_old_uid_t old_uid_t; +typedef __kernel_old_gid_t old_gid_t; +#endif /* CONFIG_UID16 */ + +/* libc5 includes this file to define uid_t, thus uid_t can never change + * when it is included by non-kernel code + */ +#else +typedef __kernel_uid_t uid_t; +typedef __kernel_gid_t gid_t; +#endif /* __KERNEL__ */ + +#if defined(__GNUC__) +typedef __kernel_loff_t loff_t; +#endif + +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef __kernel_time_t time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __kernel_clock_t clock_t; +#endif + +#ifndef _CADDR_T +#define _CADDR_T +typedef __kernel_caddr_t caddr_t; +#endif + +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ + +typedef __u8 u_int8_t; +typedef __s8 int8_t; +typedef __u16 u_int16_t; +typedef __s16 int16_t; +typedef __u32 u_int32_t; +typedef __s32 int32_t; + +#endif /* !(__BIT_TYPES_DEFINED__) */ + +typedef __u8 uint8_t; +typedef __u16 uint16_t; +typedef __u32 uint32_t; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __u64 uint64_t; +typedef __u64 u_int64_t; +typedef __s64 int64_t; +#endif + +#endif /* __KERNEL_STRICT_NAMES */ + +/* + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. + */ + +struct ustat { + __kernel_daddr_t f_tfree; + __kernel_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + + + + + + + + + + + + + + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +#if 1 /* swab */ + +/* + * linux/byteorder/swab.h + * Byte-swapping, independently from CPU endianness + * swabXX[ps]?(foo) + * + * Francois-Rene Rideau 19971205 + * separated swab functions from cpu_to_XX, + * to clean up support for bizarre-endian architectures. + * + * See asm-i386/byteorder.h and suches for examples of how to provide + * architecture-dependent optimized versions + * + */ + +/* casts are necessary for constants, because we never know how for sure + * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. + */ +#define ___swab16(x) \ +({ \ + __u16 __x = (x); \ + ((__u16)( \ + (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ +}) + +#define ___swab24(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + ((__x & (__u32)0x000000ffUL) << 16) | \ + (__x & (__u32)0x0000ff00UL) | \ + ((__x & (__u32)0x00ff0000UL) >> 16) )); \ +}) + +#define ___swab32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ +}) + +#define ___swab64(x) \ +({ \ + __u64 __x = (x); \ + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +}) + +#define ___constant_swab16(x) \ + ((__u16)( \ + (((__u16)(x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(x) & (__u16)0xff00U) >> 8) )) +#define ___constant_swab24(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffU) << 16) | \ + (((__u32)(x) & (__u32)0x0000ff00U) | \ + (((__u32)(x) & (__u32)0x00ff0000U) >> 16) )) +#define ___constant_swab32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +#define ___constant_swab64(x) \ + ((__u64)( \ + (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) )) + +/* + * provide defaults when no architecture-specific optimization is detected + */ +#ifndef __arch__swab16 +# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); }) +#endif +#ifndef __arch__swab24 +# define __arch__swab24(x) ({ __u32 __tmp = (x) ; ___swab24(__tmp); }) +#endif +#ifndef __arch__swab32 +# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); }) +#endif +#ifndef __arch__swab64 +# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); }) +#endif + +#ifndef __arch__swab16p +# define __arch__swab16p(x) __arch__swab16(*(x)) +#endif +#ifndef __arch__swab24p +# define __arch__swab24p(x) __arch__swab24(*(x)) +#endif +#ifndef __arch__swab32p +# define __arch__swab32p(x) __arch__swab32(*(x)) +#endif +#ifndef __arch__swab64p +# define __arch__swab64p(x) __arch__swab64(*(x)) +#endif + +#ifndef __arch__swab16s +# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0) +#endif +#ifndef __arch__swab24s +# define __arch__swab24s(x) do { *(x) = __arch__swab24p((x)); } while (0) +#endif +#ifndef __arch__swab32s +# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0) +#endif +#ifndef __arch__swab64s +# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0) +#endif + + +/* + * Allow constant folding + */ +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) +# define __swab16(x) \ +(__builtin_constant_p((__u16)(x)) ? \ + ___swab16((x)) : \ + __fswab16((x))) +# define __swab24(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swab24((x)) : \ + __fswab24((x))) +# define __swab32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swab32((x)) : \ + __fswab32((x))) +# define __swab64(x) \ +(__builtin_constant_p((__u64)(x)) ? \ + ___swab64((x)) : \ + __fswab64((x))) +#else +# define __swab16(x) __fswab16(x) +# define __swab24(x) __fswab24(x) +# define __swab32(x) __fswab32(x) +# define __swab64(x) __fswab64(x) +#endif /* OPTIMIZE */ + + +static __inline__ __const__ __u16 __fswab16(__u16 x) +{ + return __arch__swab16(x); +} +static __inline__ __u16 __swab16p(__u16 *x) +{ + return __arch__swab16p(x); +} +static __inline__ void __swab16s(__u16 *addr) +{ + __arch__swab16s(addr); +} + +static __inline__ __const__ __u32 __fswab24(__u32 x) +{ + return __arch__swab24(x); +} +static __inline__ __u32 __swab24p(__u32 *x) +{ + return __arch__swab24p(x); +} +static __inline__ void __swab24s(__u32 *addr) +{ + __arch__swab24s(addr); +} + +static __inline__ __const__ __u32 __fswab32(__u32 x) +{ + return __arch__swab32(x); +} +static __inline__ __u32 __swab32p(__u32 *x) +{ + return __arch__swab32p(x); +} +static __inline__ void __swab32s(__u32 *addr) +{ + __arch__swab32s(addr); +} + +#ifdef __BYTEORDER_HAS_U64__ +static __inline__ __const__ __u64 __fswab64(__u64 x) +{ +# ifdef __SWAB_64_THRU_32__ + __u32 h = x >> 32; + __u32 l = x & ((1ULL<<32)-1); + return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h))); +# else + return __arch__swab64(x); +# endif +} +static __inline__ __u64 __swab64p(__u64 *x) +{ + return __arch__swab64p(x); +} +static __inline__ void __swab64s(__u64 *addr) +{ + __arch__swab64s(addr); +} +#endif /* __BYTEORDER_HAS_U64__ */ + +#if defined(__KERNEL__) +#define swab16 __swab16 +#define swab24 __swab24 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab24p __swab24p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab24s __swab24s +#define swab32s __swab32s +#define swab64s __swab64s +#endif + +#endif /* swab */ + + + +#if 1 /* generic */ + +/* + * linux/byteorder_generic.h + * Generic Byte-reordering support + * + * Francois-Rene Rideau 19970707 + * gathered all the good ideas from all asm-foo/byteorder.h into one file, + * cleaned them up. + * I hope it is compliant with non-GCC compilers. + * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, + * because I wasn't sure it would be ok to put it in types.h + * Upgraded it to 2.1.43 + * Francois-Rene Rideau 19971012 + * Upgraded it to 2.1.57 + * to please Linus T., replaced huge #ifdef's between little/big endian + * by nestedly #include'd files. + * Francois-Rene Rideau 19971205 + * Made it to 2.1.71; now a facelift: + * Put files under include/linux/byteorder/ + * Split swab from generic support. + * + * TODO: + * = Regular kernel maintainers could also replace all these manual + * byteswap macros that remain, disseminated among drivers, + * after some grep or the sources... + * = Linus might want to rename all these macros and files to fit his taste, + * to fit his personal naming scheme. + * = it seems that a few drivers would also appreciate + * nybble swapping support... + * = every architecture could add their byteswap macro in asm/byteorder.h + * see how some architectures already do (i386, alpha, ppc, etc) + * = cpu_to_beXX and beXX_to_cpu might some day need to be well + * distinguished throughout the kernel. This is not the case currently, + * since little endian, big endian, and pdp endian machines needn't it. + * But this might be the case for, say, a port of Linux to 20/21 bit + * architectures (and F21 Linux addict around?). + */ + +/* + * The following macros are to be defined by : + * + * Conversion of long and short int between network and host format + * ntohl(__u32 x) + * ntohs(__u16 x) + * htonl(__u32 x) + * htons(__u16 x) + * It seems that some programs (which? where? or perhaps a standard? POSIX?) + * might like the above to be functions, not macros (why?). + * if that's true, then detect them, and take measures. + * Anyway, the measure is: define only ___ntohl as a macro instead, + * and in a separate file, have + * unsigned long inline ntohl(x){return ___ntohl(x);} + * + * The same for constant arguments + * __constant_ntohl(__u32 x) + * __constant_ntohs(__u16 x) + * __constant_htonl(__u32 x) + * __constant_htons(__u16 x) + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + * + */ + + +#if defined(__KERNEL__) +/* + * inside the kernel, we can use nicknames; + * outside of it, we must avoid POSIX namespace pollution... + */ +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus +#endif + + +/* + * Handle ntohl and suches. These have various compatibility + * issues - like we want to give the prototype even though we + * also have a macro for them in case some strange program + * wants to take the address of the thing or something.. + * + * Note that these used to return a "long" in libc5, even though + * long is often 64-bit these days.. Thus the casts. + * + * They have to be macros in order to do the constant folding + * correctly - if the argument passed into a inline function + * it is no longer constant according to gcc.. + */ + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +/* + * Do the prototypes. Somebody might want to take the + * address or some such sick thing.. + */ +#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2) +extern __u32 ntohl(__u32); +extern __u32 htonl(__u32); +#else +extern unsigned long int ntohl(unsigned long int); +extern unsigned long int htonl(unsigned long int); +#endif +extern unsigned short int ntohs(unsigned short int); +extern unsigned short int htons(unsigned short int); + + +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) && !defined(__STRICT_ANSI__) + +#define ___htonl(x) __cpu_to_be32(x) +#define ___htons(x) __cpu_to_be16(x) +#define ___ntohl(x) __be32_to_cpu(x) +#define ___ntohs(x) __be16_to_cpu(x) + +#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#else +#define htonl(x) ((unsigned long)___htonl(x)) +#define ntohl(x) ((unsigned long)___ntohl(x)) +#endif +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#endif /* OPTIMIZE */ + +#endif /* generic */ + + +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) +#define __constant_cpu_to_le64(x) ((__u64)(x)) +#define __constant_le64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_le32(x) ((__u32)(x)) +#define __constant_le32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le24(x) ((__u32)(x)) +#define __constant_le24_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le16(x) ((__u16)(x)) +#define __constant_le16_to_cpu(x) ((__u16)(x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be24(x) ___constant_swab24((x)) +#define __constant_be24_to_cpu(x) ___constant_swab24((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) +#define __cpu_to_le64(x) ((__u64)(x)) +#define __le64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_le32(x) ((__u32)(x)) +#define __le32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le24(x) ((__u32)(x)) +#define __le24_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le16(x) ((__u16)(x)) +#define __le16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_be64(x) __swab64((x)) +#define __be64_to_cpu(x) __swab64((x)) +#define __cpu_to_be32(x) __swab32((x)) +#define __be32_to_cpu(x) __swab32((x)) +#define __cpu_to_be24(x) __swab24((x)) +#define __be24_to_cpu(x) __swab24((x)) +#define __cpu_to_be16(x) __swab16((x)) +#define __be16_to_cpu(x) __swab16((x)) +#define __cpu_to_le64p(x) (*(__u64*)(x)) +#define __le64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_le32p(x) (*(__u32*)(x)) +#define __le32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le24p(x) (*(__u32*)(x)) +#define __le24_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le16p(x) (*(__u16*)(x)) +#define __le16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_be64p(x) __swab64p((x)) +#define __be64_to_cpup(x) __swab64p((x)) +#define __cpu_to_be32p(x) __swab32p((x)) +#define __be32_to_cpup(x) __swab32p((x)) +#define __cpu_to_be24p(x) __swab24p((x)) +#define __be24_to_cpup(x) __swab24p((x)) +#define __cpu_to_be16p(x) __swab16p((x)) +#define __be16_to_cpup(x) __swab16p((x)) +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le24s(x) do {} while (0) +#define __le24_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be24s(x) __swab24s((x)) +#define __be24_to_cpus(x) __swab24s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) + + + + + + + + +#if 1 + +/* Dummy types */ + +#define ____cacheline_aligned + +typedef struct +{ + volatile unsigned int lock; +} rwlock_t; + +typedef struct { + volatile unsigned int lock; +} spinlock_t; + +struct task_struct; + + + + + +#if 1 /* atomic */ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#ifdef CONFIG_SMP +#define LOCK "lock ; " +#else +#define LOCK "" +#endif + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_read(v) ((v)->counter) + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_set(v,i) (((v)->counter) = (i)) + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. Note that the guaranteed useful range + * of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_add(int i, atomic_t *v) +{ +#if 0 + __asm__ __volatile__( + LOCK "addl %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +#endif +} + +/** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_sub(int i, atomic_t *v) +{ +#if 0 + __asm__ __volatile__( + LOCK "subl %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +#endif +} + +/** + * atomic_sub_and_test - subtract value from variable and test result + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v and returns + * true if the result is zero, or false for all + * other cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_sub_and_test(int i, atomic_t *v) +{ +#if 0 + unsigned char c; + + __asm__ __volatile__( + LOCK "subl %2,%0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +#endif +} + +/** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_inc(atomic_t *v) +{ +#if 0 + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (v->counter) + :"m" (v->counter)); +#endif +} + +/** + * atomic_dec - decrement atomic variable + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_dec(atomic_t *v) +{ +#if 0 + __asm__ __volatile__( + LOCK "decl %0" + :"=m" (v->counter) + :"m" (v->counter)); +#endif +} + +/** + * atomic_dec_and_test - decrement and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ +#if 0 + unsigned char c; + + __asm__ __volatile__( + LOCK "decl %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +#else + return 1; +#endif +} + +/** + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_inc_and_test(atomic_t *v) +{ +#if 0 + unsigned char c; + + __asm__ __volatile__( + LOCK "incl %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +#else + return 1; +#endif +} + +/** + * atomic_add_negative - add and test if negative + * @v: pointer of type atomic_t + * @i: integer value to add + * + * Atomically adds @i to @v and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_add_negative(int i, atomic_t *v) +{ +#if 0 + unsigned char c; + + __asm__ __volatile__( + LOCK "addl %2,%0; sets %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +#else + return 0; +#endif +} + +/* These are x86-specific, used by some header files */ +#define atomic_clear_mask(mask, addr) +#if 0 +__asm__ __volatile__(LOCK "andl %0,%1" \ +: : "r" (~(mask)),"m" (*addr) : "memory") +#endif + +#define atomic_set_mask(mask, addr) +#if 0 +__asm__ __volatile__(LOCK "orl %0,%1" \ +: : "r" (mask),"m" (*addr) : "memory") +#endif + +/* Atomic operations are already serializing on x86 */ +#define smp_mb__before_atomic_dec() +#define smp_mb__after_atomic_dec() +#define smp_mb__before_atomic_inc() +#define smp_mb__after_atomic_inc() + + + +#endif /* atomic */ + + + + + +#if 1 /* list */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ +#if 0 + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +#endif +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ +#if 0 + __list_add(new, head, head->next); +#endif +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ +#if 0 + __list_add(new, head->prev, head); +#endif +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ +#if 0 + __list_del(entry->prev, entry->next); + entry->next = (void *) 0; + entry->prev = (void *) 0; +#endif +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ +#if 0 + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +#endif +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ +#if 0 + __list_del(list->prev, list->next); + list_add(list, head); +#endif +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ +#if 0 + __list_del(list->prev, list->next); + list_add_tail(list, head); +#endif +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ +#if 0 + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +#endif +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ +#if 0 + if (!list_empty(list)) + __list_splice(list, head); +#endif +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ +#if 0 + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +#endif +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) +#if 0 + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) +#endif + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) +#if 0 + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) +#endif + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) +#if 0 + for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \ + pos = pos->prev, prefetch(pos->prev)) +#endif + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) +#if 0 + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) +#endif + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) +#if 0 + for (pos = list_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) +#endif + +#endif /* list */ + + + + + +#if 1 /* wait */ + +#define WNOHANG 0x00000001 +#define WUNTRACED 0x00000002 + +#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */ +#define __WALL 0x40000000 /* Wait on all children, regardless of type */ +#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */ + +#if 0 +#include +#include +#include +#include +#include + +#include +#include +#endif + +/* + * Debug control. Slow but useful. + */ +#if defined(CONFIG_DEBUG_WAITQ) +#define WAITQUEUE_DEBUG 1 +#else +#define WAITQUEUE_DEBUG 0 +#endif + +struct __wait_queue { + unsigned int flags; +#define WQ_FLAG_EXCLUSIVE 0x01 + struct task_struct * task; + struct list_head task_list; +#if WAITQUEUE_DEBUG + long __magic; + long __waker; +#endif +}; +typedef struct __wait_queue wait_queue_t; + +/* + * 'dual' spinlock architecture. Can be switched between spinlock_t and + * rwlock_t locks via changing this define. Since waitqueues are quite + * decoupled in the new architecture, lightweight 'simple' spinlocks give + * us slightly better latencies and smaller waitqueue structure size. + */ +#define USE_RW_WAIT_QUEUE_SPINLOCK 0 + +#if USE_RW_WAIT_QUEUE_SPINLOCK +# define wq_lock_t rwlock_t +# define WAITQUEUE_RW_LOCK_UNLOCKED RW_LOCK_UNLOCKED + +# define wq_read_lock read_lock +# define wq_read_lock_irqsave read_lock_irqsave +# define wq_read_unlock_irqrestore read_unlock_irqrestore +# define wq_read_unlock read_unlock +# define wq_write_lock_irq write_lock_irq +# define wq_write_lock_irqsave write_lock_irqsave +# define wq_write_unlock_irqrestore write_unlock_irqrestore +# define wq_write_unlock write_unlock +#else +# define wq_lock_t spinlock_t +# define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED + +# define wq_read_lock spin_lock +# define wq_read_lock_irqsave spin_lock_irqsave +# define wq_read_unlock spin_unlock +# define wq_read_unlock_irqrestore spin_unlock_irqrestore +# define wq_write_lock_irq spin_lock_irq +# define wq_write_lock_irqsave spin_lock_irqsave +# define wq_write_unlock_irqrestore spin_unlock_irqrestore +# define wq_write_unlock spin_unlock +#endif + +struct __wait_queue_head { + wq_lock_t lock; + struct list_head task_list; +#if WAITQUEUE_DEBUG + long __magic; + long __creator; +#endif +}; +typedef struct __wait_queue_head wait_queue_head_t; + + +/* + * Debugging macros. We eschew `do { } while (0)' because gcc can generate + * spurious .aligns. + */ +#if WAITQUEUE_DEBUG +#define WQ_BUG() BUG() +#define CHECK_MAGIC(x) +#if 0 + do { \ + if ((x) != (long)&(x)) { \ + printk("bad magic %lx (should be %lx), ", \ + (long)x, (long)&(x)); \ + WQ_BUG(); \ + } \ + } while (0) +#endif + +#define CHECK_MAGIC_WQHEAD(x) +#if 0 + do { \ + if ((x)->__magic != (long)&((x)->__magic)) { \ + printk("bad magic %lx (should be %lx, creator %lx), ", \ + (x)->__magic, (long)&((x)->__magic), (x)->__creator); \ + WQ_BUG(); \ + } \ + } while (0) +#endif + +#define WQ_CHECK_LIST_HEAD(list) +#if 0 + do { \ + if (!(list)->next || !(list)->prev) \ + WQ_BUG(); \ + } while(0) +#endif + +#define WQ_NOTE_WAKER(tsk) +#if 0 + do { \ + (tsk)->__waker = (long)__builtin_return_address(0); \ + } while (0) +#endif +#else +#define WQ_BUG() +#define CHECK_MAGIC(x) +#define CHECK_MAGIC_WQHEAD(x) +#define WQ_CHECK_LIST_HEAD(list) +#define WQ_NOTE_WAKER(tsk) +#endif + +/* + * Macros for declaration and initialisaton of the datatypes + */ + +#if WAITQUEUE_DEBUG +# define __WAITQUEUE_DEBUG_INIT(name) //(long)&(name).__magic, 0 +# define __WAITQUEUE_HEAD_DEBUG_INIT(name) //(long)&(name).__magic, (long)&(name).__magic +#else +# define __WAITQUEUE_DEBUG_INIT(name) +# define __WAITQUEUE_HEAD_DEBUG_INIT(name) +#endif + +#define __WAITQUEUE_INITIALIZER(name, tsk) +#if 0 +{ + task: tsk, \ + task_list: { NULL, NULL }, \ + __WAITQUEUE_DEBUG_INIT(name)} +#endif + +#define DECLARE_WAITQUEUE(name, tsk) +#if 0 + wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) +#endif + +#define __WAIT_QUEUE_HEAD_INITIALIZER(name) +#if 0 +{ + lock: WAITQUEUE_RW_LOCK_UNLOCKED, \ + task_list: { &(name).task_list, &(name).task_list }, \ + __WAITQUEUE_HEAD_DEBUG_INIT(name)} +#endif + +#define DECLARE_WAIT_QUEUE_HEAD(name) +#if 0 + wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) +#endif + +static inline void init_waitqueue_head(wait_queue_head_t *q) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!q) + WQ_BUG(); +#endif + q->lock = WAITQUEUE_RW_LOCK_UNLOCKED; + INIT_LIST_HEAD(&q->task_list); +#if WAITQUEUE_DEBUG + q->__magic = (long)&q->__magic; + q->__creator = (long)current_text_addr(); +#endif +#endif +} + +static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!q || !p) + WQ_BUG(); +#endif + q->flags = 0; + q->task = p; +#if WAITQUEUE_DEBUG + q->__magic = (long)&q->__magic; +#endif +#endif +} + +static inline int waitqueue_active(wait_queue_head_t *q) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!q) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(q); +#endif + + return !list_empty(&q->task_list); +#endif +} + +static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!head || !new) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(head); + CHECK_MAGIC(new->__magic); + if (!head->task_list.next || !head->task_list.prev) + WQ_BUG(); +#endif + list_add(&new->task_list, &head->task_list); +#endif +} + +/* + * Used for wake-one threads: + */ +static inline void __add_wait_queue_tail(wait_queue_head_t *head, + wait_queue_t *new) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!head || !new) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(head); + CHECK_MAGIC(new->__magic); + if (!head->task_list.next || !head->task_list.prev) + WQ_BUG(); +#endif + list_add_tail(&new->task_list, &head->task_list); +#endif +} + +static inline void __remove_wait_queue(wait_queue_head_t *head, + wait_queue_t *old) +{ +#if 0 +#if WAITQUEUE_DEBUG + if (!old) + WQ_BUG(); + CHECK_MAGIC(old->__magic); +#endif + list_del(&old->task_list); +#endif +} + + + + +#endif /* wait */ + + +#endif + + + + +#if 1 /* slab */ + +typedef struct +{ + int x; +} kmem_cache_s; + +typedef struct kmem_cache_s kmem_cache_t; + +#if 0 +#include +#include +#endif + +/* flags for kmem_cache_alloc() */ +#define SLAB_NOFS GFP_NOFS +#define SLAB_NOIO GFP_NOIO +#define SLAB_NOHIGHIO GFP_NOHIGHIO +#define SLAB_ATOMIC GFP_ATOMIC +#define SLAB_USER GFP_USER +#define SLAB_KERNEL GFP_KERNEL +#define SLAB_NFS GFP_NFS +#define SLAB_DMA GFP_DMA + +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS) +#define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ + +/* flags to pass to kmem_cache_create(). + * The first 3 are only valid when the allocator as been build + * SLAB_DEBUG_SUPPORT. + */ +#define SLAB_DEBUG_FREE 0x00000100UL /* Peform (expensive) checks on free */ +#define SLAB_DEBUG_INITIAL 0x00000200UL /* Call constructor (as verifier) */ +#define SLAB_RED_ZONE 0x00000400UL /* Red zone objs in a cache */ +#define SLAB_POISON 0x00000800UL /* Poison objects */ +#define SLAB_NO_REAP 0x00001000UL /* never reap from the cache */ +#define SLAB_HWCACHE_ALIGN 0x00002000UL /* align objs on a h/w cache lines */ +#define SLAB_CACHE_DMA 0x00004000UL /* use GFP_DMA memory */ +#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* force alignment */ + +/* flags passed to a constructor func */ +#define SLAB_CTOR_CONSTRUCTOR 0x001UL /* if not set, then deconstructor */ +#define SLAB_CTOR_ATOMIC 0x002UL /* tell constructor it can't sleep */ +#define SLAB_CTOR_VERIFY 0x004UL /* tell constructor it's a verify call */ + +/* prototypes */ +extern void kmem_cache_init(void); +extern void kmem_cache_sizes_init(void); + +extern kmem_cache_t *kmem_find_general_cachep(size_t, int gfpflags); +extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned long, + void (*)(void *, kmem_cache_t *, unsigned long), + void (*)(void *, kmem_cache_t *, unsigned long)); +extern int kmem_cache_destroy(kmem_cache_t *); +extern int kmem_cache_shrink(kmem_cache_t *); +extern void *kmem_cache_alloc(kmem_cache_t *, int); +extern void kmem_cache_free(kmem_cache_t *, void *); +extern unsigned int kmem_cache_size(kmem_cache_t *); + +extern void *kmalloc(size_t, int); +extern void kfree(const void *); + +//extern int FASTCALL(kmem_cache_reap(int)); + +/* System wide caches */ +extern kmem_cache_t *vm_area_cachep; +extern kmem_cache_t *mm_cachep; +extern kmem_cache_t *names_cachep; +extern kmem_cache_t *files_cachep; +extern kmem_cache_t *filp_cachep; +extern kmem_cache_t *dquot_cachep; +extern kmem_cache_t *bh_cachep; +extern kmem_cache_t *fs_cachep; +extern kmem_cache_t *sigact_cachep; + +#endif /* slab */ + + + +/* + * Berkeley style UIO structures - Alan Cox 1994. + * + * 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. + */ + + +/* A word of warning: Our uio structure will clash with the C library one (which is now obsolete). Remove the C + library one from sys/uio.h if you have a very old library set */ + +struct iovec +{ + void *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */ + __kernel_size_t iov_len; /* Must be size_t (1003.1g) */ +}; + +/* + * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1) + */ + +#define UIO_FASTIOV 8 +#define UIO_MAXIOV 1024 +#if 0 +#define UIO_MAXIOV 16 /* Maximum iovec's in one operation + 16 matches BSD */ + /* Beg pardon: BSD has 1024 --ANK */ +#endif + + + +/* + * In Linux 2.4, static timers have been removed from the kernel. + * Timers may be dynamically created and destroyed, and should be initialized + * by a call to init_timer() upon creation. + * + * The "data" field enables use of a common timeout function for several + * timeouts. You can use this field to distinguish between the different + * invocations. + */ +struct timer_list { + struct list_head list; + unsigned long expires; + unsigned long data; + void (*function)(unsigned long); +}; + + + +struct timeval { + unsigned long tv_sec; + unsigned long tv_usec; +// time_t tv_sec; /* seconds */ +// suseconds_t tv_usec; /* microseconds */ +}; + + + + + + + +#if 1 /* poll */ + +struct file; + +struct poll_table_page; + +typedef struct poll_table_struct { + int error; + struct poll_table_page * table; +} poll_table; + +extern void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p); + +static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) +{ + if (p && wait_address) + __pollwait(filp, wait_address, p); +} + +static inline void poll_initwait(poll_table* pt) +{ + pt->error = 0; + pt->table = NULL; +} +extern void poll_freewait(poll_table* pt); + + +/* + * Scaleable version of the fd_set. + */ + +typedef struct { + unsigned long *in, *out, *ex; + unsigned long *res_in, *res_out, *res_ex; +} fd_set_bits; + +/* + * How many longwords for "nr" bits? + */ +#define FDS_BITPERLONG (8*sizeof(long)) +#define FDS_LONGS(nr) (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG) +#define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long)) + +/* + * We do a VERIFY_WRITE here even though we are only reading this time: + * we'll write to it eventually.. + * + * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned. + */ +static inline +int get_fd_set(unsigned long nr, void *ufdset, unsigned long *fdset) +{ +#if 0 + nr = FDS_BYTES(nr); + if (ufdset) { + int error; + error = verify_area(VERIFY_WRITE, ufdset, nr); + if (!error && __copy_from_user(fdset, ufdset, nr)) + error = -EFAULT; + return error; + } + memset(fdset, 0, nr); + return 0; +#else + return 0; +#endif +} + +static inline +void set_fd_set(unsigned long nr, void *ufdset, unsigned long *fdset) +{ +#if 0 + if (ufdset) + __copy_to_user(ufdset, fdset, FDS_BYTES(nr)); +#endif +} + +static inline +void zero_fd_set(unsigned long nr, unsigned long *fdset) +{ +#if 0 + memset(fdset, 0, FDS_BYTES(nr)); +#endif +} + +extern int do_select(int n, fd_set_bits *fds, long *timeout); + +#endif /* poll */ + + + +typedef struct +{ + int x; +} read_descriptor_t; + + + + + +#if 1 /* poll */ + +/* These are specified by iBCS2 */ +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 + +/* The rest seem to be more-or-less nonstandard. Check them! */ +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif /* poll */ + +#endif /* _LINUX_TYPES_H */ diff --git a/drivers/net/tcpip/include/tcpcore.h b/drivers/net/tcpip/include/tcpcore.h new file mode 100755 index 0000000..cda54ed --- /dev/null +++ b/drivers/net/tcpip/include/tcpcore.h @@ -0,0 +1,3856 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: include/tcpcore.h + * PURPOSE: Transmission Control Protocol definitions + * REVISIONS: + * CSH 01/01-2003 Ported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the TCP module. + * + * Version: @(#)tcp.h 1.0.5 05/23/93 + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * + * 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. + */ +#ifndef __TCPCORE_H +#define __TCPCORE_H + +#include "tcpdef.h" + + +struct socket; + + + +#if 1 /* skbuff */ + +#define HAVE_ALLOC_SKB /* For the drivers to know */ +#define HAVE_ALIGNABLE_SKB /* Ditto 8) */ +#define SLAB_SKB /* Slabified skbuffs */ + +#define CHECKSUM_NONE 0 +#define CHECKSUM_HW 1 +#define CHECKSUM_UNNECESSARY 2 + +#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES-1)) & ~(SMP_CACHE_BYTES-1)) +#define SKB_MAX_ORDER(X,ORDER) (((PAGE_SIZE<<(ORDER)) - (X) - sizeof(struct skb_shared_info))&~(SMP_CACHE_BYTES-1)) +#define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X),0)) +#define SKB_MAX_ALLOC (SKB_MAX_ORDER(0,2)) + +/* A. Checksumming of received packets by device. + * + * NONE: device failed to checksum this packet. + * skb->csum is undefined. + * + * UNNECESSARY: device parsed packet and wouldbe verified checksum. + * skb->csum is undefined. + * It is bad option, but, unfortunately, many of vendors do this. + * Apparently with secret goal to sell you new device, when you + * will add new protocol to your host. F.e. IPv6. 8) + * + * HW: the most generic way. Device supplied checksum of _all_ + * the packet as seen by netif_rx in skb->csum. + * NOTE: Even if device supports only some protocols, but + * is able to produce some skb->csum, it MUST use HW, + * not UNNECESSARY. + * + * B. Checksumming on output. + * + * NONE: skb is checksummed by protocol or csum is not required. + * + * HW: device is required to csum packet as seen by hard_start_xmit + * from skb->h.raw to the end and to record the checksum + * at skb->h.raw+skb->csum. + * + * Device must show its capabilities in dev->features, set + * at device setup time. + * NETIF_F_HW_CSUM - it is clever device, it is able to checksum + * everything. + * NETIF_F_NO_CSUM - loopback or reliable single hop media. + * NETIF_F_IP_CSUM - device is dumb. It is able to csum only + * TCP/UDP over IPv4. Sigh. Vendors like this + * way by an unknown reason. Though, see comment above + * about CHECKSUM_UNNECESSARY. 8) + * + * Any questions? No questions, good. --ANK + */ + +#ifdef __i386__ +#define NET_CALLER(arg) (*(((void**)&arg)-1)) +#else +#define NET_CALLER(arg) __builtin_return_address(0) +#endif + +#ifdef CONFIG_NETFILTER +struct nf_conntrack { + atomic_t use; + void (*destroy)(struct nf_conntrack *); +}; + +struct nf_ct_info { + struct nf_conntrack *master; +}; +#endif + +struct sk_buff_head { + /* These two members must be first. */ + struct sk_buff * next; + struct sk_buff * prev; + + __u32 qlen; + spinlock_t lock; +}; + +struct sk_buff; + +#define MAX_SKB_FRAGS 6 + +typedef struct skb_frag_struct skb_frag_t; + +struct skb_frag_struct +{ + struct page *page; + __u16 page_offset; + __u16 size; +}; + +/* This data is invariant across clones and lives at + * the end of the header data, ie. at skb->end. + */ +struct skb_shared_info { + atomic_t dataref; + unsigned int nr_frags; + struct sk_buff *frag_list; + skb_frag_t frags[MAX_SKB_FRAGS]; +}; + +struct sk_buff { + /* These two members must be first. */ + struct sk_buff * next; /* Next buffer in list */ + struct sk_buff * prev; /* Previous buffer in list */ + + struct sk_buff_head * list; /* List we are on */ + struct sock *sk; /* Socket we are owned by */ + struct timeval stamp; /* Time we arrived */ + struct net_device *dev; /* Device we arrived on/are leaving by */ + + /* Transport layer header */ + union + { + struct tcphdr *th; + struct udphdr *uh; + struct icmphdr *icmph; + struct igmphdr *igmph; + struct iphdr *ipiph; + struct spxhdr *spxh; + unsigned char *raw; + } h; + + /* Network layer header */ + union + { + struct iphdr *iph; + struct ipv6hdr *ipv6h; + struct arphdr *arph; + struct ipxhdr *ipxh; + unsigned char *raw; + } nh; + + /* Link layer header */ + union + { + struct ethhdr *ethernet; + unsigned char *raw; + } mac; + + struct dst_entry *dst; + + /* + * This is the control buffer. It is free to use for every + * layer. Please put your private variables there. If you + * want to keep them across layers you have to do a skb_clone() + * first. This is owned by whoever has the skb queued ATM. + */ + char cb[48]; + + unsigned int len; /* Length of actual data */ + unsigned int data_len; + unsigned int csum; /* Checksum */ + unsigned char __unused, /* Dead field, may be reused */ + cloned, /* head may be cloned (check refcnt to be sure). */ + pkt_type, /* Packet class */ + ip_summed; /* Driver fed us an IP checksum */ + __u32 priority; /* Packet queueing priority */ + atomic_t users; /* User count - see datagram.c,tcp.c */ + unsigned short protocol; /* Packet protocol from driver. */ + unsigned short security; /* Security level of packet */ + unsigned int truesize; /* Buffer size */ + + unsigned char *head; /* Head of buffer */ + unsigned char *data; /* Data head pointer */ + unsigned char *tail; /* Tail pointer */ + unsigned char *end; /* End pointer */ + + void (*destructor)(struct sk_buff *); /* Destruct function */ +#ifdef CONFIG_NETFILTER + /* Can be used for communication between hooks. */ + unsigned long nfmark; + /* Cache info */ + __u32 nfcache; + /* Associated connection, if any */ + struct nf_ct_info *nfct; +#ifdef CONFIG_NETFILTER_DEBUG + unsigned int nf_debug; +#endif +#endif /*CONFIG_NETFILTER*/ + +#if defined(CONFIG_HIPPI) + union{ + __u32 ifield; + } private; +#endif + +#ifdef CONFIG_NET_SCHED + __u32 tc_index; /* traffic control index */ +#endif +}; + +#define SK_WMEM_MAX 65535 +#define SK_RMEM_MAX 65535 + +#if 1 +//#ifdef __KERNEL__ +/* + * Handling routines are only of interest to the kernel + */ + +extern void __kfree_skb(struct sk_buff *skb); +extern struct sk_buff * alloc_skb(unsigned int size, int priority); +extern void kfree_skbmem(struct sk_buff *skb); +extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority); +extern struct sk_buff * skb_copy(const struct sk_buff *skb, int priority); +extern struct sk_buff * pskb_copy(struct sk_buff *skb, int gfp_mask); +extern int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask); +extern struct sk_buff * skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom); +extern struct sk_buff * skb_copy_expand(const struct sk_buff *skb, + int newheadroom, + int newtailroom, + int priority); +#define dev_kfree_skb(a) kfree_skb(a) +extern void skb_over_panic(struct sk_buff *skb, int len, void *here); +extern void skb_under_panic(struct sk_buff *skb, int len, void *here); + +/* Internal */ +#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) + +/** + * skb_queue_empty - check if a queue is empty + * @list: queue head + * + * Returns true if the queue is empty, false otherwise. + */ + +static inline int skb_queue_empty(struct sk_buff_head *list) +{ + return (list->next == (struct sk_buff *) list); +} + +/** + * skb_get - reference buffer + * @skb: buffer to reference + * + * Makes another reference to a socket buffer and returns a pointer + * to the buffer. + */ + +static inline struct sk_buff *skb_get(struct sk_buff *skb) +{ + atomic_inc(&skb->users); + return skb; +} + +/* + * If users==1, we are the only owner and are can avoid redundant + * atomic change. + */ + +/** + * kfree_skb - free an sk_buff + * @skb: buffer to free + * + * Drop a reference to the buffer and free it if the usage count has + * hit zero. + */ + +static inline void kfree_skb(struct sk_buff *skb) +{ + if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) + __kfree_skb(skb); +} + +/* Use this if you didn't touch the skb state [for fast switching] */ +static inline void kfree_skb_fast(struct sk_buff *skb) +{ + if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) + kfree_skbmem(skb); +} + +/** + * skb_cloned - is the buffer a clone + * @skb: buffer to check + * + * Returns true if the buffer was generated with skb_clone() and is + * one of multiple shared copies of the buffer. Cloned buffers are + * shared data so must not be written to under normal circumstances. + */ + +static inline int skb_cloned(struct sk_buff *skb) +{ + return skb->cloned && atomic_read(&skb_shinfo(skb)->dataref) != 1; +} + +/** + * skb_shared - is the buffer shared + * @skb: buffer to check + * + * Returns true if more than one person has a reference to this + * buffer. + */ + +static inline int skb_shared(struct sk_buff *skb) +{ + return (atomic_read(&skb->users) != 1); +} + +/** + * skb_share_check - check if buffer is shared and if so clone it + * @skb: buffer to check + * @pri: priority for memory allocation + * + * If the buffer is shared the buffer is cloned and the old copy + * drops a reference. A new clone with a single reference is returned. + * If the buffer is not shared the original buffer is returned. When + * being called from interrupt status or with spinlocks held pri must + * be GFP_ATOMIC. + * + * NULL is returned on a memory allocation failure. + */ + +static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri) +{ + if (skb_shared(skb)) { + struct sk_buff *nskb; + nskb = skb_clone(skb, pri); + kfree_skb(skb); + return nskb; + } + return skb; +} + + +/* + * Copy shared buffers into a new sk_buff. We effectively do COW on + * packets to handle cases where we have a local reader and forward + * and a couple of other messy ones. The normal one is tcpdumping + * a packet thats being forwarded. + */ + +/** + * skb_unshare - make a copy of a shared buffer + * @skb: buffer to check + * @pri: priority for memory allocation + * + * If the socket buffer is a clone then this function creates a new + * copy of the data, drops a reference count on the old copy and returns + * the new copy with the reference count at 1. If the buffer is not a clone + * the original buffer is returned. When called with a spinlock held or + * from interrupt state @pri must be %GFP_ATOMIC + * + * %NULL is returned on a memory allocation failure. + */ + +static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri) +{ + struct sk_buff *nskb; + if(!skb_cloned(skb)) + return skb; + nskb=skb_copy(skb, pri); + kfree_skb(skb); /* Free our shared copy */ + return nskb; +} + +/** + * skb_peek + * @list_: list to peek at + * + * Peek an &sk_buff. Unlike most other operations you _MUST_ + * be careful with this one. A peek leaves the buffer on the + * list and someone else may run off with it. You must hold + * the appropriate locks or have a private queue to do this. + * + * Returns %NULL for an empty list or a pointer to the head element. + * The reference count is not incremented and the reference is therefore + * volatile. Use with caution. + */ + +static inline struct sk_buff *skb_peek(struct sk_buff_head *list_) +{ + struct sk_buff *list = ((struct sk_buff *)list_)->next; + if (list == (struct sk_buff *)list_) + list = NULL; + return list; +} + +/** + * skb_peek_tail + * @list_: list to peek at + * + * Peek an &sk_buff. Unlike most other operations you _MUST_ + * be careful with this one. A peek leaves the buffer on the + * list and someone else may run off with it. You must hold + * the appropriate locks or have a private queue to do this. + * + * Returns %NULL for an empty list or a pointer to the tail element. + * The reference count is not incremented and the reference is therefore + * volatile. Use with caution. + */ + +static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_) +{ + struct sk_buff *list = ((struct sk_buff *)list_)->prev; + if (list == (struct sk_buff *)list_) + list = NULL; + return list; +} + +/** + * skb_queue_len - get queue length + * @list_: list to measure + * + * Return the length of an &sk_buff queue. + */ + +static inline __u32 skb_queue_len(struct sk_buff_head *list_) +{ + return(list_->qlen); +} + +static inline void skb_queue_head_init(struct sk_buff_head *list) +{ + spin_lock_init(&list->lock); + list->prev = (struct sk_buff *)list; + list->next = (struct sk_buff *)list; + list->qlen = 0; +} + +/* + * Insert an sk_buff at the start of a list. + * + * The "__skb_xxxx()" functions are the non-atomic ones that + * can only be called with interrupts disabled. + */ + +/** + * __skb_queue_head - queue a buffer at the list head + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the start of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + * + * A buffer cannot be placed on two lists at the same time. + */ + +static inline void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) +{ + struct sk_buff *prev, *next; + + newsk->list = list; + list->qlen++; + prev = (struct sk_buff *)list; + next = prev->next; + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; +} + + +/** + * skb_queue_head - queue a buffer at the list head + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the start of the list. This function takes the + * list lock and can be used safely with other locking &sk_buff functions + * safely. + * + * A buffer cannot be placed on two lists at the same time. + */ + +static inline void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) +{ + unsigned long flags; + + spin_lock_irqsave(&list->lock, flags); + __skb_queue_head(list, newsk); + spin_unlock_irqrestore(&list->lock, flags); +} + +/** + * __skb_queue_tail - queue a buffer at the list tail + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the end of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + * + * A buffer cannot be placed on two lists at the same time. + */ + + +static inline void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + struct sk_buff *prev, *next; + + newsk->list = list; + list->qlen++; + next = (struct sk_buff *)list; + prev = next->prev; + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; +} + +/** + * skb_queue_tail - queue a buffer at the list tail + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the tail of the list. This function takes the + * list lock and can be used safely with other locking &sk_buff functions + * safely. + * + * A buffer cannot be placed on two lists at the same time. + */ + +static inline void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + unsigned long flags; + + spin_lock_irqsave(&list->lock, flags); + __skb_queue_tail(list, newsk); + spin_unlock_irqrestore(&list->lock, flags); +} + +/** + * __skb_dequeue - remove from the head of the queue + * @list: list to dequeue from + * + * Remove the head of the list. This function does not take any locks + * so must be used with appropriate locks held only. The head item is + * returned or %NULL if the list is empty. + */ + +static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list) +{ + struct sk_buff *next, *prev, *result; + + prev = (struct sk_buff *) list; + next = prev->next; + result = NULL; + if (next != prev) { + result = next; + next = next->next; + list->qlen--; + next->prev = prev; + prev->next = next; + result->next = NULL; + result->prev = NULL; + result->list = NULL; + } + return result; +} + +/** + * skb_dequeue - remove from the head of the queue + * @list: list to dequeue from + * + * Remove the head of the list. The list lock is taken so the function + * may be used safely with other locking list functions. The head item is + * returned or %NULL if the list is empty. + */ + +static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list) +{ + unsigned long flags; + struct sk_buff *result; + + spin_lock_irqsave(&list->lock, flags); + result = __skb_dequeue(list); + spin_unlock_irqrestore(&list->lock, flags); + return result; +} + +/* + * Insert a packet on a list. + */ + +static inline void __skb_insert(struct sk_buff *newsk, + struct sk_buff * prev, struct sk_buff *next, + struct sk_buff_head * list) +{ + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; + newsk->list = list; + list->qlen++; +} + +/** + * skb_insert - insert a buffer + * @old: buffer to insert before + * @newsk: buffer to insert + * + * Place a packet before a given packet in a list. The list locks are taken + * and this function is atomic with respect to other list locked calls + * A buffer cannot be placed on two lists at the same time. + */ + +static inline void skb_insert(struct sk_buff *old, struct sk_buff *newsk) +{ + unsigned long flags; + + spin_lock_irqsave(&old->list->lock, flags); + __skb_insert(newsk, old->prev, old, old->list); + spin_unlock_irqrestore(&old->list->lock, flags); +} + +/* + * Place a packet after a given packet in a list. + */ + +static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk) +{ + __skb_insert(newsk, old, old->next, old->list); +} + +/** + * skb_append - append a buffer + * @old: buffer to insert after + * @newsk: buffer to insert + * + * Place a packet after a given packet in a list. The list locks are taken + * and this function is atomic with respect to other list locked calls. + * A buffer cannot be placed on two lists at the same time. + */ + + +static inline void skb_append(struct sk_buff *old, struct sk_buff *newsk) +{ + unsigned long flags; + + spin_lock_irqsave(&old->list->lock, flags); + __skb_append(old, newsk); + spin_unlock_irqrestore(&old->list->lock, flags); +} + +/* + * remove sk_buff from list. _Must_ be called atomically, and with + * the list known.. + */ + +static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) +{ + struct sk_buff * next, * prev; + + list->qlen--; + next = skb->next; + prev = skb->prev; + skb->next = NULL; + skb->prev = NULL; + skb->list = NULL; + next->prev = prev; + prev->next = next; +} + +/** + * skb_unlink - remove a buffer from a list + * @skb: buffer to remove + * + * Place a packet after a given packet in a list. The list locks are taken + * and this function is atomic with respect to other list locked calls + * + * Works even without knowing the list it is sitting on, which can be + * handy at times. It also means that THE LIST MUST EXIST when you + * unlink. Thus a list must have its contents unlinked before it is + * destroyed. + */ + +static inline void skb_unlink(struct sk_buff *skb) +{ + struct sk_buff_head *list = skb->list; + + if(list) { + unsigned long flags; + + spin_lock_irqsave(&list->lock, flags); + if(skb->list == list) + __skb_unlink(skb, skb->list); + spin_unlock_irqrestore(&list->lock, flags); + } +} + +/* XXX: more streamlined implementation */ + +/** + * __skb_dequeue_tail - remove from the tail of the queue + * @list: list to dequeue from + * + * Remove the tail of the list. This function does not take any locks + * so must be used with appropriate locks held only. The tail item is + * returned or %NULL if the list is empty. + */ + +static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list) +{ + struct sk_buff *skb = skb_peek_tail(list); + if (skb) + __skb_unlink(skb, list); + return skb; +} + +/** + * skb_dequeue - remove from the head of the queue + * @list: list to dequeue from + * + * Remove the head of the list. The list lock is taken so the function + * may be used safely with other locking list functions. The tail item is + * returned or %NULL if the list is empty. + */ + +static inline struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) +{ + unsigned long flags; + struct sk_buff *result; + + spin_lock_irqsave(&list->lock, flags); + result = __skb_dequeue_tail(list); + spin_unlock_irqrestore(&list->lock, flags); + return result; +} + +static inline int skb_is_nonlinear(const struct sk_buff *skb) +{ + return skb->data_len; +} + +static inline int skb_headlen(const struct sk_buff *skb) +{ + return skb->len - skb->data_len; +} + +#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) out_of_line_bug(); } while (0) +#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) out_of_line_bug(); } while (0) +#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) out_of_line_bug(); } while (0) + +/* + * Add data to an sk_buff + */ + +static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len) +{ + unsigned char *tmp=skb->tail; + SKB_LINEAR_ASSERT(skb); + skb->tail+=len; + skb->len+=len; + return tmp; +} + +/** + * skb_put - add data to a buffer + * @skb: buffer to use + * @len: amount of data to add + * + * This function extends the used data area of the buffer. If this would + * exceed the total buffer size the kernel will panic. A pointer to the + * first byte of the extra data is returned. + */ + +static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len) +{ +#if 0 + unsigned char *tmp=skb->tail; + SKB_LINEAR_ASSERT(skb); + skb->tail+=len; + skb->len+=len; + if(skb->tail>skb->end) { + skb_over_panic(skb, len, current_text_addr()); + } + return tmp; +#else +return NULL; +#endif +} + +static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len) +{ + skb->data-=len; + skb->len+=len; + return skb->data; +} + +/** + * skb_push - add data to the start of a buffer + * @skb: buffer to use + * @len: amount of data to add + * + * This function extends the used data area of the buffer at the buffer + * start. If this would exceed the total buffer headroom the kernel will + * panic. A pointer to the first byte of the extra data is returned. + */ + +static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len) +{ +#if 0 + skb->data-=len; + skb->len+=len; + if(skb->datahead) { + skb_under_panic(skb, len, current_text_addr()); + } + return skb->data; +#else + return NULL; +#endif +} + +static inline char *__skb_pull(struct sk_buff *skb, unsigned int len) +{ + skb->len-=len; + if (skb->len < skb->data_len) + out_of_line_bug(); + return skb->data+=len; +} + +/** + * skb_pull - remove data from the start of a buffer + * @skb: buffer to use + * @len: amount of data to remove + * + * This function removes data from the start of a buffer, returning + * the memory to the headroom. A pointer to the next data in the buffer + * is returned. Once the data has been pulled future pushes will overwrite + * the old data. + */ + +static inline unsigned char * skb_pull(struct sk_buff *skb, unsigned int len) +{ + if (len > skb->len) + return NULL; + return __skb_pull(skb,len); +} + +extern unsigned char * __pskb_pull_tail(struct sk_buff *skb, int delta); + +static inline char *__pskb_pull(struct sk_buff *skb, unsigned int len) +{ + if (len > skb_headlen(skb) && + __pskb_pull_tail(skb, len-skb_headlen(skb)) == NULL) + return NULL; + skb->len -= len; + return skb->data += len; +} + +static inline unsigned char * pskb_pull(struct sk_buff *skb, unsigned int len) +{ + if (len > skb->len) + return NULL; + return __pskb_pull(skb,len); +} + +static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len) +{ + if (len <= skb_headlen(skb)) + return 1; + if (len > skb->len) + return 0; + return (__pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL); +} + +/** + * skb_headroom - bytes at buffer head + * @skb: buffer to check + * + * Return the number of bytes of free space at the head of an &sk_buff. + */ + +static inline int skb_headroom(const struct sk_buff *skb) +{ + return skb->data-skb->head; +} + +/** + * skb_tailroom - bytes at buffer end + * @skb: buffer to check + * + * Return the number of bytes of free space at the tail of an sk_buff + */ + +static inline int skb_tailroom(const struct sk_buff *skb) +{ + return skb_is_nonlinear(skb) ? 0 : skb->end-skb->tail; +} + +/** + * skb_reserve - adjust headroom + * @skb: buffer to alter + * @len: bytes to move + * + * Increase the headroom of an empty &sk_buff by reducing the tail + * room. This is only allowed for an empty buffer. + */ + +static inline void skb_reserve(struct sk_buff *skb, unsigned int len) +{ + skb->data+=len; + skb->tail+=len; +} + +extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); + +static inline void __skb_trim(struct sk_buff *skb, unsigned int len) +{ + if (!skb->data_len) { + skb->len = len; + skb->tail = skb->data+len; + } else { + ___pskb_trim(skb, len, 0); + } +} + +/** + * skb_trim - remove end from a buffer + * @skb: buffer to alter + * @len: new length + * + * Cut the length of a buffer down by removing data from the tail. If + * the buffer is already under the length specified it is not modified. + */ + +static inline void skb_trim(struct sk_buff *skb, unsigned int len) +{ + if (skb->len > len) { + __skb_trim(skb, len); + } +} + + +static inline int __pskb_trim(struct sk_buff *skb, unsigned int len) +{ + if (!skb->data_len) { + skb->len = len; + skb->tail = skb->data+len; + return 0; + } else { + return ___pskb_trim(skb, len, 1); + } +} + +static inline int pskb_trim(struct sk_buff *skb, unsigned int len) +{ + if (len < skb->len) + return __pskb_trim(skb, len); + return 0; +} + +/** + * skb_orphan - orphan a buffer + * @skb: buffer to orphan + * + * If a buffer currently has an owner then we call the owner's + * destructor function and make the @skb unowned. The buffer continues + * to exist but is no longer charged to its former owner. + */ + + +static inline void skb_orphan(struct sk_buff *skb) +{ + if (skb->destructor) + skb->destructor(skb); + skb->destructor = NULL; + skb->sk = NULL; +} + +/** + * skb_purge - empty a list + * @list: list to empty + * + * Delete all buffers on an &sk_buff list. Each buffer is removed from + * the list and one reference dropped. This function takes the list + * lock and is atomic with respect to other list locking functions. + */ + + +static inline void skb_queue_purge(struct sk_buff_head *list) +{ + struct sk_buff *skb; + while ((skb=skb_dequeue(list))!=NULL) + kfree_skb(skb); +} + +/** + * __skb_purge - empty a list + * @list: list to empty + * + * Delete all buffers on an &sk_buff list. Each buffer is removed from + * the list and one reference dropped. This function does not take the + * list lock and the caller must hold the relevant locks to use it. + */ + + +static inline void __skb_queue_purge(struct sk_buff_head *list) +{ + struct sk_buff *skb; + while ((skb=__skb_dequeue(list))!=NULL) + kfree_skb(skb); +} + +/** + * __dev_alloc_skb - allocate an skbuff for sending + * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The + * buffer has unspecified headroom built in. Users should allocate + * the headroom they think they need without accounting for the + * built in space. The built in space is used for optimisations. + * + * %NULL is returned in there is no free memory. + */ + +static inline struct sk_buff *__dev_alloc_skb(unsigned int length, + int gfp_mask) +{ + struct sk_buff *skb; + + skb = alloc_skb(length+16, gfp_mask); + if (skb) + skb_reserve(skb,16); + return skb; +} + +/** + * dev_alloc_skb - allocate an skbuff for sending + * @length: length to allocate + * + * Allocate a new &sk_buff and assign it a usage count of one. The + * buffer has unspecified headroom built in. Users should allocate + * the headroom they think they need without accounting for the + * built in space. The built in space is used for optimisations. + * + * %NULL is returned in there is no free memory. Although this function + * allocates memory it can be called from an interrupt. + */ + +static inline struct sk_buff *dev_alloc_skb(unsigned int length) +{ +#if 0 + return __dev_alloc_skb(length, GFP_ATOMIC); +#else + return NULL; +#endif +} + +/** + * skb_cow - copy header of skb when it is required + * @skb: buffer to cow + * @headroom: needed headroom + * + * If the skb passed lacks sufficient headroom or its data part + * is shared, data is reallocated. If reallocation fails, an error + * is returned and original skb is not changed. + * + * The result is skb with writable area skb->head...skb->tail + * and at least @headroom of space at head. + */ + +static inline int +skb_cow(struct sk_buff *skb, unsigned int headroom) +{ +#if 0 + int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb); + + if (delta < 0) + delta = 0; + + if (delta || skb_cloned(skb)) + return pskb_expand_head(skb, (delta+15)&~15, 0, GFP_ATOMIC); + return 0; +#else + return 0; +#endif +} + +/** + * skb_linearize - convert paged skb to linear one + * @skb: buffer to linarize + * @gfp: allocation mode + * + * If there is no free memory -ENOMEM is returned, otherwise zero + * is returned and the old skb data released. */ +int skb_linearize(struct sk_buff *skb, int gfp); + +static inline void *kmap_skb_frag(const skb_frag_t *frag) +{ +#if 0 +#ifdef CONFIG_HIGHMEM + if (in_irq()) + out_of_line_bug(); + + local_bh_disable(); +#endif + return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ); +#else + return NULL; +#endif +} + +static inline void kunmap_skb_frag(void *vaddr) +{ +#if 0 + kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); +#ifdef CONFIG_HIGHMEM + local_bh_enable(); +#endif +#endif +} + +#define skb_queue_walk(queue, skb) \ + for (skb = (queue)->next; \ + (skb != (struct sk_buff *)(queue)); \ + skb=skb->next) + + +extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err); +extern unsigned int datagram_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait); +extern int skb_copy_datagram(const struct sk_buff *from, int offset, char *to,int size); +extern int skb_copy_datagram_iovec(const struct sk_buff *from, int offset, struct iovec *to,int size); +extern int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int *csump); +extern int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb, int hlen, struct iovec *iov); +extern void skb_free_datagram(struct sock * sk, struct sk_buff *skb); + +extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, int len, unsigned int csum); +extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); +extern unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int csum); +extern void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to); + +extern void skb_init(void); +extern void skb_add_mtu(int mtu); + +#ifdef CONFIG_NETFILTER +static inline void +nf_conntrack_put(struct nf_ct_info *nfct) +{ + if (nfct && atomic_dec_and_test(&nfct->master->use)) + nfct->master->destroy(nfct->master); +} +static inline void +nf_conntrack_get(struct nf_ct_info *nfct) +{ + if (nfct) + atomic_inc(&nfct->master->use); +} +#endif + + +#endif /* skbuff */ + + + + + +struct sock; + +typedef struct sockaddr +{ + int x; +} _sockaddr; + + +struct msghdr { + void * msg_name; /* Socket name */ + int msg_namelen; /* Length of name */ + struct iovec * msg_iov; /* Data blocks */ + __kernel_size_t msg_iovlen; /* Number of blocks */ + void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */ + __kernel_size_t msg_controllen; /* Length of cmsg list */ + unsigned msg_flags; +}; + + +/* IP protocol blocks we attach to sockets. + * socket layer -> transport layer interface + * transport -> network interface is defined by struct inet_proto + */ +struct proto { + void (*close)(struct sock *sk, + long timeout); + int (*connect)(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + int (*disconnect)(struct sock *sk, int flags); + + struct sock * (*accept) (struct sock *sk, int flags, int *err); + + int (*ioctl)(struct sock *sk, int cmd, + unsigned long arg); + int (*init)(struct sock *sk); + int (*destroy)(struct sock *sk); + void (*shutdown)(struct sock *sk, int how); + int (*setsockopt)(struct sock *sk, int level, + int optname, char *optval, int optlen); + int (*getsockopt)(struct sock *sk, int level, + int optname, char *optval, + int *option); + int (*sendmsg)(struct sock *sk, struct msghdr *msg, + int len); + int (*recvmsg)(struct sock *sk, struct msghdr *msg, + int len, int noblock, int flags, + int *addr_len); + int (*bind)(struct sock *sk, + struct sockaddr *uaddr, int addr_len); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); + + /* Keeping track of sk's, looking them up, and port selection methods. */ + void (*hash)(struct sock *sk); + void (*unhash)(struct sock *sk); + int (*get_port)(struct sock *sk, unsigned short snum); + + char name[32]; + + struct { + int inuse; + } stats[32]; +// u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; +// } stats[NR_CPUS]; +}; + + + + + + + +/* This defines a selective acknowledgement block. */ +struct tcp_sack_block { + __u32 start_seq; + __u32 end_seq; +}; + + +struct tcp_opt { + int tcp_header_len; /* Bytes of tcp header to send */ + +/* + * Header prediction flags + * 0x5?10 << 16 + snd_wnd in net byte order + */ + __u32 pred_flags; + +/* + * RFC793 variables by their proper names. This means you can + * read the code and the spec side by side (and laugh ...) + * See RFC793 and RFC1122. The RFC writes these in capitals. + */ + __u32 rcv_nxt; /* What we want to receive next */ + __u32 snd_nxt; /* Next sequence we send */ + + __u32 snd_una; /* First byte we want an ack for */ + __u32 snd_sml; /* Last byte of the most recently transmitted small packet */ + __u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ + __u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ + + /* Delayed ACK control data */ + struct { + __u8 pending; /* ACK is pending */ + __u8 quick; /* Scheduled number of quick acks */ + __u8 pingpong; /* The session is interactive */ + __u8 blocked; /* Delayed ACK was blocked by socket lock*/ + __u32 ato; /* Predicted tick of soft clock */ + unsigned long timeout; /* Currently scheduled timeout */ + __u32 lrcvtime; /* timestamp of last received data packet*/ + __u16 last_seg_size; /* Size of last incoming segment */ + __u16 rcv_mss; /* MSS used for delayed ACK decisions */ + } ack; + + /* Data for direct copy to user */ + struct { + //struct sk_buff_head prequeue; + struct task_struct *task; + struct iovec *iov; + int memory; + int len; + } ucopy; + + __u32 snd_wl1; /* Sequence for window update */ + __u32 snd_wnd; /* The window we expect to receive */ + __u32 max_window; /* Maximal window ever seen from peer */ + __u32 pmtu_cookie; /* Last pmtu seen by socket */ + __u16 mss_cache; /* Cached effective mss, not including SACKS */ + __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ + __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ + __u8 ca_state; /* State of fast-retransmit machine */ + __u8 retransmits; /* Number of unrecovered RTO timeouts. */ + + __u8 reordering; /* Packet reordering metric. */ + __u8 queue_shrunk; /* Write queue has been shrunk recently.*/ + __u8 defer_accept; /* User waits for some data after accept() */ + +/* RTT measurement */ + __u8 backoff; /* backoff */ + __u32 srtt; /* smothed round trip time << 3 */ + __u32 mdev; /* medium deviation */ + __u32 mdev_max; /* maximal mdev for the last rtt period */ + __u32 rttvar; /* smoothed mdev_max */ + __u32 rtt_seq; /* sequence number to update rttvar */ + __u32 rto; /* retransmit timeout */ + + __u32 packets_out; /* Packets which are "in flight" */ + __u32 left_out; /* Packets which leaved network */ + __u32 retrans_out; /* Retransmitted packets out */ + + +/* + * Slow start and congestion control (see also Nagle, and Karn & Partridge) + */ + __u32 snd_ssthresh; /* Slow start size threshold */ + __u32 snd_cwnd; /* Sending congestion window */ + __u16 snd_cwnd_cnt; /* Linear increase counter */ + __u16 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */ + __u32 snd_cwnd_used; + __u32 snd_cwnd_stamp; + + /* Two commonly used timers in both sender and receiver paths. */ + unsigned long timeout; + struct timer_list retransmit_timer; /* Resend (no ack) */ + struct timer_list delack_timer; /* Ack delay */ + + struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ + + struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */ + struct sk_buff *send_head; /* Front of stuff to transmit */ + struct page *sndmsg_page; /* Cached page for sendmsg */ + u32 sndmsg_off; /* Cached offset for sendmsg */ + + __u32 rcv_wnd; /* Current receiver window */ + __u32 rcv_wup; /* rcv_nxt on last window update sent */ + __u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ + __u32 pushed_seq; /* Last pushed seq, required to talk to windows */ + __u32 copied_seq; /* Head of yet unread data */ +/* + * Options received (usually on last packet, some only on SYN packets). + */ + char tstamp_ok, /* TIMESTAMP seen on SYN packet */ + wscale_ok, /* Wscale seen on SYN packet */ + sack_ok; /* SACK seen on SYN packet */ + char saw_tstamp; /* Saw TIMESTAMP on last packet */ + __u8 snd_wscale; /* Window scaling received from sender */ + __u8 rcv_wscale; /* Window scaling to send to receiver */ + __u8 nonagle; /* Disable Nagle algorithm? */ + __u8 keepalive_probes; /* num of allowed keep alive probes */ + +/* PAWS/RTTM data */ + __u32 rcv_tsval; /* Time stamp value */ + __u32 rcv_tsecr; /* Time stamp echo reply */ + __u32 ts_recent; /* Time stamp to echo next */ + long ts_recent_stamp;/* Time we stored ts_recent (for aging) */ + +/* SACKs data */ + __u16 user_mss; /* mss requested by user in ioctl */ + __u8 dsack; /* D-SACK is scheduled */ + __u8 eff_sacks; /* Size of SACK array to send with next packet */ + struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */ + struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/ + + __u32 window_clamp; /* Maximal window to advertise */ + __u32 rcv_ssthresh; /* Current window clamp */ + __u8 probes_out; /* unanswered 0 window probes */ + __u8 num_sacks; /* Number of SACK blocks */ + __u16 advmss; /* Advertised MSS */ + + __u8 syn_retries; /* num of allowed syn retries */ + __u8 ecn_flags; /* ECN status bits. */ + __u16 prior_ssthresh; /* ssthresh saved at recovery start */ + __u32 lost_out; /* Lost packets */ + __u32 sacked_out; /* SACK'd packets */ + __u32 fackets_out; /* FACK'd packets */ + __u32 high_seq; /* snd_nxt at onset of congestion */ + + __u32 retrans_stamp; /* Timestamp of the last retransmit, + * also used in SYN-SENT to remember stamp of + * the first SYN. */ + __u32 undo_marker; /* tracking retrans started here. */ + int undo_retrans; /* number of undoable retransmissions. */ + __u32 urg_seq; /* Seq of received urgent pointer */ + __u16 urg_data; /* Saved octet of OOB data and control flags */ + __u8 pending; /* Scheduled timer event */ + __u8 urg_mode; /* In urgent mode */ + __u32 snd_up; /* Urgent pointer */ + + /* The syn_wait_lock is necessary only to avoid tcp_get_info having + * to grab the main lock sock while browsing the listening hash + * (otherwise it's deadlock prone). + * This lock is acquired in read mode only from tcp_get_info() and + * it's acquired in write mode _only_ from code that is actively + * changing the syn_wait_queue. All readers that are holding + * the master sock lock don't need to grab this lock in read mode + * too as the syn_wait_queue writes are always protected from + * the main sock lock. + */ + rwlock_t syn_wait_lock; + struct tcp_listen_opt *listen_opt; + + /* FIFO of established children */ + struct open_request *accept_queue; + struct open_request *accept_queue_tail; + + int write_pending; /* A write to socket waits to start. */ + + unsigned int keepalive_time; /* time before keep alive takes place */ + unsigned int keepalive_intvl; /* time interval between keep alive probes */ + int linger2; + + unsigned long last_synq_overflow; +}; + + + + +/* This is the per-socket lock. The spinlock provides a synchronization + * between user contexts and software interrupt processing, whereas the + * mini-semaphore synchronizes multiple users amongst themselves. + */ +typedef struct { + spinlock_t slock; + unsigned int users; + wait_queue_head_t wq; +} socket_lock_t; + +struct sock { + /* Socket demultiplex comparisons on incoming packets. */ + __u32 daddr; /* Foreign IPv4 addr */ + __u32 rcv_saddr; /* Bound local IPv4 addr */ + __u16 dport; /* Destination port */ + unsigned short num; /* Local port */ + int bound_dev_if; /* Bound device index if != 0 */ + + /* Main hash linkage for various protocol lookup tables. */ + struct sock *next; + struct sock **pprev; + struct sock *bind_next; + struct sock **bind_pprev; + + volatile unsigned char state, /* Connection state */ + zapped; /* In ax25 & ipx means not linked */ + __u16 sport; /* Source port */ + + unsigned short family; /* Address family */ + unsigned char reuse; /* SO_REUSEADDR setting */ + unsigned char shutdown; + atomic_t refcnt; /* Reference count */ + + socket_lock_t lock; /* Synchronizer... */ + int rcvbuf; /* Size of receive buffer in bytes */ + + wait_queue_head_t *sleep; /* Sock wait queue */ + struct dst_entry *dst_cache; /* Destination cache */ + rwlock_t dst_lock; + atomic_t rmem_alloc; /* Receive queue bytes committed */ + struct sk_buff_head receive_queue; /* Incoming packets */ + atomic_t wmem_alloc; /* Transmit queue bytes committed */ + struct sk_buff_head write_queue; /* Packet sending queue */ + atomic_t omem_alloc; /* "o" is "option" or "other" */ + int wmem_queued; /* Persistent queue size */ + int forward_alloc; /* Space allocated forward. */ + __u32 saddr; /* Sending source */ + unsigned int allocation; /* Allocation mode */ + int sndbuf; /* Size of send buffer in bytes */ + struct sock *prev; + + /* Not all are volatile, but some are, so we might as well say they all are. + * XXX Make this a flag word -DaveM + */ + volatile char dead, + done, + urginline, + keepopen, + linger, + destroy, + no_check, + broadcast, + bsdism; + unsigned char debug; + unsigned char rcvtstamp; + unsigned char use_write_queue; + unsigned char userlocks; + /* Hole of 3 bytes. Try to pack. */ + int route_caps; + int proc; + unsigned long lingertime; + + int hashent; + struct sock *pair; + + /* The backlog queue is special, it is always used with + * the per-socket spinlock held and requires low latency + * access. Therefore we special case it's implementation. + */ + struct { + struct sk_buff *head; + struct sk_buff *tail; + } backlog; + + rwlock_t callback_lock; + + /* Error queue, rarely used. */ + struct sk_buff_head error_queue; + + struct proto *prot; + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + union { + struct ipv6_pinfo af_inet6; + } net_pinfo; +#endif + + union { + struct tcp_opt af_tcp; +#if defined(CONFIG_INET) || defined (CONFIG_INET_MODULE) + struct raw_opt tp_raw4; +#endif +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct raw6_opt tp_raw; +#endif /* CONFIG_IPV6 */ +#if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE) + struct spx_opt af_spx; +#endif /* CONFIG_SPX */ + + } tp_pinfo; + + int err, err_soft; /* Soft holds errors that don't + cause failure but are the cause + of a persistent failure not just + 'timed out' */ + unsigned short ack_backlog; + unsigned short max_ack_backlog; + __u32 priority; + unsigned short type; + unsigned char localroute; /* Route locally only */ + unsigned char protocol; +// struct ucred peercred; + int rcvlowat; + long rcvtimeo; + long sndtimeo; + +#ifdef CONFIG_FILTER + /* Socket Filtering Instructions */ + struct sk_filter *filter; +#endif /* CONFIG_FILTER */ + + /* This is where all the private (optional) areas that don't + * overlap will eventually live. + */ + union { + void *destruct_hook; +// struct unix_opt af_unix; +#if defined(CONFIG_INET) || defined (CONFIG_INET_MODULE) + struct inet_opt af_inet; +#endif +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) + struct atalk_sock af_at; +#endif +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) + struct ipx_opt af_ipx; +#endif +#if defined (CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE) + struct dn_scp dn; +#endif +#if defined (CONFIG_PACKET) || defined(CONFIG_PACKET_MODULE) + struct packet_opt *af_packet; +#endif +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) + x25_cb *x25; +#endif +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) + ax25_cb *ax25; +#endif +#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) + nr_cb *nr; +#endif +#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) + rose_cb *rose; +#endif +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) + struct pppox_opt *pppox; +#endif + struct netlink_opt *af_netlink; +#if defined(CONFIG_ECONET) || defined(CONFIG_ECONET_MODULE) + struct econet_opt *af_econet; +#endif +#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE) + struct atm_vcc *af_atm; +#endif +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) + struct irda_sock *irda; +#endif +#if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE) + struct wanpipe_opt *af_wanpipe; +#endif + } protinfo; + + + /* This part is used for the timeout functions. */ + struct timer_list timer; /* This is the sock cleanup timer. */ + struct timeval stamp; + + /* Identd and reporting IO signals */ + struct socket *socket; + + /* RPC layer private data */ + void *user_data; + + /* Callbacks */ + void (*state_change)(struct sock *sk); + void (*data_ready)(struct sock *sk,int bytes); + void (*write_space)(struct sock *sk); + void (*error_report)(struct sock *sk); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); + void (*destruct)(struct sock *sk); +}; + + + + +#if 1 /* dst (_NET_DST_H) */ + +#if 0 +#include +#include +#endif + +/* + * 0 - no debugging messages + * 1 - rare events and bugs (default) + * 2 - trace mode. + */ +#define RT_CACHE_DEBUG 0 + +#define DST_GC_MIN (1*HZ) +#define DST_GC_INC (5*HZ) +#define DST_GC_MAX (120*HZ) + +struct sk_buff; + +struct dst_entry +{ + struct dst_entry *next; + atomic_t __refcnt; /* client references */ + int __use; + struct net_device *dev; + int obsolete; + int flags; +#define DST_HOST 1 + unsigned long lastuse; + unsigned long expires; + + unsigned mxlock; + unsigned pmtu; + unsigned window; + unsigned rtt; + unsigned rttvar; + unsigned ssthresh; + unsigned cwnd; + unsigned advmss; + unsigned reordering; + + unsigned long rate_last; /* rate limiting for ICMP */ + unsigned long rate_tokens; + + int error; + + struct neighbour *neighbour; + struct hh_cache *hh; + + int (*input)(struct sk_buff*); + int (*output)(struct sk_buff*); + +#ifdef CONFIG_NET_CLS_ROUTE + __u32 tclassid; +#endif + + struct dst_ops *ops; + + char info[0]; +}; + + +struct dst_ops +{ + unsigned short family; + unsigned short protocol; + unsigned gc_thresh; + + int (*gc)(void); + struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); + struct dst_entry * (*reroute)(struct dst_entry *, + struct sk_buff *); + void (*destroy)(struct dst_entry *); + struct dst_entry * (*negative_advice)(struct dst_entry *); + void (*link_failure)(struct sk_buff *); + int entry_size; + + atomic_t entries; + kmem_cache_t *kmem_cachep; +}; + +#ifdef __KERNEL__ + +static inline void dst_hold(struct dst_entry * dst) +{ + atomic_inc(&dst->__refcnt); +} + +static inline +struct dst_entry * dst_clone(struct dst_entry * dst) +{ + if (dst) + atomic_inc(&dst->__refcnt); + return dst; +} + +static inline +void dst_release(struct dst_entry * dst) +{ + if (dst) + atomic_dec(&dst->__refcnt); +} + +extern void * dst_alloc(struct dst_ops * ops); +extern void __dst_free(struct dst_entry * dst); +extern void dst_destroy(struct dst_entry * dst); + +static inline +void dst_free(struct dst_entry * dst) +{ + if (dst->obsolete > 1) + return; + if (!atomic_read(&dst->__refcnt)) { + dst_destroy(dst); + return; + } + __dst_free(dst); +} + +static inline void dst_confirm(struct dst_entry *dst) +{ + if (dst) + neigh_confirm(dst->neighbour); +} + +static inline void dst_negative_advice(struct dst_entry **dst_p) +{ + struct dst_entry * dst = *dst_p; + if (dst && dst->ops->negative_advice) + *dst_p = dst->ops->negative_advice(dst); +} + +static inline void dst_link_failure(struct sk_buff *skb) +{ + struct dst_entry * dst = skb->dst; + if (dst && dst->ops && dst->ops->link_failure) + dst->ops->link_failure(skb); +} + +static inline void dst_set_expires(struct dst_entry *dst, int timeout) +{ + unsigned long expires = jiffies + timeout; + + if (expires == 0) + expires = 1; + + if (dst->expires == 0 || (long)(dst->expires - expires) > 0) + dst->expires = expires; +} + +extern void dst_init(void); + +#endif /* dst */ + + + +#if 1 +/* dummy types */ + + +#endif + +#define TCP_DEBUG 1 +#define FASTRETRANS_DEBUG 1 + +/* Cancel timers, when they are not required. */ +#undef TCP_CLEAR_TIMERS + +#if 0 +#include +#include +#include +#include +#include +#include +#else +#include "linux.h" +#endif + +/* This is for all connections with a full identity, no wildcards. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. + */ +struct tcp_ehash_bucket { + rwlock_t lock; + struct sock *chain; +} __attribute__((__aligned__(8))); + +/* This is for listening sockets, thus all sockets which possess wildcards. */ +#define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ + +/* There are a few simple rules, which allow for local port reuse by + * an application. In essence: + * + * 1) Sockets bound to different interfaces may share a local port. + * Failing that, goto test 2. + * 2) If all sockets have sk->reuse set, and none of them are in + * TCP_LISTEN state, the port may be shared. + * Failing that, goto test 3. + * 3) If all sockets are bound to a specific sk->rcv_saddr local + * address, and none of them are the same, the port may be + * shared. + * Failing this, the port cannot be shared. + * + * The interesting point, is test #2. This is what an FTP server does + * all day. To optimize this case we use a specific flag bit defined + * below. As we add sockets to a bind bucket list, we perform a + * check of: (newsk->reuse && (newsk->state != TCP_LISTEN)) + * As long as all sockets added to a bind bucket pass this test, + * the flag bit will be set. + * The resulting situation is that tcp_v[46]_verify_bind() can just check + * for this flag bit, if it is set and the socket trying to bind has + * sk->reuse set, we don't even have to walk the owners list at all, + * we return that it is ok to bind this socket to the requested local port. + * + * Sounds like a lot of work, but it is worth it. In a more naive + * implementation (ie. current FreeBSD etc.) the entire list of ports + * must be walked for each data port opened by an ftp server. Needless + * to say, this does not scale at all. With a couple thousand FTP + * users logged onto your box, isn't it nice to know that new data + * ports are created in O(1) time? I thought so. ;-) -DaveM + */ +struct tcp_bind_bucket { + unsigned short port; + signed short fastreuse; + struct tcp_bind_bucket *next; + struct sock *owners; + struct tcp_bind_bucket **pprev; +}; + +struct tcp_bind_hashbucket { + spinlock_t lock; + struct tcp_bind_bucket *chain; +}; + +extern struct tcp_hashinfo { + /* This is for sockets with full identity only. Sockets here will + * always be without wildcards and will have the following invariant: + * + * TCP_ESTABLISHED <= sk->state < TCP_CLOSE + * + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. + */ + struct tcp_ehash_bucket *__tcp_ehash; + + /* Ok, let's try this, I give up, we do need a local binding + * TCP hash as well as the others for fast bind/connect. + */ + struct tcp_bind_hashbucket *__tcp_bhash; + + int __tcp_bhash_size; + int __tcp_ehash_size; + + /* All sockets in TCP_LISTEN state will be in here. This is the only + * table where wildcard'd TCP sockets can exist. Hash function here + * is just local port number. + */ + struct sock *__tcp_listening_hash[TCP_LHTABLE_SIZE]; + + /* All the above members are written once at bootup and + * never written again _or_ are predominantly read-access. + * + * Now align to a new cache line as all the following members + * are often dirty. + */ + rwlock_t __tcp_lhash_lock ____cacheline_aligned; + atomic_t __tcp_lhash_users; + wait_queue_head_t __tcp_lhash_wait; + spinlock_t __tcp_portalloc_lock; +} tcp_hashinfo; + +#define tcp_ehash (tcp_hashinfo.__tcp_ehash) +#define tcp_bhash (tcp_hashinfo.__tcp_bhash) +#define tcp_ehash_size (tcp_hashinfo.__tcp_ehash_size) +#define tcp_bhash_size (tcp_hashinfo.__tcp_bhash_size) +#define tcp_listening_hash (tcp_hashinfo.__tcp_listening_hash) +#define tcp_lhash_lock (tcp_hashinfo.__tcp_lhash_lock) +#define tcp_lhash_users (tcp_hashinfo.__tcp_lhash_users) +#define tcp_lhash_wait (tcp_hashinfo.__tcp_lhash_wait) +#define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock) + +extern kmem_cache_t *tcp_bucket_cachep; +extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, + unsigned short snum); +extern void tcp_bucket_unlock(struct sock *sk); +extern int tcp_port_rover; +extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif); + +/* These are AF independent. */ +static __inline__ int tcp_bhashfn(__u16 lport) +{ + return (lport & (tcp_bhash_size - 1)); +} + +/* This is a TIME_WAIT bucket. It works around the memory consumption + * problems of sockets in such a state on heavily loaded servers, but + * without violating the protocol specification. + */ +struct tcp_tw_bucket { + /* These _must_ match the beginning of struct sock precisely. + * XXX Yes I know this is gross, but I'd have to edit every single + * XXX networking file if I created a "struct sock_header". -DaveM + */ + __u32 daddr; + __u32 rcv_saddr; + __u16 dport; + unsigned short num; + int bound_dev_if; + struct sock *next; + struct sock **pprev; + struct sock *bind_next; + struct sock **bind_pprev; + unsigned char state, + substate; /* "zapped" is replaced with "substate" */ + __u16 sport; + unsigned short family; + unsigned char reuse, + rcv_wscale; /* It is also TW bucket specific */ + atomic_t refcnt; + + /* And these are ours. */ + int hashent; + int timeout; + __u32 rcv_nxt; + __u32 snd_nxt; + __u32 rcv_wnd; + __u32 ts_recent; + long ts_recent_stamp; + unsigned long ttd; + struct tcp_bind_bucket *tb; + struct tcp_tw_bucket *next_death; + struct tcp_tw_bucket **pprev_death; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct in6_addr v6_daddr; + struct in6_addr v6_rcv_saddr; +#endif +}; + +extern kmem_cache_t *tcp_timewait_cachep; + +static inline void tcp_tw_put(struct tcp_tw_bucket *tw) +{ + if (atomic_dec_and_test(&tw->refcnt)) { +#ifdef INET_REFCNT_DEBUG + printk(KERN_DEBUG "tw_bucket %p released\n", tw); +#endif + kmem_cache_free(tcp_timewait_cachep, tw); + } +} + +extern atomic_t tcp_orphan_count; +extern int tcp_tw_count; +extern void tcp_time_wait(struct sock *sk, int state, int timeo); +extern void tcp_timewait_kill(struct tcp_tw_bucket *tw); +extern void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo); +extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw); + + +/* Socket demux engine toys. */ +#ifdef __BIG_ENDIAN +#define TCP_COMBINED_PORTS(__sport, __dport) \ + (((__u32)(__sport)<<16) | (__u32)(__dport)) +#else /* __LITTLE_ENDIAN */ +#define TCP_COMBINED_PORTS(__sport, __dport) \ + (((__u32)(__dport)<<16) | (__u32)(__sport)) +#endif + +#if (BITS_PER_LONG == 64) +#ifdef __BIG_ENDIAN +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ + __u64 __name = (((__u64)(__saddr))<<32)|((__u64)(__daddr)); +#else /* __LITTLE_ENDIAN */ +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ + __u64 __name = (((__u64)(__daddr))<<32)|((__u64)(__saddr)); +#endif /* __BIG_ENDIAN */ +#define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ + (((*((__u64 *)&((__sk)->daddr)))== (__cookie)) && \ + ((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) +#else /* 32-bit arch */ +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) +#define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ + (((__sk)->daddr == (__saddr)) && \ + ((__sk)->rcv_saddr == (__daddr)) && \ + ((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) +#endif /* 64-bit arch */ + +#define TCP_IPV6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \ + (((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + ((__sk)->family == AF_INET6) && \ + !ipv6_addr_cmp(&(__sk)->net_pinfo.af_inet6.daddr, (__saddr)) && \ + !ipv6_addr_cmp(&(__sk)->net_pinfo.af_inet6.rcv_saddr, (__daddr)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) + +/* These can have wildcards, don't try too hard. */ +static __inline__ int tcp_lhashfn(unsigned short num) +{ +#if 0 + return num & (TCP_LHTABLE_SIZE - 1); +#else + return 0; +#endif +} + +static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) +{ +#if 0 + return tcp_lhashfn(sk->num); +#else + return 0; +#endif +} + +#define MAX_TCP_HEADER (128 + MAX_HEADER) + +/* + * Never offer a window over 32767 without using window scaling. Some + * poor stacks do signed 16bit maths! + */ +#define MAX_TCP_WINDOW 32767U + +/* Minimal accepted MSS. It is (60+60+8) - (20+20). */ +#define TCP_MIN_MSS 88U + +/* Minimal RCV_MSS. */ +#define TCP_MIN_RCVMSS 536U + +/* After receiving this amount of duplicate ACKs fast retransmit starts. */ +#define TCP_FASTRETRANS_THRESH 3 + +/* Maximal reordering. */ +#define TCP_MAX_REORDERING 127 + +/* Maximal number of ACKs sent quickly to accelerate slow-start. */ +#define TCP_MAX_QUICKACKS 16U + +/* urg_data states */ +#define TCP_URG_VALID 0x0100 +#define TCP_URG_NOTYET 0x0200 +#define TCP_URG_READ 0x0400 + +#define TCP_RETR1 3 /* + * This is how many retries it does before it + * tries to figure out if the gateway is + * down. Minimal RFC value is 3; it corresponds + * to ~3sec-8min depending on RTO. + */ + +#define TCP_RETR2 15 /* + * This should take at least + * 90 minutes to time out. + * RFC1122 says that the limit is 100 sec. + * 15 is ~13-30min depending on RTO. + */ + +#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a + * connection: ~180sec is RFC minumum */ + +#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a + * connection: ~180sec is RFC minumum */ + + +#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned + * socket. 7 is ~50sec-16min. + */ + + +#define TCP_TIMEWAIT_LEN (60*1000) +//#define TCP_TIMEWAIT_LEN (60*HZ) +/* how long to wait to destroy TIME-WAIT + * state, about 60 seconds */ +#define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN + /* BSD style FIN_WAIT2 deadlock breaker. + * It used to be 3min, new value is 60sec, + * to combine FIN-WAIT-2 timeout with + * TIME-WAIT timer. + */ + +#define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */ +#if HZ >= 100 +#define TCP_DELACK_MIN ((unsigned)(HZ/25)) /* minimal time to delay before sending an ACK */ +#define TCP_ATO_MIN ((unsigned)(HZ/25)) +#else +#define TCP_DELACK_MIN 4U +#define TCP_ATO_MIN 4U +#endif +#define TCP_RTO_MAX ((unsigned)(120*HZ)) +#define TCP_RTO_MIN ((unsigned)(HZ/5)) +#define TCP_TIMEOUT_INIT ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value */ + +#define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes + * for local resources. + */ + +#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ +#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ +#define TCP_KEEPALIVE_INTVL (75*HZ) + +#define MAX_TCP_KEEPIDLE 32767 +#define MAX_TCP_KEEPINTVL 32767 +#define MAX_TCP_KEEPCNT 127 +#define MAX_TCP_SYNCNT 127 + +/* TIME_WAIT reaping mechanism. */ +#define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ +#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) + +#define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ +#define TCP_SYNQ_HSIZE 512 /* Size of SYNACK hash table */ + +#define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) +#define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated + * after this time. It should be equal + * (or greater than) TCP_TIMEWAIT_LEN + * to provide reliability equal to one + * provided by timewait state. + */ +#define TCP_PAWS_WINDOW 1 /* Replay window for per-host + * timestamps. It must be less than + * minimal timewait lifetime. + */ + +#define TCP_TW_RECYCLE_SLOTS_LOG 5 +#define TCP_TW_RECYCLE_SLOTS (1< 4sec, it is "slow" path, no recycling is required, + so that we select tick to get range about 4 seconds. + */ + +#if 0 +#if HZ <= 16 || HZ > 4096 +# error Unsupported: HZ <= 16 or HZ > 4096 +#elif HZ <= 32 +# define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 64 +# define TCP_TW_RECYCLE_TICK (6+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 128 +# define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 256 +# define TCP_TW_RECYCLE_TICK (8+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 512 +# define TCP_TW_RECYCLE_TICK (9+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 1024 +# define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 2048 +# define TCP_TW_RECYCLE_TICK (11+2-TCP_TW_RECYCLE_SLOTS_LOG) +#else +# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) +#endif +#else +#define TCP_TW_RECYCLE_TICK (0) +#endif + +/* + * TCP option + */ + +#define TCPOPT_NOP 1 /* Padding */ +#define TCPOPT_EOL 0 /* End of options */ +#define TCPOPT_MSS 2 /* Segment size negotiating */ +#define TCPOPT_WINDOW 3 /* Window scaling */ +#define TCPOPT_SACK_PERM 4 /* SACK Permitted */ +#define TCPOPT_SACK 5 /* SACK Block */ +#define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ + +/* + * TCP option lengths + */ + +#define TCPOLEN_MSS 4 +#define TCPOLEN_WINDOW 3 +#define TCPOLEN_SACK_PERM 2 +#define TCPOLEN_TIMESTAMP 10 + +/* But this is what stacks really send out. */ +#define TCPOLEN_TSTAMP_ALIGNED 12 +#define TCPOLEN_WSCALE_ALIGNED 4 +#define TCPOLEN_SACKPERM_ALIGNED 4 +#define TCPOLEN_SACK_BASE 2 +#define TCPOLEN_SACK_BASE_ALIGNED 4 +#define TCPOLEN_SACK_PERBLOCK 8 + +#define TCP_TIME_RETRANS 1 /* Retransmit timer */ +#define TCP_TIME_DACK 2 /* Delayed ack timer */ +#define TCP_TIME_PROBE0 3 /* Zero window probe timer */ +#define TCP_TIME_KEEPOPEN 4 /* Keepalive timer */ + +#if 0 +/* sysctl variables for tcp */ +extern int sysctl_max_syn_backlog; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; +extern int sysctl_tcp_sack; +extern int sysctl_tcp_fin_timeout; +extern int sysctl_tcp_tw_recycle; +extern int sysctl_tcp_keepalive_time; +extern int sysctl_tcp_keepalive_probes; +extern int sysctl_tcp_keepalive_intvl; +extern int sysctl_tcp_syn_retries; +extern int sysctl_tcp_synack_retries; +extern int sysctl_tcp_retries1; +extern int sysctl_tcp_retries2; +extern int sysctl_tcp_orphan_retries; +extern int sysctl_tcp_syncookies; +extern int sysctl_tcp_retrans_collapse; +extern int sysctl_tcp_stdurg; +extern int sysctl_tcp_rfc1337; +extern int sysctl_tcp_abort_on_overflow; +extern int sysctl_tcp_max_orphans; +extern int sysctl_tcp_max_tw_buckets; +extern int sysctl_tcp_fack; +extern int sysctl_tcp_reordering; +extern int sysctl_tcp_ecn; +extern int sysctl_tcp_dsack; +extern int sysctl_tcp_mem[3]; +extern int sysctl_tcp_wmem[3]; +extern int sysctl_tcp_rmem[3]; +extern int sysctl_tcp_app_win; +extern int sysctl_tcp_adv_win_scale; +extern int sysctl_tcp_tw_reuse; +#endif + +extern atomic_t tcp_memory_allocated; +extern atomic_t tcp_sockets_allocated; +extern int tcp_memory_pressure; + +struct open_request; + +struct or_calltable { + int family; + int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*); + void (*send_ack) (struct sk_buff *skb, struct open_request *req); + void (*destructor) (struct open_request *req); + void (*send_reset) (struct sk_buff *skb); +}; + +struct tcp_v4_open_req { + __u32 loc_addr; + __u32 rmt_addr; + struct ip_options *opt; +}; + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +struct tcp_v6_open_req { + struct in6_addr loc_addr; + struct in6_addr rmt_addr; + struct sk_buff *pktopts; + int iif; +}; +#endif + +/* this structure is too big */ +struct open_request { + struct open_request *dl_next; /* Must be first member! */ + __u32 rcv_isn; + __u32 snt_isn; + __u16 rmt_port; + __u16 mss; + __u8 retrans; + __u8 __pad; + __u16 snd_wscale : 4, + rcv_wscale : 4, + tstamp_ok : 1, + sack_ok : 1, + wscale_ok : 1, + ecn_ok : 1, + acked : 1; + /* The following two fields can be easily recomputed I think -AK */ + __u32 window_clamp; /* window clamp at creation time */ + __u32 rcv_wnd; /* rcv_wnd offered first time */ + __u32 ts_recent; + unsigned long expires; + struct or_calltable *class; + struct sock *sk; + union { + struct tcp_v4_open_req v4_req; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct tcp_v6_open_req v6_req; +#endif + } af; +}; + +/* SLAB cache for open requests. */ +extern kmem_cache_t *tcp_openreq_cachep; + +#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) +#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req) + +static inline void tcp_openreq_free(struct open_request *req) +{ + req->class->destructor(req); + tcp_openreq_fastfree(req); +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#define TCP_INET_FAMILY(fam) ((fam) == AF_INET) +#else +#define TCP_INET_FAMILY(fam) 1 +#endif + +/* + * Pointers to address related TCP functions + * (i.e. things that depend on the address family) + * + * BUGGG_FUTURE: all the idea behind this struct is wrong. + * It mixes socket frontend with transport function. + * With port sharing between IPv6/v4 it gives the only advantage, + * only poor IPv6 needs to permanently recheck, that it + * is still IPv6 8)8) It must be cleaned up as soon as possible. + * --ANK (980802) + */ + +struct tcp_func { + int (*queue_xmit) (struct sk_buff *skb); + + void (*send_check) (struct sock *sk, + struct tcphdr *th, + int len, + struct sk_buff *skb); + + int (*rebuild_header) (struct sock *sk); + + int (*conn_request) (struct sock *sk, + struct sk_buff *skb); + + struct sock * (*syn_recv_sock) (struct sock *sk, + struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst); + + int (*remember_stamp) (struct sock *sk); + + __u16 net_header_len; + + int (*setsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int optlen); + + int (*getsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int *optlen); + + + void (*addr2sockaddr) (struct sock *sk, + struct sockaddr *); + + int sockaddr_len; +}; + +/* + * The next routines deal with comparing 32 bit unsigned ints + * and worry about wraparound (automatic with unsigned arithmetic). + */ + +extern __inline int before(__u32 seq1, __u32 seq2) +{ + return (__s32)(seq1-seq2) < 0; +} + +extern __inline int after(__u32 seq1, __u32 seq2) +{ + return (__s32)(seq2-seq1) < 0; +} + + +/* is s2<=s1<=s3 ? */ +extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) +{ + return seq3 - seq2 >= seq1 - seq2; +} + + +extern struct proto tcp_prot; + +#ifdef ROS_STATISTICS +extern struct tcp_mib tcp_statistics[NR_CPUS*2]; + +#define TCP_INC_STATS(field) SNMP_INC_STATS(tcp_statistics, field) +#define TCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(tcp_statistics, field) +#define TCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(tcp_statistics, field) +#endif + +extern void tcp_put_port(struct sock *sk); +extern void __tcp_put_port(struct sock *sk); +extern void tcp_inherit_port(struct sock *sk, struct sock *child); + +extern void tcp_v4_err(struct sk_buff *skb, u32); + +extern void tcp_shutdown (struct sock *sk, int how); + +extern int tcp_v4_rcv(struct sk_buff *skb); + +extern int tcp_v4_remember_stamp(struct sock *sk); + +extern int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw); + +extern int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size); +extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); + +extern int tcp_ioctl(struct sock *sk, + int cmd, + unsigned long arg); + +extern int tcp_rcv_state_process(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +extern int tcp_rcv_established(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +enum tcp_ack_state_t +{ + TCP_ACK_SCHED = 1, + TCP_ACK_TIMER = 2, + TCP_ACK_PUSHED= 4 +}; + +static inline void tcp_schedule_ack(struct tcp_opt *tp) +{ + tp->ack.pending |= TCP_ACK_SCHED; +} + +static inline int tcp_ack_scheduled(struct tcp_opt *tp) +{ + return tp->ack.pending&TCP_ACK_SCHED; +} + +static __inline__ void tcp_dec_quickack_mode(struct tcp_opt *tp) +{ + if (tp->ack.quick && --tp->ack.quick == 0) { + /* Leaving quickack mode we deflate ATO. */ + tp->ack.ato = TCP_ATO_MIN; + } +} + +extern void tcp_enter_quickack_mode(struct tcp_opt *tp); + +static __inline__ void tcp_delack_init(struct tcp_opt *tp) +{ + memset(&tp->ack, 0, sizeof(tp->ack)); +} + +static inline void tcp_clear_options(struct tcp_opt *tp) +{ + tp->tstamp_ok = tp->sack_ok = tp->wscale_ok = tp->snd_wscale = 0; +} + +enum tcp_tw_status +{ + TCP_TW_SUCCESS = 0, + TCP_TW_RST = 1, + TCP_TW_ACK = 2, + TCP_TW_SYN = 3 +}; + + +extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, + struct open_request *req, + struct open_request **prev); +extern int tcp_child_process(struct sock *parent, + struct sock *child, + struct sk_buff *skb); +extern void tcp_enter_loss(struct sock *sk, int how); +extern void tcp_clear_retrans(struct tcp_opt *tp); +extern void tcp_update_metrics(struct sock *sk); + +extern void tcp_close(struct sock *sk, + long timeout); +extern struct sock * tcp_accept(struct sock *sk, int flags, int *err); +extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); +extern void tcp_write_space(struct sock *sk); + +extern int tcp_getsockopt(struct sock *sk, int level, + int optname, char *optval, + int *optlen); +extern int tcp_setsockopt(struct sock *sk, int level, + int optname, char *optval, + int optlen); +extern void tcp_set_keepalive(struct sock *sk, int val); +extern int tcp_recvmsg(struct sock *sk, + struct msghdr *msg, + int len, int nonblock, + int flags, int *addr_len); + +extern int tcp_listen_start(struct sock *sk); + +extern void tcp_parse_options(struct sk_buff *skb, + struct tcp_opt *tp, + int estab); + +/* + * TCP v4 functions exported for the inet6 API + */ + +extern int tcp_v4_rebuild_header(struct sock *sk); + +extern int tcp_v4_build_header(struct sock *sk, + struct sk_buff *skb); + +extern void tcp_v4_send_check(struct sock *sk, + struct tcphdr *th, int len, + struct sk_buff *skb); + +extern int tcp_v4_conn_request(struct sock *sk, + struct sk_buff *skb); + +extern struct sock * tcp_create_openreq_child(struct sock *sk, + struct open_request *req, + struct sk_buff *skb); + +extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, + struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst); + +extern int tcp_v4_do_rcv(struct sock *sk, + struct sk_buff *skb); + +extern int tcp_v4_connect(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + +extern int tcp_connect(struct sock *sk); + +extern struct sk_buff * tcp_make_synack(struct sock *sk, + struct dst_entry *dst, + struct open_request *req); + +extern int tcp_disconnect(struct sock *sk, int flags); + +extern void tcp_unhash(struct sock *sk); + +extern int tcp_v4_hash_connecting(struct sock *sk); + + +/* From syncookies.c */ +extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, + struct ip_options *opt); +extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, + __u16 *mss); + +/* tcp_output.c */ + +extern int tcp_write_xmit(struct sock *, int nonagle); +extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); +extern void tcp_xmit_retransmit_queue(struct sock *); +extern void tcp_simple_retransmit(struct sock *); + +extern void tcp_send_probe0(struct sock *); +extern void tcp_send_partial(struct sock *); +extern int tcp_write_wakeup(struct sock *); +extern void tcp_send_fin(struct sock *sk); +extern void tcp_send_active_reset(struct sock *sk, int priority); +extern int tcp_send_synack(struct sock *); +extern int tcp_transmit_skb(struct sock *, struct sk_buff *); +extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue, unsigned mss_now); +extern void tcp_push_one(struct sock *, unsigned mss_now); +extern void tcp_send_ack(struct sock *sk); +extern void tcp_send_delayed_ack(struct sock *sk); + +/* tcp_timer.c */ +extern void tcp_init_xmit_timers(struct sock *); +extern void tcp_clear_xmit_timers(struct sock *); + +extern void tcp_delete_keepalive_timer (struct sock *); +extern void tcp_reset_keepalive_timer (struct sock *, unsigned long); +extern int tcp_sync_mss(struct sock *sk, u32 pmtu); + +extern const char timer_bug_msg[]; + +/* Read 'sendfile()'-style from a TCP socket */ +typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, + unsigned int, size_t); +extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor); + +static inline void tcp_clear_xmit_timer(struct sock *sk, int what) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + switch (what) { + case TCP_TIME_RETRANS: + case TCP_TIME_PROBE0: + tp->pending = 0; + +#ifdef TCP_CLEAR_TIMERS + if (timer_pending(&tp->retransmit_timer) && + del_timer(&tp->retransmit_timer)) + __sock_put(sk); +#endif + break; + case TCP_TIME_DACK: + tp->ack.blocked = 0; + tp->ack.pending = 0; + +#ifdef TCP_CLEAR_TIMERS + if (timer_pending(&tp->delack_timer) && + del_timer(&tp->delack_timer)) + __sock_put(sk); +#endif + break; + default: + printk(timer_bug_msg); + return; + }; +#endif +} + +/* + * Reset the retransmission timer + */ +static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (when > TCP_RTO_MAX) { +#ifdef TCP_DEBUG + printk(KERN_DEBUG "reset_xmit_timer sk=%p %d when=0x%lx, caller=%p\n", sk, what, when, current_text_addr()); +#endif + when = TCP_RTO_MAX; + } + + switch (what) { + case TCP_TIME_RETRANS: + case TCP_TIME_PROBE0: + tp->pending = what; + tp->timeout = jiffies+when; + if (!mod_timer(&tp->retransmit_timer, tp->timeout)) + sock_hold(sk); + break; + + case TCP_TIME_DACK: + tp->ack.pending |= TCP_ACK_TIMER; + tp->ack.timeout = jiffies+when; + if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) + sock_hold(sk); + break; + + default: + printk(KERN_DEBUG "bug: unknown timer value\n"); + }; +#endif +} + +/* Compute the current effective MSS, taking SACKs and IP options, + * and even PMTU discovery events into account. + */ + +static __inline__ unsigned int tcp_current_mss(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct dst_entry *dst = __sk_dst_get(sk); + int mss_now = tp->mss_cache; + + if (dst && dst->pmtu != tp->pmtu_cookie) + mss_now = tcp_sync_mss(sk, dst->pmtu); + + if (tp->eff_sacks) + mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + + (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK)); + return mss_now; +#else + return 0; +#endif +} + +/* Initialize RCV_MSS value. + * RCV_MSS is an our guess about MSS used by the peer. + * We haven't any direct information about the MSS. + * It's better to underestimate the RCV_MSS rather than overestimate. + * Overestimations make us ACKing less frequently than needed. + * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss(). + */ + +static inline void tcp_initialize_rcv_mss(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + unsigned int hint = min(tp->advmss, tp->mss_cache); + + hint = min(hint, tp->rcv_wnd/2); + hint = min(hint, TCP_MIN_RCVMSS); + hint = max(hint, TCP_MIN_MSS); + + tp->ack.rcv_mss = hint; +#endif +} + +static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd) +{ +#if 0 + tp->pred_flags = htonl((tp->tcp_header_len << 26) | + ntohl(TCP_FLAG_ACK) | + snd_wnd); +#endif +} + +static __inline__ void tcp_fast_path_on(struct tcp_opt *tp) +{ +#if 0 + __tcp_fast_path_on(tp, tp->snd_wnd>>tp->snd_wscale); +#endif +} + +static inline void tcp_fast_path_check(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (skb_queue_len(&tp->out_of_order_queue) == 0 && + tp->rcv_wnd && + atomic_read(&sk->rmem_alloc) < sk->rcvbuf && + !tp->urg_data) + tcp_fast_path_on(tp); +#endif +} + +/* Compute the actual receive window we are currently advertising. + * Rcv_nxt can be after the window if our peer push more data + * than the offered window. + */ +static __inline__ u32 tcp_receive_window(struct tcp_opt *tp) +{ +#if 0 + s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt; + + if (win < 0) + win = 0; + return (u32) win; +#else + return 0; +#endif +} + +/* Choose a new window, without checks for shrinking, and without + * scaling applied to the result. The caller does these things + * if necessary. This is a "raw" window selection. + */ +extern u32 __tcp_select_window(struct sock *sk); + +/* TCP timestamps are only 32-bits, this causes a slight + * complication on 64-bit systems since we store a snapshot + * of jiffies in the buffer control blocks below. We decidely + * only use of the low 32-bits of jiffies and hide the ugly + * casts with the following macro. + */ +#define tcp_time_stamp ((__u32)(jiffies)) + +/* This is what the send packet queueing engine uses to pass + * TCP per-packet control information to the transmission + * code. We also store the host-order sequence numbers in + * here too. This is 36 bytes on 32-bit architectures, + * 40 bytes on 64-bit machines, if this grows please adjust + * skbuff.h:skbuff->cb[xxx] size appropriately. + */ +struct tcp_skb_cb { + union { +#if 0 + struct inet_skb_parm h4; +#endif +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct inet6_skb_parm h6; +#endif + } header; /* For incoming frames */ + __u32 seq; /* Starting sequence number */ + __u32 end_seq; /* SEQ + FIN + SYN + datalen */ + __u32 when; /* used to compute rtt's */ + __u8 flags; /* TCP header flags. */ + + /* NOTE: These must match up to the flags byte in a + * real TCP header. + */ +#define TCPCB_FLAG_FIN 0x01 +#define TCPCB_FLAG_SYN 0x02 +#define TCPCB_FLAG_RST 0x04 +#define TCPCB_FLAG_PSH 0x08 +#define TCPCB_FLAG_ACK 0x10 +#define TCPCB_FLAG_URG 0x20 +#define TCPCB_FLAG_ECE 0x40 +#define TCPCB_FLAG_CWR 0x80 + + __u8 sacked; /* State flags for SACK/FACK. */ +#define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ +#define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ +#define TCPCB_LOST 0x04 /* SKB is lost */ +#define TCPCB_TAGBITS 0x07 /* All tag bits */ + +#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */ +#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS) + +#define TCPCB_URG 0x20 /* Urgent pointer advenced here */ + +#define TCPCB_AT_TAIL (TCPCB_URG) + + __u16 urg_ptr; /* Valid w/URG flags is set. */ + __u32 ack_seq; /* Sequence number ACK'd */ +}; + +#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) + +#define for_retrans_queue(skb, sk, tp) \ + for (skb = (sk)->write_queue.next; \ + (skb != (tp)->send_head) && \ + (skb != (struct sk_buff *)&(sk)->write_queue); \ + skb=skb->next) + + +//#include + + +/* + * Compute minimal free write space needed to queue new packets. + */ +static inline int tcp_min_write_space(struct sock *sk) +{ +#if 0 + return sk->wmem_queued/2; +#else +return 0; +#endif +} + +static inline int tcp_wspace(struct sock *sk) +{ +#if 0 + return sk->sndbuf - sk->wmem_queued; +#else +return 0; +#endif +} + + +/* This determines how many packets are "in the network" to the best + * of our knowledge. In many cases it is conservative, but where + * detailed information is available from the receiver (via SACK + * blocks etc.) we can make more aggressive calculations. + * + * Use this for decisions involving congestion control, use just + * tp->packets_out to determine if the send queue is empty or not. + * + * Read this equation as: + * + * "Packets sent once on transmission queue" MINUS + * "Packets left network, but not honestly ACKed yet" PLUS + * "Packets fast retransmitted" + */ +static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp) +{ +#if 0 + return tp->packets_out - tp->left_out + tp->retrans_out; +#else + return 0; +#endif +} + +/* Recalculate snd_ssthresh, we want to set it to: + * + * one half the current congestion window, but no + * less than two segments + */ +static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) +{ +#if 0 + return max(tp->snd_cwnd >> 1U, 2U); +#else + return 0; +#endif +} + +/* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. + * The exception is rate halving phase, when cwnd is decreasing towards + * ssthresh. + */ +static inline __u32 tcp_current_ssthresh(struct tcp_opt *tp) +{ +#if 0 + if ((1<ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery)) + return tp->snd_ssthresh; + else + return max(tp->snd_ssthresh, + ((tp->snd_cwnd >> 1) + + (tp->snd_cwnd >> 2))); +#else + return 0; +#endif +} + +static inline void tcp_sync_left_out(struct tcp_opt *tp) +{ +#if 0 + if (tp->sack_ok && tp->sacked_out >= tp->packets_out - tp->lost_out) + tp->sacked_out = tp->packets_out - tp->lost_out; + tp->left_out = tp->sacked_out + tp->lost_out; +#endif +} + +extern void tcp_cwnd_application_limited(struct sock *sk); + +/* Congestion window validation. (RFC2861) */ + +static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (tp->packets_out >= tp->snd_cwnd) { + /* Network is feed fully. */ + tp->snd_cwnd_used = 0; + tp->snd_cwnd_stamp = tcp_time_stamp; + } else { + /* Network starves. */ + if (tp->packets_out > tp->snd_cwnd_used) + tp->snd_cwnd_used = tp->packets_out; + + if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) + tcp_cwnd_application_limited(sk); + } +#endif +} + +/* Set slow start threshould and cwnd not falling to slow start */ +static inline void __tcp_enter_cwr(struct tcp_opt *tp) +{ +#if 0 + tp->undo_marker = 0; + tp->snd_ssthresh = tcp_recalc_ssthresh(tp); + tp->snd_cwnd = min(tp->snd_cwnd, + tcp_packets_in_flight(tp) + 1U); + tp->snd_cwnd_cnt = 0; + tp->high_seq = tp->snd_nxt; + tp->snd_cwnd_stamp = tcp_time_stamp; + TCP_ECN_queue_cwr(tp); +#endif +} + +static inline void tcp_enter_cwr(struct tcp_opt *tp) +{ +#if 0 + tp->prior_ssthresh = 0; + if (tp->ca_state < TCP_CA_CWR) { + __tcp_enter_cwr(tp); + tp->ca_state = TCP_CA_CWR; + } +#endif +} + +extern __u32 tcp_init_cwnd(struct tcp_opt *tp); + +/* Slow start with delack produces 3 packets of burst, so that + * it is safe "de facto". + */ +static __inline__ __u32 tcp_max_burst(struct tcp_opt *tp) +{ + return 3; +} + +static __inline__ int tcp_minshall_check(struct tcp_opt *tp) +{ +#if 0 + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +#else + return 0; +#endif +} + +static __inline__ void tcp_minshall_update(struct tcp_opt *tp, int mss, struct sk_buff *skb) +{ +#if 0 + if (skb->len < mss) + tp->snd_sml = TCP_SKB_CB(skb)->end_seq; +#endif +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + 1. It is full sized. + 2. Or it contains FIN. + 3. Or TCP_NODELAY was set. + 4. Or TCP_CORK is not set, and all sent packets are ACKed. + With Minshall's modification: all sent small packets are ACKed. + */ + +static __inline__ int +tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int nonagle) +{ +#if 0 + return (skb->len < mss_now && + !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && + (nonagle == 2 || + (!nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +#else + return 0; +#endif +} + +/* This checks if the data bearing packet SKB (usually tp->send_head) + * should be put on the wire right now. + */ +static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb, + unsigned cur_mss, int nonagle) +{ +#if 0 + /* RFC 1122 - section 4.2.3.4 + * + * We must queue if + * + * a) The right edge of this frame exceeds the window + * b) There are packets in flight and we have a small segment + * [SWS avoidance and Nagle algorithm] + * (part of SWS is done on packetization) + * Minshall version sounds: there are no _small_ + * segments in flight. (tcp_nagle_check) + * c) We have too many packets 'in flight' + * + * Don't use the nagle rule for urgent data (or + * for the final FIN -DaveM). + * + * Also, Nagle rule does not apply to frames, which + * sit in the middle of queue (they have no chances + * to get new data) and if room at tail of skb is + * not enough to save something seriously (<32 for now). + */ + + /* Don't be strict about the congestion window for the + * final FIN frame. -DaveM + */ + return ((nonagle==1 || tp->urg_mode + || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && + ((tcp_packets_in_flight(tp) < tp->snd_cwnd) || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && + !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); +#else + return 0; +#endif +} + +static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (!tp->packets_out && !tp->pending) + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); +#endif +} + +static __inline__ int tcp_skb_is_last(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + return (skb->next == (struct sk_buff*)&sk->write_queue); +#else + return 0; +#endif +} + +/* Push out any pending frames which were held back due to + * TCP_CORK or attempt at coalescing tiny packets. + * The socket must be locked by the caller. + */ +static __inline__ void __tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp, + unsigned cur_mss, + int nonagle) +{ +#if 0 + struct sk_buff *skb = tp->send_head; + + if (skb) { + if (!tcp_skb_is_last(sk, skb)) + nonagle = 1; + if (!tcp_snd_test(tp, skb, cur_mss, nonagle) || + tcp_write_xmit(sk, nonagle)) + tcp_check_probe_timer(sk, tp); + } + tcp_cwnd_validate(sk, tp); +#endif +} + +static __inline__ void tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp) +{ +#if 0 + __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk), tp->nonagle); +#endif +} + +static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + struct sk_buff *skb = tp->send_head; + + return (skb && + tcp_snd_test(tp, skb, tcp_current_mss(sk), + tcp_skb_is_last(sk, skb) ? 1 : tp->nonagle)); +#else + return 0; +#endif +} + +static __inline__ void tcp_init_wl(struct tcp_opt *tp, u32 ack, u32 seq) +{ +#if 0 + tp->snd_wl1 = seq; +#endif +} + +static __inline__ void tcp_update_wl(struct tcp_opt *tp, u32 ack, u32 seq) +{ +#if 0 + tp->snd_wl1 = seq; +#endif +} + +extern void tcp_destroy_sock(struct sock *sk); + + +/* + * Calculate(/check) TCP checksum + */ +static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, + unsigned long saddr, unsigned long daddr, + unsigned long base) +{ +#if 0 + return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); +#else + return 0; +#endif +} + +static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) +{ +#if 0 + return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); +#else + return 0; +#endif +} + +static __inline__ int tcp_checksum_complete(struct sk_buff *skb) +{ +#if 0 + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __tcp_checksum_complete(skb); +#else + return 0; +#endif +} + +/* Prequeue for VJ style copy to user, combined with checksumming. */ + +static __inline__ void tcp_prequeue_init(struct tcp_opt *tp) +{ +#if 0 + tp->ucopy.task = NULL; + tp->ucopy.len = 0; + tp->ucopy.memory = 0; + skb_queue_head_init(&tp->ucopy.prequeue); +#endif +} + +/* Packet is added to VJ-style prequeue for processing in process + * context, if a reader task is waiting. Apparently, this exciting + * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) + * failed somewhere. Latency? Burstiness? Well, at least now we will + * see, why it failed. 8)8) --ANK + * + * NOTE: is this not too big to inline? + */ +static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (tp->ucopy.task) { + __skb_queue_tail(&tp->ucopy.prequeue, skb); + tp->ucopy.memory += skb->truesize; + if (tp->ucopy.memory > sk->rcvbuf) { + struct sk_buff *skb1; + + if (sk->lock.users) + out_of_line_bug(); + + while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { + sk->backlog_rcv(sk, skb1); + NET_INC_STATS_BH(TCPPrequeueDropped); + } + + tp->ucopy.memory = 0; + } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { + wake_up_interruptible(sk->sleep); + if (!tcp_ack_scheduled(tp)) + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, (3*TCP_RTO_MIN)/4); + } + return 1; + } + return 0; +#else + return 0; +#endif +} + + +#undef STATE_TRACE + +#ifdef STATE_TRACE +static char *statename[]={ + "Unused","Established","Syn Sent","Syn Recv", + "Fin Wait 1","Fin Wait 2","Time Wait", "Close", + "Close Wait","Last ACK","Listen","Closing" +}; +#endif + +static __inline__ void tcp_set_state(struct sock *sk, int state) +{ +#if 0 + int oldstate = sk->state; + + switch (state) { + case TCP_ESTABLISHED: + if (oldstate != TCP_ESTABLISHED) + TCP_INC_STATS(TcpCurrEstab); + break; + + case TCP_CLOSE: + sk->prot->unhash(sk); + if (sk->prev && !(sk->userlocks&SOCK_BINDPORT_LOCK)) + tcp_put_port(sk); + /* fall through */ + default: + if (oldstate==TCP_ESTABLISHED) + tcp_statistics[smp_processor_id()*2+!in_softirq()].TcpCurrEstab--; + } + + /* Change state AFTER socket is unhashed to avoid closed + * socket sitting in hash tables. + */ + sk->state = state; + +#ifdef STATE_TRACE + SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); +#endif +#endif +} + +static __inline__ void tcp_done(struct sock *sk) +{ +#if 0 + tcp_set_state(sk, TCP_CLOSE); + tcp_clear_xmit_timers(sk); + + sk->shutdown = SHUTDOWN_MASK; + + if (!sk->dead) + sk->state_change(sk); + else + tcp_destroy_sock(sk); +#endif +} + +static __inline__ void tcp_sack_reset(struct tcp_opt *tp) +{ +#if 0 + tp->dsack = 0; + tp->eff_sacks = 0; + tp->num_sacks = 0; +#endif +} + +static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_opt *tp, __u32 tstamp) +{ +#if 0 + if (tp->tstamp_ok) { + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP); + *ptr++ = htonl(tstamp); + *ptr++ = htonl(tp->ts_recent); + } + if (tp->eff_sacks) { + struct tcp_sack_block *sp = tp->dsack ? tp->duplicate_sack : tp->selective_acks; + int this_sack; + + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_SACK << 8) | + (TCPOLEN_SACK_BASE + + (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK))); + for(this_sack = 0; this_sack < tp->eff_sacks; this_sack++) { + *ptr++ = htonl(sp[this_sack].start_seq); + *ptr++ = htonl(sp[this_sack].end_seq); + } + if (tp->dsack) { + tp->dsack = 0; + tp->eff_sacks--; + } + } +#endif +} + +/* Construct a tcp options header for a SYN or SYN_ACK packet. + * If this is every changed make sure to change the definition of + * MAX_SYN_SIZE to match the new maximum number of options that you + * can generate. + */ +static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, + int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent) +{ +#if 0 + /* We always get an MSS option. + * The option bytes which will be seen in normal data + * packets should timestamps be used, must be in the MSS + * advertised. But we subtract them from tp->mss_cache so + * that calculations in tcp_sendmsg are simpler etc. + * So account for this fact here if necessary. If we + * don't do this correctly, as a receiver we won't + * recognize data packets as being full sized when we + * should, and thus we won't abide by the delayed ACK + * rules correctly. + * SACKs don't matter, we never delay an ACK when we + * have any of those going out. + */ + *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); + if (ts) { + if(sack) + *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + else + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(tstamp); /* TSVAL */ + *ptr++ = htonl(ts_recent); /* TSECR */ + } else if(sack) + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); + if (offer_wscale) + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); +#endif +} + +/* Determine a window scaling and initial window to offer. + * Based on the assumption that the given amount of space + * will be offered. Store the results in the tp structure. + * NOTE: for smooth operation initial space offering should + * be a multiple of mss if possible. We assume here that mss >= 1. + * This MUST be enforced by all callers. + */ +static inline void tcp_select_initial_window(int __space, __u32 mss, + __u32 *rcv_wnd, + __u32 *window_clamp, + int wscale_ok, + __u8 *rcv_wscale) +{ +#if 0 + unsigned int space = (__space < 0 ? 0 : __space); + + /* If no clamp set the clamp to the max possible scaled window */ + if (*window_clamp == 0) + (*window_clamp) = (65535 << 14); + space = min(*window_clamp, space); + + /* Quantize space offering to a multiple of mss if possible. */ + if (space > mss) + space = (space / mss) * mss; + + /* NOTE: offering an initial window larger than 32767 + * will break some buggy TCP stacks. We try to be nice. + * If we are not window scaling, then this truncates + * our initial window offering to 32k. There should also + * be a sysctl option to stop being nice. + */ + (*rcv_wnd) = min(space, MAX_TCP_WINDOW); + (*rcv_wscale) = 0; + if (wscale_ok) { + /* See RFC1323 for an explanation of the limit to 14 */ + while (space > 65535 && (*rcv_wscale) < 14) { + space >>= 1; + (*rcv_wscale)++; + } + if (*rcv_wscale && sysctl_tcp_app_win && space>=mss && + space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2) + (*rcv_wscale)--; + } + + /* Set initial window to value enough for senders, + * following RFC1414. Senders, not following this RFC, + * will be satisfied with 2. + */ + if (mss > (1<<*rcv_wscale)) { + int init_cwnd = 4; + if (mss > 1460*3) + init_cwnd = 2; + else if (mss > 1460) + init_cwnd = 3; + if (*rcv_wnd > init_cwnd*mss) + *rcv_wnd = init_cwnd*mss; + } + /* Set the clamp no higher than max representable value */ + (*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp); +#endif +} + +static inline int tcp_win_from_space(int space) +{ +#if 0 + return sysctl_tcp_adv_win_scale<=0 ? + (space>>(-sysctl_tcp_adv_win_scale)) : + space - (space>>sysctl_tcp_adv_win_scale); +#else + return 0; +#endif +} + +/* Note: caller must be prepared to deal with negative returns */ +static inline int tcp_space(struct sock *sk) +{ +#if 0 + return tcp_win_from_space(sk->rcvbuf - atomic_read(&sk->rmem_alloc)); +#else + return 0; +#endif +} + +static inline int tcp_full_space( struct sock *sk) +{ +#if 0 + return tcp_win_from_space(sk->rcvbuf); +#else + return 0; +#endif +} + +static inline void tcp_acceptq_removed(struct sock *sk) +{ +#if 0 + sk->ack_backlog--; +#endif +} + +static inline void tcp_acceptq_added(struct sock *sk) +{ +#if 0 + sk->ack_backlog++; +#endif +} + +static inline int tcp_acceptq_is_full(struct sock *sk) +{ +#if 0 + return sk->ack_backlog > sk->max_ack_backlog; +#else + return 0; +#endif +} + +static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req, + struct sock *child) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + req->sk = child; + tcp_acceptq_added(sk); + + if (!tp->accept_queue_tail) { + tp->accept_queue = req; + } else { + tp->accept_queue_tail->dl_next = req; + } + tp->accept_queue_tail = req; + req->dl_next = NULL; +#endif +} + +struct tcp_listen_opt +{ + u8 max_qlen_log; /* log_2 of maximal queued SYNs */ + int qlen; + int qlen_young; + int clock_hand; + struct open_request *syn_table[TCP_SYNQ_HSIZE]; +}; + +static inline void +tcp_synq_removed(struct sock *sk, struct open_request *req) +{ +#if 0 + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (--lopt->qlen == 0) + tcp_delete_keepalive_timer(sk); + if (req->retrans == 0) + lopt->qlen_young--; +#endif +} + +static inline void tcp_synq_added(struct sock *sk) +{ +#if 0 + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (lopt->qlen++ == 0) + tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT); + lopt->qlen_young++; +#endif +} + +static inline int tcp_synq_len(struct sock *sk) +{ +#if 0 + return sk->tp_pinfo.af_tcp.listen_opt->qlen; +#else + return 0; +#endif +} + +static inline int tcp_synq_young(struct sock *sk) +{ +#if 0 + return sk->tp_pinfo.af_tcp.listen_opt->qlen_young; +#else + return 0; +#endif +} + +static inline int tcp_synq_is_full(struct sock *sk) +{ +#if 0 + return tcp_synq_len(sk)>>sk->tp_pinfo.af_tcp.listen_opt->max_qlen_log; +#else + return 0; +#endif +} + +static inline void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req, + struct open_request **prev) +{ +#if 0 + write_lock(&tp->syn_wait_lock); + *prev = req->dl_next; + write_unlock(&tp->syn_wait_lock); +#endif +} + +static inline void tcp_synq_drop(struct sock *sk, struct open_request *req, + struct open_request **prev) +{ +#if 0 + tcp_synq_unlink(&sk->tp_pinfo.af_tcp, req, prev); + tcp_synq_removed(sk, req); + tcp_openreq_free(req); +#endif +} + +static __inline__ void tcp_openreq_init(struct open_request *req, + struct tcp_opt *tp, + struct sk_buff *skb) +{ +#if 0 + req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ + req->rcv_isn = TCP_SKB_CB(skb)->seq; + req->mss = tp->mss_clamp; + req->ts_recent = tp->saw_tstamp ? tp->rcv_tsval : 0; + req->tstamp_ok = tp->tstamp_ok; + req->sack_ok = tp->sack_ok; + req->snd_wscale = tp->snd_wscale; + req->wscale_ok = tp->wscale_ok; + req->acked = 0; + req->ecn_ok = 0; + req->rmt_port = skb->h.th->source; +#endif +} + +#define TCP_MEM_QUANTUM ((int)PAGE_SIZE) + +static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + sk->tp_pinfo.af_tcp.queue_shrunk = 1; + sk->wmem_queued -= skb->truesize; + sk->forward_alloc += skb->truesize; + __kfree_skb(skb); +#endif +} + +static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + sk->wmem_queued += skb->truesize; + sk->forward_alloc -= skb->truesize; +#endif +} + +extern void __tcp_mem_reclaim(struct sock *sk); +extern int tcp_mem_schedule(struct sock *sk, int size, int kind); + +static inline void tcp_mem_reclaim(struct sock *sk) +{ +#if 0 + if (sk->forward_alloc >= TCP_MEM_QUANTUM) + __tcp_mem_reclaim(sk); +#endif +} + +static inline void tcp_enter_memory_pressure(void) +{ +#if 0 + if (!tcp_memory_pressure) { + NET_INC_STATS(TCPMemoryPressures); + tcp_memory_pressure = 1; + } +#endif +} + +static inline void tcp_moderate_sndbuf(struct sock *sk) +{ +#if 0 + if (!(sk->userlocks&SOCK_SNDBUF_LOCK)) { + sk->sndbuf = min(sk->sndbuf, sk->wmem_queued/2); + sk->sndbuf = max(sk->sndbuf, SOCK_MIN_SNDBUF); + } +#endif +} + +static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) +{ +#if 0 + struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp); + + if (skb) { + skb->truesize += mem; + if (sk->forward_alloc >= (int)skb->truesize || + tcp_mem_schedule(sk, skb->truesize, 0)) { + skb_reserve(skb, MAX_TCP_HEADER); + return skb; + } + __kfree_skb(skb); + } else { + tcp_enter_memory_pressure(); + tcp_moderate_sndbuf(sk); + } + return NULL; +#else + return NULL; +#endif +} + +static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) +{ +#if 0 + return tcp_alloc_pskb(sk, size, 0, gfp); +#else + return NULL; +#endif +} + +static inline struct page * tcp_alloc_page(struct sock *sk) +{ +#if 0 + if (sk->forward_alloc >= (int)PAGE_SIZE || + tcp_mem_schedule(sk, PAGE_SIZE, 0)) { + struct page *page = alloc_pages(sk->allocation, 0); + if (page) + return page; + } + tcp_enter_memory_pressure(); + tcp_moderate_sndbuf(sk); + return NULL; +#else + return NULL; +#endif +} + +static inline void tcp_writequeue_purge(struct sock *sk) +{ +#if 0 + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&sk->write_queue)) != NULL) + tcp_free_skb(sk, skb); + tcp_mem_reclaim(sk); +#endif +} + +extern void tcp_rfree(struct sk_buff *skb); + +static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk) +{ +#if 0 + skb->sk = sk; + skb->destructor = tcp_rfree; + atomic_add(skb->truesize, &sk->rmem_alloc); + sk->forward_alloc -= skb->truesize; +#endif +} + +extern void tcp_listen_wlock(void); + +/* - We may sleep inside this lock. + * - If sleeping is not required (or called from BH), + * use plain read_(un)lock(&tcp_lhash_lock). + */ + +static inline void tcp_listen_lock(void) +{ +#if 0 + /* read_lock synchronizes to candidates to writers */ + read_lock(&tcp_lhash_lock); + atomic_inc(&tcp_lhash_users); + read_unlock(&tcp_lhash_lock); +#endif +} + +static inline void tcp_listen_unlock(void) +{ +#if 0 + if (atomic_dec_and_test(&tcp_lhash_users)) + wake_up(&tcp_lhash_wait); +#endif +} + +static inline int keepalive_intvl_when(struct tcp_opt *tp) +{ +#if 0 + return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl; +#else + return 0; +#endif +} + +static inline int keepalive_time_when(struct tcp_opt *tp) +{ +#if 0 + return tp->keepalive_time ? : sysctl_tcp_keepalive_time; +#else + return 0; +#endif +} + +static inline int tcp_fin_time(struct tcp_opt *tp) +{ +#if 0 + int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout; + + if (fin_timeout < (tp->rto<<2) - (tp->rto>>1)) + fin_timeout = (tp->rto<<2) - (tp->rto>>1); + + return fin_timeout; +#else + return 0; +#endif +} + +static inline int tcp_paws_check(struct tcp_opt *tp, int rst) +{ +#if 0 + if ((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) + return 0; + if (xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) + return 0; + + /* RST segments are not recommended to carry timestamp, + and, if they do, it is recommended to ignore PAWS because + "their cleanup function should take precedence over timestamps." + Certainly, it is mistake. It is necessary to understand the reasons + of this constraint to relax it: if peer reboots, clock may go + out-of-sync and half-open connections will not be reset. + Actually, the problem would be not existing if all + the implementations followed draft about maintaining clock + via reboots. Linux-2.2 DOES NOT! + + However, we can relax time bounds for RST segments to MSL. + */ + if (rst && xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_MSL) + return 0; + return 1; +#else + return 0; +#endif +} + +#define TCP_CHECK_TIMER(sk) do { } while (0) + +#endif /* __TCPCORE_H */ + + +// +#endif +#endif diff --git a/drivers/net/tcpip/include/tcpdef.h b/drivers/net/tcpip/include/tcpdef.h new file mode 100755 index 0000000..8005de2 --- /dev/null +++ b/drivers/net/tcpip/include/tcpdef.h @@ -0,0 +1,187 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the TCP protocol. + * + * Version: @(#)tcp.h 1.0.2 04/28/93 + * + * Author: Fred N. van Kempen, + * + * 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. + */ +#ifndef _LINUX_TCP_H +#define _LINUX_TCP_H + +#include "linux.h" + +struct tcphdr { + __u16 source; + __u16 dest; + __u32 seq; + __u32 ack_seq; +//#if defined(__LITTLE_ENDIAN_BITFIELD) + __u16 res1:4, + doff:4, + fin:1, + syn:1, + rst:1, + psh:1, + ack:1, + urg:1, + ece:1, + cwr:1; +/*#elif defined(__BIG_ENDIAN_BITFIELD) + __u16 doff:4, + res1:4, + cwr:1, + ece:1, + urg:1, + ack:1, + psh:1, + rst:1, + syn:1, + fin:1; +#else +#error "Adjust your defines" +#endif */ + __u16 window; + __u16 check; + __u16 urg_ptr; +}; + + +enum { + TCP_ESTABLISHED = 1, + TCP_SYN_SENT, + TCP_SYN_RECV, + TCP_FIN_WAIT1, + TCP_FIN_WAIT2, + TCP_TIME_WAIT, + TCP_CLOSE, + TCP_CLOSE_WAIT, + TCP_LAST_ACK, + TCP_LISTEN, + TCP_CLOSING, /* now a valid state */ + + TCP_MAX_STATES /* Leave at the end! */ +}; + +#define TCP_STATE_MASK 0xF +#define TCP_ACTION_FIN (1 << 7) + +enum { + TCPF_ESTABLISHED = (1 << 1), + TCPF_SYN_SENT = (1 << 2), + TCPF_SYN_RECV = (1 << 3), + TCPF_FIN_WAIT1 = (1 << 4), + TCPF_FIN_WAIT2 = (1 << 5), + TCPF_TIME_WAIT = (1 << 6), + TCPF_CLOSE = (1 << 7), + TCPF_CLOSE_WAIT = (1 << 8), + TCPF_LAST_ACK = (1 << 9), + TCPF_LISTEN = (1 << 10), + TCPF_CLOSING = (1 << 11) +}; + +/* + * The union cast uses a gcc extension to avoid aliasing problems + * (union is compatible to any of its members) + * This means this part of the code is -fstrict-aliasing safe now. + */ +union tcp_word_hdr { + struct tcphdr hdr; + __u32 words[5]; +}; + +#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) + +enum { + TCP_FLAG_CWR = 0x00800000, // __constant_htonl(0x00800000), + TCP_FLAG_ECE = 0x00400000, //__constant_htonl(0x00400000), + TCP_FLAG_URG = 0x00200000, //__constant_htonl(0x00200000), + TCP_FLAG_ACK = 0x00100000, //__constant_htonl(0x00100000), + TCP_FLAG_PSH = 0x00080000, //__constant_htonl(0x00080000), + TCP_FLAG_RST = 0x00040000, //__constant_htonl(0x00040000), + TCP_FLAG_SYN = 0x00020000, //__constant_htonl(0x00020000), + TCP_FLAG_FIN = 0x00010000, //__constant_htonl(0x00010000), + TCP_RESERVED_BITS = 0x0F000000, //__constant_htonl(0x0F000000), + TCP_DATA_OFFSET = 0xF0000000, //__constant_htonl(0xF0000000) +}; + +/* TCP socket options */ +#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */ +#define TCP_MAXSEG 2 /* Limit MSS */ +#define TCP_CORK 3 /* Never send partially complete segments */ +#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ +#define TCP_KEEPINTVL 5 /* Interval between keepalives */ +#define TCP_KEEPCNT 6 /* Number of keepalives before death */ +#define TCP_SYNCNT 7 /* Number of SYN retransmits */ +#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ +#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ +#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ +#define TCP_INFO 11 /* Information about this connection. */ +#define TCP_QUICKACK 12 /* Block/reenable quick acks */ + +#define TCPI_OPT_TIMESTAMPS 1 +#define TCPI_OPT_SACK 2 +#define TCPI_OPT_WSCALE 4 +#define TCPI_OPT_ECN 8 + +enum tcp_ca_state +{ + TCP_CA_Open = 0, +#define TCPF_CA_Open (1<DstAddr, NULL); +#if 1 + //NCE = RouteFindRouter(&IPPacket->DstAddr, NULL); + NCE = NULL; if (NCE) { /* FIXME: Possibly fragment datagram */ /* Forward the packet */ diff --git a/drivers/net/tcpip/tcpip/.cvsignore b/drivers/net/tcpip/tcpip/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/tcpip/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tcpip/transport/datagram/.cvsignore b/drivers/net/tcpip/transport/datagram/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/transport/datagram/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tcpip/transport/rawip/.cvsignore b/drivers/net/tcpip/transport/rawip/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/transport/rawip/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tcpip/transport/tcp/.cvsignore b/drivers/net/tcpip/transport/tcp/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tcpip/transport/tcp/tcp.c b/drivers/net/tcpip/transport/tcp/tcp.c index ffebef0..a22c133 100644 --- a/drivers/net/tcpip/transport/tcp/tcp.c +++ b/drivers/net/tcpip/transport/tcp/tcp.c @@ -467,6 +467,8 @@ NTSTATUS TCPStartup( * Status of operation */ { + tcp_init(); + /* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); diff --git a/drivers/net/tcpip/transport/tcp/tcp_input.c b/drivers/net/tcpip/transport/tcp/tcp_input.c new file mode 100755 index 0000000..484d558 --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/tcp_input.c @@ -0,0 +1,4184 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: transport/tcp/tcp_input.c + * PURPOSE: Transmission Control Protocol + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 15-01-2003 Imported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Implementation of the Transmission Control Protocol(TCP). + * + * Version: $Id$ + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * Mark Evans, + * Corey Minyard + * Florian La Roche, + * Charles Hedrick, + * Linus Torvalds, + * Alan Cox, + * Matthew Dillon, + * Arnt Gulbrandsen, + * Jorge Cwik, + */ + +/* + * Changes: + * Pedro Roque : Fast Retransmit/Recovery. + * Two receive queues. + * Retransmit queue handled by TCP. + * Better retransmit timer handling. + * New congestion avoidance. + * Header prediction. + * Variable renaming. + * + * Eric : Fast Retransmit. + * Randy Scott : MSS option defines. + * Eric Schenk : Fixes to slow start algorithm. + * Eric Schenk : Yet another double ACK bug. + * Eric Schenk : Delayed ACK bug fixes. + * Eric Schenk : Floyd style fast retrans war avoidance. + * David S. Miller : Don't allow zero congestion window. + * Eric Schenk : Fix retransmitter so that it sends + * next packet on ack of previous packet. + * Andi Kleen : Moved open_request checking here + * and process RSTs for open_requests. + * Andi Kleen : Better prune_queue, and other fixes. + * Andrey Savochkin: Fix RTT measurements in the presnce of + * timestamps. + * Andrey Savochkin: Check sequence numbers correctly when + * removing SACKs due to in sequence incoming + * data segments. + * Andi Kleen: Make sure we never ack data there is not + * enough room for. Also make this condition + * a fatal error if it might still happen. + * Andi Kleen: Add tcp_measure_rcv_mss to make + * connections with MSS +#include +#include +#include +#include +#include +#else +#include "linux.h" +#include "tcpcore.h" +#endif + +int sysctl_tcp_timestamps = 1; +int sysctl_tcp_window_scaling = 1; +int sysctl_tcp_sack = 1; +int sysctl_tcp_fack = 1; +int sysctl_tcp_reordering = TCP_FASTRETRANS_THRESH; +#ifdef CONFIG_INET_ECN +int sysctl_tcp_ecn = 1; +#else +int sysctl_tcp_ecn = 0; +#endif +int sysctl_tcp_dsack = 1; +int sysctl_tcp_app_win = 31; +int sysctl_tcp_adv_win_scale = 2; + +int sysctl_tcp_stdurg = 0; +int sysctl_tcp_rfc1337 = 0; +//int sysctl_tcp_max_orphans = NR_FILE; + +#define FLAG_DATA 0x01 /* Incoming frame contained data. */ +#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ +#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ +#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ +#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ +#define FLAG_DATA_SACKED 0x20 /* New SACK. */ +#define FLAG_ECE 0x40 /* ECE in this ACK */ +#define FLAG_DATA_LOST 0x80 /* SACK detected data lossage. */ +#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ + +#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) +#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) +#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) +#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) + +#define IsReno(tp) ((tp)->sack_ok == 0) +#define IsFack(tp) ((tp)->sack_ok & 2) +#define IsDSack(tp) ((tp)->sack_ok & 4) + +#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) + +/* Adapt the MSS value used to make delayed ack decision to the + * real world. + */ +static __inline__ void tcp_measure_rcv_mss(struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + unsigned int len, lss; + + lss = tp->ack.last_seg_size; + tp->ack.last_seg_size = 0; + + /* skb->len may jitter because of SACKs, even if peer + * sends good full-sized frames. + */ + len = skb->len; + if (len >= tp->ack.rcv_mss) { + tp->ack.rcv_mss = len; + } else { + /* Otherwise, we make more careful check taking into account, + * that SACKs block is variable. + * + * "len" is invariant segment length, including TCP header. + */ + len += skb->data - skb->h.raw; + if (len >= TCP_MIN_RCVMSS + sizeof(struct tcphdr) || + /* If PSH is not set, packet should be + * full sized, provided peer TCP is not badly broken. + * This observation (if it is correct 8)) allows + * to handle super-low mtu links fairly. + */ + (len >= TCP_MIN_MSS + sizeof(struct tcphdr) && + !(tcp_flag_word(skb->h.th)&TCP_REMNANT))) { + /* Subtract also invariant (if peer is RFC compliant), + * tcp header plus fixed timestamp option length. + * Resulting "len" is MSS free of SACK jitter. + */ + len -= tp->tcp_header_len; + tp->ack.last_seg_size = len; + if (len == lss) { + tp->ack.rcv_mss = len; + return; + } + } + tp->ack.pending |= TCP_ACK_PUSHED; + } +#endif +} + +static void tcp_incr_quickack(struct tcp_opt *tp) +{ +#if 0 + unsigned quickacks = tp->rcv_wnd/(2*tp->ack.rcv_mss); + + if (quickacks==0) + quickacks=2; + if (quickacks > tp->ack.quick) + tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS); +#endif +} + +void tcp_enter_quickack_mode(struct tcp_opt *tp) +{ +#if 0 + tcp_incr_quickack(tp); + tp->ack.pingpong = 0; + tp->ack.ato = TCP_ATO_MIN; +#endif +} + +/* Send ACKs quickly, if "quick" count is not exhausted + * and the session is not interactive. + */ + +static __inline__ int tcp_in_quickack_mode(struct tcp_opt *tp) +{ +#if 0 + return (tp->ack.quick && !tp->ack.pingpong); +#else + return 0; +#endif +} + +/* Buffer size and advertised window tuning. + * + * 1. Tuning sk->sndbuf, when connection enters established state. + */ + +static void tcp_fixup_sndbuf(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int sndmem = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff); + + if (sk->sndbuf < 3*sndmem) + sk->sndbuf = min(3*sndmem, sysctl_tcp_wmem[2]); +#endif +} + +/* 2. Tuning advertised window (window_clamp, rcv_ssthresh) + * + * All tcp_full_space() is split to two parts: "network" buffer, allocated + * forward and advertised in receiver window (tp->rcv_wnd) and + * "application buffer", required to isolate scheduling/application + * latencies from network. + * window_clamp is maximal advertised window. It can be less than + * tcp_full_space(), in this case tcp_full_space() - window_clamp + * is reserved for "application" buffer. The less window_clamp is + * the smoother our behaviour from viewpoint of network, but the lower + * throughput and the higher sensitivity of the connection to losses. 8) + * + * rcv_ssthresh is more strict window_clamp used at "slow start" + * phase to predict further behaviour of this connection. + * It is used for two goals: + * - to enforce header prediction at sender, even when application + * requires some significant "application buffer". It is check #1. + * - to prevent pruning of receive queue because of misprediction + * of receiver window. Check #2. + * + * The scheme does not work when sender sends good segments opening + * window and then starts to feed us spagetti. But it should work + * in common situations. Otherwise, we have to rely on queue collapsing. + */ + +/* Slow part of check#2. */ +static int +__tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + /* Optimize this! */ + int truesize = tcp_win_from_space(skb->truesize)/2; + int window = tcp_full_space(sk)/2; + + while (tp->rcv_ssthresh <= window) { + if (truesize <= skb->len) + return 2*tp->ack.rcv_mss; + + truesize >>= 1; + window >>= 1; + } + return 0; +#else + return 0; +#endif +} + +static __inline__ void +tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + /* Check #1 */ + if (tp->rcv_ssthresh < tp->window_clamp && + (int)tp->rcv_ssthresh < tcp_space(sk) && + !tcp_memory_pressure) { + int incr; + + /* Check #2. Increase window, if skb with such overhead + * will fit to rcvbuf in future. + */ + if (tcp_win_from_space(skb->truesize) <= skb->len) + incr = 2*tp->advmss; + else + incr = __tcp_grow_window(sk, tp, skb); + + if (incr) { + tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp); + tp->ack.quick |= 1; + } + } +#endif +} + +/* 3. Tuning rcvbuf, when connection enters established state. */ + +static void tcp_fixup_rcvbuf(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int rcvmem = tp->advmss+MAX_TCP_HEADER+16+sizeof(struct sk_buff); + + /* Try to select rcvbuf so that 4 mss-sized segments + * will fit to window and correspoding skbs will fit to our rcvbuf. + * (was 3; 4 is minimum to allow fast retransmit to work.) + */ + while (tcp_win_from_space(rcvmem) < tp->advmss) + rcvmem += 128; + if (sk->rcvbuf < 4*rcvmem) + sk->rcvbuf = min(4*rcvmem, sysctl_tcp_rmem[2]); +#endif +} + +/* 4. Try to fixup all. It is made iimediately after connection enters + * established state. + */ +static void tcp_init_buffer_space(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int maxwin; + + if (!(sk->userlocks&SOCK_RCVBUF_LOCK)) + tcp_fixup_rcvbuf(sk); + if (!(sk->userlocks&SOCK_SNDBUF_LOCK)) + tcp_fixup_sndbuf(sk); + + maxwin = tcp_full_space(sk); + + if (tp->window_clamp >= maxwin) { + tp->window_clamp = maxwin; + + if (sysctl_tcp_app_win && maxwin>4*tp->advmss) + tp->window_clamp = max(maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss); + } + + /* Force reservation of one segment. */ + if (sysctl_tcp_app_win && + tp->window_clamp > 2*tp->advmss && + tp->window_clamp + tp->advmss > maxwin) + tp->window_clamp = max(2*tp->advmss, maxwin-tp->advmss); + + tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp); + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +/* 5. Recalculate window clamp after socket hit its memory bounds. */ +static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + struct sk_buff *skb; + unsigned int app_win = tp->rcv_nxt - tp->copied_seq; + int ofo_win = 0; + + tp->ack.quick = 0; + + skb_queue_walk(&tp->out_of_order_queue, skb) { + ofo_win += skb->len; + } + + /* If overcommit is due to out of order segments, + * do not clamp window. Try to expand rcvbuf instead. + */ + if (ofo_win) { + if (sk->rcvbuf < sysctl_tcp_rmem[2] && + !(sk->userlocks&SOCK_RCVBUF_LOCK) && + !tcp_memory_pressure && + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) + sk->rcvbuf = min(atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]); + } + if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) { + app_win += ofo_win; + if (atomic_read(&sk->rmem_alloc) >= 2*sk->rcvbuf) + app_win >>= 1; + if (app_win > tp->ack.rcv_mss) + app_win -= tp->ack.rcv_mss; + app_win = max(app_win, 2U*tp->advmss); + + if (!ofo_win) + tp->window_clamp = min(tp->window_clamp, app_win); + tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss); + } +#endif +} + +/* There is something which you must keep in mind when you analyze the + * behavior of the tp->ato delayed ack timeout interval. When a + * connection starts up, we want to ack as quickly as possible. The + * problem is that "good" TCP's do slow start at the beginning of data + * transmission. The means that until we send the first few ACK's the + * sender will sit on his end and only queue most of his data, because + * he can only send snd_cwnd unacked packets at any given time. For + * each ACK we send, he increments snd_cwnd and transmits more of his + * queue. -DaveM + */ +static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + u32 now; + + tcp_schedule_ack(tp); + + tcp_measure_rcv_mss(tp, skb); + + now = tcp_time_stamp; + + if (!tp->ack.ato) { + /* The _first_ data packet received, initialize + * delayed ACK engine. + */ + tcp_incr_quickack(tp); + tp->ack.ato = TCP_ATO_MIN; + } else { + int m = now - tp->ack.lrcvtime; + + if (m <= TCP_ATO_MIN/2) { + /* The fastest case is the first. */ + tp->ack.ato = (tp->ack.ato>>1) + TCP_ATO_MIN/2; + } else if (m < tp->ack.ato) { + tp->ack.ato = (tp->ack.ato>>1) + m; + if (tp->ack.ato > tp->rto) + tp->ack.ato = tp->rto; + } else if (m > tp->rto) { + /* Too long gap. Apparently sender falled to + * restart window, so that we send ACKs quickly. + */ + tcp_incr_quickack(tp); + tcp_mem_reclaim(sk); + } + } + tp->ack.lrcvtime = now; + + TCP_ECN_check_ce(tp, skb); + + if (skb->len >= 128) + tcp_grow_window(sk, tp, skb); +#endif +} + +/* Called to compute a smoothed rtt estimate. The data fed to this + * routine either comes from timestamps, or from segments that were + * known _not_ to have been retransmitted [see Karn/Partridge + * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88 + * piece by Van Jacobson. + * NOTE: the next three routines used to be one big routine. + * To save cycles in the RFC 1323 implementation it was better to break + * it up into three procedures. -- erics + */ +static __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt) +{ +#if 0 + long m = mrtt; /* RTT */ + + /* The following amusing code comes from Jacobson's + * article in SIGCOMM '88. Note that rtt and mdev + * are scaled versions of rtt and mean deviation. + * This is designed to be as fast as possible + * m stands for "measurement". + * + * On a 1990 paper the rto value is changed to: + * RTO = rtt + 4 * mdev + * + * Funny. This algorithm seems to be very broken. + * These formulae increase RTO, when it should be decreased, increase + * too slowly, when it should be incresed fastly, decrease too fastly + * etc. I guess in BSD RTO takes ONE value, so that it is absolutely + * does not matter how to _calculate_ it. Seems, it was trap + * that VJ failed to avoid. 8) + */ + if(m == 0) + m = 1; + if (tp->srtt != 0) { + m -= (tp->srtt >> 3); /* m is now error in rtt est */ + tp->srtt += m; /* rtt = 7/8 rtt + 1/8 new */ + if (m < 0) { + m = -m; /* m is now abs(error) */ + m -= (tp->mdev >> 2); /* similar update on mdev */ + /* This is similar to one of Eifel findings. + * Eifel blocks mdev updates when rtt decreases. + * This solution is a bit different: we use finer gain + * for mdev in this case (alpha*beta). + * Like Eifel it also prevents growth of rto, + * but also it limits too fast rto decreases, + * happening in pure Eifel. + */ + if (m > 0) + m >>= 3; + } else { + m -= (tp->mdev >> 2); /* similar update on mdev */ + } + tp->mdev += m; /* mdev = 3/4 mdev + 1/4 new */ + if (tp->mdev > tp->mdev_max) { + tp->mdev_max = tp->mdev; + if (tp->mdev_max > tp->rttvar) + tp->rttvar = tp->mdev_max; + } + if (after(tp->snd_una, tp->rtt_seq)) { + if (tp->mdev_max < tp->rttvar) + tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2; + tp->rtt_seq = tp->snd_nxt; + tp->mdev_max = TCP_RTO_MIN; + } + } else { + /* no previous measure. */ + tp->srtt = m<<3; /* take the measured time to be rtt */ + tp->mdev = m<<1; /* make sure rto = 3*rtt */ + tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); + tp->rtt_seq = tp->snd_nxt; + } +#endif +} + +/* Calculate rto without backoff. This is the second half of Van Jacobson's + * routine referred to above. + */ +static __inline__ void tcp_set_rto(struct tcp_opt *tp) +{ +#if 0 + /* Old crap is replaced with new one. 8) + * + * More seriously: + * 1. If rtt variance happened to be less 50msec, it is hallucination. + * It cannot be less due to utterly erratic ACK generation made + * at least by solaris and freebsd. "Erratic ACKs" has _nothing_ + * to do with delayed acks, because at cwnd>2 true delack timeout + * is invisible. Actually, Linux-2.4 also generates erratic + * ACKs in some curcumstances. + */ + tp->rto = (tp->srtt >> 3) + tp->rttvar; + + /* 2. Fixups made earlier cannot be right. + * If we do not estimate RTO correctly without them, + * all the algo is pure shit and should be replaced + * with correct one. It is exaclty, which we pretend to do. + */ +#endif +} + +/* NOTE: clamping at TCP_RTO_MIN is not required, current algo + * guarantees that rto is higher. + */ +static __inline__ void tcp_bound_rto(struct tcp_opt *tp) +{ +#if 0 + if (tp->rto > TCP_RTO_MAX) + tp->rto = TCP_RTO_MAX; +#endif +} + +/* Save metrics learned by this TCP session. + This function is called only, when TCP finishes successfully + i.e. when it enters TIME-WAIT or goes from LAST-ACK to CLOSE. + */ +void tcp_update_metrics(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct dst_entry *dst = __sk_dst_get(sk); + + dst_confirm(dst); + + if (dst && (dst->flags&DST_HOST)) { + int m; + + if (tp->backoff || !tp->srtt) { + /* This session failed to estimate rtt. Why? + * Probably, no packets returned in time. + * Reset our results. + */ + if (!(dst->mxlock&(1<rtt = 0; + return; + } + + m = dst->rtt - tp->srtt; + + /* If newly calculated rtt larger than stored one, + * store new one. Otherwise, use EWMA. Remember, + * rtt overestimation is always better than underestimation. + */ + if (!(dst->mxlock&(1<rtt = tp->srtt; + else + dst->rtt -= (m>>3); + } + + if (!(dst->mxlock&(1<>= 1; + if (m < tp->mdev) + m = tp->mdev; + + if (m >= dst->rttvar) + dst->rttvar = m; + else + dst->rttvar -= (dst->rttvar - m)>>2; + } + + if (tp->snd_ssthresh >= 0xFFFF) { + /* Slow start still did not finish. */ + if (dst->ssthresh && + !(dst->mxlock&(1<snd_cwnd>>1) > dst->ssthresh) + dst->ssthresh = (tp->snd_cwnd>>1); + if (!(dst->mxlock&(1<snd_cwnd > dst->cwnd) + dst->cwnd = tp->snd_cwnd; + } else if (tp->snd_cwnd > tp->snd_ssthresh && + tp->ca_state == TCP_CA_Open) { + /* Cong. avoidance phase, cwnd is reliable. */ + if (!(dst->mxlock&(1<ssthresh = max(tp->snd_cwnd>>1, tp->snd_ssthresh); + if (!(dst->mxlock&(1<cwnd = (dst->cwnd + tp->snd_cwnd)>>1; + } else { + /* Else slow start did not finish, cwnd is non-sense, + ssthresh may be also invalid. + */ + if (!(dst->mxlock&(1<cwnd = (dst->cwnd + tp->snd_ssthresh)>>1; + if (dst->ssthresh && + !(dst->mxlock&(1<snd_ssthresh > dst->ssthresh) + dst->ssthresh = tp->snd_ssthresh; + } + + if (!(dst->mxlock&(1<reordering < tp->reordering && + tp->reordering != sysctl_tcp_reordering) + dst->reordering = tp->reordering; + } + } +#endif +} + +/* Increase initial CWND conservatively: if estimated + * RTT is low enough (<20msec) or if we have some preset ssthresh. + * + * Numbers are taken from RFC2414. + */ +__u32 tcp_init_cwnd(struct tcp_opt *tp) +{ +#if 0 + __u32 cwnd; + + if (tp->mss_cache > 1460) + return 2; + + cwnd = (tp->mss_cache > 1095) ? 3 : 4; + + if (!tp->srtt || (tp->snd_ssthresh >= 0xFFFF && tp->srtt > ((HZ/50)<<3))) + cwnd = 2; + else if (cwnd > tp->snd_ssthresh) + cwnd = tp->snd_ssthresh; + + return min_t(__u32, cwnd, tp->snd_cwnd_clamp); +#else + return 0; +#endif +} + +/* Initialize metrics on socket. */ + +static void tcp_init_metrics(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct dst_entry *dst = __sk_dst_get(sk); + + if (dst == NULL) + goto reset; + + dst_confirm(dst); + + if (dst->mxlock&(1<snd_cwnd_clamp = dst->cwnd; + if (dst->ssthresh) { + tp->snd_ssthresh = dst->ssthresh; + if (tp->snd_ssthresh > tp->snd_cwnd_clamp) + tp->snd_ssthresh = tp->snd_cwnd_clamp; + } + if (dst->reordering && tp->reordering != dst->reordering) { + tp->sack_ok &= ~2; + tp->reordering = dst->reordering; + } + + if (dst->rtt == 0) + goto reset; + + if (!tp->srtt && dst->rtt < (TCP_TIMEOUT_INIT<<3)) + goto reset; + + /* Initial rtt is determined from SYN,SYN-ACK. + * The segment is small and rtt may appear much + * less than real one. Use per-dst memory + * to make it more realistic. + * + * A bit of theory. RTT is time passed after "normal" sized packet + * is sent until it is ACKed. In normal curcumstances sending small + * packets force peer to delay ACKs and calculation is correct too. + * The algorithm is adaptive and, provided we follow specs, it + * NEVER underestimate RTT. BUT! If peer tries to make some clever + * tricks sort of "quick acks" for time long enough to decrease RTT + * to low value, and then abruptly stops to do it and starts to delay + * ACKs, wait for troubles. + */ + if (dst->rtt > tp->srtt) + tp->srtt = dst->rtt; + if (dst->rttvar > tp->mdev) { + tp->mdev = dst->rttvar; + tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); + } + tcp_set_rto(tp); + tcp_bound_rto(tp); + if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp) + goto reset; + tp->snd_cwnd = tcp_init_cwnd(tp); + tp->snd_cwnd_stamp = tcp_time_stamp; + return; + +reset: + /* Play conservative. If timestamps are not + * supported, TCP will fail to recalculate correct + * rtt, if initial rto is too small. FORGET ALL AND RESET! + */ + if (!tp->saw_tstamp && tp->srtt) { + tp->srtt = 0; + tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT; + tp->rto = TCP_TIMEOUT_INIT; + } +#endif +} + +static void tcp_update_reordering(struct tcp_opt *tp, int metric, int ts) +{ +#if 0 + if (metric > tp->reordering) { + tp->reordering = min(TCP_MAX_REORDERING, metric); + + /* This exciting event is worth to be remembered. 8) */ + if (ts) + NET_INC_STATS_BH(TCPTSReorder); + else if (IsReno(tp)) + NET_INC_STATS_BH(TCPRenoReorder); + else if (IsFack(tp)) + NET_INC_STATS_BH(TCPFACKReorder); + else + NET_INC_STATS_BH(TCPSACKReorder); +#if FASTRETRANS_DEBUG > 1 + printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n", + tp->sack_ok, tp->ca_state, + tp->reordering, tp->fackets_out, tp->sacked_out, + tp->undo_marker ? tp->undo_retrans : 0); +#endif + /* Disable FACK yet. */ + tp->sack_ok &= ~2; + } +#endif +} + +/* This procedure tags the retransmission queue when SACKs arrive. + * + * We have three tag bits: SACKED(S), RETRANS(R) and LOST(L). + * Packets in queue with these bits set are counted in variables + * sacked_out, retrans_out and lost_out, correspondingly. + * + * Valid combinations are: + * Tag InFlight Description + * 0 1 - orig segment is in flight. + * S 0 - nothing flies, orig reached receiver. + * L 0 - nothing flies, orig lost by net. + * R 2 - both orig and retransmit are in flight. + * L|R 1 - orig is lost, retransmit is in flight. + * S|R 1 - orig reached receiver, retrans is still in flight. + * (L|S|R is logically valid, it could occur when L|R is sacked, + * but it is equivalent to plain S and code short-curcuits it to S. + * L|S is logically invalid, it would mean -1 packet in flight 8)) + * + * These 6 states form finite state machine, controlled by the following events: + * 1. New ACK (+SACK) arrives. (tcp_sacktag_write_queue()) + * 2. Retransmission. (tcp_retransmit_skb(), tcp_xmit_retransmit_queue()) + * 3. Loss detection event of one of three flavors: + * A. Scoreboard estimator decided the packet is lost. + * A'. Reno "three dupacks" marks head of queue lost. + * A''. Its FACK modfication, head until snd.fack is lost. + * B. SACK arrives sacking data transmitted after never retransmitted + * hole was sent out. + * C. SACK arrives sacking SND.NXT at the moment, when the + * segment was retransmitted. + * 4. D-SACK added new rule: D-SACK changes any tag to S. + * + * It is pleasant to note, that state diagram turns out to be commutative, + * so that we are allowed not to be bothered by order of our actions, + * when multiple events arrive simultaneously. (see the function below). + * + * Reordering detection. + * -------------------- + * Reordering metric is maximal distance, which a packet can be displaced + * in packet stream. With SACKs we can estimate it: + * + * 1. SACK fills old hole and the corresponding segment was not + * ever retransmitted -> reordering. Alas, we cannot use it + * when segment was retransmitted. + * 2. The last flaw is solved with D-SACK. D-SACK arrives + * for retransmitted and already SACKed segment -> reordering.. + * Both of these heuristics are not used in Loss state, when we cannot + * account for retransmits accurately. + */ +static int +tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_una) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked; + struct tcp_sack_block *sp = (struct tcp_sack_block *)(ptr+2); + int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3; + int reord = tp->packets_out; + int prior_fackets; + u32 lost_retrans = 0; + int flag = 0; + int i; + + if (!tp->sacked_out) + tp->fackets_out = 0; + prior_fackets = tp->fackets_out; + + for (i=0; istart_seq); + __u32 end_seq = ntohl(sp->end_seq); + int fack_count = 0; + int dup_sack = 0; + + /* Check for D-SACK. */ + if (i == 0) { + u32 ack = TCP_SKB_CB(ack_skb)->ack_seq; + + if (before(start_seq, ack)) { + dup_sack = 1; + tp->sack_ok |= 4; + NET_INC_STATS_BH(TCPDSACKRecv); + } else if (num_sacks > 1 && + !after(end_seq, ntohl(sp[1].end_seq)) && + !before(start_seq, ntohl(sp[1].start_seq))) { + dup_sack = 1; + tp->sack_ok |= 4; + NET_INC_STATS_BH(TCPDSACKOfoRecv); + } + + /* D-SACK for already forgotten data... + * Do dumb counting. */ + if (dup_sack && + !after(end_seq, prior_snd_una) && + after(end_seq, tp->undo_marker)) + tp->undo_retrans--; + + /* Eliminate too old ACKs, but take into + * account more or less fresh ones, they can + * contain valid SACK info. + */ + if (before(ack, prior_snd_una-tp->max_window)) + return 0; + } + + /* Event "B" in the comment above. */ + if (after(end_seq, tp->high_seq)) + flag |= FLAG_DATA_LOST; + + for_retrans_queue(skb, sk, tp) { + u8 sacked = TCP_SKB_CB(skb)->sacked; + int in_sack; + + /* The retransmission queue is always in order, so + * we can short-circuit the walk early. + */ + if(!before(TCP_SKB_CB(skb)->seq, end_seq)) + break; + + fack_count++; + + in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && + !before(end_seq, TCP_SKB_CB(skb)->end_seq); + + /* Account D-SACK for retransmitted packet. */ + if ((dup_sack && in_sack) && + (sacked & TCPCB_RETRANS) && + after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker)) + tp->undo_retrans--; + + /* The frame is ACKed. */ + if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) { + if (sacked&TCPCB_RETRANS) { + if ((dup_sack && in_sack) && + (sacked&TCPCB_SACKED_ACKED)) + reord = min(fack_count, reord); + } else { + /* If it was in a hole, we detected reordering. */ + if (fack_count < prior_fackets && + !(sacked&TCPCB_SACKED_ACKED)) + reord = min(fack_count, reord); + } + + /* Nothing to do; acked frame is about to be dropped. */ + continue; + } + + if ((sacked&TCPCB_SACKED_RETRANS) && + after(end_seq, TCP_SKB_CB(skb)->ack_seq) && + (!lost_retrans || after(end_seq, lost_retrans))) + lost_retrans = end_seq; + + if (!in_sack) + continue; + + if (!(sacked&TCPCB_SACKED_ACKED)) { + if (sacked & TCPCB_SACKED_RETRANS) { + /* If the segment is not tagged as lost, + * we do not clear RETRANS, believing + * that retransmission is still in flight. + */ + if (sacked & TCPCB_LOST) { + TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); + tp->lost_out--; + tp->retrans_out--; + } + } else { + /* New sack for not retransmitted frame, + * which was in hole. It is reordering. + */ + if (!(sacked & TCPCB_RETRANS) && + fack_count < prior_fackets) + reord = min(fack_count, reord); + + if (sacked & TCPCB_LOST) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; + tp->lost_out--; + } + } + + TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; + flag |= FLAG_DATA_SACKED; + tp->sacked_out++; + + if (fack_count > tp->fackets_out) + tp->fackets_out = fack_count; + } else { + if (dup_sack && (sacked&TCPCB_RETRANS)) + reord = min(fack_count, reord); + } + + /* D-SACK. We can detect redundant retransmission + * in S|R and plain R frames and clear it. + * undo_retrans is decreased above, L|R frames + * are accounted above as well. + */ + if (dup_sack && + (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; + tp->retrans_out--; + } + } + } + + /* Check for lost retransmit. This superb idea is + * borrowed from "ratehalving". Event "C". + * Later note: FACK people cheated me again 8), + * we have to account for reordering! Ugly, + * but should help. + */ + if (lost_retrans && tp->ca_state == TCP_CA_Recovery) { + struct sk_buff *skb; + + for_retrans_queue(skb, sk, tp) { + if (after(TCP_SKB_CB(skb)->seq, lost_retrans)) + break; + if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) + continue; + if ((TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) && + after(lost_retrans, TCP_SKB_CB(skb)->ack_seq) && + (IsFack(tp) || + !before(lost_retrans, TCP_SKB_CB(skb)->ack_seq+tp->reordering*tp->mss_cache))) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; + tp->retrans_out--; + + if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) { + tp->lost_out++; + TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; + flag |= FLAG_DATA_SACKED; + NET_INC_STATS_BH(TCPLostRetransmit); + } + } + } + } + + tp->left_out = tp->sacked_out + tp->lost_out; + + if (reord < tp->fackets_out && tp->ca_state != TCP_CA_Loss) + tcp_update_reordering(tp, (tp->fackets_out+1)-reord, 0); + +#if FASTRETRANS_DEBUG > 0 + BUG_TRAP((int)tp->sacked_out >= 0); + BUG_TRAP((int)tp->lost_out >= 0); + BUG_TRAP((int)tp->retrans_out >= 0); + BUG_TRAP((int)tcp_packets_in_flight(tp) >= 0); +#endif + return flag; +#else + return 0; +#endif +} + +void tcp_clear_retrans(struct tcp_opt *tp) +{ +#if 0 + tp->left_out = 0; + tp->retrans_out = 0; + + tp->fackets_out = 0; + tp->sacked_out = 0; + tp->lost_out = 0; + + tp->undo_marker = 0; + tp->undo_retrans = 0; +#endif +} + +/* Enter Loss state. If "how" is not zero, forget all SACK information + * and reset tags completely, otherwise preserve SACKs. If receiver + * dropped its ofo queue, we will know this due to reneging detection. + */ +void tcp_enter_loss(struct sock *sk, int how) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct sk_buff *skb; + int cnt = 0; + + /* Reduce ssthresh if it has not yet been made inside this window. */ + if (tp->ca_state <= TCP_CA_Disorder || + tp->snd_una == tp->high_seq || + (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) { + tp->prior_ssthresh = tcp_current_ssthresh(tp); + tp->snd_ssthresh = tcp_recalc_ssthresh(tp); + } + tp->snd_cwnd = 1; + tp->snd_cwnd_cnt = 0; + tp->snd_cwnd_stamp = tcp_time_stamp; + + tcp_clear_retrans(tp); + + /* Push undo marker, if it was plain RTO and nothing + * was retransmitted. */ + if (!how) + tp->undo_marker = tp->snd_una; + + for_retrans_queue(skb, sk, tp) { + cnt++; + if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS) + tp->undo_marker = 0; + TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; + if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; + TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; + tp->lost_out++; + } else { + tp->sacked_out++; + tp->fackets_out = cnt; + } + } + tcp_sync_left_out(tp); + + tp->reordering = min_t(unsigned int, tp->reordering, sysctl_tcp_reordering); + tp->ca_state = TCP_CA_Loss; + tp->high_seq = tp->snd_nxt; + TCP_ECN_queue_cwr(tp); +#endif +} + +static int tcp_check_sack_reneging(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + struct sk_buff *skb; + + /* If ACK arrived pointing to a remembered SACK, + * it means that our remembered SACKs do not reflect + * real state of receiver i.e. + * receiver _host_ is heavily congested (or buggy). + * Do processing similar to RTO timeout. + */ + if ((skb = skb_peek(&sk->write_queue)) != NULL && + (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) { + NET_INC_STATS_BH(TCPSACKReneging); + + tcp_enter_loss(sk, 1); + tp->retransmits++; + tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return 1; + } + return 0; +#else + return 0; +#endif +} + +static inline int tcp_fackets_out(struct tcp_opt *tp) +{ +#if 0 + return IsReno(tp) ? tp->sacked_out+1 : tp->fackets_out; +#else + return 0; +#endif +} + +static inline int tcp_skb_timedout(struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + return (tcp_time_stamp - TCP_SKB_CB(skb)->when > tp->rto); +#else + return 0; +#endif +} + +static inline int tcp_head_timedout(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + return tp->packets_out && tcp_skb_timedout(tp, skb_peek(&sk->write_queue)); +#else + return 0; +#endif +} + +/* Linux NewReno/SACK/FACK/ECN state machine. + * -------------------------------------- + * + * "Open" Normal state, no dubious events, fast path. + * "Disorder" In all the respects it is "Open", + * but requires a bit more attention. It is entered when + * we see some SACKs or dupacks. It is split of "Open" + * mainly to move some processing from fast path to slow one. + * "CWR" CWND was reduced due to some Congestion Notification event. + * It can be ECN, ICMP source quench, local device congestion. + * "Recovery" CWND was reduced, we are fast-retransmitting. + * "Loss" CWND was reduced due to RTO timeout or SACK reneging. + * + * tcp_fastretrans_alert() is entered: + * - each incoming ACK, if state is not "Open" + * - when arrived ACK is unusual, namely: + * * SACK + * * Duplicate ACK. + * * ECN ECE. + * + * Counting packets in flight is pretty simple. + * + * in_flight = packets_out - left_out + retrans_out + * + * packets_out is SND.NXT-SND.UNA counted in packets. + * + * retrans_out is number of retransmitted segments. + * + * left_out is number of segments left network, but not ACKed yet. + * + * left_out = sacked_out + lost_out + * + * sacked_out: Packets, which arrived to receiver out of order + * and hence not ACKed. With SACKs this number is simply + * amount of SACKed data. Even without SACKs + * it is easy to give pretty reliable estimate of this number, + * counting duplicate ACKs. + * + * lost_out: Packets lost by network. TCP has no explicit + * "loss notification" feedback from network (for now). + * It means that this number can be only _guessed_. + * Actually, it is the heuristics to predict lossage that + * distinguishes different algorithms. + * + * F.e. after RTO, when all the queue is considered as lost, + * lost_out = packets_out and in_flight = retrans_out. + * + * Essentially, we have now two algorithms counting + * lost packets. + * + * FACK: It is the simplest heuristics. As soon as we decided + * that something is lost, we decide that _all_ not SACKed + * packets until the most forward SACK are lost. I.e. + * lost_out = fackets_out - sacked_out and left_out = fackets_out. + * It is absolutely correct estimate, if network does not reorder + * packets. And it loses any connection to reality when reordering + * takes place. We use FACK by default until reordering + * is suspected on the path to this destination. + * + * NewReno: when Recovery is entered, we assume that one segment + * is lost (classic Reno). While we are in Recovery and + * a partial ACK arrives, we assume that one more packet + * is lost (NewReno). This heuristics are the same in NewReno + * and SACK. + * + * Imagine, that's all! Forget about all this shamanism about CWND inflation + * deflation etc. CWND is real congestion window, never inflated, changes + * only according to classic VJ rules. + * + * Really tricky (and requiring careful tuning) part of algorithm + * is hidden in functions tcp_time_to_recover() and tcp_xmit_retransmit_queue(). + * The first determines the moment _when_ we should reduce CWND and, + * hence, slow down forward transmission. In fact, it determines the moment + * when we decide that hole is caused by loss, rather than by a reorder. + * + * tcp_xmit_retransmit_queue() decides, _what_ we should retransmit to fill + * holes, caused by lost packets. + * + * And the most logically complicated part of algorithm is undo + * heuristics. We detect false retransmits due to both too early + * fast retransmit (reordering) and underestimated RTO, analyzing + * timestamps and D-SACKs. When we detect that some segments were + * retransmitted by mistake and CWND reduction was wrong, we undo + * window reduction and abort recovery phase. This logic is hidden + * inside several functions named tcp_try_undo_. + */ + +/* This function decides, when we should leave Disordered state + * and enter Recovery phase, reducing congestion window. + * + * Main question: may we further continue forward transmission + * with the same cwnd? + */ +static int +tcp_time_to_recover(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + /* Trick#1: The loss is proven. */ + if (tp->lost_out) + return 1; + + /* Not-A-Trick#2 : Classic rule... */ + if (tcp_fackets_out(tp) > tp->reordering) + return 1; + + /* Trick#3 : when we use RFC2988 timer restart, fast + * retransmit can be triggered by timeout of queue head. + */ + if (tcp_head_timedout(sk, tp)) + return 1; + + /* Trick#4: It is still not OK... But will it be useful to delay + * recovery more? + */ + if (tp->packets_out <= tp->reordering && + tp->sacked_out >= max_t(__u32, tp->packets_out/2, sysctl_tcp_reordering) && + !tcp_may_send_now(sk, tp)) { + /* We have nothing to send. This connection is limited + * either by receiver window or by application. + */ + return 1; + } + + return 0; +#else + return 0; +#endif +} + +/* If we receive more dupacks than we expected counting segments + * in assumption of absent reordering, interpret this as reordering. + * The only another reason could be bug in receiver TCP. + */ +static void tcp_check_reno_reordering(struct tcp_opt *tp, int addend) +{ +#if 0 + u32 holes; + + holes = max(tp->lost_out, 1U); + holes = min(holes, tp->packets_out); + + if (tp->sacked_out + holes > tp->packets_out) { + tp->sacked_out = tp->packets_out - holes; + tcp_update_reordering(tp, tp->packets_out+addend, 0); + } +#endif +} + +/* Emulate SACKs for SACKless connection: account for a new dupack. */ + +static void tcp_add_reno_sack(struct tcp_opt *tp) +{ +#if 0 + ++tp->sacked_out; + tcp_check_reno_reordering(tp, 0); + tcp_sync_left_out(tp); +#endif +} + +/* Account for ACK, ACKing some data in Reno Recovery phase. */ + +static void tcp_remove_reno_sacks(struct sock *sk, struct tcp_opt *tp, int acked) +{ +#if 0 + if (acked > 0) { + /* One ACK acked hole. The rest eat duplicate ACKs. */ + if (acked-1 >= tp->sacked_out) + tp->sacked_out = 0; + else + tp->sacked_out -= acked-1; + } + tcp_check_reno_reordering(tp, acked); + tcp_sync_left_out(tp); +#endif +} + +static inline void tcp_reset_reno_sack(struct tcp_opt *tp) +{ +#if 0 + tp->sacked_out = 0; + tp->left_out = tp->lost_out; +#endif +} + +/* Mark head of queue up as lost. */ +static void +tcp_mark_head_lost(struct sock *sk, struct tcp_opt *tp, int packets, u32 high_seq) +{ +#if 0 + struct sk_buff *skb; + int cnt = packets; + + BUG_TRAP(cnt <= tp->packets_out); + + for_retrans_queue(skb, sk, tp) { + if (--cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq)) + break; + if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { + TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; + tp->lost_out++; + } + } + tcp_sync_left_out(tp); +#endif +} + +/* Account newly detected lost packet(s) */ + +static void tcp_update_scoreboard(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (IsFack(tp)) { + int lost = tp->fackets_out - tp->reordering; + if (lost <= 0) + lost = 1; + tcp_mark_head_lost(sk, tp, lost, tp->high_seq); + } else { + tcp_mark_head_lost(sk, tp, 1, tp->high_seq); + } + + /* New heuristics: it is possible only after we switched + * to restart timer each time when something is ACKed. + * Hence, we can detect timed out packets during fast + * retransmit without falling to slow start. + */ + if (tcp_head_timedout(sk, tp)) { + struct sk_buff *skb; + + for_retrans_queue(skb, sk, tp) { + if (tcp_skb_timedout(tp, skb) && + !(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { + TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; + tp->lost_out++; + } + } + tcp_sync_left_out(tp); + } +#endif +} + +/* CWND moderation, preventing bursts due to too big ACKs + * in dubious situations. + */ +static __inline__ void tcp_moderate_cwnd(struct tcp_opt *tp) +{ +#if 0 + tp->snd_cwnd = min(tp->snd_cwnd, + tcp_packets_in_flight(tp)+tcp_max_burst(tp)); + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +/* Decrease cwnd each second ack. */ + +static void tcp_cwnd_down(struct tcp_opt *tp) +{ +#if 0 + int decr = tp->snd_cwnd_cnt + 1; + + tp->snd_cwnd_cnt = decr&1; + decr >>= 1; + + if (decr && tp->snd_cwnd > tp->snd_ssthresh/2) + tp->snd_cwnd -= decr; + + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +/* Nothing was retransmitted or returned timestamp is less + * than timestamp of the first retransmission. + */ +static __inline__ int tcp_packet_delayed(struct tcp_opt *tp) +{ +#if 0 + return !tp->retrans_stamp || + (tp->saw_tstamp && tp->rcv_tsecr && + (__s32)(tp->rcv_tsecr - tp->retrans_stamp) < 0); +#else + return 0; +#endif +} + +/* Undo procedures. */ + +#if FASTRETRANS_DEBUG > 1 +static void DBGUNDO(struct sock *sk, struct tcp_opt *tp, const char *msg) +{ +#if 0 + printk(KERN_DEBUG "Undo %s %u.%u.%u.%u/%u c%u l%u ss%u/%u p%u\n", + msg, + NIPQUAD(sk->daddr), ntohs(sk->dport), + tp->snd_cwnd, tp->left_out, + tp->snd_ssthresh, tp->prior_ssthresh, tp->packets_out); +#endif +} +#else +#define DBGUNDO(x...) do { } while (0) +#endif + +static void tcp_undo_cwr(struct tcp_opt *tp, int undo) +{ +#if 0 + if (tp->prior_ssthresh) { + tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); + + if (undo && tp->prior_ssthresh > tp->snd_ssthresh) { + tp->snd_ssthresh = tp->prior_ssthresh; + TCP_ECN_withdraw_cwr(tp); + } + } else { + tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh); + } + tcp_moderate_cwnd(tp); + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +static inline int tcp_may_undo(struct tcp_opt *tp) +{ +#if 0 + return tp->undo_marker && + (!tp->undo_retrans || tcp_packet_delayed(tp)); +#else + return 0; +#endif +} + +/* People celebrate: "We love our President!" */ +static int tcp_try_undo_recovery(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (tcp_may_undo(tp)) { + /* Happy end! We did not retransmit anything + * or our original transmission succeeded. + */ + DBGUNDO(sk, tp, tp->ca_state == TCP_CA_Loss ? "loss" : "retrans"); + tcp_undo_cwr(tp, 1); + if (tp->ca_state == TCP_CA_Loss) + NET_INC_STATS_BH(TCPLossUndo); + else + NET_INC_STATS_BH(TCPFullUndo); + tp->undo_marker = 0; + } + if (tp->snd_una == tp->high_seq && IsReno(tp)) { + /* Hold old state until something *above* high_seq + * is ACKed. For Reno it is MUST to prevent false + * fast retransmits (RFC2582). SACK TCP is safe. */ + tcp_moderate_cwnd(tp); + return 1; + } + tp->ca_state = TCP_CA_Open; + return 0; +#else + return 0; +#endif +} + +/* Try to undo cwnd reduction, because D-SACKs acked all retransmitted data */ +static void tcp_try_undo_dsack(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (tp->undo_marker && !tp->undo_retrans) { + DBGUNDO(sk, tp, "D-SACK"); + tcp_undo_cwr(tp, 1); + tp->undo_marker = 0; + NET_INC_STATS_BH(TCPDSACKUndo); + } +#endif +} + +/* Undo during fast recovery after partial ACK. */ + +static int tcp_try_undo_partial(struct sock *sk, struct tcp_opt *tp, int acked) +{ +#if 0 + /* Partial ACK arrived. Force Hoe's retransmit. */ + int failed = IsReno(tp) || tp->fackets_out>tp->reordering; + + if (tcp_may_undo(tp)) { + /* Plain luck! Hole if filled with delayed + * packet, rather than with a retransmit. + */ + if (tp->retrans_out == 0) + tp->retrans_stamp = 0; + + tcp_update_reordering(tp, tcp_fackets_out(tp)+acked, 1); + + DBGUNDO(sk, tp, "Hoe"); + tcp_undo_cwr(tp, 0); + NET_INC_STATS_BH(TCPPartialUndo); + + /* So... Do not make Hoe's retransmit yet. + * If the first packet was delayed, the rest + * ones are most probably delayed as well. + */ + failed = 0; + } + return failed; +#else + return 0; +#endif +} + +/* Undo during loss recovery after partial ACK. */ +static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (tcp_may_undo(tp)) { + struct sk_buff *skb; + for_retrans_queue(skb, sk, tp) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; + } + DBGUNDO(sk, tp, "partial loss"); + tp->lost_out = 0; + tp->left_out = tp->sacked_out; + tcp_undo_cwr(tp, 1); + NET_INC_STATS_BH(TCPLossUndo); + tp->retransmits = 0; + tp->undo_marker = 0; + if (!IsReno(tp)) + tp->ca_state = TCP_CA_Open; + return 1; + } + return 0; +#else + return 0; +#endif +} + +static __inline__ void tcp_complete_cwr(struct tcp_opt *tp) +{ +#if 0 + tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +static void tcp_try_to_open(struct sock *sk, struct tcp_opt *tp, int flag) +{ +#if 0 + tp->left_out = tp->sacked_out; + + if (tp->retrans_out == 0) + tp->retrans_stamp = 0; + + if (flag&FLAG_ECE) + tcp_enter_cwr(tp); + + if (tp->ca_state != TCP_CA_CWR) { + int state = TCP_CA_Open; + + if (tp->left_out || + tp->retrans_out || + tp->undo_marker) + state = TCP_CA_Disorder; + + if (tp->ca_state != state) { + tp->ca_state = state; + tp->high_seq = tp->snd_nxt; + } + tcp_moderate_cwnd(tp); + } else { + tcp_cwnd_down(tp); + } +#endif +} + +/* Process an event, which can update packets-in-flight not trivially. + * Main goal of this function is to calculate new estimate for left_out, + * taking into account both packets sitting in receiver's buffer and + * packets lost by network. + * + * Besides that it does CWND reduction, when packet loss is detected + * and changes state of machine. + * + * It does _not_ decide what to send, it is made in function + * tcp_xmit_retransmit_queue(). + */ +static void +tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una, + int prior_packets, int flag) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int is_dupack = (tp->snd_una == prior_snd_una && !(flag&FLAG_NOT_DUP)); + + /* Some technical things: + * 1. Reno does not count dupacks (sacked_out) automatically. */ + if (!tp->packets_out) + tp->sacked_out = 0; + /* 2. SACK counts snd_fack in packets inaccurately. */ + if (tp->sacked_out == 0) + tp->fackets_out = 0; + + /* Now state machine starts. + * A. ECE, hence prohibit cwnd undoing, the reduction is required. */ + if (flag&FLAG_ECE) + tp->prior_ssthresh = 0; + + /* B. In all the states check for reneging SACKs. */ + if (tp->sacked_out && tcp_check_sack_reneging(sk, tp)) + return; + + /* C. Process data loss notification, provided it is valid. */ + if ((flag&FLAG_DATA_LOST) && + before(tp->snd_una, tp->high_seq) && + tp->ca_state != TCP_CA_Open && + tp->fackets_out > tp->reordering) { + tcp_mark_head_lost(sk, tp, tp->fackets_out-tp->reordering, tp->high_seq); + NET_INC_STATS_BH(TCPLoss); + } + + /* D. Synchronize left_out to current state. */ + tcp_sync_left_out(tp); + + /* E. Check state exit conditions. State can be terminated + * when high_seq is ACKed. */ + if (tp->ca_state == TCP_CA_Open) { + BUG_TRAP(tp->retrans_out == 0); + tp->retrans_stamp = 0; + } else if (!before(tp->snd_una, tp->high_seq)) { + switch (tp->ca_state) { + case TCP_CA_Loss: + tp->retransmits = 0; + if (tcp_try_undo_recovery(sk, tp)) + return; + break; + + case TCP_CA_CWR: + /* CWR is to be held something *above* high_seq + * is ACKed for CWR bit to reach receiver. */ + if (tp->snd_una != tp->high_seq) { + tcp_complete_cwr(tp); + tp->ca_state = TCP_CA_Open; + } + break; + + case TCP_CA_Disorder: + tcp_try_undo_dsack(sk, tp); + if (!tp->undo_marker || + /* For SACK case do not Open to allow to undo + * catching for all duplicate ACKs. */ + IsReno(tp) || tp->snd_una != tp->high_seq) { + tp->undo_marker = 0; + tp->ca_state = TCP_CA_Open; + } + break; + + case TCP_CA_Recovery: + if (IsReno(tp)) + tcp_reset_reno_sack(tp); + if (tcp_try_undo_recovery(sk, tp)) + return; + tcp_complete_cwr(tp); + break; + } + } + + /* F. Process state. */ + switch (tp->ca_state) { + case TCP_CA_Recovery: + if (prior_snd_una == tp->snd_una) { + if (IsReno(tp) && is_dupack) + tcp_add_reno_sack(tp); + } else { + int acked = prior_packets - tp->packets_out; + if (IsReno(tp)) + tcp_remove_reno_sacks(sk, tp, acked); + is_dupack = tcp_try_undo_partial(sk, tp, acked); + } + break; + case TCP_CA_Loss: + if (flag&FLAG_DATA_ACKED) + tp->retransmits = 0; + if (!tcp_try_undo_loss(sk, tp)) { + tcp_moderate_cwnd(tp); + tcp_xmit_retransmit_queue(sk); + return; + } + if (tp->ca_state != TCP_CA_Open) + return; + /* Loss is undone; fall through to processing in Open state. */ + default: + if (IsReno(tp)) { + if (tp->snd_una != prior_snd_una) + tcp_reset_reno_sack(tp); + if (is_dupack) + tcp_add_reno_sack(tp); + } + + if (tp->ca_state == TCP_CA_Disorder) + tcp_try_undo_dsack(sk, tp); + + if (!tcp_time_to_recover(sk, tp)) { + tcp_try_to_open(sk, tp, flag); + return; + } + + /* Otherwise enter Recovery state */ + + if (IsReno(tp)) + NET_INC_STATS_BH(TCPRenoRecovery); + else + NET_INC_STATS_BH(TCPSackRecovery); + + tp->high_seq = tp->snd_nxt; + tp->prior_ssthresh = 0; + tp->undo_marker = tp->snd_una; + tp->undo_retrans = tp->retrans_out; + + if (tp->ca_state < TCP_CA_CWR) { + if (!(flag&FLAG_ECE)) + tp->prior_ssthresh = tcp_current_ssthresh(tp); + tp->snd_ssthresh = tcp_recalc_ssthresh(tp); + TCP_ECN_queue_cwr(tp); + } + + tp->snd_cwnd_cnt = 0; + tp->ca_state = TCP_CA_Recovery; + } + + if (is_dupack || tcp_head_timedout(sk, tp)) + tcp_update_scoreboard(sk, tp); + tcp_cwnd_down(tp); + tcp_xmit_retransmit_queue(sk); +#endif +} + +/* Read draft-ietf-tcplw-high-performance before mucking + * with this code. (Superceeds RFC1323) + */ +static void tcp_ack_saw_tstamp(struct tcp_opt *tp, int flag) +{ +#if 0 + __u32 seq_rtt; + + /* RTTM Rule: A TSecr value received in a segment is used to + * update the averaged RTT measurement only if the segment + * acknowledges some new data, i.e., only if it advances the + * left edge of the send window. + * + * See draft-ietf-tcplw-high-performance-00, section 3.3. + * 1998/04/10 Andrey V. Savochkin + * + * Changed: reset backoff as soon as we see the first valid sample. + * If we do not, we get strongly overstimated rto. With timestamps + * samples are accepted even from very old segments: f.e., when rtt=1 + * increases to 8, we retransmit 5 times and after 8 seconds delayed + * answer arrives rto becomes 120 seconds! If at least one of segments + * in window is lost... Voila. --ANK (010210) + */ + seq_rtt = tcp_time_stamp - tp->rcv_tsecr; + tcp_rtt_estimator(tp, seq_rtt); + tcp_set_rto(tp); + tp->backoff = 0; + tcp_bound_rto(tp); +#endif +} + +static void tcp_ack_no_tstamp(struct tcp_opt *tp, u32 seq_rtt, int flag) +{ +#if 0 + /* We don't have a timestamp. Can only use + * packets that are not retransmitted to determine + * rtt estimates. Also, we must not reset the + * backoff for rto until we get a non-retransmitted + * packet. This allows us to deal with a situation + * where the network delay has increased suddenly. + * I.e. Karn's algorithm. (SIGCOMM '87, p5.) + */ + + if (flag & FLAG_RETRANS_DATA_ACKED) + return; + + tcp_rtt_estimator(tp, seq_rtt); + tcp_set_rto(tp); + tp->backoff = 0; + tcp_bound_rto(tp); +#endif +} + +static __inline__ void +tcp_ack_update_rtt(struct tcp_opt *tp, int flag, s32 seq_rtt) +{ +#if 0 + /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */ + if (tp->saw_tstamp && tp->rcv_tsecr) + tcp_ack_saw_tstamp(tp, flag); + else if (seq_rtt >= 0) + tcp_ack_no_tstamp(tp, seq_rtt, flag); +#endif +} + +/* This is Jacobson's slow start and congestion avoidance. + * SIGCOMM '88, p. 328. + */ +static __inline__ void tcp_cong_avoid(struct tcp_opt *tp) +{ +#if 0 + if (tp->snd_cwnd <= tp->snd_ssthresh) { + /* In "safe" area, increase. */ + if (tp->snd_cwnd < tp->snd_cwnd_clamp) + tp->snd_cwnd++; + } else { + /* In dangerous area, increase slowly. + * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd + */ + if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { + if (tp->snd_cwnd < tp->snd_cwnd_clamp) + tp->snd_cwnd++; + tp->snd_cwnd_cnt=0; + } else + tp->snd_cwnd_cnt++; + } + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + +/* Restart timer after forward progress on connection. + * RFC2988 recommends to restart timer to now+rto. + */ + +static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + if (tp->packets_out==0) { + tcp_clear_xmit_timer(sk, TCP_TIME_RETRANS); + } else { + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + } +#endif +} + +/* Remove acknowledged frames from the retransmission queue. */ +static int tcp_clean_rtx_queue(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + __u32 now = tcp_time_stamp; + int acked = 0; + __s32 seq_rtt = -1; + + while((skb=skb_peek(&sk->write_queue)) && (skb != tp->send_head)) { + struct tcp_skb_cb *scb = TCP_SKB_CB(skb); + __u8 sacked = scb->sacked; + + /* If our packet is before the ack sequence we can + * discard it as it's confirmed to have arrived at + * the other end. + */ + if (after(scb->end_seq, tp->snd_una)) + break; + + /* Initial outgoing SYN's get put onto the write_queue + * just like anything else we transmit. It is not + * true data, and if we misinform our callers that + * this ACK acks real data, we will erroneously exit + * connection startup slow start one packet too + * quickly. This is severely frowned upon behavior. + */ + if(!(scb->flags & TCPCB_FLAG_SYN)) { + acked |= FLAG_DATA_ACKED; + } else { + acked |= FLAG_SYN_ACKED; + tp->retrans_stamp = 0; + } + + if (sacked) { + if(sacked & TCPCB_RETRANS) { + if(sacked & TCPCB_SACKED_RETRANS) + tp->retrans_out--; + acked |= FLAG_RETRANS_DATA_ACKED; + seq_rtt = -1; + } else if (seq_rtt < 0) + seq_rtt = now - scb->when; + if(sacked & TCPCB_SACKED_ACKED) + tp->sacked_out--; + if(sacked & TCPCB_LOST) + tp->lost_out--; + if(sacked & TCPCB_URG) { + if (tp->urg_mode && + !before(scb->end_seq, tp->snd_up)) + tp->urg_mode = 0; + } + } else if (seq_rtt < 0) + seq_rtt = now - scb->when; + if(tp->fackets_out) + tp->fackets_out--; + tp->packets_out--; + __skb_unlink(skb, skb->list); + tcp_free_skb(sk, skb); + } + + if (acked&FLAG_ACKED) { + tcp_ack_update_rtt(tp, acked, seq_rtt); + tcp_ack_packets_out(sk, tp); + } + +#if FASTRETRANS_DEBUG > 0 + BUG_TRAP((int)tp->sacked_out >= 0); + BUG_TRAP((int)tp->lost_out >= 0); + BUG_TRAP((int)tp->retrans_out >= 0); + if (tp->packets_out==0 && tp->sack_ok) { + if (tp->lost_out) { + printk(KERN_DEBUG "Leak l=%u %d\n", tp->lost_out, tp->ca_state); + tp->lost_out = 0; + } + if (tp->sacked_out) { + printk(KERN_DEBUG "Leak s=%u %d\n", tp->sacked_out, tp->ca_state); + tp->sacked_out = 0; + } + if (tp->retrans_out) { + printk(KERN_DEBUG "Leak r=%u %d\n", tp->retrans_out, tp->ca_state); + tp->retrans_out = 0; + } + } +#endif + return acked; +#else + return 0; +#endif +} + +static void tcp_ack_probe(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* Was it a usable window open? */ + + if (!after(TCP_SKB_CB(tp->send_head)->end_seq, tp->snd_una + tp->snd_wnd)) { + tp->backoff = 0; + tcp_clear_xmit_timer(sk, TCP_TIME_PROBE0); + /* Socket must be waked up by subsequent tcp_data_snd_check(). + * This function is not for random using! + */ + } else { + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RTO_MAX)); + } +#endif +} + +static __inline__ int tcp_ack_is_dubious(struct tcp_opt *tp, int flag) +{ +#if 0 + return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || + tp->ca_state != TCP_CA_Open); +#else + return 0; +#endif +} + +static __inline__ int tcp_may_raise_cwnd(struct tcp_opt *tp, int flag) +{ +#if 0 + return (!(flag & FLAG_ECE) || tp->snd_cwnd < tp->snd_ssthresh) && + !((1<ca_state)&(TCPF_CA_Recovery|TCPF_CA_CWR)); +#else + return 0; +#endif +} + +/* Check that window update is acceptable. + * The function assumes that snd_una<=ack<=snd_next. + */ +static __inline__ int +tcp_may_update_window(struct tcp_opt *tp, u32 ack, u32 ack_seq, u32 nwin) +{ +#if 0 + return (after(ack, tp->snd_una) || + after(ack_seq, tp->snd_wl1) || + (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); +#else + return 0; +#endif +} + +/* Update our send window. + * + * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2 + * and in FreeBSD. NetBSD's one is even worse.) is wrong. + */ +static int tcp_ack_update_window(struct sock *sk, struct tcp_opt *tp, + struct sk_buff *skb, u32 ack, u32 ack_seq) +{ +#if 0 + int flag = 0; + u32 nwin = ntohs(skb->h.th->window) << tp->snd_wscale; + + if (tcp_may_update_window(tp, ack, ack_seq, nwin)) { + flag |= FLAG_WIN_UPDATE; + tcp_update_wl(tp, ack, ack_seq); + + if (tp->snd_wnd != nwin) { + tp->snd_wnd = nwin; + + /* Note, it is the only place, where + * fast path is recovered for sending TCP. + */ + tcp_fast_path_check(sk, tp); + + if (nwin > tp->max_window) { + tp->max_window = nwin; + tcp_sync_mss(sk, tp->pmtu_cookie); + } + } + } + + tp->snd_una = ack; + + return flag; +#else + return 0; +#endif +} + +/* This routine deals with incoming acks, but not outgoing ones. */ +static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + u32 prior_snd_una = tp->snd_una; + u32 ack_seq = TCP_SKB_CB(skb)->seq; + u32 ack = TCP_SKB_CB(skb)->ack_seq; + u32 prior_in_flight; + int prior_packets; + + /* If the ack is newer than sent or older than previous acks + * then we can probably ignore it. + */ + if (after(ack, tp->snd_nxt)) + goto uninteresting_ack; + + if (before(ack, prior_snd_una)) + goto old_ack; + + if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { + /* Window is constant, pure forward advance. + * No more checks are required. + * Note, we use the fact that SND.UNA>=SND.WL2. + */ + tcp_update_wl(tp, ack, ack_seq); + tp->snd_una = ack; + flag |= FLAG_WIN_UPDATE; + + NET_INC_STATS_BH(TCPHPAcks); + } else { + if (ack_seq != TCP_SKB_CB(skb)->end_seq) + flag |= FLAG_DATA; + else + NET_INC_STATS_BH(TCPPureAcks); + + flag |= tcp_ack_update_window(sk, tp, skb, ack, ack_seq); + + if (TCP_SKB_CB(skb)->sacked) + flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); + + if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th)) + flag |= FLAG_ECE; + } + + /* We passed data and got it acked, remove any soft error + * log. Something worked... + */ + sk->err_soft = 0; + tp->rcv_tstamp = tcp_time_stamp; + if ((prior_packets = tp->packets_out) == 0) + goto no_queue; + + prior_in_flight = tcp_packets_in_flight(tp); + + /* See if we can take anything off of the retransmit queue. */ + flag |= tcp_clean_rtx_queue(sk); + + if (tcp_ack_is_dubious(tp, flag)) { + /* Advanve CWND, if state allows this. */ + if ((flag&FLAG_DATA_ACKED) && prior_in_flight >= tp->snd_cwnd && + tcp_may_raise_cwnd(tp, flag)) + tcp_cong_avoid(tp); + tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag); + } else { + if ((flag&FLAG_DATA_ACKED) && prior_in_flight >= tp->snd_cwnd) + tcp_cong_avoid(tp); + } + + if ((flag & FLAG_FORWARD_PROGRESS) || !(flag&FLAG_NOT_DUP)) + dst_confirm(sk->dst_cache); + + return 1; + +no_queue: + tp->probes_out = 0; + + /* If this ack opens up a zero window, clear backoff. It was + * being used to time the probes, and is probably far higher than + * it needs to be for normal retransmission. + */ + if (tp->send_head) + tcp_ack_probe(sk); + return 1; + +old_ack: + if (TCP_SKB_CB(skb)->sacked) + tcp_sacktag_write_queue(sk, skb, prior_snd_una); + +uninteresting_ack: + SOCK_DEBUG(sk, "Ack %u out of %u:%u\n", ack, tp->snd_una, tp->snd_nxt); + return 0; +#else + return 0; +#endif +} + + +/* Look for tcp options. Normally only called on SYN and SYNACK packets. + * But, this can also be called on packets in the established flow when + * the fast version below fails. + */ +void tcp_parse_options(struct sk_buff *skb, struct tcp_opt *tp, int estab) +{ +#if 0 + unsigned char *ptr; + struct tcphdr *th = skb->h.th; + int length=(th->doff*4)-sizeof(struct tcphdr); + + ptr = (unsigned char *)(th + 1); + tp->saw_tstamp = 0; + + while(length>0) { + int opcode=*ptr++; + int opsize; + + switch (opcode) { + case TCPOPT_EOL: + return; + case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ + length--; + continue; + default: + opsize=*ptr++; + if (opsize < 2) /* "silly options" */ + return; + if (opsize > length) + return; /* don't parse partial options */ + switch(opcode) { + case TCPOPT_MSS: + if(opsize==TCPOLEN_MSS && th->syn && !estab) { + u16 in_mss = ntohs(*(__u16 *)ptr); + if (in_mss) { + if (tp->user_mss && tp->user_mss < in_mss) + in_mss = tp->user_mss; + tp->mss_clamp = in_mss; + } + } + break; + case TCPOPT_WINDOW: + if(opsize==TCPOLEN_WINDOW && th->syn && !estab) + if (sysctl_tcp_window_scaling) { + tp->wscale_ok = 1; + tp->snd_wscale = *(__u8 *)ptr; + if(tp->snd_wscale > 14) { + if(net_ratelimit()) + printk("tcp_parse_options: Illegal window " + "scaling value %d >14 received.", + tp->snd_wscale); + tp->snd_wscale = 14; + } + } + break; + case TCPOPT_TIMESTAMP: + if(opsize==TCPOLEN_TIMESTAMP) { + if ((estab && tp->tstamp_ok) || + (!estab && sysctl_tcp_timestamps)) { + tp->saw_tstamp = 1; + tp->rcv_tsval = ntohl(*(__u32 *)ptr); + tp->rcv_tsecr = ntohl(*(__u32 *)(ptr+4)); + } + } + break; + case TCPOPT_SACK_PERM: + if(opsize==TCPOLEN_SACK_PERM && th->syn && !estab) { + if (sysctl_tcp_sack) { + tp->sack_ok = 1; + tcp_sack_reset(tp); + } + } + break; + + case TCPOPT_SACK: + if((opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK)) && + !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK) && + tp->sack_ok) { + TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th; + } + }; + ptr+=opsize-2; + length-=opsize; + }; + } +#endif +} + +/* Fast parse options. This hopes to only see timestamps. + * If it is wrong it falls back on tcp_parse_options(). + */ +static __inline__ int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, struct tcp_opt *tp) +{ +#if 0 + if (th->doff == sizeof(struct tcphdr)>>2) { + tp->saw_tstamp = 0; + return 0; + } else if (tp->tstamp_ok && + th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) { + __u32 *ptr = (__u32 *)(th + 1); + if (*ptr == ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { + tp->saw_tstamp = 1; + ++ptr; + tp->rcv_tsval = ntohl(*ptr); + ++ptr; + tp->rcv_tsecr = ntohl(*ptr); + return 1; + } + } + tcp_parse_options(skb, tp, 1); + return 1; +#else + return 0; +#endif +} + +extern __inline__ void +tcp_store_ts_recent(struct tcp_opt *tp) +{ +#if 0 + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = xtime.tv_sec; +#endif +} + +extern __inline__ void +tcp_replace_ts_recent(struct tcp_opt *tp, u32 seq) +{ +#if 0 + if (tp->saw_tstamp && !after(seq, tp->rcv_wup)) { + /* PAWS bug workaround wrt. ACK frames, the PAWS discard + * extra check below makes sure this can only happen + * for pure ACK frames. -DaveM + * + * Not only, also it occurs for expired timestamps. + */ + + if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0 || + xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) + tcp_store_ts_recent(tp); + } +#endif +} + +/* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM + * + * It is not fatal. If this ACK does _not_ change critical state (seqs, window) + * it can pass through stack. So, the following predicate verifies that + * this segment is not used for anything but congestion avoidance or + * fast retransmit. Moreover, we even are able to eliminate most of such + * second order effects, if we apply some small "replay" window (~RTO) + * to timestamp space. + * + * All these measures still do not guarantee that we reject wrapped ACKs + * on networks with high bandwidth, when sequence space is recycled fastly, + * but it guarantees that such events will be very rare and do not affect + * connection seriously. This doesn't look nice, but alas, PAWS is really + * buggy extension. + * + * [ Later note. Even worse! It is buggy for segments _with_ data. RFC + * states that events when retransmit arrives after original data are rare. + * It is a blatant lie. VJ forgot about fast retransmit! 8)8) It is + * the biggest problem on large power networks even with minor reordering. + * OK, let's give it small replay window. If peer clock is even 1hz, it is safe + * up to bandwidth of 18Gigabit/sec. 8) ] + */ + +static int tcp_disordered_ack(struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + struct tcphdr *th = skb->h.th; + u32 seq = TCP_SKB_CB(skb)->seq; + u32 ack = TCP_SKB_CB(skb)->ack_seq; + + return (/* 1. Pure ACK with correct sequence number. */ + (th->ack && seq == TCP_SKB_CB(skb)->end_seq && seq == tp->rcv_nxt) && + + /* 2. ... and duplicate ACK. */ + ack == tp->snd_una && + + /* 3. ... and does not update window. */ + !tcp_may_update_window(tp, ack, seq, ntohs(th->window)<snd_wscale) && + + /* 4. ... and sits in replay window. */ + (s32)(tp->ts_recent - tp->rcv_tsval) <= (tp->rto*1024)/HZ); +#endif +} + +extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + return ((s32)(tp->ts_recent - tp->rcv_tsval) > TCP_PAWS_WINDOW && + xtime.tv_sec < tp->ts_recent_stamp + TCP_PAWS_24DAYS && + !tcp_disordered_ack(tp, skb)); +#else + return 0; +#endif +} + +/* Check segment sequence number for validity. + * + * Segment controls are considered valid, if the segment + * fits to the window after truncation to the window. Acceptability + * of data (and SYN, FIN, of course) is checked separately. + * See tcp_data_queue(), for example. + * + * Also, controls (RST is main one) are accepted using RCV.WUP instead + * of RCV.NXT. Peer still did not advance his SND.UNA when we + * delayed ACK, so that hisSND.UNA<=ourRCV.WUP. + * (borrowed from freebsd) + */ + +static inline int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) +{ +#if 0 + return !before(end_seq, tp->rcv_wup) && + !after(seq, tp->rcv_nxt + tcp_receive_window(tp)); +#else + return 0; +#endif +} + +/* When we get a reset we do this. */ +static void tcp_reset(struct sock *sk) +{ +#if 0 + /* We want the right error as BSD sees it (and indeed as we do). */ + switch (sk->state) { + case TCP_SYN_SENT: + sk->err = ECONNREFUSED; + break; + case TCP_CLOSE_WAIT: + sk->err = EPIPE; + break; + case TCP_CLOSE: + return; + default: + sk->err = ECONNRESET; + } + + if (!sk->dead) + sk->error_report(sk); + + tcp_done(sk); +#endif +} + +/* + * Process the FIN bit. This now behaves as it is supposed to work + * and the FIN takes effect when it is validly part of sequence + * space. Not before when we get holes. + * + * If we are ESTABLISHED, a received fin moves us to CLOSE-WAIT + * (and thence onto LAST-ACK and finally, CLOSE, we never enter + * TIME-WAIT) + * + * If we are in FINWAIT-1, a received FIN indicates simultaneous + * close and we go into CLOSING (and later onto TIME-WAIT) + * + * If we are in FINWAIT-2, a received FIN moves us to TIME-WAIT. + */ +static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tcp_schedule_ack(tp); + + sk->shutdown |= RCV_SHUTDOWN; + sk->done = 1; + + switch(sk->state) { + case TCP_SYN_RECV: + case TCP_ESTABLISHED: + /* Move to CLOSE_WAIT */ + tcp_set_state(sk, TCP_CLOSE_WAIT); + tp->ack.pingpong = 1; + break; + + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + /* Received a retransmission of the FIN, do + * nothing. + */ + break; + case TCP_LAST_ACK: + /* RFC793: Remain in the LAST-ACK state. */ + break; + + case TCP_FIN_WAIT1: + /* This case occurs when a simultaneous close + * happens, we must ack the received FIN and + * enter the CLOSING state. + */ + tcp_send_ack(sk); + tcp_set_state(sk, TCP_CLOSING); + break; + case TCP_FIN_WAIT2: + /* Received a FIN -- send ACK and enter TIME_WAIT. */ + tcp_send_ack(sk); + tcp_time_wait(sk, TCP_TIME_WAIT, 0); + break; + default: + /* Only TCP_LISTEN and TCP_CLOSE are left, in these + * cases we should never reach this piece of code. + */ + printk("tcp_fin: Impossible, sk->state=%d\n", sk->state); + break; + }; + + /* It _is_ possible, that we have something out-of-order _after_ FIN. + * Probably, we should reset in this case. For now drop them. + */ + __skb_queue_purge(&tp->out_of_order_queue); + if (tp->sack_ok) + tcp_sack_reset(tp); + tcp_mem_reclaim(sk); + + if (!sk->dead) { + sk->state_change(sk); + + /* Do not send POLL_HUP for half duplex close. */ + if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE) + sk_wake_async(sk, 1, POLL_HUP); + else + sk_wake_async(sk, 1, POLL_IN); + } +#endif +} + +static __inline__ int +tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) +{ +#if 0 + if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) { + if (before(seq, sp->start_seq)) + sp->start_seq = seq; + if (after(end_seq, sp->end_seq)) + sp->end_seq = end_seq; + return 1; + } + return 0; +#else + return 0; +#endif +} + +static __inline__ void tcp_dsack_set(struct tcp_opt *tp, u32 seq, u32 end_seq) +{ +#if 0 + if (tp->sack_ok && sysctl_tcp_dsack) { + if (before(seq, tp->rcv_nxt)) + NET_INC_STATS_BH(TCPDSACKOldSent); + else + NET_INC_STATS_BH(TCPDSACKOfoSent); + + tp->dsack = 1; + tp->duplicate_sack[0].start_seq = seq; + tp->duplicate_sack[0].end_seq = end_seq; + tp->eff_sacks = min(tp->num_sacks+1, 4-tp->tstamp_ok); + } +#endif +} + +static __inline__ void tcp_dsack_extend(struct tcp_opt *tp, u32 seq, u32 end_seq) +{ +#if 0 + if (!tp->dsack) + tcp_dsack_set(tp, seq, end_seq); + else + tcp_sack_extend(tp->duplicate_sack, seq, end_seq); +#endif +} + +static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && + before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + NET_INC_STATS_BH(DelayedACKLost); + tcp_enter_quickack_mode(tp); + + if (tp->sack_ok && sysctl_tcp_dsack) { + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) + end_seq = tp->rcv_nxt; + tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, end_seq); + } + } + + tcp_send_ack(sk); +#endif +} + +/* These routines update the SACK block as out-of-order packets arrive or + * in-order packets close up the sequence space. + */ +static void tcp_sack_maybe_coalesce(struct tcp_opt *tp) +{ +#if 0 + int this_sack; + struct tcp_sack_block *sp = &tp->selective_acks[0]; + struct tcp_sack_block *swalk = sp+1; + + /* See if the recent change to the first SACK eats into + * or hits the sequence space of other SACK blocks, if so coalesce. + */ + for (this_sack = 1; this_sack < tp->num_sacks; ) { + if (tcp_sack_extend(sp, swalk->start_seq, swalk->end_seq)) { + int i; + + /* Zap SWALK, by moving every further SACK up by one slot. + * Decrease num_sacks. + */ + tp->num_sacks--; + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); + for(i=this_sack; i < tp->num_sacks; i++) + sp[i] = sp[i+1]; + continue; + } + this_sack++, swalk++; + } +#endif +} + +static __inline__ void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2) +{ +#if 0 + __u32 tmp; + + tmp = sack1->start_seq; + sack1->start_seq = sack2->start_seq; + sack2->start_seq = tmp; + + tmp = sack1->end_seq; + sack1->end_seq = sack2->end_seq; + sack2->end_seq = tmp; +#endif +} + +static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_sack_block *sp = &tp->selective_acks[0]; + int cur_sacks = tp->num_sacks; + int this_sack; + + if (!cur_sacks) + goto new_sack; + + for (this_sack=0; this_sack0; this_sack--, sp--) + tcp_sack_swap(sp, sp-1); + if (cur_sacks > 1) + tcp_sack_maybe_coalesce(tp); + return; + } + } + + /* Could not find an adjacent existing SACK, build a new one, + * put it at the front, and shift everyone else down. We + * always know there is at least one SACK present already here. + * + * If the sack array is full, forget about the last one. + */ + if (this_sack >= 4) { + this_sack--; + tp->num_sacks--; + sp--; + } + for(; this_sack > 0; this_sack--, sp--) + *sp = *(sp-1); + +new_sack: + /* Build the new head SACK, and we're done. */ + sp->start_seq = seq; + sp->end_seq = end_seq; + tp->num_sacks++; + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); +#endif +} + +/* RCV.NXT advances, some SACKs should be eaten. */ + +static void tcp_sack_remove(struct tcp_opt *tp) +{ +#if 0 + struct tcp_sack_block *sp = &tp->selective_acks[0]; + int num_sacks = tp->num_sacks; + int this_sack; + + /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */ + if (skb_queue_len(&tp->out_of_order_queue) == 0) { + tp->num_sacks = 0; + tp->eff_sacks = tp->dsack; + return; + } + + for(this_sack = 0; this_sack < num_sacks; ) { + /* Check if the start of the sack is covered by RCV.NXT. */ + if (!before(tp->rcv_nxt, sp->start_seq)) { + int i; + + /* RCV.NXT must cover all the block! */ + BUG_TRAP(!before(tp->rcv_nxt, sp->end_seq)); + + /* Zap this SACK, by moving forward any other SACKS. */ + for (i=this_sack+1; i < num_sacks; i++) + tp->selective_acks[i-1] = tp->selective_acks[i]; + num_sacks--; + continue; + } + this_sack++; + sp++; + } + if (num_sacks != tp->num_sacks) { + tp->num_sacks = num_sacks; + tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok); + } +#endif +} + +/* This one checks to see if we can put data from the + * out_of_order queue into the receive_queue. + */ +static void tcp_ofo_queue(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + __u32 dsack_high = tp->rcv_nxt; + struct sk_buff *skb; + + while ((skb = skb_peek(&tp->out_of_order_queue)) != NULL) { + if (after(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) + break; + + if (before(TCP_SKB_CB(skb)->seq, dsack_high)) { + __u32 dsack = dsack_high; + if (before(TCP_SKB_CB(skb)->end_seq, dsack_high)) + dsack_high = TCP_SKB_CB(skb)->end_seq; + tcp_dsack_extend(tp, TCP_SKB_CB(skb)->seq, dsack); + } + + if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { + SOCK_DEBUG(sk, "ofo packet was already received \n"); + __skb_unlink(skb, skb->list); + __kfree_skb(skb); + continue; + } + SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n", + tp->rcv_nxt, TCP_SKB_CB(skb)->seq, + TCP_SKB_CB(skb)->end_seq); + + __skb_unlink(skb, skb->list); + __skb_queue_tail(&sk->receive_queue, skb); + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + if(skb->h.th->fin) + tcp_fin(skb, sk, skb->h.th); + } +#endif +} + +static inline int tcp_rmem_schedule(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + return (int)skb->truesize <= sk->forward_alloc || + tcp_mem_schedule(sk, skb->truesize, 1); +#else + return 0; +#endif +} + +static int tcp_prune_queue(struct sock *sk); + +static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcphdr *th = skb->h.th; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int eaten = -1; + + if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) + goto drop; + + th = skb->h.th; + __skb_pull(skb, th->doff*4); + + TCP_ECN_accept_cwr(tp, skb); + + if (tp->dsack) { + tp->dsack = 0; + tp->eff_sacks = min_t(unsigned int, tp->num_sacks, 4-tp->tstamp_ok); + } + + /* Queue data for delivery to the user. + * Packets in sequence go to the receive queue. + * Out of sequence packets to the out_of_order_queue. + */ + if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { + if (tcp_receive_window(tp) == 0) + goto out_of_window; + + /* Ok. In sequence. In window. */ + if (tp->ucopy.task == current && + tp->copied_seq == tp->rcv_nxt && + tp->ucopy.len && + sk->lock.users && + !tp->urg_data) { + int chunk = min_t(unsigned int, skb->len, tp->ucopy.len); + + __set_current_state(TASK_RUNNING); + + local_bh_enable(); + if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { + tp->ucopy.len -= chunk; + tp->copied_seq += chunk; + eaten = (chunk == skb->len && !th->fin); + } + local_bh_disable(); + } + + if (eaten <= 0) { +queue_and_out: + if (eaten < 0 && + (atomic_read(&sk->rmem_alloc) > sk->rcvbuf || + !tcp_rmem_schedule(sk, skb))) { + if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + goto drop; + } + tcp_set_owner_r(skb, sk); + __skb_queue_tail(&sk->receive_queue, skb); + } + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + if(skb->len) + tcp_event_data_recv(sk, tp, skb); + if(th->fin) + tcp_fin(skb, sk, th); + + if (skb_queue_len(&tp->out_of_order_queue)) { + tcp_ofo_queue(sk); + + /* RFC2581. 4.2. SHOULD send immediate ACK, when + * gap in queue is filled. + */ + if (skb_queue_len(&tp->out_of_order_queue) == 0) + tp->ack.pingpong = 0; + } + + if(tp->num_sacks) + tcp_sack_remove(tp); + + tcp_fast_path_check(sk, tp); + + if (eaten > 0) { + __kfree_skb(skb); + } else if (!sk->dead) + sk->data_ready(sk, 0); + return; + } + + if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { + /* A retransmit, 2nd most common case. Force an immediate ack. */ + NET_INC_STATS_BH(DelayedACKLost); + tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + +out_of_window: + tcp_enter_quickack_mode(tp); + tcp_schedule_ack(tp); +drop: + __kfree_skb(skb); + return; + } + + /* Out of window. F.e. zero window probe. */ + if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt+tcp_receive_window(tp))) + goto out_of_window; + + tcp_enter_quickack_mode(tp); + + if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + /* Partial packet, seq < rcv_next < end_seq */ + SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n", + tp->rcv_nxt, TCP_SKB_CB(skb)->seq, + TCP_SKB_CB(skb)->end_seq); + + tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, tp->rcv_nxt); + + /* If window is closed, drop tail of packet. But after + * remembering D-SACK for its head made in previous line. + */ + if (!tcp_receive_window(tp)) + goto out_of_window; + goto queue_and_out; + } + + TCP_ECN_check_ce(tp, skb); + + if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf || + !tcp_rmem_schedule(sk, skb)) { + if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + goto drop; + } + + /* Disable header prediction. */ + tp->pred_flags = 0; + tcp_schedule_ack(tp); + + SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", + tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + + tcp_set_owner_r(skb, sk); + + if (skb_peek(&tp->out_of_order_queue) == NULL) { + /* Initial out of order segment, build 1 SACK. */ + if(tp->sack_ok) { + tp->num_sacks = 1; + tp->dsack = 0; + tp->eff_sacks = 1; + tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq; + tp->selective_acks[0].end_seq = TCP_SKB_CB(skb)->end_seq; + } + __skb_queue_head(&tp->out_of_order_queue,skb); + } else { + struct sk_buff *skb1=tp->out_of_order_queue.prev; + u32 seq = TCP_SKB_CB(skb)->seq; + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + if (seq == TCP_SKB_CB(skb1)->end_seq) { + __skb_append(skb1, skb); + + if (tp->num_sacks == 0 || + tp->selective_acks[0].end_seq != seq) + goto add_sack; + + /* Common case: data arrive in order after hole. */ + tp->selective_acks[0].end_seq = end_seq; + return; + } + + /* Find place to insert this segment. */ + do { + if (!after(TCP_SKB_CB(skb1)->seq, seq)) + break; + } while ((skb1=skb1->prev) != (struct sk_buff*)&tp->out_of_order_queue); + + /* Do skb overlap to previous one? */ + if (skb1 != (struct sk_buff*)&tp->out_of_order_queue && + before(seq, TCP_SKB_CB(skb1)->end_seq)) { + if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { + /* All the bits are present. Drop. */ + __kfree_skb(skb); + tcp_dsack_set(tp, seq, end_seq); + goto add_sack; + } + if (after(seq, TCP_SKB_CB(skb1)->seq)) { + /* Partial overlap. */ + tcp_dsack_set(tp, seq, TCP_SKB_CB(skb1)->end_seq); + } else { + skb1 = skb1->prev; + } + } + __skb_insert(skb, skb1, skb1->next, &tp->out_of_order_queue); + + /* And clean segments covered by new one as whole. */ + while ((skb1 = skb->next) != (struct sk_buff*)&tp->out_of_order_queue && + after(end_seq, TCP_SKB_CB(skb1)->seq)) { + if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { + tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, end_seq); + break; + } + __skb_unlink(skb1, skb1->list); + tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq); + __kfree_skb(skb1); + } + +add_sack: + if (tp->sack_ok) + tcp_sack_new_ofo_skb(sk, seq, end_seq); + } +#endif +} + +/* Collapse contiguous sequence of skbs head..tail with + * sequence numbers start..end. + * Segments with FIN/SYN are not collapsed (only because this + * simplifies code) + */ +static void +tcp_collapse(struct sock *sk, struct sk_buff *head, + struct sk_buff *tail, u32 start, u32 end) +{ +#if 0 + struct sk_buff *skb; + + /* First, check that queue is collapsable and find + * the point where collapsing can be useful. */ + for (skb = head; skb != tail; ) { + /* No new bits? It is possible on ofo queue. */ + if (!before(start, TCP_SKB_CB(skb)->end_seq)) { + struct sk_buff *next = skb->next; + __skb_unlink(skb, skb->list); + __kfree_skb(skb); + NET_INC_STATS_BH(TCPRcvCollapsed); + skb = next; + continue; + } + + /* The first skb to collapse is: + * - not SYN/FIN and + * - bloated or contains data before "start" or + * overlaps to the next one. + */ + if (!skb->h.th->syn && !skb->h.th->fin && + (tcp_win_from_space(skb->truesize) > skb->len || + before(TCP_SKB_CB(skb)->seq, start) || + (skb->next != tail && + TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq))) + break; + + /* Decided to skip this, advance start seq. */ + start = TCP_SKB_CB(skb)->end_seq; + skb = skb->next; + } + if (skb == tail || skb->h.th->syn || skb->h.th->fin) + return; + + while (before(start, end)) { + struct sk_buff *nskb; + int header = skb_headroom(skb); + int copy = (PAGE_SIZE - sizeof(struct sk_buff) - + sizeof(struct skb_shared_info) - header - 31)&~15; + + /* Too big header? This can happen with IPv6. */ + if (copy < 0) + return; + if (end-start < copy) + copy = end-start; + nskb = alloc_skb(copy+header, GFP_ATOMIC); + if (!nskb) + return; + skb_reserve(nskb, header); + memcpy(nskb->head, skb->head, header); + nskb->nh.raw = nskb->head + (skb->nh.raw-skb->head); + nskb->h.raw = nskb->head + (skb->h.raw-skb->head); + nskb->mac.raw = nskb->head + (skb->mac.raw-skb->head); + memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); + TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start; + __skb_insert(nskb, skb->prev, skb, skb->list); + tcp_set_owner_r(nskb, sk); + + /* Copy data, releasing collapsed skbs. */ + while (copy > 0) { + int offset = start - TCP_SKB_CB(skb)->seq; + int size = TCP_SKB_CB(skb)->end_seq - start; + + if (offset < 0) BUG(); + if (size > 0) { + size = min(copy, size); + if (skb_copy_bits(skb, offset, skb_put(nskb, size), size)) + BUG(); + TCP_SKB_CB(nskb)->end_seq += size; + copy -= size; + start += size; + } + if (!before(start, TCP_SKB_CB(skb)->end_seq)) { + struct sk_buff *next = skb->next; + __skb_unlink(skb, skb->list); + __kfree_skb(skb); + NET_INC_STATS_BH(TCPRcvCollapsed); + skb = next; + if (skb == tail || skb->h.th->syn || skb->h.th->fin) + return; + } + } + } +#endif +} + +/* Collapse ofo queue. Algorithm: select contiguous sequence of skbs + * and tcp_collapse() them until all the queue is collapsed. + */ +static void tcp_collapse_ofo_queue(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb = skb_peek(&tp->out_of_order_queue); + struct sk_buff *head; + u32 start, end; + + if (skb == NULL) + return; + + start = TCP_SKB_CB(skb)->seq; + end = TCP_SKB_CB(skb)->end_seq; + head = skb; + + for (;;) { + skb = skb->next; + + /* Segment is terminated when we see gap or when + * we are at the end of all the queue. */ + if (skb == (struct sk_buff *)&tp->out_of_order_queue || + after(TCP_SKB_CB(skb)->seq, end) || + before(TCP_SKB_CB(skb)->end_seq, start)) { + tcp_collapse(sk, head, skb, start, end); + head = skb; + if (skb == (struct sk_buff *)&tp->out_of_order_queue) + break; + /* Start new segment */ + start = TCP_SKB_CB(skb)->seq; + end = TCP_SKB_CB(skb)->end_seq; + } else { + if (before(TCP_SKB_CB(skb)->seq, start)) + start = TCP_SKB_CB(skb)->seq; + if (after(TCP_SKB_CB(skb)->end_seq, end)) + end = TCP_SKB_CB(skb)->end_seq; + } + } +#endif +} + +/* Reduce allocated memory if we can, trying to get + * the socket within its memory limits again. + * + * Return less than zero if we should start dropping frames + * until the socket owning process reads some of the data + * to stabilize the situation. + */ +static int tcp_prune_queue(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq); + + NET_INC_STATS_BH(PruneCalled); + + if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf) + tcp_clamp_window(sk, tp); + else if (tcp_memory_pressure) + tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); + + tcp_collapse_ofo_queue(sk); + tcp_collapse(sk, sk->receive_queue.next, + (struct sk_buff*)&sk->receive_queue, + tp->copied_seq, tp->rcv_nxt); + tcp_mem_reclaim(sk); + + if (atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) + return 0; + + /* Collapsing did not help, destructive actions follow. + * This must not ever occur. */ + + /* First, purge the out_of_order queue. */ + if (skb_queue_len(&tp->out_of_order_queue)) { + net_statistics[smp_processor_id()*2].OfoPruned += skb_queue_len(&tp->out_of_order_queue); + __skb_queue_purge(&tp->out_of_order_queue); + + /* Reset SACK state. A conforming SACK implementation will + * do the same at a timeout based retransmit. When a connection + * is in a sad state like this, we care only about integrity + * of the connection not performance. + */ + if(tp->sack_ok) + tcp_sack_reset(tp); + tcp_mem_reclaim(sk); + } + + if(atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) + return 0; + + /* If we are really being abused, tell the caller to silently + * drop receive data on the floor. It will get retransmitted + * and hopefully then we'll have sufficient space. + */ + NET_INC_STATS_BH(RcvPruned); + + /* Massive buffer overcommit. */ + tp->pred_flags = 0; + return -1; +#else + return 0; +#endif +} + + +/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. + * As additional protections, we do not touch cwnd in retransmission phases, + * and if application hit its sndbuf limit recently. + */ +void tcp_cwnd_application_limited(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (tp->ca_state == TCP_CA_Open && + sk->socket && !test_bit(SOCK_NOSPACE, &sk->socket->flags)) { + /* Limited by application or receiver window. */ + u32 win_used = max(tp->snd_cwnd_used, 2U); + if (win_used < tp->snd_cwnd) { + tp->snd_ssthresh = tcp_current_ssthresh(tp); + tp->snd_cwnd = (tp->snd_cwnd+win_used)>>1; + } + tp->snd_cwnd_used = 0; + } + tp->snd_cwnd_stamp = tcp_time_stamp; +#endif +} + + +/* When incoming ACK allowed to free some skb from write_queue, + * we remember this event in flag tp->queue_shrunk and wake up socket + * on the exit from tcp input handler. + */ +static void tcp_new_space(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (tp->packets_out < tp->snd_cwnd && + !(sk->userlocks&SOCK_SNDBUF_LOCK) && + !tcp_memory_pressure && + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + int sndmem, demanded; + + sndmem = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff); + demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering+1); + sndmem *= 2*demanded; + if (sndmem > sk->sndbuf) + sk->sndbuf = min(sndmem, sysctl_tcp_wmem[2]); + tp->snd_cwnd_stamp = tcp_time_stamp; + } + + sk->write_space(sk); +#endif +} + +static inline void tcp_check_space(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (tp->queue_shrunk) { + tp->queue_shrunk = 0; + if (sk->socket && test_bit(SOCK_NOSPACE, &sk->socket->flags)) + tcp_new_space(sk); + } +#endif +} + +static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || + tcp_packets_in_flight(tp) >= tp->snd_cwnd || + tcp_write_xmit(sk, tp->nonagle)) + tcp_check_probe_timer(sk, tp); +#endif +} + +static __inline__ void tcp_data_snd_check(struct sock *sk) +{ +#if 0 + struct sk_buff *skb = sk->tp_pinfo.af_tcp.send_head; + + if (skb != NULL) + __tcp_data_snd_check(sk, skb); + tcp_check_space(sk); +#endif +} + +/* + * Check if sending an ack is needed. + */ +static __inline__ void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* More than one full frame received... */ + if (((tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss + /* ... and right edge of window advances far enough. + * (tcp_recvmsg() will send ACK otherwise). Or... + */ + && __tcp_select_window(sk) >= tp->rcv_wnd) || + /* We ACK each frame or... */ + tcp_in_quickack_mode(tp) || + /* We have out of order data. */ + (ofo_possible && + skb_peek(&tp->out_of_order_queue) != NULL)) { + /* Then ack it now */ + tcp_send_ack(sk); + } else { + /* Else, send delayed ack. */ + tcp_send_delayed_ack(sk); + } +#endif +} + +static __inline__ void tcp_ack_snd_check(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + if (!tcp_ack_scheduled(tp)) { + /* We sent a data segment already. */ + return; + } + __tcp_ack_snd_check(sk, 1); +#endif +} + +/* + * This routine is only called when we have urgent data + * signalled. Its the 'slow' part of tcp_urg. It could be + * moved inline now as tcp_urg is only called from one + * place. We handle URGent data wrong. We have to - as + * BSD still doesn't use the correction from RFC961. + * For 1003.1g we should support a new option TCP_STDURG to permit + * either form (or just set the sysctl tcp_stdurg). + */ + +static void tcp_check_urg(struct sock * sk, struct tcphdr * th) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + u32 ptr = ntohs(th->urg_ptr); + + if (ptr && !sysctl_tcp_stdurg) + ptr--; + ptr += ntohl(th->seq); + + /* Ignore urgent data that we've already seen and read. */ + if (after(tp->copied_seq, ptr)) + return; + + /* Do not replay urg ptr. + * + * NOTE: interesting situation not covered by specs. + * Misbehaving sender may send urg ptr, pointing to segment, + * which we already have in ofo queue. We are not able to fetch + * such data and will stay in TCP_URG_NOTYET until will be eaten + * by recvmsg(). Seems, we are not obliged to handle such wicked + * situations. But it is worth to think about possibility of some + * DoSes using some hypothetical application level deadlock. + */ + if (before(ptr, tp->rcv_nxt)) + return; + + /* Do we already have a newer (or duplicate) urgent pointer? */ + if (tp->urg_data && !after(ptr, tp->urg_seq)) + return; + + /* Tell the world about our new urgent pointer. */ + if (sk->proc != 0) { + if (sk->proc > 0) + kill_proc(sk->proc, SIGURG, 1); + else + kill_pg(-sk->proc, SIGURG, 1); + sk_wake_async(sk, 3, POLL_PRI); + } + + /* We may be adding urgent data when the last byte read was + * urgent. To do this requires some care. We cannot just ignore + * tp->copied_seq since we would read the last urgent byte again + * as data, nor can we alter copied_seq until this data arrives + * or we break the sematics of SIOCATMARK (and thus sockatmark()) + * + * NOTE. Double Dutch. Rendering to plain English: author of comment + * above did something sort of send("A", MSG_OOB); send("B", MSG_OOB); + * and expect that both A and B disappear from stream. This is _wrong_. + * Though this happens in BSD with high probability, this is occasional. + * Any application relying on this is buggy. Note also, that fix "works" + * only in this artificial test. Insert some normal data between A and B and we will + * decline of BSD again. Verdict: it is better to remove to trap + * buggy users. + */ + if (tp->urg_seq == tp->copied_seq && tp->urg_data && + !sk->urginline && + tp->copied_seq != tp->rcv_nxt) { + struct sk_buff *skb = skb_peek(&sk->receive_queue); + tp->copied_seq++; + if (skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)) { + __skb_unlink(skb, skb->list); + __kfree_skb(skb); + } + } + + tp->urg_data = TCP_URG_NOTYET; + tp->urg_seq = ptr; + + /* Disable header prediction. */ + tp->pred_flags = 0; +#endif +} + +/* This is the 'fast' part of urgent handling. */ +static inline void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* Check if we get a new urgent pointer - normally not. */ + if (th->urg) + tcp_check_urg(sk,th); + + /* Do we wait for any urgent data? - normally not... */ + if (tp->urg_data == TCP_URG_NOTYET) { + u32 ptr = tp->urg_seq - ntohl(th->seq) + (th->doff*4) - th->syn; + + /* Is the urgent pointer pointing into this packet? */ + if (ptr < skb->len) { + u8 tmp; + if (skb_copy_bits(skb, ptr, &tmp, 1)) + BUG(); + tp->urg_data = TCP_URG_VALID | tmp; + if (!sk->dead) + sk->data_ready(sk,0); + } + } +#endif +} + +static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int chunk = skb->len - hlen; + int err; + + local_bh_enable(); + if (skb->ip_summed==CHECKSUM_UNNECESSARY) + err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk); + else + err = skb_copy_and_csum_datagram_iovec(skb, hlen, tp->ucopy.iov); + + if (!err) { + tp->ucopy.len -= chunk; + tp->copied_seq += chunk; + } + + local_bh_disable(); + return err; +#else + return 0; +#endif +} + +static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + int result; + + if (sk->lock.users) { + local_bh_enable(); + result = __tcp_checksum_complete(skb); + local_bh_disable(); + } else { + result = __tcp_checksum_complete(skb); + } + return result; +#else + return 0; +#endif +} + +static __inline__ int +tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __tcp_checksum_complete_user(sk, skb); +#else + return 0; +#endif +} + +/* + * TCP receive function for the ESTABLISHED state. + * + * It is split into a fast path and a slow path. The fast path is + * disabled when: + * - A zero window was announced from us - zero window probing + * is only handled properly in the slow path. + * - Out of order segments arrived. + * - Urgent data is expected. + * - There is no buffer space left + * - Unexpected TCP flags/window values/header lengths are received + * (detected by checking the TCP header against pred_flags) + * - Data is sent in both directions. Fast path only supports pure senders + * or pure receivers (this means either the sequence number or the ack + * value must stay constant) + * - Unexpected TCP option. + * + * When these conditions are not satisfied it drops into a standard + * receive procedure patterned after RFC793 to handle all cases. + * The first three cases are guaranteed by proper pred_flags setting, + * the rest is checked inline. Fast processing is turned on in + * tcp_data_queue when everything is OK. + */ +int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, + struct tcphdr *th, unsigned len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* + * Header prediction. + * The code losely follows the one in the famous + * "30 instruction TCP receive" Van Jacobson mail. + * + * Van's trick is to deposit buffers into socket queue + * on a device interrupt, to call tcp_recv function + * on the receive process context and checksum and copy + * the buffer to user space. smart... + * + * Our current scheme is not silly either but we take the + * extra cost of the net_bh soft interrupt processing... + * We do checksum and copy also but from device to kernel. + */ + + tp->saw_tstamp = 0; + + /* pred_flags is 0xS?10 << 16 + snd_wnd + * if header_predition is to be made + * 'S' will always be tp->tcp_header_len >> 2 + * '?' will be 0 for the fast path, otherwise pred_flags is 0 to + * turn it off (when there are holes in the receive + * space for instance) + * PSH flag is ignored. + */ + + if ((tcp_flag_word(th) & TCP_HP_BITS) == tp->pred_flags && + TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { + int tcp_header_len = tp->tcp_header_len; + + /* Timestamp header prediction: tcp_header_len + * is automatically equal to th->doff*4 due to pred_flags + * match. + */ + + /* Check timestamp */ + if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) { + __u32 *ptr = (__u32 *)(th + 1); + + /* No? Slow path! */ + if (*ptr != ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) + goto slow_path; + + tp->saw_tstamp = 1; + ++ptr; + tp->rcv_tsval = ntohl(*ptr); + ++ptr; + tp->rcv_tsecr = ntohl(*ptr); + + /* If PAWS failed, check it more carefully in slow path */ + if ((s32)(tp->rcv_tsval - tp->ts_recent) < 0) + goto slow_path; + + /* DO NOT update ts_recent here, if checksum fails + * and timestamp was corrupted part, it will result + * in a hung connection since we will drop all + * future packets due to the PAWS test. + */ + } + + if (len <= tcp_header_len) { + /* Bulk data transfer: sender */ + if (len == tcp_header_len) { + /* Predicted packet is in window by definition. + * seq == rcv_nxt and rcv_wup <= rcv_nxt. + * Hence, check seq<=rcv_wup reduces to: + */ + if (tcp_header_len == + (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) && + tp->rcv_nxt == tp->rcv_wup) + tcp_store_ts_recent(tp); + /* We know that such packets are checksummed + * on entry. + */ + tcp_ack(sk, skb, 0); + __kfree_skb(skb); + tcp_data_snd_check(sk); + return 0; + } else { /* Header too small */ + TCP_INC_STATS_BH(TcpInErrs); + goto discard; + } + } else { + int eaten = 0; + + if (tp->ucopy.task == current && + tp->copied_seq == tp->rcv_nxt && + len - tcp_header_len <= tp->ucopy.len && + sk->lock.users) { + __set_current_state(TASK_RUNNING); + + if (!tcp_copy_to_iovec(sk, skb, tcp_header_len)) { + /* Predicted packet is in window by definition. + * seq == rcv_nxt and rcv_wup <= rcv_nxt. + * Hence, check seq<=rcv_wup reduces to: + */ + if (tcp_header_len == + (sizeof(struct tcphdr) + + TCPOLEN_TSTAMP_ALIGNED) && + tp->rcv_nxt == tp->rcv_wup) + tcp_store_ts_recent(tp); + + __skb_pull(skb, tcp_header_len); + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + NET_INC_STATS_BH(TCPHPHitsToUser); + eaten = 1; + } + } + if (!eaten) { + if (tcp_checksum_complete_user(sk, skb)) + goto csum_error; + + /* Predicted packet is in window by definition. + * seq == rcv_nxt and rcv_wup <= rcv_nxt. + * Hence, check seq<=rcv_wup reduces to: + */ + if (tcp_header_len == + (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) && + tp->rcv_nxt == tp->rcv_wup) + tcp_store_ts_recent(tp); + + if ((int)skb->truesize > sk->forward_alloc) + goto step5; + + NET_INC_STATS_BH(TCPHPHits); + + /* Bulk data transfer: receiver */ + __skb_pull(skb,tcp_header_len); + __skb_queue_tail(&sk->receive_queue, skb); + tcp_set_owner_r(skb, sk); + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + } + + tcp_event_data_recv(sk, tp, skb); + + if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) { + /* Well, only one small jumplet in fast path... */ + tcp_ack(sk, skb, FLAG_DATA); + tcp_data_snd_check(sk); + if (!tcp_ack_scheduled(tp)) + goto no_ack; + } + + if (eaten) { + if (tcp_in_quickack_mode(tp)) { + tcp_send_ack(sk); + } else { + tcp_send_delayed_ack(sk); + } + } else { + __tcp_ack_snd_check(sk, 0); + } + +no_ack: + if (eaten) + __kfree_skb(skb); + else + sk->data_ready(sk, 0); + return 0; + } + } + +slow_path: + if (len < (th->doff<<2) || tcp_checksum_complete_user(sk, skb)) + goto csum_error; + + /* + * RFC1323: H1. Apply PAWS check first. + */ + if (tcp_fast_parse_options(skb, th, tp) && tp->saw_tstamp && + tcp_paws_discard(tp, skb)) { + if (!th->rst) { + NET_INC_STATS_BH(PAWSEstabRejected); + tcp_send_dupack(sk, skb); + goto discard; + } + /* Resets are accepted even if PAWS failed. + + ts_recent update must be made after we are sure + that the packet is in window. + */ + } + + /* + * Standard slow path. + */ + + if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) { + /* RFC793, page 37: "In all states except SYN-SENT, all reset + * (RST) segments are validated by checking their SEQ-fields." + * And page 69: "If an incoming segment is not acceptable, + * an acknowledgment should be sent in reply (unless the RST bit + * is set, if so drop the segment and return)". + */ + if (!th->rst) + tcp_send_dupack(sk, skb); + goto discard; + } + + if(th->rst) { + tcp_reset(sk); + goto discard; + } + + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + + if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + TCP_INC_STATS_BH(TcpInErrs); + NET_INC_STATS_BH(TCPAbortOnSyn); + tcp_reset(sk); + return 1; + } + +step5: + if(th->ack) + tcp_ack(sk, skb, FLAG_SLOWPATH); + + /* Process urgent data. */ + tcp_urg(sk, skb, th); + + /* step 7: process the segment text */ + tcp_data_queue(sk, skb); + + tcp_data_snd_check(sk); + tcp_ack_snd_check(sk); + return 0; + +csum_error: + TCP_INC_STATS_BH(TcpInErrs); + +discard: + __kfree_skb(skb); + return 0; +#else + return 0; +#endif +} + +static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, + struct tcphdr *th, unsigned len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int saved_clamp = tp->mss_clamp; + + tcp_parse_options(skb, tp, 0); + + if (th->ack) { + /* rfc793: + * "If the state is SYN-SENT then + * first check the ACK bit + * If the ACK bit is set + * If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send + * a reset (unless the RST bit is set, if so drop + * the segment and return)" + * + * We do not send data with SYN, so that RFC-correct + * test reduces to: + */ + if (TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt) + goto reset_and_undo; + + if (tp->saw_tstamp && tp->rcv_tsecr && + !between(tp->rcv_tsecr, tp->retrans_stamp, tcp_time_stamp)) { + NET_INC_STATS_BH(PAWSActiveRejected); + goto reset_and_undo; + } + + /* Now ACK is acceptable. + * + * "If the RST bit is set + * If the ACK was acceptable then signal the user "error: + * connection reset", drop the segment, enter CLOSED state, + * delete TCB, and return." + */ + + if (th->rst) { + tcp_reset(sk); + goto discard; + } + + /* rfc793: + * "fifth, if neither of the SYN or RST bits is set then + * drop the segment and return." + * + * See note below! + * --ANK(990513) + */ + if (!th->syn) + goto discard_and_undo; + + /* rfc793: + * "If the SYN bit is on ... + * are acceptable then ... + * (our SYN has been ACKed), change the connection + * state to ESTABLISHED..." + */ + + TCP_ECN_rcv_synack(tp, th); + + tp->snd_wl1 = TCP_SKB_CB(skb)->seq; + tcp_ack(sk, skb, FLAG_SLOWPATH); + + /* Ok.. it's good. Set up sequence numbers and + * move to established. + */ + tp->rcv_nxt = TCP_SKB_CB(skb)->seq+1; + tp->rcv_wup = TCP_SKB_CB(skb)->seq+1; + + /* RFC1323: The window in SYN & SYN/ACK segments is + * never scaled. + */ + tp->snd_wnd = ntohs(th->window); + tcp_init_wl(tp, TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(skb)->seq); + + if (tp->wscale_ok == 0) { + tp->snd_wscale = tp->rcv_wscale = 0; + tp->window_clamp = min(tp->window_clamp, 65535U); + } + + if (tp->saw_tstamp) { + tp->tstamp_ok = 1; + tp->tcp_header_len = + sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; + tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; + tcp_store_ts_recent(tp); + } else { + tp->tcp_header_len = sizeof(struct tcphdr); + } + + if (tp->sack_ok && sysctl_tcp_fack) + tp->sack_ok |= 2; + + tcp_sync_mss(sk, tp->pmtu_cookie); + tcp_initialize_rcv_mss(sk); + tcp_init_metrics(sk); + tcp_init_buffer_space(sk); + + if (sk->keepopen) + tcp_reset_keepalive_timer(sk, keepalive_time_when(tp)); + + if (tp->snd_wscale == 0) + __tcp_fast_path_on(tp, tp->snd_wnd); + else + tp->pred_flags = 0; + + /* Remember, tcp_poll() does not lock socket! + * Change state from SYN-SENT only after copied_seq + * is initialized. */ + tp->copied_seq = tp->rcv_nxt; + mb(); + tcp_set_state(sk, TCP_ESTABLISHED); + + if(!sk->dead) { + sk->state_change(sk); + sk_wake_async(sk, 0, POLL_OUT); + } + + if (tp->write_pending || tp->defer_accept || tp->ack.pingpong) { + /* Save one ACK. Data will be ready after + * several ticks, if write_pending is set. + * + * It may be deleted, but with this feature tcpdumps + * look so _wonderfully_ clever, that I was not able + * to stand against the temptation 8) --ANK + */ + tcp_schedule_ack(tp); + tp->ack.lrcvtime = tcp_time_stamp; + tp->ack.ato = TCP_ATO_MIN; + tcp_incr_quickack(tp); + tcp_enter_quickack_mode(tp); + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MAX); + +discard: + __kfree_skb(skb); + return 0; + } else { + tcp_send_ack(sk); + } + return -1; + } + + /* No ACK in the segment */ + + if (th->rst) { + /* rfc793: + * "If the RST bit is set + * + * Otherwise (no ACK) drop the segment and return." + */ + + goto discard_and_undo; + } + + /* PAWS check. */ + if (tp->ts_recent_stamp && tp->saw_tstamp && tcp_paws_check(tp, 0)) + goto discard_and_undo; + + if (th->syn) { + /* We see SYN without ACK. It is attempt of + * simultaneous connect with crossed SYNs. + * Particularly, it can be connect to self. + */ + tcp_set_state(sk, TCP_SYN_RECV); + + if (tp->saw_tstamp) { + tp->tstamp_ok = 1; + tcp_store_ts_recent(tp); + tp->tcp_header_len = + sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; + } else { + tp->tcp_header_len = sizeof(struct tcphdr); + } + + tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; + tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; + + /* RFC1323: The window in SYN & SYN/ACK segments is + * never scaled. + */ + tp->snd_wnd = ntohs(th->window); + tp->snd_wl1 = TCP_SKB_CB(skb)->seq; + tp->max_window = tp->snd_wnd; + + tcp_sync_mss(sk, tp->pmtu_cookie); + tcp_initialize_rcv_mss(sk); + + TCP_ECN_rcv_syn(tp, th); + + tcp_send_synack(sk); +#if 0 + /* Note, we could accept data and URG from this segment. + * There are no obstacles to make this. + * + * However, if we ignore data in ACKless segments sometimes, + * we have no reasons to accept it sometimes. + * Also, seems the code doing it in step6 of tcp_rcv_state_process + * is not flawless. So, discard packet for sanity. + * Uncomment this return to process the data. + */ + return -1; +#else + goto discard; +#endif + } + /* "fifth, if neither of the SYN or RST bits is set then + * drop the segment and return." + */ + +discard_and_undo: + tcp_clear_options(tp); + tp->mss_clamp = saved_clamp; + goto discard; + +reset_and_undo: + tcp_clear_options(tp); + tp->mss_clamp = saved_clamp; + return 1; +#else + return 0; +#endif +} + + +/* + * This function implements the receiving procedure of RFC 793 for + * all states except ESTABLISHED and TIME_WAIT. + * It's called from both tcp_v4_rcv and tcp_v6_rcv and should be + * address independent. + */ + +int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + struct tcphdr *th, unsigned len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int queued = 0; + + tp->saw_tstamp = 0; + + switch (sk->state) { + case TCP_CLOSE: + goto discard; + + case TCP_LISTEN: + if(th->ack) + return 1; + + if(th->rst) + goto discard; + + if(th->syn) { + if(tp->af_specific->conn_request(sk, skb) < 0) + return 1; + + /* Now we have several options: In theory there is + * nothing else in the frame. KA9Q has an option to + * send data with the syn, BSD accepts data with the + * syn up to the [to be] advertised window and + * Solaris 2.1 gives you a protocol error. For now + * we just ignore it, that fits the spec precisely + * and avoids incompatibilities. It would be nice in + * future to drop through and process the data. + * + * Now that TTCP is starting to be used we ought to + * queue this data. + * But, this leaves one open to an easy denial of + * service attack, and SYN cookies can't defend + * against this problem. So, we drop the data + * in the interest of security over speed. + */ + goto discard; + } + goto discard; + + case TCP_SYN_SENT: + queued = tcp_rcv_synsent_state_process(sk, skb, th, len); + if (queued >= 0) + return queued; + + /* Do step6 onward by hand. */ + tcp_urg(sk, skb, th); + __kfree_skb(skb); + tcp_data_snd_check(sk); + return 0; + } + + if (tcp_fast_parse_options(skb, th, tp) && tp->saw_tstamp && + tcp_paws_discard(tp, skb)) { + if (!th->rst) { + NET_INC_STATS_BH(PAWSEstabRejected); + tcp_send_dupack(sk, skb); + goto discard; + } + /* Reset is accepted even if it did not pass PAWS. */ + } + + /* step 1: check sequence number */ + if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) { + if (!th->rst) + tcp_send_dupack(sk, skb); + goto discard; + } + + /* step 2: check RST bit */ + if(th->rst) { + tcp_reset(sk); + goto discard; + } + + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + + /* step 3: check security and precedence [ignored] */ + + /* step 4: + * + * Check for a SYN in window. + */ + if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + NET_INC_STATS_BH(TCPAbortOnSyn); + tcp_reset(sk); + return 1; + } + + /* step 5: check the ACK field */ + if (th->ack) { + int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH); + + switch(sk->state) { + case TCP_SYN_RECV: + if (acceptable) { + tp->copied_seq = tp->rcv_nxt; + mb(); + tcp_set_state(sk, TCP_ESTABLISHED); + sk->state_change(sk); + + /* Note, that this wakeup is only for marginal + * crossed SYN case. Passively open sockets + * are not waked up, because sk->sleep == NULL + * and sk->socket == NULL. + */ + if (sk->socket) { + sk_wake_async(sk,0,POLL_OUT); + } + + tp->snd_una = TCP_SKB_CB(skb)->ack_seq; + tp->snd_wnd = ntohs(th->window) << tp->snd_wscale; + tcp_init_wl(tp, TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(skb)->seq); + + /* tcp_ack considers this ACK as duplicate + * and does not calculate rtt. + * Fix it at least with timestamps. + */ + if (tp->saw_tstamp && tp->rcv_tsecr && !tp->srtt) + tcp_ack_saw_tstamp(tp, 0); + + if (tp->tstamp_ok) + tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; + + tcp_init_metrics(sk); + tcp_initialize_rcv_mss(sk); + tcp_init_buffer_space(sk); + tcp_fast_path_on(tp); + } else { + return 1; + } + break; + + case TCP_FIN_WAIT1: + if (tp->snd_una == tp->write_seq) { + tcp_set_state(sk, TCP_FIN_WAIT2); + sk->shutdown |= SEND_SHUTDOWN; + dst_confirm(sk->dst_cache); + + if (!sk->dead) { + /* Wake up lingering close() */ + sk->state_change(sk); + } else { + int tmo; + + if (tp->linger2 < 0 || + (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && + after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt))) { + tcp_done(sk); + NET_INC_STATS_BH(TCPAbortOnData); + return 1; + } + + tmo = tcp_fin_time(tp); + if (tmo > TCP_TIMEWAIT_LEN) { + tcp_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); + } else if (th->fin || sk->lock.users) { + /* Bad case. We could lose such FIN otherwise. + * It is not a big problem, but it looks confusing + * and not so rare event. We still can lose it now, + * if it spins in bh_lock_sock(), but it is really + * marginal case. + */ + tcp_reset_keepalive_timer(sk, tmo); + } else { + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto discard; + } + } + } + break; + + case TCP_CLOSING: + if (tp->snd_una == tp->write_seq) { + tcp_time_wait(sk, TCP_TIME_WAIT, 0); + goto discard; + } + break; + + case TCP_LAST_ACK: + if (tp->snd_una == tp->write_seq) { + tcp_update_metrics(sk); + tcp_done(sk); + goto discard; + } + break; + } + } else + goto discard; + + /* step 6: check the URG bit */ + tcp_urg(sk, skb, th); + + /* step 7: process the segment text */ + switch (sk->state) { + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + case TCP_LAST_ACK: + if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) + break; + case TCP_FIN_WAIT1: + case TCP_FIN_WAIT2: + /* RFC 793 says to queue data in these states, + * RFC 1122 says we MUST send a reset. + * BSD 4.4 also does reset. + */ + if (sk->shutdown & RCV_SHUTDOWN) { + if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && + after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { + NET_INC_STATS_BH(TCPAbortOnData); + tcp_reset(sk); + return 1; + } + } + /* Fall through */ + case TCP_ESTABLISHED: + tcp_data_queue(sk, skb); + queued = 1; + break; + } + + /* tcp_data could move socket to TIME-WAIT */ + if (sk->state != TCP_CLOSE) { + tcp_data_snd_check(sk); + tcp_ack_snd_check(sk); + } + + if (!queued) { +discard: + __kfree_skb(skb); + } + return 0; +#else + return 0; +#endif +} diff --git a/drivers/net/tcpip/transport/tcp/tcp_ipv4.c b/drivers/net/tcpip/transport/tcp/tcp_ipv4.c new file mode 100755 index 0000000..caddc67 --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/tcp_ipv4.c @@ -0,0 +1,2523 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: transport/tcp/tcp_ipv4.c + * PURPOSE: Transmission Control Protocol + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 15-01-2003 Imported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Implementation of the Transmission Control Protocol(TCP). + * + * Version: $Id$ + * + * IPv4 specific functions + * + * + * code split from: + * linux/ipv4/tcp.c + * linux/ipv4/tcp_input.c + * linux/ipv4/tcp_output.c + * + * See tcp.c for author information + * + * 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. + */ + +/* + * Changes: + * David S. Miller : New socket lookup architecture. + * This code is dedicated to John Dyson. + * David S. Miller : Change semantics of established hash, + * half is devoted to TIME_WAIT sockets + * and the rest go in the other half. + * Andi Kleen : Add support for syncookies and fixed + * some bugs: ip options weren't passed to + * the TCP layer, missed a check for an ACK bit. + * Andi Kleen : Implemented fast path mtu discovery. + * Fixed many serious bugs in the + * open_request handling and moved + * most of it into the af independent code. + * Added tail drop and some other bugfixes. + * Added new listen sematics. + * Mike McLagan : Routing by source + * Juan Jose Ciarlante: ip_dynaddr bits + * Andi Kleen: various fixes. + * Vitaly E. Lavrov : Transparent proxy revived after year coma. + * Andi Kleen : Fix new listen. + * Andi Kleen : Fix accept error reporting. + */ + +#if 0 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#else +#include "linux.h" +#include "tcpcore.h" +#endif + +extern int sysctl_ip_dynaddr; +extern int sysctl_ip_default_ttl; +int sysctl_tcp_tw_reuse = 0; + +/* Check TCP sequence numbers in ICMP packets. */ +#define ICMP_MIN_LENGTH 8 + +/* Socket used for sending RSTs */ +#if 0 +static struct inode tcp_inode; +static struct socket *tcp_socket=&tcp_inode.u.socket_i; +#endif + +void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, + struct sk_buff *skb); + +/* + * ALL members must be initialised to prevent gcc-2.7.2.3 miscompilation + */ +#if 0 +struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = { + __tcp_ehash: NULL, + __tcp_bhash: NULL, + __tcp_bhash_size: 0, + __tcp_ehash_size: 0, + __tcp_listening_hash: { NULL, }, + __tcp_lhash_lock: RW_LOCK_UNLOCKED, + __tcp_lhash_users: ATOMIC_INIT(0), + __tcp_lhash_wait: + __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait), + __tcp_portalloc_lock: SPIN_LOCK_UNLOCKED +}; +#endif + +/* + * This array holds the first and last local port number. + * For high-usage systems, use sysctl to change this to + * 32768-61000 + */ +int sysctl_local_port_range[2] = { 1024, 4999 }; +int tcp_port_rover = (1024 - 1); + +static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport, + __u32 faddr, __u16 fport) +{ + int h = ((laddr ^ lport) ^ (faddr ^ fport)); + h ^= h>>16; + h ^= h>>8; + return h & (tcp_ehash_size - 1); +} + +static __inline__ int tcp_sk_hashfn(struct sock *sk) +{ + __u32 laddr = sk->rcv_saddr; + __u16 lport = sk->num; + __u32 faddr = sk->daddr; + __u16 fport = sk->dport; + + return tcp_hashfn(laddr, lport, faddr, fport); +} + +/* Allocate and initialize a new TCP local port bind bucket. + * The bindhash mutex for snum's hash chain must be held here. + */ +struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, + unsigned short snum) +{ +#if 0 + struct tcp_bind_bucket *tb; + + tb = kmem_cache_alloc(tcp_bucket_cachep, SLAB_ATOMIC); + if(tb != NULL) { + tb->port = snum; + tb->fastreuse = 0; + tb->owners = NULL; + if((tb->next = head->chain) != NULL) + tb->next->pprev = &tb->next; + head->chain = tb; + tb->pprev = &head->chain; + } + return tb; +#else + return NULL; +#endif +} + +/* Caller must disable local BH processing. */ +static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child) +{ +#if 0 + struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(child->num)]; + struct tcp_bind_bucket *tb; + + spin_lock(&head->lock); + tb = (struct tcp_bind_bucket *)sk->prev; + if ((child->bind_next = tb->owners) != NULL) + tb->owners->bind_pprev = &child->bind_next; + tb->owners = child; + child->bind_pprev = &tb->owners; + child->prev = (struct sock *) tb; + spin_unlock(&head->lock); +#endif +} + +__inline__ void tcp_inherit_port(struct sock *sk, struct sock *child) +{ +#if 0 + local_bh_disable(); + __tcp_inherit_port(sk, child); + local_bh_enable(); +#endif +} + +static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, unsigned short snum) +{ +#if 0 + sk->num = snum; + if ((sk->bind_next = tb->owners) != NULL) + tb->owners->bind_pprev = &sk->bind_next; + tb->owners = sk; + sk->bind_pprev = &tb->owners; + sk->prev = (struct sock *) tb; +#endif +} + +static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb) +{ +#if 0 + struct sock *sk2 = tb->owners; + int sk_reuse = sk->reuse; + + for( ; sk2 != NULL; sk2 = sk2->bind_next) { + if (sk != sk2 && + sk2->reuse <= 1 && + sk->bound_dev_if == sk2->bound_dev_if) { + if (!sk_reuse || + !sk2->reuse || + sk2->state == TCP_LISTEN) { + if (!sk2->rcv_saddr || + !sk->rcv_saddr || + (sk2->rcv_saddr == sk->rcv_saddr)) + break; + } + } + } + return sk2 != NULL; +#else + return 0; +#endif +} + +/* Obtain a reference to a local port for the given sock, + * if snum is zero it means select any available local port. + */ +static int tcp_v4_get_port(struct sock *sk, unsigned short snum) +{ +#if 0 + struct tcp_bind_hashbucket *head; + struct tcp_bind_bucket *tb; + int ret; + + local_bh_disable(); + if (snum == 0) { + int low = sysctl_local_port_range[0]; + int high = sysctl_local_port_range[1]; + int remaining = (high - low) + 1; + int rover; + + spin_lock(&tcp_portalloc_lock); + rover = tcp_port_rover; + do { rover++; + if ((rover < low) || (rover > high)) + rover = low; + head = &tcp_bhash[tcp_bhashfn(rover)]; + spin_lock(&head->lock); + for (tb = head->chain; tb; tb = tb->next) + if (tb->port == rover) + goto next; + break; + next: + spin_unlock(&head->lock); + } while (--remaining > 0); + tcp_port_rover = rover; + spin_unlock(&tcp_portalloc_lock); + + /* Exhausted local port range during search? */ + ret = 1; + if (remaining <= 0) + goto fail; + + /* OK, here is the one we will use. HEAD is + * non-NULL and we hold it's mutex. + */ + snum = rover; + tb = NULL; + } else { + head = &tcp_bhash[tcp_bhashfn(snum)]; + spin_lock(&head->lock); + for (tb = head->chain; tb != NULL; tb = tb->next) + if (tb->port == snum) + break; + } + if (tb != NULL && tb->owners != NULL) { + if (sk->reuse > 1) + goto success; + if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) { + goto success; + } else { + ret = 1; + if (tcp_bind_conflict(sk, tb)) + goto fail_unlock; + } + } + ret = 1; + if (tb == NULL && + (tb = tcp_bucket_create(head, snum)) == NULL) + goto fail_unlock; + if (tb->owners == NULL) { + if (sk->reuse && sk->state != TCP_LISTEN) + tb->fastreuse = 1; + else + tb->fastreuse = 0; + } else if (tb->fastreuse && + ((sk->reuse == 0) || (sk->state == TCP_LISTEN))) + tb->fastreuse = 0; +success: + if (sk->prev == NULL) + tcp_bind_hash(sk, tb, snum); + BUG_TRAP(sk->prev == (struct sock *) tb); + ret = 0; + +fail_unlock: + spin_unlock(&head->lock); +fail: + local_bh_enable(); + return ret; +#else + return 0; +#endif +} + +/* Get rid of any references to a local port held by the + * given sock. + */ +__inline__ void __tcp_put_port(struct sock *sk) +{ +#if 0 + struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(sk->num)]; + struct tcp_bind_bucket *tb; + + spin_lock(&head->lock); + tb = (struct tcp_bind_bucket *) sk->prev; + if (sk->bind_next) + sk->bind_next->bind_pprev = sk->bind_pprev; + *(sk->bind_pprev) = sk->bind_next; + sk->prev = NULL; + sk->num = 0; + if (tb->owners == NULL) { + if (tb->next) + tb->next->pprev = tb->pprev; + *(tb->pprev) = tb->next; + kmem_cache_free(tcp_bucket_cachep, tb); + } + spin_unlock(&head->lock); +#endif +} + +void tcp_put_port(struct sock *sk) +{ +#if 0 + local_bh_disable(); + __tcp_put_port(sk); + local_bh_enable(); +#endif +} + +/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. + * Look, when several writers sleep and reader wakes them up, all but one + * immediately hit write lock and grab all the cpus. Exclusive sleep solves + * this, _but_ remember, it adds useless work on UP machines (wake up each + * exclusive lock release). It should be ifdefed really. + */ + +void tcp_listen_wlock(void) +{ +#if 0 + write_lock(&tcp_lhash_lock); + + if (atomic_read(&tcp_lhash_users)) { + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue_exclusive(&tcp_lhash_wait, &wait); + for (;;) { + set_current_state(TASK_UNINTERRUPTIBLE); + if (atomic_read(&tcp_lhash_users) == 0) + break; + write_unlock_bh(&tcp_lhash_lock); + schedule(); + write_lock_bh(&tcp_lhash_lock); + } + + __set_current_state(TASK_RUNNING); + remove_wait_queue(&tcp_lhash_wait, &wait); + } +#endif +} + +static __inline__ void __tcp_v4_hash(struct sock *sk, const int listen_possible) +{ +#if 0 + struct sock **skp; + rwlock_t *lock; + + BUG_TRAP(sk->pprev==NULL); + if(listen_possible && sk->state == TCP_LISTEN) { + skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; + lock = &tcp_lhash_lock; + tcp_listen_wlock(); + } else { + skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))].chain; + lock = &tcp_ehash[sk->hashent].lock; + write_lock(lock); + } + if((sk->next = *skp) != NULL) + (*skp)->pprev = &sk->next; + *skp = sk; + sk->pprev = skp; + sock_prot_inc_use(sk->prot); + write_unlock(lock); + if (listen_possible && sk->state == TCP_LISTEN) + wake_up(&tcp_lhash_wait); +#endif +} + +static void tcp_v4_hash(struct sock *sk) +{ +#if 0 + if (sk->state != TCP_CLOSE) { + local_bh_disable(); + __tcp_v4_hash(sk, 1); + local_bh_enable(); + } +#endif +} + +void tcp_unhash(struct sock *sk) +{ +#if 0 + rwlock_t *lock; + + if (!sk->pprev) + goto ende; + + if (sk->state == TCP_LISTEN) { + local_bh_disable(); + tcp_listen_wlock(); + lock = &tcp_lhash_lock; + } else { + struct tcp_ehash_bucket *head = &tcp_ehash[sk->hashent]; + lock = &head->lock; + write_lock_bh(&head->lock); + } + + if(sk->pprev) { + if(sk->next) + sk->next->pprev = sk->pprev; + *sk->pprev = sk->next; + sk->pprev = NULL; + sock_prot_dec_use(sk->prot); + } + write_unlock_bh(lock); + + ende: + if (sk->state == TCP_LISTEN) + wake_up(&tcp_lhash_wait); +#endif +} + +/* Don't inline this cruft. Here are some nice properties to + * exploit here. The BSD API does not allow a listening TCP + * to specify the remote port nor the remote address for the + * connection. So always assume those are both wildcarded + * during the search since they can never be otherwise. + */ +static struct sock *__tcp_v4_lookup_listener(struct sock *sk, u32 daddr, unsigned short hnum, int dif) +{ +#if 0 + struct sock *result = NULL; + int score, hiscore; + + hiscore=0; + for(; sk; sk = sk->next) { + if(sk->num == hnum) { + __u32 rcv_saddr = sk->rcv_saddr; + + score = 1; + if(rcv_saddr) { + if (rcv_saddr != daddr) + continue; + score++; + } + if (sk->bound_dev_if) { + if (sk->bound_dev_if != dif) + continue; + score++; + } + if (score == 3) + return sk; + if (score > hiscore) { + hiscore = score; + result = sk; + } + } + } + return result; +#else + return NULL; +#endif +} + +/* Optimize the common listener case. */ +__inline__ struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum, int dif) +{ +#if 0 + struct sock *sk; + + read_lock(&tcp_lhash_lock); + sk = tcp_listening_hash[tcp_lhashfn(hnum)]; + if (sk) { + if (sk->num == hnum && + sk->next == NULL && + (!sk->rcv_saddr || sk->rcv_saddr == daddr) && + !sk->bound_dev_if) + goto sherry_cache; + sk = __tcp_v4_lookup_listener(sk, daddr, hnum, dif); + } + if (sk) { +sherry_cache: + sock_hold(sk); + } + read_unlock(&tcp_lhash_lock); + return sk; +#else + return NULL; +#endif +} + +/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so + * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM + * + * Local BH must be disabled here. + */ + +static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport, + u32 daddr, u16 hnum, int dif) +{ +#if 0 + struct tcp_ehash_bucket *head; + TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) + __u32 ports = TCP_COMBINED_PORTS(sport, hnum); + struct sock *sk; + int hash; + + /* Optimize here for direct hit, only listening connections can + * have wildcards anyways. + */ + hash = tcp_hashfn(daddr, hnum, saddr, sport); + head = &tcp_ehash[hash]; + read_lock(&head->lock); + for(sk = head->chain; sk; sk = sk->next) { + if(TCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif)) + goto hit; /* You sunk my battleship! */ + } + + /* Must check for a TIME_WAIT'er before going to listener hash. */ + for(sk = (head + tcp_ehash_size)->chain; sk; sk = sk->next) + if(TCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif)) + goto hit; + read_unlock(&head->lock); + + return NULL; + +hit: + sock_hold(sk); + read_unlock(&head->lock); + return sk; +#else + return NULL; +#endif +} + +static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport, + u32 daddr, u16 hnum, int dif) +{ +#if 0 + struct sock *sk; + + sk = __tcp_v4_lookup_established(saddr, sport, daddr, hnum, dif); + + if (sk) + return sk; + + return tcp_v4_lookup_listener(daddr, hnum, dif); +#else + return NULL; +#endif +} + +__inline__ struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) +{ +#if 0 + struct sock *sk; + + local_bh_disable(); + sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif); + local_bh_enable(); + + return sk; +#else + return NULL; +#endif +} + +static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + return secure_tcp_sequence_number(skb->nh.iph->daddr, + skb->nh.iph->saddr, + skb->h.th->dest, + skb->h.th->source); +#else + return 0; +#endif +} + +/* called with local bh disabled */ +static int __tcp_v4_check_established(struct sock *sk, __u16 lport, + struct tcp_tw_bucket **twp) +{ +#if 0 + u32 daddr = sk->rcv_saddr; + u32 saddr = sk->daddr; + int dif = sk->bound_dev_if; + TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) + __u32 ports = TCP_COMBINED_PORTS(sk->dport, lport); + int hash = tcp_hashfn(daddr, lport, saddr, sk->dport); + struct tcp_ehash_bucket *head = &tcp_ehash[hash]; + struct sock *sk2, **skp; + struct tcp_tw_bucket *tw; + + write_lock(&head->lock); + + /* Check TIME-WAIT sockets first. */ + for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp) != NULL; + skp = &sk2->next) { + tw = (struct tcp_tw_bucket*)sk2; + + if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* With PAWS, it is safe from the viewpoint + of data integrity. Even without PAWS it + is safe provided sequence spaces do not + overlap i.e. at data rates <= 80Mbit/sec. + + Actually, the idea is close to VJ's one, + only timestamp cache is held not per host, + but per port pair and TW bucket is used + as state holder. + + If TW bucket has been already destroyed we + fall back to VJ's scheme and use initial + timestamp retrieved from peer table. + */ + if (tw->ts_recent_stamp && + (!twp || (sysctl_tcp_tw_reuse && + xtime.tv_sec - tw->ts_recent_stamp > 1))) { + if ((tp->write_seq = tw->snd_nxt+65535+2) == 0) + tp->write_seq = 1; + tp->ts_recent = tw->ts_recent; + tp->ts_recent_stamp = tw->ts_recent_stamp; + sock_hold(sk2); + skp = &head->chain; + goto unique; + } else + goto not_unique; + } + } + tw = NULL; + + /* And established part... */ + for(skp = &head->chain; (sk2=*skp)!=NULL; skp = &sk2->next) { + if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) + goto not_unique; + } + +unique: + /* Must record num and sport now. Otherwise we will see + * in hash table socket with a funny identity. */ + sk->num = lport; + sk->sport = htons(lport); + BUG_TRAP(sk->pprev==NULL); + if ((sk->next = *skp) != NULL) + (*skp)->pprev = &sk->next; + + *skp = sk; + sk->pprev = skp; + sk->hashent = hash; + sock_prot_inc_use(sk->prot); + write_unlock(&head->lock); + + if (twp) { + *twp = tw; + NET_INC_STATS_BH(TimeWaitRecycled); + } else if (tw) { + /* Silly. Should hash-dance instead... */ + tcp_tw_deschedule(tw); + tcp_timewait_kill(tw); + NET_INC_STATS_BH(TimeWaitRecycled); + + tcp_tw_put(tw); + } + + return 0; + +not_unique: + write_unlock(&head->lock); + return -EADDRNOTAVAIL; +#else + return 0; +#endif +} + +/* + * Bind a port for a connect operation and hash it. + */ +static int tcp_v4_hash_connect(struct sock *sk) +{ +#if 0 + unsigned short snum = sk->num; + struct tcp_bind_hashbucket *head; + struct tcp_bind_bucket *tb; + + if (snum == 0) { + int rover; + int low = sysctl_local_port_range[0]; + int high = sysctl_local_port_range[1]; + int remaining = (high - low) + 1; + struct tcp_tw_bucket *tw = NULL; + + local_bh_disable(); + + /* TODO. Actually it is not so bad idea to remove + * tcp_portalloc_lock before next submission to Linus. + * As soon as we touch this place at all it is time to think. + * + * Now it protects single _advisory_ variable tcp_port_rover, + * hence it is mostly useless. + * Code will work nicely if we just delete it, but + * I am afraid in contented case it will work not better or + * even worse: another cpu just will hit the same bucket + * and spin there. + * So some cpu salt could remove both contention and + * memory pingpong. Any ideas how to do this in a nice way? + */ + spin_lock(&tcp_portalloc_lock); + rover = tcp_port_rover; + + do { + rover++; + if ((rover < low) || (rover > high)) + rover = low; + head = &tcp_bhash[tcp_bhashfn(rover)]; + spin_lock(&head->lock); + + /* Does not bother with rcv_saddr checks, + * because the established check is already + * unique enough. + */ + for (tb = head->chain; tb; tb = tb->next) { + if (tb->port == rover) { + BUG_TRAP(tb->owners != NULL); + if (tb->fastreuse >= 0) + goto next_port; + if (!__tcp_v4_check_established(sk, rover, &tw)) + goto ok; + goto next_port; + } + } + + tb = tcp_bucket_create(head, rover); + if (!tb) { + spin_unlock(&head->lock); + break; + } + tb->fastreuse = -1; + goto ok; + + next_port: + spin_unlock(&head->lock); + } while (--remaining > 0); + tcp_port_rover = rover; + spin_unlock(&tcp_portalloc_lock); + + local_bh_enable(); + + return -EADDRNOTAVAIL; + + ok: + /* All locks still held and bhs disabled */ + tcp_port_rover = rover; + spin_unlock(&tcp_portalloc_lock); + + tcp_bind_hash(sk, tb, rover); + if (!sk->pprev) { + sk->sport = htons(rover); + __tcp_v4_hash(sk, 0); + } + spin_unlock(&head->lock); + + if (tw) { + tcp_tw_deschedule(tw); + tcp_timewait_kill(tw); + tcp_tw_put(tw); + } + + local_bh_enable(); + return 0; + } + + head = &tcp_bhash[tcp_bhashfn(snum)]; + tb = (struct tcp_bind_bucket *)sk->prev; + spin_lock_bh(&head->lock); + if (tb->owners == sk && sk->bind_next == NULL) { + __tcp_v4_hash(sk, 0); + spin_unlock_bh(&head->lock); + return 0; + } else { + int ret; + spin_unlock(&head->lock); + /* No definite answer... Walk to established hash table */ + ret = __tcp_v4_check_established(sk, snum, NULL); + local_bh_enable(); + return ret; + } +#else + return 0; +#endif +} + +/* This will initiate an outgoing connection. */ +int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sockaddr_in *usin = (struct sockaddr_in *) uaddr; + struct rtable *rt; + u32 daddr, nexthop; + int tmp; + int err; + + if (addr_len < sizeof(struct sockaddr_in)) + return(-EINVAL); + + if (usin->sin_family != AF_INET) + return(-EAFNOSUPPORT); + + nexthop = daddr = usin->sin_addr.s_addr; + if (sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) { + if (daddr == 0) + return -EINVAL; + nexthop = sk->protinfo.af_inet.opt->faddr; + } + + tmp = ip_route_connect(&rt, nexthop, sk->saddr, + RT_CONN_FLAGS(sk), sk->bound_dev_if); + if (tmp < 0) + return tmp; + + if (rt->rt_flags&(RTCF_MULTICAST|RTCF_BROADCAST)) { + ip_rt_put(rt); + return -ENETUNREACH; + } + + __sk_dst_set(sk, &rt->u.dst); + sk->route_caps = rt->u.dst.dev->features; + + if (!sk->protinfo.af_inet.opt || !sk->protinfo.af_inet.opt->srr) + daddr = rt->rt_dst; + + if (!sk->saddr) + sk->saddr = rt->rt_src; + sk->rcv_saddr = sk->saddr; + + if (tp->ts_recent_stamp && sk->daddr != daddr) { + /* Reset inherited state */ + tp->ts_recent = 0; + tp->ts_recent_stamp = 0; + tp->write_seq = 0; + } + + if (sysctl_tcp_tw_recycle && + !tp->ts_recent_stamp && + rt->rt_dst == daddr) { + struct inet_peer *peer = rt_get_peer(rt); + + /* VJ's idea. We save last timestamp seen from + * the destination in peer table, when entering state TIME-WAIT + * and initialize ts_recent from it, when trying new connection. + */ + + if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) { + tp->ts_recent_stamp = peer->tcp_ts_stamp; + tp->ts_recent = peer->tcp_ts; + } + } + + sk->dport = usin->sin_port; + sk->daddr = daddr; + + tp->ext_header_len = 0; + if (sk->protinfo.af_inet.opt) + tp->ext_header_len = sk->protinfo.af_inet.opt->optlen; + + tp->mss_clamp = 536; + + /* Socket identity is still unknown (sport may be zero). + * However we set state to SYN-SENT and not releasing socket + * lock select source port, enter ourselves into the hash tables and + * complete initalization after this. + */ + tcp_set_state(sk, TCP_SYN_SENT); + err = tcp_v4_hash_connect(sk); + if (err) + goto failure; + + if (!tp->write_seq) + tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr, + sk->sport, usin->sin_port); + + sk->protinfo.af_inet.id = tp->write_seq^jiffies; + + err = tcp_connect(sk); + if (err) + goto failure; + + return 0; + +failure: + tcp_set_state(sk, TCP_CLOSE); + __sk_dst_reset(sk); + sk->route_caps = 0; + sk->dport = 0; + return err; +#else + return 0; +#endif +} + +static __inline__ int tcp_v4_iif(struct sk_buff *skb) +{ +#if 0 + return ((struct rtable*)skb->dst)->rt_iif; +#else + return 0; +#endif +} + +static __inline__ unsigned tcp_v4_synq_hash(u32 raddr, u16 rport) +{ +#if 0 + unsigned h = raddr ^ rport; + h ^= h>>16; + h ^= h>>8; + return h&(TCP_SYNQ_HSIZE-1); +#else + return 0; +#endif +} + +static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, + struct open_request ***prevp, + __u16 rport, + __u32 raddr, __u32 laddr) +{ +#if 0 + struct tcp_listen_opt *lopt = tp->listen_opt; + struct open_request *req, **prev; + + for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)]; + (req = *prev) != NULL; + prev = &req->dl_next) { + if (req->rmt_port == rport && + req->af.v4_req.rmt_addr == raddr && + req->af.v4_req.loc_addr == laddr && + TCP_INET_FAMILY(req->class->family)) { + BUG_TRAP(req->sk == NULL); + *prevp = prev; + return req; + } + } + + return NULL; +#else + return NULL; +#endif +} + +static void tcp_v4_synq_add(struct sock *sk, struct open_request *req) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct tcp_listen_opt *lopt = tp->listen_opt; + unsigned h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port); + + req->expires = jiffies + TCP_TIMEOUT_INIT; + req->retrans = 0; + req->sk = NULL; + req->dl_next = lopt->syn_table[h]; + + write_lock(&tp->syn_wait_lock); + lopt->syn_table[h] = req; + write_unlock(&tp->syn_wait_lock); + + tcp_synq_added(sk); +#endif +} + + +/* + * This routine does path mtu discovery as defined in RFC1191. + */ +static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip, unsigned mtu) +{ +#if 0 + struct dst_entry *dst; + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs + * send out by Linux are always <576bytes so they should go through + * unfragmented). + */ + if (sk->state == TCP_LISTEN) + return; + + /* We don't check in the destentry if pmtu discovery is forbidden + * on this route. We just assume that no packet_to_big packets + * are send back when pmtu discovery is not active. + * There is a small race when the user changes this flag in the + * route, but I think that's acceptable. + */ + if ((dst = __sk_dst_check(sk, 0)) == NULL) + return; + + ip_rt_update_pmtu(dst, mtu); + + /* Something is about to be wrong... Remember soft error + * for the case, if this connection will not able to recover. + */ + if (mtu < dst->pmtu && ip_dont_fragment(sk, dst)) + sk->err_soft = EMSGSIZE; + + if (sk->protinfo.af_inet.pmtudisc != IP_PMTUDISC_DONT && + tp->pmtu_cookie > dst->pmtu) { + tcp_sync_mss(sk, dst->pmtu); + + /* Resend the TCP packet because it's + * clear that the old packet has been + * dropped. This is the new "fast" path mtu + * discovery. + */ + tcp_simple_retransmit(sk); + } /* else let the usual retransmit timer handle it */ +#endif +} + +/* + * This routine is called by the ICMP module when it gets some + * sort of error condition. If err < 0 then the socket should + * be closed and the error returned to the user. If err > 0 + * it's just the icmp type << 8 | icmp code. After adjustment + * header points to the first 8 bytes of the tcp header. We need + * to find the appropriate port. + * + * The locking strategy used here is very "optimistic". When + * someone else accesses the socket the ICMP is just dropped + * and for some paths there is no check at all. + * A more general error queue to queue errors for later handling + * is probably better. + * + */ + +void tcp_v4_err(struct sk_buff *skb, u32 info) +{ +#if 0 + struct iphdr *iph = (struct iphdr*)skb->data; + struct tcphdr *th = (struct tcphdr*)(skb->data+(iph->ihl<<2)); + struct tcp_opt *tp; + int type = skb->h.icmph->type; + int code = skb->h.icmph->code; + struct sock *sk; + __u32 seq; + int err; + + if (skb->len < (iph->ihl << 2) + 8) { + ICMP_INC_STATS_BH(IcmpInErrors); + return; + } + + sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, tcp_v4_iif(skb)); + if (sk == NULL) { + ICMP_INC_STATS_BH(IcmpInErrors); + return; + } + if (sk->state == TCP_TIME_WAIT) { + tcp_tw_put((struct tcp_tw_bucket*)sk); + return; + } + + bh_lock_sock(sk); + /* If too many ICMPs get dropped on busy + * servers this needs to be solved differently. + */ + if (sk->lock.users != 0) + NET_INC_STATS_BH(LockDroppedIcmps); + + if (sk->state == TCP_CLOSE) + goto out; + + tp = &sk->tp_pinfo.af_tcp; + seq = ntohl(th->seq); + if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) { + NET_INC_STATS(OutOfWindowIcmps); + goto out; + } + + switch (type) { + case ICMP_SOURCE_QUENCH: + /* This is deprecated, but if someone generated it, + * we have no reasons to ignore it. + */ + if (sk->lock.users == 0) + tcp_enter_cwr(tp); + goto out; + case ICMP_PARAMETERPROB: + err = EPROTO; + break; + case ICMP_DEST_UNREACH: + if (code > NR_ICMP_UNREACH) + goto out; + + if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ + if (sk->lock.users == 0) + do_pmtu_discovery(sk, iph, info); + goto out; + } + + err = icmp_err_convert[code].errno; + break; + case ICMP_TIME_EXCEEDED: + err = EHOSTUNREACH; + break; + default: + goto out; + } + + switch (sk->state) { + struct open_request *req, **prev; + case TCP_LISTEN: + if (sk->lock.users != 0) + goto out; + + req = tcp_v4_search_req(tp, &prev, + th->dest, + iph->daddr, iph->saddr); + if (!req) + goto out; + + /* ICMPs are not backlogged, hence we cannot get + an established socket here. + */ + BUG_TRAP(req->sk == NULL); + + if (seq != req->snt_isn) { + NET_INC_STATS_BH(OutOfWindowIcmps); + goto out; + } + + /* + * Still in SYN_RECV, just remove it silently. + * There is no good way to pass the error to the newly + * created socket, and POSIX does not want network + * errors returned from accept(). + */ + tcp_synq_drop(sk, req, prev); + goto out; + + case TCP_SYN_SENT: + case TCP_SYN_RECV: /* Cannot happen. + It can f.e. if SYNs crossed. + */ + if (sk->lock.users == 0) { + TCP_INC_STATS_BH(TcpAttemptFails); + sk->err = err; + + sk->error_report(sk); + + tcp_done(sk); + } else { + sk->err_soft = err; + } + goto out; + } + + /* If we've already connected we will keep trying + * until we time out, or the user gives up. + * + * rfc1122 4.2.3.9 allows to consider as hard errors + * only PROTO_UNREACH and PORT_UNREACH (well, FRAG_FAILED too, + * but it is obsoleted by pmtu discovery). + * + * Note, that in modern internet, where routing is unreliable + * and in each dark corner broken firewalls sit, sending random + * errors ordered by their masters even this two messages finally lose + * their original sense (even Linux sends invalid PORT_UNREACHs) + * + * Now we are in compliance with RFCs. + * --ANK (980905) + */ + + if (sk->lock.users == 0 && sk->protinfo.af_inet.recverr) { + sk->err = err; + sk->error_report(sk); + } else { /* Only an error on timeout */ + sk->err_soft = err; + } + +out: + bh_unlock_sock(sk); + sock_put(sk); +#endif +} + +/* This routine computes an IPv4 TCP checksum. */ +void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, + struct sk_buff *skb) +{ +#if 0 + if (skb->ip_summed == CHECKSUM_HW) { + th->check = ~tcp_v4_check(th, len, sk->saddr, sk->daddr, 0); + skb->csum = offsetof(struct tcphdr, check); + } else { + th->check = tcp_v4_check(th, len, sk->saddr, sk->daddr, + csum_partial((char *)th, th->doff<<2, skb->csum)); + } +#endif +} + +/* + * This routine will send an RST to the other tcp. + * + * Someone asks: why I NEVER use socket parameters (TOS, TTL etc.) + * for reset. + * Answer: if a packet caused RST, it is not for a socket + * existing in our system, if it is matched to a socket, + * it is just duplicate segment or bug in other side's TCP. + * So that we build reply only basing on parameters + * arrived with segment. + * Exception: precedence violation. We do not implement it in any case. + */ + +static void tcp_v4_send_reset(struct sk_buff *skb) +{ +#if 0 + struct tcphdr *th = skb->h.th; + struct tcphdr rth; + struct ip_reply_arg arg; + + /* Never send a reset in response to a reset. */ + if (th->rst) + return; + + if (((struct rtable*)skb->dst)->rt_type != RTN_LOCAL) + return; + + /* Swap the send and the receive. */ + memset(&rth, 0, sizeof(struct tcphdr)); + rth.dest = th->source; + rth.source = th->dest; + rth.doff = sizeof(struct tcphdr)/4; + rth.rst = 1; + + if (th->ack) { + rth.seq = th->ack_seq; + } else { + rth.ack = 1; + rth.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin + + skb->len - (th->doff<<2)); + } + + memset(&arg, 0, sizeof arg); + arg.iov[0].iov_base = (unsigned char *)&rth; + arg.iov[0].iov_len = sizeof rth; + arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr, + skb->nh.iph->saddr, /*XXX*/ + sizeof(struct tcphdr), + IPPROTO_TCP, + 0); + arg.n_iov = 1; + arg.csumoffset = offsetof(struct tcphdr, check) / 2; + + tcp_socket->sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl; + ip_send_reply(tcp_socket->sk, skb, &arg, sizeof rth); + + TCP_INC_STATS_BH(TcpOutSegs); + TCP_INC_STATS_BH(TcpOutRsts); +#endif +} + +/* The code following below sending ACKs in SYN-RECV and TIME-WAIT states + outside socket context is ugly, certainly. What can I do? + */ + +static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) +{ +#if 0 + struct tcphdr *th = skb->h.th; + struct { + struct tcphdr th; + u32 tsopt[3]; + } rep; + struct ip_reply_arg arg; + + memset(&rep.th, 0, sizeof(struct tcphdr)); + memset(&arg, 0, sizeof arg); + + arg.iov[0].iov_base = (unsigned char *)&rep; + arg.iov[0].iov_len = sizeof(rep.th); + arg.n_iov = 1; + if (ts) { + rep.tsopt[0] = htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP); + rep.tsopt[1] = htonl(tcp_time_stamp); + rep.tsopt[2] = htonl(ts); + arg.iov[0].iov_len = sizeof(rep); + } + + /* Swap the send and the receive. */ + rep.th.dest = th->source; + rep.th.source = th->dest; + rep.th.doff = arg.iov[0].iov_len/4; + rep.th.seq = htonl(seq); + rep.th.ack_seq = htonl(ack); + rep.th.ack = 1; + rep.th.window = htons(win); + + arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr, + skb->nh.iph->saddr, /*XXX*/ + arg.iov[0].iov_len, + IPPROTO_TCP, + 0); + arg.csumoffset = offsetof(struct tcphdr, check) / 2; + + ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); + + TCP_INC_STATS_BH(TcpOutSegs); +#endif +} + +static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; + + tcp_v4_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, + tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent); + + tcp_tw_put(tw); +#endif +} + +static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req) +{ +#if 0 + tcp_v4_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, + req->ts_recent); +#endif +} + +static struct dst_entry* tcp_v4_route_req(struct sock *sk, struct open_request *req) +{ +#if 0 + struct rtable *rt; + struct ip_options *opt; + + opt = req->af.v4_req.opt; + if(ip_route_output(&rt, ((opt && opt->srr) ? + opt->faddr : + req->af.v4_req.rmt_addr), + req->af.v4_req.loc_addr, + RT_CONN_FLAGS(sk), sk->bound_dev_if)) { + IP_INC_STATS_BH(IpOutNoRoutes); + return NULL; + } + if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { + ip_rt_put(rt); + IP_INC_STATS_BH(IpOutNoRoutes); + return NULL; + } + return &rt->u.dst; +#else + return NULL; +#endif +} + +/* + * Send a SYN-ACK after having received an ACK. + * This still operates on a open_request only, not on a big + * socket. + */ +static int tcp_v4_send_synack(struct sock *sk, struct open_request *req, + struct dst_entry *dst) +{ +#if 0 + int err = -1; + struct sk_buff * skb; + + /* First, grab a route. */ + if (dst == NULL && + (dst = tcp_v4_route_req(sk, req)) == NULL) + goto out; + + skb = tcp_make_synack(sk, dst, req); + + if (skb) { + struct tcphdr *th = skb->h.th; + + th->check = tcp_v4_check(th, skb->len, + req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr, + csum_partial((char *)th, skb->len, skb->csum)); + + err = ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr, + req->af.v4_req.rmt_addr, req->af.v4_req.opt); + if (err == NET_XMIT_CN) + err = 0; + } + +out: + dst_release(dst); + return err; +#else + return 0; +#endif +} + +/* + * IPv4 open_request destructor. + */ +static void tcp_v4_or_free(struct open_request *req) +{ +#if 0 + if (req->af.v4_req.opt) + kfree(req->af.v4_req.opt); +#endif +} + +static inline void syn_flood_warning(struct sk_buff *skb) +{ +#if 0 + static unsigned long warntime; + + if (jiffies - warntime > HZ*60) { + warntime = jiffies; + printk(KERN_INFO + "possible SYN flooding on port %d. Sending cookies.\n", + ntohs(skb->h.th->dest)); + } +#endif +} + +/* + * Save and compile IPv4 options into the open_request if needed. + */ +static inline struct ip_options * +tcp_v4_save_options(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct ip_options *opt = &(IPCB(skb)->opt); + struct ip_options *dopt = NULL; + + if (opt && opt->optlen) { + int opt_size = optlength(opt); + dopt = kmalloc(opt_size, GFP_ATOMIC); + if (dopt) { + if (ip_options_echo(dopt, skb)) { + kfree(dopt); + dopt = NULL; + } + } + } + return dopt; +#else + return NULL; +#endif +} + +/* + * Maximum number of SYN_RECV sockets in queue per LISTEN socket. + * One SYN_RECV socket costs about 80bytes on a 32bit machine. + * It would be better to replace it with a global counter for all sockets + * but then some measure against one socket starving all other sockets + * would be needed. + * + * It was 128 by default. Experiments with real servers show, that + * it is absolutely not enough even at 100conn/sec. 256 cures most + * of problems. This value is adjusted to 128 for very small machines + * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). + * Further increasing requires to change hash table size. + */ +int sysctl_max_syn_backlog = 256; + +#if 0 +struct or_calltable or_ipv4 = { + PF_INET, + tcp_v4_send_synack, + tcp_v4_or_send_ack, + tcp_v4_or_free, + tcp_v4_send_reset +}; +#endif + +int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_opt tp; + struct open_request *req; + __u32 saddr = skb->nh.iph->saddr; + __u32 daddr = skb->nh.iph->daddr; + __u32 isn = TCP_SKB_CB(skb)->when; + struct dst_entry *dst = NULL; +#ifdef CONFIG_SYN_COOKIES + int want_cookie = 0; +#else +#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */ +#endif + + /* Never answer to SYNs send to broadcast or multicast */ + if (((struct rtable *)skb->dst)->rt_flags & + (RTCF_BROADCAST|RTCF_MULTICAST)) + goto drop; + + /* TW buckets are converted to open requests without + * limitations, they conserve resources and peer is + * evidently real one. + */ + if (tcp_synq_is_full(sk) && !isn) { +#ifdef CONFIG_SYN_COOKIES + if (sysctl_tcp_syncookies) { + want_cookie = 1; + } else +#endif + goto drop; + } + + /* Accept backlog is full. If we have already queued enough + * of warm entries in syn queue, drop request. It is better than + * clogging syn queue with openreqs with exponentially increasing + * timeout. + */ + if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) + goto drop; + + req = tcp_openreq_alloc(); + if (req == NULL) + goto drop; + + tcp_clear_options(&tp); + tp.mss_clamp = 536; + tp.user_mss = sk->tp_pinfo.af_tcp.user_mss; + + tcp_parse_options(skb, &tp, 0); + + if (want_cookie) { + tcp_clear_options(&tp); + tp.saw_tstamp = 0; + } + + if (tp.saw_tstamp && tp.rcv_tsval == 0) { + /* Some OSes (unknown ones, but I see them on web server, which + * contains information interesting only for windows' + * users) do not send their stamp in SYN. It is easy case. + * We simply do not advertise TS support. + */ + tp.saw_tstamp = 0; + tp.tstamp_ok = 0; + } + tp.tstamp_ok = tp.saw_tstamp; + + tcp_openreq_init(req, &tp, skb); + + req->af.v4_req.loc_addr = daddr; + req->af.v4_req.rmt_addr = saddr; + req->af.v4_req.opt = tcp_v4_save_options(sk, skb); + req->class = &or_ipv4; + if (!want_cookie) + TCP_ECN_create_request(req, skb->h.th); + + if (want_cookie) { +#ifdef CONFIG_SYN_COOKIES + syn_flood_warning(skb); +#endif + isn = cookie_v4_init_sequence(sk, skb, &req->mss); + } else if (isn == 0) { + struct inet_peer *peer = NULL; + + /* VJ's idea. We save last timestamp seen + * from the destination in peer table, when entering + * state TIME-WAIT, and check against it before + * accepting new connection request. + * + * If "isn" is not zero, this request hit alive + * timewait bucket, so that all the necessary checks + * are made in the function processing timewait state. + */ + if (tp.saw_tstamp && + sysctl_tcp_tw_recycle && + (dst = tcp_v4_route_req(sk, req)) != NULL && + (peer = rt_get_peer((struct rtable*)dst)) != NULL && + peer->v4daddr == saddr) { + if (xtime.tv_sec < peer->tcp_ts_stamp + TCP_PAWS_MSL && + (s32)(peer->tcp_ts - req->ts_recent) > TCP_PAWS_WINDOW) { + NET_INC_STATS_BH(PAWSPassiveRejected); + dst_release(dst); + goto drop_and_free; + } + } + /* Kill the following clause, if you dislike this way. */ + else if (!sysctl_tcp_syncookies && + (sysctl_max_syn_backlog - tcp_synq_len(sk) + < (sysctl_max_syn_backlog>>2)) && + (!peer || !peer->tcp_ts_stamp) && + (!dst || !dst->rtt)) { + /* Without syncookies last quarter of + * backlog is filled with destinations, proven to be alive. + * It means that we continue to communicate + * to destinations, already remembered + * to the moment of synflood. + */ + NETDEBUG(if (net_ratelimit()) \ + printk(KERN_DEBUG "TCP: drop open request from %u.%u.%u.%u/%u\n", \ + NIPQUAD(saddr), ntohs(skb->h.th->source))); + dst_release(dst); + goto drop_and_free; + } + + isn = tcp_v4_init_sequence(sk, skb); + } + req->snt_isn = isn; + + if (tcp_v4_send_synack(sk, req, dst)) + goto drop_and_free; + + if (want_cookie) { + tcp_openreq_free(req); + } else { + tcp_v4_synq_add(sk, req); + } + return 0; + +drop_and_free: + tcp_openreq_free(req); +drop: + TCP_INC_STATS_BH(TcpAttemptFails); + return 0; +#else + return 0; +#endif +} + + +/* + * The three way handshake has completed - we got a valid synack - + * now create the new socket. + */ +struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst) +{ +#if 0 + struct tcp_opt *newtp; + struct sock *newsk; + + if (tcp_acceptq_is_full(sk)) + goto exit_overflow; + + if (dst == NULL && + (dst = tcp_v4_route_req(sk, req)) == NULL) + goto exit; + + newsk = tcp_create_openreq_child(sk, req, skb); + if (!newsk) + goto exit; + + newsk->dst_cache = dst; + newsk->route_caps = dst->dev->features; + + newtp = &(newsk->tp_pinfo.af_tcp); + newsk->daddr = req->af.v4_req.rmt_addr; + newsk->saddr = req->af.v4_req.loc_addr; + newsk->rcv_saddr = req->af.v4_req.loc_addr; + newsk->protinfo.af_inet.opt = req->af.v4_req.opt; + req->af.v4_req.opt = NULL; + newsk->protinfo.af_inet.mc_index = tcp_v4_iif(skb); + newsk->protinfo.af_inet.mc_ttl = skb->nh.iph->ttl; + newtp->ext_header_len = 0; + if (newsk->protinfo.af_inet.opt) + newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen; + newsk->protinfo.af_inet.id = newtp->write_seq^jiffies; + + tcp_sync_mss(newsk, dst->pmtu); + newtp->advmss = dst->advmss; + tcp_initialize_rcv_mss(newsk); + + __tcp_v4_hash(newsk, 0); + __tcp_inherit_port(sk, newsk); + + return newsk; + +exit_overflow: + NET_INC_STATS_BH(ListenOverflows); +exit: + NET_INC_STATS_BH(ListenDrops); + dst_release(dst); + return NULL; +#else + return NULL; +#endif +} + +static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb) +{ +#if 0 + struct open_request *req, **prev; + struct tcphdr *th = skb->h.th; + struct iphdr *iph = skb->nh.iph; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sock *nsk; + + /* Find possible connection requests. */ + req = tcp_v4_search_req(tp, &prev, + th->source, + iph->saddr, iph->daddr); + if (req) + return tcp_check_req(sk, skb, req, prev); + + nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr, + th->source, + skb->nh.iph->daddr, + ntohs(th->dest), + tcp_v4_iif(skb)); + + if (nsk) { + if (nsk->state != TCP_TIME_WAIT) { + bh_lock_sock(nsk); + return nsk; + } + tcp_tw_put((struct tcp_tw_bucket*)nsk); + return NULL; + } + +#ifdef CONFIG_SYN_COOKIES + if (!th->rst && !th->syn && th->ack) + sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt)); +#endif + return sk; +#else + return NULL; +#endif +} + +static int tcp_v4_checksum_init(struct sk_buff *skb) +{ +#if 0 + if (skb->ip_summed == CHECKSUM_HW) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + if (!tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr,skb->csum)) + return 0; + + NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v4 csum failed\n")); + skb->ip_summed = CHECKSUM_NONE; + } + if (skb->len <= 76) { + if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr, + skb_checksum(skb, 0, skb->len, 0))) + return -1; + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->csum = ~tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr,0); + } + return 0; +#else + return 0; +#endif +} + + +/* The socket must have it's spinlock held when we get + * here. + * + * We have a potential double-lock case here, so even when + * doing backlog processing we use the BH locking scheme. + * This is because we cannot sleep with the original spinlock + * held. + */ +int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) +{ +#if 0 +#ifdef CONFIG_FILTER + struct sk_filter *filter = sk->filter; + if (filter && sk_filter(skb, filter)) + goto discard; +#endif /* CONFIG_FILTER */ + + IP_INC_STATS_BH(IpInDelivers); + + if (sk->state == TCP_ESTABLISHED) { /* Fast path */ + TCP_CHECK_TIMER(sk); + if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) + goto reset; + TCP_CHECK_TIMER(sk); + return 0; + } + + if (skb->len < (skb->h.th->doff<<2) || tcp_checksum_complete(skb)) + goto csum_err; + + if (sk->state == TCP_LISTEN) { + struct sock *nsk = tcp_v4_hnd_req(sk, skb); + if (!nsk) + goto discard; + + if (nsk != sk) { + if (tcp_child_process(sk, nsk, skb)) + goto reset; + return 0; + } + } + + TCP_CHECK_TIMER(sk); + if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len)) + goto reset; + TCP_CHECK_TIMER(sk); + return 0; + +reset: + tcp_v4_send_reset(skb); +discard: + kfree_skb(skb); + /* Be careful here. If this function gets more complicated and + * gcc suffers from register pressure on the x86, sk (in %ebx) + * might be destroyed here. This current version compiles correctly, + * but you have been warned. + */ + return 0; + +csum_err: + TCP_INC_STATS_BH(TcpInErrs); + goto discard; +#else + return 0; +#endif +} + +/* + * From tcp_input.c + */ + +int tcp_v4_rcv(struct sk_buff *skb) +{ +#if 0 + struct tcphdr *th; + struct sock *sk; + int ret; + + if (skb->pkt_type!=PACKET_HOST) + goto discard_it; + + /* Count it even if it's bad */ + TCP_INC_STATS_BH(TcpInSegs); + + if (!pskb_may_pull(skb, sizeof(struct tcphdr))) + goto discard_it; + + th = skb->h.th; + + if (th->doff < sizeof(struct tcphdr)/4) + goto bad_packet; + if (!pskb_may_pull(skb, th->doff*4)) + goto discard_it; + + /* An explanation is required here, I think. + * Packet length and doff are validated by header prediction, + * provided case of th->doff==0 is elimineted. + * So, we defer the checks. */ + if ((skb->ip_summed != CHECKSUM_UNNECESSARY && + tcp_v4_checksum_init(skb) < 0)) + goto bad_packet; + + th = skb->h.th; + TCP_SKB_CB(skb)->seq = ntohl(th->seq); + TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + + skb->len - th->doff*4); + TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); + TCP_SKB_CB(skb)->when = 0; + TCP_SKB_CB(skb)->flags = skb->nh.iph->tos; + TCP_SKB_CB(skb)->sacked = 0; + + sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source, + skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb)); + + if (!sk) + goto no_tcp_socket; + +process: + if(!ipsec_sk_policy(sk,skb)) + goto discard_and_relse; + + if (sk->state == TCP_TIME_WAIT) + goto do_time_wait; + + skb->dev = NULL; + + bh_lock_sock(sk); + ret = 0; + if (!sk->lock.users) { + if (!tcp_prequeue(sk, skb)) + ret = tcp_v4_do_rcv(sk, skb); + } else + sk_add_backlog(sk, skb); + bh_unlock_sock(sk); + + sock_put(sk); + + return ret; + +no_tcp_socket: + if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { +bad_packet: + TCP_INC_STATS_BH(TcpInErrs); + } else { + tcp_v4_send_reset(skb); + } + +discard_it: + /* Discard frame. */ + kfree_skb(skb); + return 0; + +discard_and_relse: + sock_put(sk); + goto discard_it; + +do_time_wait: + if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { + TCP_INC_STATS_BH(TcpInErrs); + goto discard_and_relse; + } + switch(tcp_timewait_state_process((struct tcp_tw_bucket *)sk, + skb, th, skb->len)) { + case TCP_TW_SYN: + { + struct sock *sk2; + + sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb)); + if (sk2 != NULL) { + tcp_tw_deschedule((struct tcp_tw_bucket *)sk); + tcp_timewait_kill((struct tcp_tw_bucket *)sk); + tcp_tw_put((struct tcp_tw_bucket *)sk); + sk = sk2; + goto process; + } + /* Fall through to ACK */ + } + case TCP_TW_ACK: + tcp_v4_timewait_ack(sk, skb); + break; + case TCP_TW_RST: + goto no_tcp_socket; + case TCP_TW_SUCCESS:; + } + goto discard_it; +#endif +} + +/* With per-bucket locks this operation is not-atomic, so that + * this version is not worse. + */ +static void __tcp_v4_rehash(struct sock *sk) +{ +#if 0 + sk->prot->unhash(sk); + sk->prot->hash(sk); +#endif +} + +static int tcp_v4_reselect_saddr(struct sock *sk) +{ +#if 0 + int err; + struct rtable *rt; + __u32 old_saddr = sk->saddr; + __u32 new_saddr; + __u32 daddr = sk->daddr; + + if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) + daddr = sk->protinfo.af_inet.opt->faddr; + + /* Query new route. */ + err = ip_route_connect(&rt, daddr, 0, + RT_TOS(sk->protinfo.af_inet.tos)|sk->localroute, + sk->bound_dev_if); + if (err) + return err; + + __sk_dst_set(sk, &rt->u.dst); + sk->route_caps = rt->u.dst.dev->features; + + new_saddr = rt->rt_src; + + if (new_saddr == old_saddr) + return 0; + + if (sysctl_ip_dynaddr > 1) { + printk(KERN_INFO "tcp_v4_rebuild_header(): shifting sk->saddr " + "from %d.%d.%d.%d to %d.%d.%d.%d\n", + NIPQUAD(old_saddr), + NIPQUAD(new_saddr)); + } + + sk->saddr = new_saddr; + sk->rcv_saddr = new_saddr; + + /* XXX The only one ugly spot where we need to + * XXX really change the sockets identity after + * XXX it has entered the hashes. -DaveM + * + * Besides that, it does not check for connection + * uniqueness. Wait for troubles. + */ + __tcp_v4_rehash(sk); + return 0; +#else + return 0; +#endif +} + +int tcp_v4_rebuild_header(struct sock *sk) +{ +#if 0 + struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); + u32 daddr; + int err; + + /* Route is OK, nothing to do. */ + if (rt != NULL) + return 0; + + /* Reroute. */ + daddr = sk->daddr; + if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) + daddr = sk->protinfo.af_inet.opt->faddr; + + err = ip_route_output(&rt, daddr, sk->saddr, + RT_CONN_FLAGS(sk), sk->bound_dev_if); + if (!err) { + __sk_dst_set(sk, &rt->u.dst); + sk->route_caps = rt->u.dst.dev->features; + return 0; + } + + /* Routing failed... */ + sk->route_caps = 0; + + if (!sysctl_ip_dynaddr || + sk->state != TCP_SYN_SENT || + (sk->userlocks & SOCK_BINDADDR_LOCK) || + (err = tcp_v4_reselect_saddr(sk)) != 0) + sk->err_soft=-err; + + return err; +#else + return 0; +#endif +} + +static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) +{ +#if 0 + struct sockaddr_in *sin = (struct sockaddr_in *) uaddr; + + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = sk->daddr; + sin->sin_port = sk->dport; +#endif +} + +/* VJ's idea. Save last timestamp seen from this destination + * and hold it at least for normal timewait interval to use for duplicate + * segment detection in subsequent connections, before they enter synchronized + * state. + */ + +int tcp_v4_remember_stamp(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct rtable *rt = (struct rtable*)__sk_dst_get(sk); + struct inet_peer *peer = NULL; + int release_it = 0; + + if (rt == NULL || rt->rt_dst != sk->daddr) { + peer = inet_getpeer(sk->daddr, 1); + release_it = 1; + } else { + if (rt->peer == NULL) + rt_bind_peer(rt, 1); + peer = rt->peer; + } + + if (peer) { + if ((s32)(peer->tcp_ts - tp->ts_recent) <= 0 || + (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec && + peer->tcp_ts_stamp <= tp->ts_recent_stamp)) { + peer->tcp_ts_stamp = tp->ts_recent_stamp; + peer->tcp_ts = tp->ts_recent; + } + if (release_it) + inet_putpeer(peer); + return 1; + } + + return 0; +#else + return 0; +#endif +} + +int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw) +{ +#if 0 + struct inet_peer *peer = NULL; + + peer = inet_getpeer(tw->daddr, 1); + + if (peer) { + if ((s32)(peer->tcp_ts - tw->ts_recent) <= 0 || + (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec && + peer->tcp_ts_stamp <= tw->ts_recent_stamp)) { + peer->tcp_ts_stamp = tw->ts_recent_stamp; + peer->tcp_ts = tw->ts_recent; + } + inet_putpeer(peer); + return 1; + } + + return 0; +#else + return 0; +#endif +} + +#if 0 +struct tcp_func ipv4_specific = { + ip_queue_xmit, + tcp_v4_send_check, + tcp_v4_rebuild_header, + tcp_v4_conn_request, + tcp_v4_syn_recv_sock, + tcp_v4_remember_stamp, + sizeof(struct iphdr), + + ip_setsockopt, + ip_getsockopt, + v4_addr2sockaddr, + sizeof(struct sockaddr_in) +}; +#endif + +/* NOTE: A lot of things set to zero explicitly by call to + * sk_alloc() so need not be done here. + */ +static int tcp_v4_init_sock(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + skb_queue_head_init(&tp->out_of_order_queue); + tcp_init_xmit_timers(sk); + tcp_prequeue_init(tp); + + tp->rto = TCP_TIMEOUT_INIT; + tp->mdev = TCP_TIMEOUT_INIT; + + /* So many TCP implementations out there (incorrectly) count the + * initial SYN frame in their delayed-ACK and congestion control + * algorithms that we must have the following bandaid to talk + * efficiently to them. -DaveM + */ + tp->snd_cwnd = 2; + + /* See draft-stevens-tcpca-spec-01 for discussion of the + * initialization of these values. + */ + tp->snd_ssthresh = 0x7fffffff; /* Infinity */ + tp->snd_cwnd_clamp = ~0; + tp->mss_cache = 536; + + tp->reordering = sysctl_tcp_reordering; + + sk->state = TCP_CLOSE; + + sk->write_space = tcp_write_space; + sk->use_write_queue = 1; + + sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific; + + sk->sndbuf = sysctl_tcp_wmem[1]; + sk->rcvbuf = sysctl_tcp_rmem[1]; + + atomic_inc(&tcp_sockets_allocated); + + return 0; +#else + return 0; +#endif +} + +static int tcp_v4_destroy_sock(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tcp_clear_xmit_timers(sk); + + /* Cleanup up the write buffer. */ + tcp_writequeue_purge(sk); + + /* Cleans up our, hopefully empty, out_of_order_queue. */ + __skb_queue_purge(&tp->out_of_order_queue); + + /* Clean prequeue, it must be empty really */ + __skb_queue_purge(&tp->ucopy.prequeue); + + /* Clean up a referenced TCP bind bucket. */ + if(sk->prev != NULL) + tcp_put_port(sk); + + /* If sendmsg cached page exists, toss it. */ + if (tp->sndmsg_page != NULL) + __free_page(tp->sndmsg_page); + + atomic_dec(&tcp_sockets_allocated); + + return 0; +#else + return 0; +#endif +} + +/* Proc filesystem TCP sock list dumping. */ +static void get_openreq(struct sock *sk, struct open_request *req, char *tmpbuf, int i, int uid) +{ +#if 0 + int ttd = req->expires - jiffies; + + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" + " %02X %08X:%08X %02X:%08X %08X %5d %8d %u %d %p", + i, + req->af.v4_req.loc_addr, + ntohs(sk->sport), + req->af.v4_req.rmt_addr, + ntohs(req->rmt_port), + TCP_SYN_RECV, + 0,0, /* could print option size, but that is af dependent. */ + 1, /* timers active (only the expire timer) */ + ttd, + req->retrans, + uid, + 0, /* non standard timer */ + 0, /* open_requests have no inode */ + atomic_read(&sk->refcnt), + req + ); +#endif +} + +static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i) +{ +#if 0 + unsigned int dest, src; + __u16 destp, srcp; + int timer_active; + unsigned long timer_expires; + struct tcp_opt *tp = &sp->tp_pinfo.af_tcp; + + dest = sp->daddr; + src = sp->rcv_saddr; + destp = ntohs(sp->dport); + srcp = ntohs(sp->sport); + if (tp->pending == TCP_TIME_RETRANS) { + timer_active = 1; + timer_expires = tp->timeout; + } else if (tp->pending == TCP_TIME_PROBE0) { + timer_active = 4; + timer_expires = tp->timeout; + } else if (timer_pending(&sp->timer)) { + timer_active = 2; + timer_expires = sp->timer.expires; + } else { + timer_active = 0; + timer_expires = jiffies; + } + + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d", + i, src, srcp, dest, destp, sp->state, + tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, + timer_active, timer_expires-jiffies, + tp->retransmits, + sock_i_uid(sp), + tp->probes_out, + sock_i_ino(sp), + atomic_read(&sp->refcnt), sp, + tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong, + tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh + ); +#endif +} + +static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) +{ +#if 0 + unsigned int dest, src; + __u16 destp, srcp; + int ttd = tw->ttd - jiffies; + + if (ttd < 0) + ttd = 0; + + dest = tw->daddr; + src = tw->rcv_saddr; + destp = ntohs(tw->dport); + srcp = ntohs(tw->sport); + + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" + " %02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", + i, src, srcp, dest, destp, tw->substate, 0, 0, + 3, ttd, 0, 0, 0, 0, + atomic_read(&tw->refcnt), tw); +#endif +} + +#define TMPSZ 150 + +int tcp_get_info(char *buffer, char **start, off_t offset, int length) +{ +#if 0 + int len = 0, num = 0, i; + off_t begin, pos = 0; + char tmpbuf[TMPSZ+1]; + + if (offset < TMPSZ) + len += sprintf(buffer, "%-*s\n", TMPSZ-1, + " sl local_address rem_address st tx_queue " + "rx_queue tr tm->when retrnsmt uid timeout inode"); + + pos = TMPSZ; + + /* First, walk listening socket table. */ + tcp_listen_lock(); + for(i = 0; i < TCP_LHTABLE_SIZE; i++) { + struct sock *sk; + struct tcp_listen_opt *lopt; + int k; + + for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) { + struct open_request *req; + int uid; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + if (!TCP_INET_FAMILY(sk->family)) + goto skip_listen; + + pos += TMPSZ; + if (pos >= offset) { + get_tcp_sock(sk, tmpbuf, num); + len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); + if (pos >= offset + length) { + tcp_listen_unlock(); + goto out_no_bh; + } + } + +skip_listen: + uid = sock_i_uid(sk); + read_lock_bh(&tp->syn_wait_lock); + lopt = tp->listen_opt; + if (lopt && lopt->qlen != 0) { + for (k=0; ksyn_table[k]; req; req = req->dl_next, num++) { + if (!TCP_INET_FAMILY(req->class->family)) + continue; + + pos += TMPSZ; + if (pos <= offset) + continue; + get_openreq(sk, req, tmpbuf, num, uid); + len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); + if (pos >= offset + length) { + read_unlock_bh(&tp->syn_wait_lock); + tcp_listen_unlock(); + goto out_no_bh; + } + } + } + } + read_unlock_bh(&tp->syn_wait_lock); + + /* Completed requests are in normal socket hash table */ + } + } + tcp_listen_unlock(); + + local_bh_disable(); + + /* Next, walk established hash chain. */ + for (i = 0; i < tcp_ehash_size; i++) { + struct tcp_ehash_bucket *head = &tcp_ehash[i]; + struct sock *sk; + struct tcp_tw_bucket *tw; + + read_lock(&head->lock); + for(sk = head->chain; sk; sk = sk->next, num++) { + if (!TCP_INET_FAMILY(sk->family)) + continue; + pos += TMPSZ; + if (pos <= offset) + continue; + get_tcp_sock(sk, tmpbuf, num); + len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); + if (pos >= offset + length) { + read_unlock(&head->lock); + goto out; + } + } + for (tw = (struct tcp_tw_bucket *)tcp_ehash[i+tcp_ehash_size].chain; + tw != NULL; + tw = (struct tcp_tw_bucket *)tw->next, num++) { + if (!TCP_INET_FAMILY(tw->family)) + continue; + pos += TMPSZ; + if (pos <= offset) + continue; + get_timewait_sock(tw, tmpbuf, num); + len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); + if (pos >= offset + length) { + read_unlock(&head->lock); + goto out; + } + } + read_unlock(&head->lock); + } + +out: + local_bh_enable(); +out_no_bh: + + begin = len - (pos - offset); + *start = buffer + begin; + len -= begin; + if (len > length) + len = length; + if (len < 0) + len = 0; + return len; +#endif +} + +struct proto tcp_prot = { + name: "TCP", + close: tcp_close, + connect: tcp_v4_connect, + disconnect: tcp_disconnect, + accept: tcp_accept, + ioctl: tcp_ioctl, + init: tcp_v4_init_sock, + destroy: tcp_v4_destroy_sock, + shutdown: tcp_shutdown, + setsockopt: tcp_setsockopt, + getsockopt: tcp_getsockopt, + sendmsg: tcp_sendmsg, + recvmsg: tcp_recvmsg, + backlog_rcv: tcp_v4_do_rcv, + hash: tcp_v4_hash, + unhash: tcp_unhash, + get_port: tcp_v4_get_port, +}; + + + +void tcp_v4_init(struct net_proto_family *ops) +{ +#if 0 + int err; + + tcp_inode.i_mode = S_IFSOCK; + tcp_inode.i_sock = 1; + tcp_inode.i_uid = 0; + tcp_inode.i_gid = 0; + init_waitqueue_head(&tcp_inode.i_wait); + init_waitqueue_head(&tcp_inode.u.socket_i.wait); + + tcp_socket->inode = &tcp_inode; + tcp_socket->state = SS_UNCONNECTED; + tcp_socket->type=SOCK_RAW; + + if ((err=ops->create(tcp_socket, IPPROTO_TCP))<0) + panic("Failed to create the TCP control socket.\n"); + tcp_socket->sk->allocation=GFP_ATOMIC; + tcp_socket->sk->protinfo.af_inet.ttl = MAXTTL; + + /* Unhash it so that IP input processing does not even + * see it, we do not wish this socket to see incoming + * packets. + */ + tcp_socket->sk->prot->unhash(tcp_socket->sk); +#endif +} diff --git a/drivers/net/tcpip/transport/tcp/tcp_output.c b/drivers/net/tcpip/transport/tcp/tcp_output.c new file mode 100755 index 0000000..01e75fb --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/tcp_output.c @@ -0,0 +1,1549 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: transport/tcp/tcp_output.c + * PURPOSE: Transmission Control Protocol + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 15-01-2003 Imported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Implementation of the Transmission Control Protocol(TCP). + * + * Version: $Id$ + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * Mark Evans, + * Corey Minyard + * Florian La Roche, + * Charles Hedrick, + * Linus Torvalds, + * Alan Cox, + * Matthew Dillon, + * Arnt Gulbrandsen, + * Jorge Cwik, + */ + +/* + * Changes: Pedro Roque : Retransmit queue handled by TCP. + * : Fragmentation on mtu decrease + * : Segment collapse on retransmit + * : AF independence + * + * Linus Torvalds : send_delayed_ack + * David S. Miller : Charge memory using the right skb + * during syn/ack processing. + * David S. Miller : Output engine completely rewritten. + * Andrea Arcangeli: SYNACK carry ts_recent in tsecr. + * Cacophonix Gaul : draft-minshall-nagle-01 + * J Hadi Salim : ECN support + * + */ + +#if 0 +#include + +#include +#include +#else +#include "linux.h" +#include "tcpcore.h" +#endif + +/* People can turn this off for buggy TCP's found in printers etc. */ +int sysctl_tcp_retrans_collapse = 1; + +static __inline__ +void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) +{ + tp->send_head = skb->next; + if (tp->send_head == (struct sk_buff *) &sk->write_queue) + tp->send_head = NULL; + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + if (tp->packets_out++ == 0) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); +} + +/* SND.NXT, if window was not shrunk. + * If window has been shrunk, what should we make? It is not clear at all. + * Using SND.UNA we will fail to open window, SND.NXT is out of window. :-( + * Anything in between SND.UNA...SND.UNA+SND.WND also can be already + * invalid. OK, let's make this for now: + */ +static __inline__ __u32 tcp_acceptable_seq(struct sock *sk, struct tcp_opt *tp) +{ + if (!before(tp->snd_una+tp->snd_wnd, tp->snd_nxt)) + return tp->snd_nxt; + else + return tp->snd_una+tp->snd_wnd; +} + +/* Calculate mss to advertise in SYN segment. + * RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that: + * + * 1. It is independent of path mtu. + * 2. Ideally, it is maximal possible segment size i.e. 65535-40. + * 3. For IPv4 it is reasonable to calculate it from maximal MTU of + * attached devices, because some buggy hosts are confused by + * large MSS. + * 4. We do not make 3, we advertise MSS, calculated from first + * hop device mtu, but allow to raise it to ip_rt_min_advmss. + * This may be overriden via information stored in routing table. + * 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible, + * probably even Jumbo". + */ +static __u16 tcp_advertise_mss(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct dst_entry *dst = __sk_dst_get(sk); + int mss = tp->advmss; + + if (dst && dst->advmss < mss) { + mss = dst->advmss; + tp->advmss = mss; + } + + return (__u16)mss; +#else + return 0; +#endif +} + +/* RFC2861. Reset CWND after idle period longer RTO to "restart window". + * This is the first part of cwnd validation mechanism. */ +static void tcp_cwnd_restart(struct tcp_opt *tp) +{ +#if 0 + s32 delta = tcp_time_stamp - tp->lsndtime; + u32 restart_cwnd = tcp_init_cwnd(tp); + u32 cwnd = tp->snd_cwnd; + + tp->snd_ssthresh = tcp_current_ssthresh(tp); + restart_cwnd = min(restart_cwnd, cwnd); + + while ((delta -= tp->rto) > 0 && cwnd > restart_cwnd) + cwnd >>= 1; + tp->snd_cwnd = max(cwnd, restart_cwnd); + tp->snd_cwnd_stamp = tcp_time_stamp; + tp->snd_cwnd_used = 0; +#endif +} + +static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb) +{ +#if 0 + u32 now = tcp_time_stamp; + + if (!tp->packets_out && (s32)(now - tp->lsndtime) > tp->rto) + tcp_cwnd_restart(tp); + + tp->lsndtime = now; + + /* If it is a reply for ato after last received + * packet, enter pingpong mode. + */ + if ((u32)(now - tp->ack.lrcvtime) < tp->ack.ato) + tp->ack.pingpong = 1; +#endif +} + +static __inline__ void tcp_event_ack_sent(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tcp_dec_quickack_mode(tp); + tcp_clear_xmit_timer(sk, TCP_TIME_DACK); +#endif +} + +/* Chose a new window to advertise, update state in tcp_opt for the + * socket, and return result with RFC1323 scaling applied. The return + * value can be stuffed directly into th->window for an outgoing + * frame. + */ +static __inline__ u16 tcp_select_window(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + u32 cur_win = tcp_receive_window(tp); + u32 new_win = __tcp_select_window(sk); + + /* Never shrink the offered window */ + if(new_win < cur_win) { + /* Danger Will Robinson! + * Don't update rcv_wup/rcv_wnd here or else + * we will not be able to advertise a zero + * window in time. --DaveM + * + * Relax Will Robinson. + */ + new_win = cur_win; + } + tp->rcv_wnd = new_win; + tp->rcv_wup = tp->rcv_nxt; + + /* RFC1323 scaling applied */ + new_win >>= tp->rcv_wscale; + + /* If we advertise zero window, disable fast path. */ + if (new_win == 0) + tp->pred_flags = 0; + + return new_win; +#else + return 0; +#endif +} + + +/* This routine actually transmits TCP packets queued in by + * tcp_do_sendmsg(). This is used by both the initial + * transmission and possible later retransmissions. + * All SKB's seen here are completely headerless. It is our + * job to build the TCP header, and pass the packet down to + * IP so it can do the same plus pass the packet off to the + * device. + * + * We are working here with either a clone of the original + * SKB, or a fresh unique copy made by the retransmit engine. + */ +int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + if(skb != NULL) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); + int tcp_header_size = tp->tcp_header_len; + struct tcphdr *th; + int sysctl_flags; + int err; + +#define SYSCTL_FLAG_TSTAMPS 0x1 +#define SYSCTL_FLAG_WSCALE 0x2 +#define SYSCTL_FLAG_SACK 0x4 + + sysctl_flags = 0; + if (tcb->flags & TCPCB_FLAG_SYN) { + tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS; + if(sysctl_tcp_timestamps) { + tcp_header_size += TCPOLEN_TSTAMP_ALIGNED; + sysctl_flags |= SYSCTL_FLAG_TSTAMPS; + } + if(sysctl_tcp_window_scaling) { + tcp_header_size += TCPOLEN_WSCALE_ALIGNED; + sysctl_flags |= SYSCTL_FLAG_WSCALE; + } + if(sysctl_tcp_sack) { + sysctl_flags |= SYSCTL_FLAG_SACK; + if(!(sysctl_flags & SYSCTL_FLAG_TSTAMPS)) + tcp_header_size += TCPOLEN_SACKPERM_ALIGNED; + } + } else if (tp->eff_sacks) { + /* A SACK is 2 pad bytes, a 2 byte header, plus + * 2 32-bit sequence numbers for each SACK block. + */ + tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED + + (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK)); + } + th = (struct tcphdr *) skb_push(skb, tcp_header_size); + skb->h.th = th; + skb_set_owner_w(skb, sk); + + /* Build TCP header and checksum it. */ + th->source = sk->sport; + th->dest = sk->dport; + th->seq = htonl(tcb->seq); + th->ack_seq = htonl(tp->rcv_nxt); + *(((__u16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) | tcb->flags); + if (tcb->flags & TCPCB_FLAG_SYN) { + /* RFC1323: The window in SYN & SYN/ACK segments + * is never scaled. + */ + th->window = htons(tp->rcv_wnd); + } else { + th->window = htons(tcp_select_window(sk)); + } + th->check = 0; + th->urg_ptr = 0; + + if (tp->urg_mode && + between(tp->snd_up, tcb->seq+1, tcb->seq+0xFFFF)) { + th->urg_ptr = htons(tp->snd_up-tcb->seq); + th->urg = 1; + } + + if (tcb->flags & TCPCB_FLAG_SYN) { + tcp_syn_build_options((__u32 *)(th + 1), + tcp_advertise_mss(sk), + (sysctl_flags & SYSCTL_FLAG_TSTAMPS), + (sysctl_flags & SYSCTL_FLAG_SACK), + (sysctl_flags & SYSCTL_FLAG_WSCALE), + tp->rcv_wscale, + tcb->when, + tp->ts_recent); + } else { + tcp_build_and_update_options((__u32 *)(th + 1), + tp, tcb->when); + + TCP_ECN_send(sk, tp, skb, tcp_header_size); + } + tp->af_specific->send_check(sk, th, skb->len, skb); + + if (tcb->flags & TCPCB_FLAG_ACK) + tcp_event_ack_sent(sk); + + if (skb->len != tcp_header_size) + tcp_event_data_sent(tp, skb); + + TCP_INC_STATS(TcpOutSegs); + + err = tp->af_specific->queue_xmit(skb); + if (err <= 0) + return err; + + tcp_enter_cwr(tp); + + /* NET_XMIT_CN is special. It does not guarantee, + * that this packet is lost. It tells that device + * is about to start to drop packets or already + * drops some packets of the same priority and + * invokes us to send less aggressively. + */ + return err == NET_XMIT_CN ? 0 : err; + } + return -ENOBUFS; +#undef SYSCTL_FLAG_TSTAMPS +#undef SYSCTL_FLAG_WSCALE +#undef SYSCTL_FLAG_SACK +#else + return 0; +#endif +} + + +/* This is the main buffer sending routine. We queue the buffer + * and decide whether to queue or transmit now. + * + * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, + * otherwise socket can stall. + */ +void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigned cur_mss) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* Advance write_seq and place onto the write_queue. */ + tp->write_seq = TCP_SKB_CB(skb)->end_seq; + __skb_queue_tail(&sk->write_queue, skb); + tcp_charge_skb(sk, skb); + + if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, tp->nonagle)) { + /* Send it out now. */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) { + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_minshall_update(tp, cur_mss, skb); + if (tp->packets_out++ == 0) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return; + } + } + /* Queue it, remembering where we must start sending. */ + if (tp->send_head == NULL) + tp->send_head = skb; +#endif +} + +/* Send _single_ skb sitting at the send head. This function requires + * true push pending frames to setup probe timer etc. + */ +void tcp_push_one(struct sock *sk, unsigned cur_mss) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb = tp->send_head; + + if (tcp_snd_test(tp, skb, cur_mss, 1)) { + /* Send it out now. */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) { + tp->send_head = NULL; + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + if (tp->packets_out++ == 0) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return; + } + } +#endif +} + +/* Split fragmented skb to two parts at length len. */ + +static void skb_split(struct sk_buff *skb, struct sk_buff *skb1, u32 len) +{ +#if 0 + int i; + int pos = skb->len - skb->data_len; + + if (len < pos) { + /* Split line is inside header. */ + memcpy(skb_put(skb1, pos-len), skb->data + len, pos-len); + + /* And move data appendix as is. */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i]; + + skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags; + skb_shinfo(skb)->nr_frags = 0; + + skb1->data_len = skb->data_len; + skb1->len += skb1->data_len; + skb->data_len = 0; + skb->len = len; + skb->tail = skb->data+len; + } else { + int k = 0; + int nfrags = skb_shinfo(skb)->nr_frags; + + /* Second chunk has no header, nothing to copy. */ + + skb_shinfo(skb)->nr_frags = 0; + skb1->len = skb1->data_len = skb->len - len; + skb->len = len; + skb->data_len = len - pos; + + for (i=0; ifrags[i].size; + if (pos + size > len) { + skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i]; + + if (pos < len) { + /* Split frag. + * We have to variants in this case: + * 1. Move all the frag to the second + * part, if it is possible. F.e. + * this approach is mandatory for TUX, + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ + get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += (len-pos); + skb_shinfo(skb1)->frags[0].size -= (len-pos); + skb_shinfo(skb)->frags[i].size = len-pos; + skb_shinfo(skb)->nr_frags++; + } + k++; + } else { + skb_shinfo(skb)->nr_frags++; + } + pos += size; + } + skb_shinfo(skb1)->nr_frags = k; + } +#endif +} + +/* Function to create two new TCP segments. Shrinks the given segment + * to the specified size and appends a new segment with the rest of the + * packet to the list. This won't be called frequently, I hope. + * Remember, these are still headerless SKBs at this point. + */ +static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct sk_buff *buff; + int nsize = skb->len - len; + u16 flags; + + if (skb_cloned(skb) && + skb_is_nonlinear(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + return -ENOMEM; + + /* Get a new skb... force flag on. */ + buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC); + if (buff == NULL) + return -ENOMEM; /* We'll just try again later. */ + tcp_charge_skb(sk, buff); + + /* Correct the sequence numbers. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; + TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; + + /* PSH and FIN should only be set in the second packet. */ + flags = TCP_SKB_CB(skb)->flags; + TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH); + TCP_SKB_CB(buff)->flags = flags; + TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_EVER_RETRANS|TCPCB_AT_TAIL); + if (TCP_SKB_CB(buff)->sacked&TCPCB_LOST) { + tp->lost_out++; + tp->left_out++; + } + TCP_SKB_CB(skb)->sacked &= ~TCPCB_AT_TAIL; + + if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_HW) { + /* Copy and checksum data tail into the new buffer. */ + buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize), + nsize, 0); + + skb_trim(skb, len); + + skb->csum = csum_block_sub(skb->csum, buff->csum, len); + } else { + skb->ip_summed = CHECKSUM_HW; + skb_split(skb, buff, len); + } + + buff->ip_summed = skb->ip_summed; + + /* Looks stupid, but our code really uses when of + * skbs, which it never sent before. --ANK + */ + TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when; + + /* Link BUFF into the send queue. */ + __skb_append(skb, buff); + + return 0; +#else + return 0; +#endif +} + +/* This function synchronize snd mss to current pmtu/exthdr set. + + tp->user_mss is mss set by user by TCP_MAXSEG. It does NOT counts + for TCP options, but includes only bare TCP header. + + tp->mss_clamp is mss negotiated at connection setup. + It is minumum of user_mss and mss received with SYN. + It also does not include TCP options. + + tp->pmtu_cookie is last pmtu, seen by this function. + + tp->mss_cache is current effective sending mss, including + all tcp options except for SACKs. It is evaluated, + taking into account current pmtu, but never exceeds + tp->mss_clamp. + + NOTE1. rfc1122 clearly states that advertised MSS + DOES NOT include either tcp or ip options. + + NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside + this function. --ANK (980731) + */ + +int tcp_sync_mss(struct sock *sk, u32 pmtu) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int mss_now; + + /* Calculate base mss without TCP options: + It is MMS_S - sizeof(tcphdr) of rfc1122 + */ + + mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr); + + /* Clamp it (mss_clamp does not include tcp options) */ + if (mss_now > tp->mss_clamp) + mss_now = tp->mss_clamp; + + /* Now subtract optional transport overhead */ + mss_now -= tp->ext_header_len; + + /* Then reserve room for full set of TCP options and 8 bytes of data */ + if (mss_now < 48) + mss_now = 48; + + /* Now subtract TCP options size, not including SACKs */ + mss_now -= tp->tcp_header_len - sizeof(struct tcphdr); + + /* Bound mss with half of window */ + if (tp->max_window && mss_now > (tp->max_window>>1)) + mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len); + + /* And store cached results */ + tp->pmtu_cookie = pmtu; + tp->mss_cache = mss_now; + return mss_now; +#else + return 0; +#endif +} + + +/* This routine writes packets to the network. It advances the + * send_head. This happens as incoming acks open up the remote + * window for us. + * + * Returns 1, if no segments are in flight and we have queued segments, but + * cannot send anything now because of SWS or another problem. + */ +int tcp_write_xmit(struct sock *sk, int nonagle) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + unsigned int mss_now; + + /* If we are closed, the bytes will have to remain here. + * In time closedown will finish, we empty the write queue and all + * will be happy. + */ + if(sk->state != TCP_CLOSE) { + struct sk_buff *skb; + int sent_pkts = 0; + + /* Account for SACKS, we may need to fragment due to this. + * It is just like the real MSS changing on us midstream. + * We also handle things correctly when the user adds some + * IP options mid-stream. Silly to do, but cover it. + */ + mss_now = tcp_current_mss(sk); + + while((skb = tp->send_head) && + tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb) ? nonagle : 1)) { + if (skb->len > mss_now) { + if (tcp_fragment(sk, skb, mss_now)) + break; + } + + TCP_SKB_CB(skb)->when = tcp_time_stamp; + if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + break; + /* Advance the send_head. This one is sent out. */ + update_send_head(sk, tp, skb); + tcp_minshall_update(tp, mss_now, skb); + sent_pkts = 1; + } + + if (sent_pkts) { + tcp_cwnd_validate(sk, tp); + return 0; + } + + return !tp->packets_out && tp->send_head; + } + return 0; +#else + return 0; +#endif +} + +/* This function returns the amount that we can raise the + * usable window based on the following constraints + * + * 1. The window can never be shrunk once it is offered (RFC 793) + * 2. We limit memory per socket + * + * RFC 1122: + * "the suggested [SWS] avoidance algorithm for the receiver is to keep + * RECV.NEXT + RCV.WIN fixed until: + * RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)" + * + * i.e. don't raise the right edge of the window until you can raise + * it at least MSS bytes. + * + * Unfortunately, the recommended algorithm breaks header prediction, + * since header prediction assumes th->window stays fixed. + * + * Strictly speaking, keeping th->window fixed violates the receiver + * side SWS prevention criteria. The problem is that under this rule + * a stream of single byte packets will cause the right side of the + * window to always advance by a single byte. + * + * Of course, if the sender implements sender side SWS prevention + * then this will not be a problem. + * + * BSD seems to make the following compromise: + * + * If the free space is less than the 1/4 of the maximum + * space available and the free space is less than 1/2 mss, + * then set the window to 0. + * [ Actually, bsd uses MSS and 1/4 of maximal _window_ ] + * Otherwise, just prevent the window from shrinking + * and from being larger than the largest representable value. + * + * This prevents incremental opening of the window in the regime + * where TCP is limited by the speed of the reader side taking + * data out of the TCP receive queue. It does nothing about + * those cases where the window is constrained on the sender side + * because the pipeline is full. + * + * BSD also seems to "accidentally" limit itself to windows that are a + * multiple of MSS, at least until the free space gets quite small. + * This would appear to be a side effect of the mbuf implementation. + * Combining these two algorithms results in the observed behavior + * of having a fixed window size at almost all times. + * + * Below we obtain similar behavior by forcing the offered window to + * a multiple of the mss when it is feasible to do so. + * + * Note, we don't "adjust" for TIMESTAMP or SACK option bytes. + * Regular options like TIMESTAMP are taken into account. + */ +u32 __tcp_select_window(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + /* MSS for the peer's data. Previous verions used mss_clamp + * here. I don't know if the value based on our guesses + * of peer's MSS is better for the performance. It's more correct + * but may be worse for the performance because of rcv_mss + * fluctuations. --SAW 1998/11/1 + */ + int mss = tp->ack.rcv_mss; + int free_space = tcp_space(sk); + int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk)); + int window; + + if (mss > full_space) + mss = full_space; + + if (free_space < full_space/2) { + tp->ack.quick = 0; + + if (tcp_memory_pressure) + tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); + + if (free_space < mss) + return 0; + } + + if (free_space > tp->rcv_ssthresh) + free_space = tp->rcv_ssthresh; + + /* Get the largest window that is a nice multiple of mss. + * Window clamp already applied above. + * If our current window offering is within 1 mss of the + * free space we just keep it. This prevents the divide + * and multiply from happening most of the time. + * We also don't do any window rounding when the free space + * is too small. + */ + window = tp->rcv_wnd; + if (window <= free_space - mss || window > free_space) + window = (free_space/mss)*mss; + + return window; +#else + return 0; +#endif +} + +/* Attempt to collapse two adjacent SKB's during retransmission. */ +static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int mss_now) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct sk_buff *next_skb = skb->next; + + /* The first test we must make is that neither of these two + * SKB's are still referenced by someone else. + */ + if(!skb_cloned(skb) && !skb_cloned(next_skb)) { + int skb_size = skb->len, next_skb_size = next_skb->len; + u16 flags = TCP_SKB_CB(skb)->flags; + + /* Also punt if next skb has been SACK'd. */ + if(TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_ACKED) + return; + + /* Next skb is out of window. */ + if (after(TCP_SKB_CB(next_skb)->end_seq, tp->snd_una+tp->snd_wnd)) + return; + + /* Punt if not enough space exists in the first SKB for + * the data in the second, or the total combined payload + * would exceed the MSS. + */ + if ((next_skb_size > skb_tailroom(skb)) || + ((skb_size + next_skb_size) > mss_now)) + return; + + /* Ok. We will be able to collapse the packet. */ + __skb_unlink(next_skb, next_skb->list); + + if (next_skb->ip_summed == CHECKSUM_HW) + skb->ip_summed = CHECKSUM_HW; + + if (skb->ip_summed != CHECKSUM_HW) { + memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); + skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size); + } + + /* Update sequence range on original skb. */ + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq; + + /* Merge over control information. */ + flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */ + TCP_SKB_CB(skb)->flags = flags; + + /* All done, get rid of second SKB and account for it so + * packet counting does not break. + */ + TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked&(TCPCB_EVER_RETRANS|TCPCB_AT_TAIL); + if (TCP_SKB_CB(next_skb)->sacked&TCPCB_SACKED_RETRANS) + tp->retrans_out--; + if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST) { + tp->lost_out--; + tp->left_out--; + } + /* Reno case is special. Sigh... */ + if (!tp->sack_ok && tp->sacked_out) { + tp->sacked_out--; + tp->left_out--; + } + + /* Not quite right: it can be > snd.fack, but + * it is better to underestimate fackets. + */ + if (tp->fackets_out) + tp->fackets_out--; + tcp_free_skb(sk, next_skb); + tp->packets_out--; + } +#endif +} + +/* Do a simple retransmit without using the backoff mechanisms in + * tcp_timer. This is used for path mtu discovery. + * The socket is already locked here. + */ +void tcp_simple_retransmit(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + unsigned int mss = tcp_current_mss(sk); + int lost = 0; + + for_retrans_queue(skb, sk, tp) { + if (skb->len > mss && + !(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) { + if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) { + TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; + tp->retrans_out--; + } + if (!(TCP_SKB_CB(skb)->sacked&TCPCB_LOST)) { + TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; + tp->lost_out++; + lost = 1; + } + } + } + + if (!lost) + return; + + tcp_sync_left_out(tp); + + /* Don't muck with the congestion window here. + * Reason is that we do not increase amount of _data_ + * in network, but units changed and effective + * cwnd/ssthresh really reduced now. + */ + if (tp->ca_state != TCP_CA_Loss) { + tp->high_seq = tp->snd_nxt; + tp->snd_ssthresh = tcp_current_ssthresh(tp); + tp->prior_ssthresh = 0; + tp->undo_marker = 0; + tp->ca_state = TCP_CA_Loss; + } + tcp_xmit_retransmit_queue(sk); +#endif +} + +/* This retransmits one SKB. Policy decisions and retransmit queue + * state updates are done by the caller. Returns non-zero if an + * error occurred which prevented the send. + */ +int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + unsigned int cur_mss = tcp_current_mss(sk); + int err; + + /* Do not sent more than we queued. 1/4 is reserved for possible + * copying overhead: frgagmentation, tunneling, mangling etc. + */ + if (atomic_read(&sk->wmem_alloc) > min(sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf)) + return -EAGAIN; + + /* If receiver has shrunk his window, and skb is out of + * new window, do not retransmit it. The exception is the + * case, when window is shrunk to zero. In this case + * our retransmit serves as a zero window probe. + */ + if (!before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd) + && TCP_SKB_CB(skb)->seq != tp->snd_una) + return -EAGAIN; + + if(skb->len > cur_mss) { + if(tcp_fragment(sk, skb, cur_mss)) + return -ENOMEM; /* We'll try again later. */ + + /* New SKB created, account for it. */ + tp->packets_out++; + } + + /* Collapse two adjacent packets if worthwhile and we can. */ + if(!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) && + (skb->len < (cur_mss >> 1)) && + (skb->next != tp->send_head) && + (skb->next != (struct sk_buff *)&sk->write_queue) && + (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) && + (sysctl_tcp_retrans_collapse != 0)) + tcp_retrans_try_collapse(sk, skb, cur_mss); + + if(tp->af_specific->rebuild_header(sk)) + return -EHOSTUNREACH; /* Routing failure or similar. */ + + /* Some Solaris stacks overoptimize and ignore the FIN on a + * retransmit when old data is attached. So strip it off + * since it is cheap to do so and saves bytes on the network. + */ + if(skb->len > 0 && + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && + tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) { + if (!pskb_trim(skb, 0)) { + TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1; + skb->ip_summed = CHECKSUM_NONE; + skb->csum = 0; + } + } + + /* Make a copy, if the first transmission SKB clone we made + * is still in somebody's hands, else make a clone. + */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + + err = tcp_transmit_skb(sk, (skb_cloned(skb) ? + pskb_copy(skb, GFP_ATOMIC): + skb_clone(skb, GFP_ATOMIC))); + + if (err == 0) { + /* Update global TCP statistics. */ + TCP_INC_STATS(TcpRetransSegs); + +#if FASTRETRANS_DEBUG > 0 + if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) { + if (net_ratelimit()) + printk(KERN_DEBUG "retrans_out leaked.\n"); + } +#endif + TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS; + tp->retrans_out++; + + /* Save stamp of the first retransmit. */ + if (!tp->retrans_stamp) + tp->retrans_stamp = TCP_SKB_CB(skb)->when; + + tp->undo_retrans++; + + /* snd_nxt is stored to detect loss of retransmitted segment, + * see tcp_input.c tcp_sacktag_write_queue(). + */ + TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt; + } + return err; +#else + return 0; +#endif +} + +/* This gets called after a retransmit timeout, and the initially + * retransmitted data is acknowledged. It tries to continue + * resending the rest of the retransmit queue, until either + * we've sent it all or the congestion window limit is reached. + * If doing SACK, the first ACK which comes back for a timeout + * based retransmit packet might feed us FACK information again. + * If so, we use it to avoid unnecessarily retransmissions. + */ +void tcp_xmit_retransmit_queue(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + int packet_cnt = tp->lost_out; + + /* First pass: retransmit lost packets. */ + if (packet_cnt) { + for_retrans_queue(skb, sk, tp) { + __u8 sacked = TCP_SKB_CB(skb)->sacked; + + if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) + return; + + if (sacked&TCPCB_LOST) { + if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) { + if (tcp_retransmit_skb(sk, skb)) + return; + if (tp->ca_state != TCP_CA_Loss) + NET_INC_STATS_BH(TCPFastRetrans); + else + NET_INC_STATS_BH(TCPSlowStartRetrans); + + if (skb == skb_peek(&sk->write_queue)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + } + + if (--packet_cnt <= 0) + break; + } + } + } + + /* OK, demanded retransmission is finished. */ + + /* Forward retransmissions are possible only during Recovery. */ + if (tp->ca_state != TCP_CA_Recovery) + return; + + /* No forward retransmissions in Reno are possible. */ + if (!tp->sack_ok) + return; + + /* Yeah, we have to make difficult choice between forward transmission + * and retransmission... Both ways have their merits... + * + * For now we do not retrnamsit anything, while we have some new + * segments to send. + */ + + if (tcp_may_send_now(sk, tp)) + return; + + packet_cnt = 0; + + for_retrans_queue(skb, sk, tp) { + if(++packet_cnt > tp->fackets_out) + break; + + if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) + break; + + if(TCP_SKB_CB(skb)->sacked & TCPCB_TAGBITS) + continue; + + /* Ok, retransmit it. */ + if(tcp_retransmit_skb(sk, skb)) + break; + + if (skb == skb_peek(&sk->write_queue)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + + NET_INC_STATS_BH(TCPForwardRetrans); + } +#endif +} + + +/* Send a fin. The caller locks the socket for us. This cannot be + * allowed to fail queueing a FIN frame under any circumstances. + */ +void tcp_send_fin(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb = skb_peek_tail(&sk->write_queue); + unsigned int mss_now; + + /* Optimization, tack on the FIN if we have a queue of + * unsent frames. But be careful about outgoing SACKS + * and IP options. + */ + mss_now = tcp_current_mss(sk); + + if(tp->send_head != NULL) { + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN; + TCP_SKB_CB(skb)->end_seq++; + tp->write_seq++; + } else { + /* Socket is locked, keep trying until memory is available. */ + for (;;) { + skb = alloc_skb(MAX_TCP_HEADER, GFP_KERNEL); + if (skb) + break; + yield(); + } + + /* Reserve space for headers and prepare control bits. */ + skb_reserve(skb, MAX_TCP_HEADER); + skb->csum = 0; + TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN); + TCP_SKB_CB(skb)->sacked = 0; + + /* FIN eats a sequence byte, write_seq advanced by tcp_send_skb(). */ + TCP_SKB_CB(skb)->seq = tp->write_seq; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; + tcp_send_skb(sk, skb, 1, mss_now); + } + __tcp_push_pending_frames(sk, tp, mss_now, 1); +#endif +} + +/* We get here when a process closes a file descriptor (either due to + * an explicit close() or as a byproduct of exit()'ing) and there + * was unread data in the receive queue. This behavior is recommended + * by draft-ietf-tcpimpl-prob-03.txt section 3.10. -DaveM + */ +void tcp_send_active_reset(struct sock *sk, int priority) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + + /* NOTE: No TCP options attached and we never retransmit this. */ + skb = alloc_skb(MAX_TCP_HEADER, priority); + if (!skb) { + NET_INC_STATS(TCPAbortFailed); + return; + } + + /* Reserve space for headers and prepare control bits. */ + skb_reserve(skb, MAX_TCP_HEADER); + skb->csum = 0; + TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST); + TCP_SKB_CB(skb)->sacked = 0; + + /* Send it off. */ + TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp); + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; + TCP_SKB_CB(skb)->when = tcp_time_stamp; + if (tcp_transmit_skb(sk, skb)) + NET_INC_STATS(TCPAbortFailed); +#endif +} + +/* WARNING: This routine must only be called when we have already sent + * a SYN packet that crossed the incoming SYN that caused this routine + * to get called. If this assumption fails then the initial rcv_wnd + * and rcv_wscale values will not be correct. + */ +int tcp_send_synack(struct sock *sk) +{ +#if 0 + struct sk_buff* skb; + + skb = skb_peek(&sk->write_queue); + if (skb == NULL || !(TCP_SKB_CB(skb)->flags&TCPCB_FLAG_SYN)) { + printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n"); + return -EFAULT; + } + if (!(TCP_SKB_CB(skb)->flags&TCPCB_FLAG_ACK)) { + if (skb_cloned(skb)) { + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); + if (nskb == NULL) + return -ENOMEM; + __skb_unlink(skb, &sk->write_queue); + __skb_queue_head(&sk->write_queue, nskb); + tcp_free_skb(sk, skb); + tcp_charge_skb(sk, nskb); + skb = nskb; + } + + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ACK; + TCP_ECN_send_synack(&sk->tp_pinfo.af_tcp, skb); + } + TCP_SKB_CB(skb)->when = tcp_time_stamp; + return tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); +#else + return 0; +#endif +} + +/* + * Prepare a SYN-ACK. + */ +struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, + struct open_request *req) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcphdr *th; + int tcp_header_size; + struct sk_buff *skb; + + skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); + if (skb == NULL) + return NULL; + + /* Reserve space for headers. */ + skb_reserve(skb, MAX_TCP_HEADER); + + skb->dst = dst_clone(dst); + + tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + + (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + + (req->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + + /* SACK_PERM is in the place of NOP NOP of TS */ + ((req->sack_ok && !req->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); + skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); + + memset(th, 0, sizeof(struct tcphdr)); + th->syn = 1; + th->ack = 1; + TCP_ECN_make_synack(req, th); + th->source = sk->sport; + th->dest = req->rmt_port; + TCP_SKB_CB(skb)->seq = req->snt_isn; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; + th->seq = htonl(TCP_SKB_CB(skb)->seq); + th->ack_seq = htonl(req->rcv_isn + 1); + if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ + __u8 rcv_wscale; + /* Set this up on the first call only */ + req->window_clamp = tp->window_clamp ? : dst->window; + /* tcp_full_space because it is guaranteed to be the first packet */ + tcp_select_initial_window(tcp_full_space(sk), + dst->advmss - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), + &req->rcv_wnd, + &req->window_clamp, + req->wscale_ok, + &rcv_wscale); + req->rcv_wscale = rcv_wscale; + } + + /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ + th->window = htons(req->rcv_wnd); + + TCP_SKB_CB(skb)->when = tcp_time_stamp; + tcp_syn_build_options((__u32 *)(th + 1), dst->advmss, req->tstamp_ok, + req->sack_ok, req->wscale_ok, req->rcv_wscale, + TCP_SKB_CB(skb)->when, + req->ts_recent); + + skb->csum = 0; + th->doff = (tcp_header_size >> 2); + TCP_INC_STATS(TcpOutSegs); + return skb; +#else + return 0; +#endif +} + +/* + * Do all connect socket setups that can be done AF independent. + */ +static inline void tcp_connect_init(struct sock *sk) +{ +#if 0 + struct dst_entry *dst = __sk_dst_get(sk); + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* We'll fix this up when we get a response from the other end. + * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT. + */ + tp->tcp_header_len = sizeof(struct tcphdr) + + (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0); + + /* If user gave his TCP_MAXSEG, record it to clamp */ + if (tp->user_mss) + tp->mss_clamp = tp->user_mss; + tp->max_window = 0; + tcp_sync_mss(sk, dst->pmtu); + + if (!tp->window_clamp) + tp->window_clamp = dst->window; + tp->advmss = dst->advmss; + tcp_initialize_rcv_mss(sk); + + tcp_select_initial_window(tcp_full_space(sk), + tp->advmss - (tp->ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), + &tp->rcv_wnd, + &tp->window_clamp, + sysctl_tcp_window_scaling, + &tp->rcv_wscale); + + tp->rcv_ssthresh = tp->rcv_wnd; + + sk->err = 0; + sk->done = 0; + tp->snd_wnd = 0; + tcp_init_wl(tp, tp->write_seq, 0); + tp->snd_una = tp->write_seq; + tp->snd_sml = tp->write_seq; + tp->rcv_nxt = 0; + tp->rcv_wup = 0; + tp->copied_seq = 0; + + tp->rto = TCP_TIMEOUT_INIT; + tp->retransmits = 0; + tcp_clear_retrans(tp); +#endif +} + +/* + * Build a SYN and send it off. + */ +int tcp_connect(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *buff; + + tcp_connect_init(sk); + + buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation); + if (unlikely(buff == NULL)) + return -ENOBUFS; + + /* Reserve space for headers. */ + skb_reserve(buff, MAX_TCP_HEADER); + + TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN; + TCP_ECN_send_syn(tp, buff); + TCP_SKB_CB(buff)->sacked = 0; + buff->csum = 0; + TCP_SKB_CB(buff)->seq = tp->write_seq++; + TCP_SKB_CB(buff)->end_seq = tp->write_seq; + tp->snd_nxt = tp->write_seq; + tp->pushed_seq = tp->write_seq; + + /* Send it off. */ + TCP_SKB_CB(buff)->when = tcp_time_stamp; + tp->retrans_stamp = TCP_SKB_CB(buff)->when; + __skb_queue_tail(&sk->write_queue, buff); + tcp_charge_skb(sk, buff); + tp->packets_out++; + tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL)); + TCP_INC_STATS(TcpActiveOpens); + + /* Timer for repeating the SYN until an answer. */ + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return 0; +#else + return 0; +#endif +} + +/* Send out a delayed ack, the caller does the policy checking + * to see if we should even be here. See tcp_input.c:tcp_ack_snd_check() + * for details. + */ +void tcp_send_delayed_ack(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int ato = tp->ack.ato; + unsigned long timeout; + + if (ato > TCP_DELACK_MIN) { + int max_ato = HZ/2; + + if (tp->ack.pingpong || (tp->ack.pending&TCP_ACK_PUSHED)) + max_ato = TCP_DELACK_MAX; + + /* Slow path, intersegment interval is "high". */ + + /* If some rtt estimate is known, use it to bound delayed ack. + * Do not use tp->rto here, use results of rtt measurements + * directly. + */ + if (tp->srtt) { + int rtt = max(tp->srtt>>3, TCP_DELACK_MIN); + + if (rtt < max_ato) + max_ato = rtt; + } + + ato = min(ato, max_ato); + } + + /* Stay within the limit we were given */ + timeout = jiffies + ato; + + /* Use new timeout only if there wasn't a older one earlier. */ + if (tp->ack.pending&TCP_ACK_TIMER) { + /* If delack timer was blocked or is about to expire, + * send ACK now. + */ + if (tp->ack.blocked || time_before_eq(tp->ack.timeout, jiffies+(ato>>2))) { + tcp_send_ack(sk); + return; + } + + if (!time_before(timeout, tp->ack.timeout)) + timeout = tp->ack.timeout; + } + tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER; + tp->ack.timeout = timeout; + if (!mod_timer(&tp->delack_timer, timeout)) + sock_hold(sk); +#endif +} + +/* This routine sends an ack and also updates the window. */ +void tcp_send_ack(struct sock *sk) +{ +#if 0 + /* If we have been reset, we may not send again. */ + if(sk->state != TCP_CLOSE) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *buff; + + /* We are not putting this on the write queue, so + * tcp_transmit_skb() will set the ownership to this + * sock. + */ + buff = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); + if (buff == NULL) { + tcp_schedule_ack(tp); + tp->ack.ato = TCP_ATO_MIN; + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MAX); + return; + } + + /* Reserve space for headers and prepare control bits. */ + skb_reserve(buff, MAX_TCP_HEADER); + buff->csum = 0; + TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK; + TCP_SKB_CB(buff)->sacked = 0; + + /* Send it off, this clears delayed acks for us. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp); + TCP_SKB_CB(buff)->when = tcp_time_stamp; + tcp_transmit_skb(sk, buff); + } +#else + return 0; +#endif +} + +/* This routine sends a packet with an out of date sequence + * number. It assumes the other end will try to ack it. + * + * Question: what should we make while urgent mode? + * 4.4BSD forces sending single byte of data. We cannot send + * out of window data, because we have SND.NXT==SND.MAX... + * + * Current solution: to send TWO zero-length segments in urgent mode: + * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is + * out-of-date with SND.UNA-1 to probe window. + */ +static int tcp_xmit_probe_skb(struct sock *sk, int urgent) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + + /* We don't queue it, tcp_transmit_skb() sets ownership. */ + skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); + if (skb == NULL) + return -1; + + /* Reserve space for headers and set control bits. */ + skb_reserve(skb, MAX_TCP_HEADER); + skb->csum = 0; + TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; + TCP_SKB_CB(skb)->sacked = urgent; + + /* Use a previous sequence. This should cause the other + * end to send an ack. Don't queue or clone SKB, just + * send it. + */ + TCP_SKB_CB(skb)->seq = urgent ? tp->snd_una : tp->snd_una - 1; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; + TCP_SKB_CB(skb)->when = tcp_time_stamp; + return tcp_transmit_skb(sk, skb); +#else + return 0; +#endif +} + +int tcp_write_wakeup(struct sock *sk) +{ +#if 0 + if (sk->state != TCP_CLOSE) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sk_buff *skb; + + if ((skb = tp->send_head) != NULL && + before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)) { + int err; + int mss = tcp_current_mss(sk); + int seg_size = tp->snd_una+tp->snd_wnd-TCP_SKB_CB(skb)->seq; + + if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) + tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; + + /* We are probing the opening of a window + * but the window size is != 0 + * must have been a result SWS avoidance ( sender ) + */ + if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || + skb->len > mss) { + seg_size = min(seg_size, mss); + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; + if (tcp_fragment(sk, skb, seg_size)) + return -1; + } + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; + TCP_SKB_CB(skb)->when = tcp_time_stamp; + err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); + if (!err) { + update_send_head(sk, tp, skb); + } + return err; + } else { + if (tp->urg_mode && + between(tp->snd_up, tp->snd_una+1, tp->snd_una+0xFFFF)) + tcp_xmit_probe_skb(sk, TCPCB_URG); + return tcp_xmit_probe_skb(sk, 0); + } + } + return -1; +#else + return 0; +#endif +} + +/* A window probe timeout has occurred. If window is not closed send + * a partial packet else a zero probe. + */ +void tcp_send_probe0(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int err; + + err = tcp_write_wakeup(sk); + + if (tp->packets_out || !tp->send_head) { + /* Cancel probe timer, if it is not required. */ + tp->probes_out = 0; + tp->backoff = 0; + return; + } + + if (err <= 0) { + tp->backoff++; + tp->probes_out++; + tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RTO_MAX)); + } else { + /* If packet was not sent due to local congestion, + * do not backoff and do not remember probes_out. + * Let local senders to fight for local resources. + * + * Use accumulated backoff yet. + */ + if (!tp->probes_out) + tp->probes_out=1; + tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL)); + } +#endif +} diff --git a/drivers/net/tcpip/transport/tcp/tcp_timer.c b/drivers/net/tcpip/transport/tcp/tcp_timer.c new file mode 100755 index 0000000..031e7d6 --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/tcp_timer.c @@ -0,0 +1,702 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: transport/tcp/tcp_input.c + * PURPOSE: Transmission Control Protocol + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 15-01-2003 Imported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Implementation of the Transmission Control Protocol(TCP). + * + * Version: $Id$ + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * Mark Evans, + * Corey Minyard + * Florian La Roche, + * Charles Hedrick, + * Linus Torvalds, + * Alan Cox, + * Matthew Dillon, + * Arnt Gulbrandsen, + * Jorge Cwik, + */ + +#if 0 +#include +#else +#include "linux.h" +#include "tcpcore.h" +#endif + +int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; +int sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES; +//int sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME; +int sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES; +//int sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL; +int sysctl_tcp_retries1 = TCP_RETR1; +int sysctl_tcp_retries2 = TCP_RETR2; +int sysctl_tcp_orphan_retries; + +static void tcp_write_timer(unsigned long); +static void tcp_delack_timer(unsigned long); +static void tcp_keepalive_timer (unsigned long data); + +//const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n"; + +/* + * Using different timers for retransmit, delayed acks and probes + * We may wish use just one timer maintaining a list of expire jiffies + * to optimize. + */ + +void tcp_init_xmit_timers(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + init_timer(&tp->retransmit_timer); + tp->retransmit_timer.function=&tcp_write_timer; + tp->retransmit_timer.data = (unsigned long) sk; + tp->pending = 0; + + init_timer(&tp->delack_timer); + tp->delack_timer.function=&tcp_delack_timer; + tp->delack_timer.data = (unsigned long) sk; + tp->ack.pending = 0; + + init_timer(&sk->timer); + sk->timer.function=&tcp_keepalive_timer; + sk->timer.data = (unsigned long) sk; +#endif +} + +void tcp_clear_xmit_timers(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + tp->pending = 0; + if (timer_pending(&tp->retransmit_timer) && + del_timer(&tp->retransmit_timer)) + __sock_put(sk); + + tp->ack.pending = 0; + tp->ack.blocked = 0; + if (timer_pending(&tp->delack_timer) && + del_timer(&tp->delack_timer)) + __sock_put(sk); + + if(timer_pending(&sk->timer) && del_timer(&sk->timer)) + __sock_put(sk); +#endif +} + +static void tcp_write_err(struct sock *sk) +{ +#if 0 + sk->err = sk->err_soft ? : ETIMEDOUT; + sk->error_report(sk); + + tcp_done(sk); + NET_INC_STATS_BH(TCPAbortOnTimeout); +#endif +} + +/* Do not allow orphaned sockets to eat all our resources. + * This is direct violation of TCP specs, but it is required + * to prevent DoS attacks. It is called when a retransmission timeout + * or zero probe timeout occurs on orphaned socket. + * + * Criterium is still not confirmed experimentally and may change. + * We kill the socket, if: + * 1. If number of orphaned sockets exceeds an administratively configured + * limit. + * 2. If we have strong memory pressure. + */ +static int tcp_out_of_resources(struct sock *sk, int do_reset) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int orphans = atomic_read(&tcp_orphan_count); + + /* If peer does not open window for long time, or did not transmit + * anything for long time, penalize it. */ + if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) + orphans <<= 1; + + /* If some dubious ICMP arrived, penalize even more. */ + if (sk->err_soft) + orphans <<= 1; + + if (orphans >= sysctl_tcp_max_orphans || + (sk->wmem_queued > SOCK_MIN_SNDBUF && + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + if (net_ratelimit()) + printk(KERN_INFO "Out of socket memory\n"); + + /* Catch exceptional cases, when connection requires reset. + * 1. Last segment was sent recently. */ + if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN || + /* 2. Window is closed. */ + (!tp->snd_wnd && !tp->packets_out)) + do_reset = 1; + if (do_reset) + tcp_send_active_reset(sk, GFP_ATOMIC); + tcp_done(sk); + NET_INC_STATS_BH(TCPAbortOnMemory); + return 1; + } + return 0; +#else + return 0; +#endif +} + +/* Calculate maximal number or retries on an orphaned socket. */ +static int tcp_orphan_retries(struct sock *sk, int alive) +{ +#if 0 + int retries = sysctl_tcp_orphan_retries; /* May be zero. */ + + /* We know from an ICMP that something is wrong. */ + if (sk->err_soft && !alive) + retries = 0; + + /* However, if socket sent something recently, select some safe + * number of retries. 8 corresponds to >100 seconds with minimal + * RTO of 200msec. */ + if (retries == 0 && alive) + retries = 8; + return retries; +#else + return 0; +#endif +} + +/* A write timeout has occurred. Process the after effects. */ +static int tcp_write_timeout(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int retry_until; + + if ((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { + if (tp->retransmits) + dst_negative_advice(&sk->dst_cache); + retry_until = tp->syn_retries ? : sysctl_tcp_syn_retries; + } else { + if (tp->retransmits >= sysctl_tcp_retries1) { + /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black + hole detection. :-( + + It is place to make it. It is not made. I do not want + to make it. It is disguisting. It does not work in any + case. Let me to cite the same draft, which requires for + us to implement this: + + "The one security concern raised by this memo is that ICMP black holes + are often caused by over-zealous security administrators who block + all ICMP messages. It is vitally important that those who design and + deploy security systems understand the impact of strict filtering on + upper-layer protocols. The safest web site in the world is worthless + if most TCP implementations cannot transfer data from it. It would + be far nicer to have all of the black holes fixed rather than fixing + all of the TCP implementations." + + Golden words :-). + */ + + dst_negative_advice(&sk->dst_cache); + } + + retry_until = sysctl_tcp_retries2; + if (sk->dead) { + int alive = (tp->rto < TCP_RTO_MAX); + + retry_until = tcp_orphan_retries(sk, alive); + + if (tcp_out_of_resources(sk, alive || tp->retransmits < retry_until)) + return 1; + } + } + + if (tp->retransmits >= retry_until) { + /* Has it gone just too far? */ + tcp_write_err(sk); + return 1; + } + return 0; +#else + return 0; +#endif +} + +static void tcp_delack_timer(unsigned long data) +{ +#if 0 + struct sock *sk = (struct sock*)data; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + bh_lock_sock(sk); + if (sk->lock.users) { + /* Try again later. */ + tp->ack.blocked = 1; + NET_INC_STATS_BH(DelayedACKLocked); + if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN)) + sock_hold(sk); + goto out_unlock; + } + + tcp_mem_reclaim(sk); + + if (sk->state == TCP_CLOSE || !(tp->ack.pending&TCP_ACK_TIMER)) + goto out; + + if ((long)(tp->ack.timeout - jiffies) > 0) { + if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) + sock_hold(sk); + goto out; + } + tp->ack.pending &= ~TCP_ACK_TIMER; + + if (skb_queue_len(&tp->ucopy.prequeue)) { + struct sk_buff *skb; + + net_statistics[smp_processor_id()*2].TCPSchedulerFailed += skb_queue_len(&tp->ucopy.prequeue); + + while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) + sk->backlog_rcv(sk, skb); + + tp->ucopy.memory = 0; + } + + if (tcp_ack_scheduled(tp)) { + if (!tp->ack.pingpong) { + /* Delayed ACK missed: inflate ATO. */ + tp->ack.ato = min(tp->ack.ato << 1, tp->rto); + } else { + /* Delayed ACK missed: leave pingpong mode and + * deflate ATO. + */ + tp->ack.pingpong = 0; + tp->ack.ato = TCP_ATO_MIN; + } + tcp_send_ack(sk); + NET_INC_STATS_BH(DelayedACKs); + } + TCP_CHECK_TIMER(sk); + +out: + if (tcp_memory_pressure) + tcp_mem_reclaim(sk); +out_unlock: + bh_unlock_sock(sk); + sock_put(sk); +#endif +} + +static void tcp_probe_timer(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int max_probes; + + if (tp->packets_out || !tp->send_head) { + tp->probes_out = 0; + return; + } + + /* *WARNING* RFC 1122 forbids this + * + * It doesn't AFAIK, because we kill the retransmit timer -AK + * + * FIXME: We ought not to do it, Solaris 2.5 actually has fixing + * this behaviour in Solaris down as a bug fix. [AC] + * + * Let me to explain. probes_out is zeroed by incoming ACKs + * even if they advertise zero window. Hence, connection is killed only + * if we received no ACKs for normal connection timeout. It is not killed + * only because window stays zero for some time, window may be zero + * until armageddon and even later. We are in full accordance + * with RFCs, only probe timer combines both retransmission timeout + * and probe timeout in one bottle. --ANK + */ + max_probes = sysctl_tcp_retries2; + + if (sk->dead) { + int alive = ((tp->rto<backoff) < TCP_RTO_MAX); + + max_probes = tcp_orphan_retries(sk, alive); + + if (tcp_out_of_resources(sk, alive || tp->probes_out <= max_probes)) + return; + } + + if (tp->probes_out > max_probes) { + tcp_write_err(sk); + } else { + /* Only send another probe if we didn't close things up. */ + tcp_send_probe0(sk); + } +#endif +} + +/* + * The TCP retransmit timer. + */ + +static void tcp_retransmit_timer(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (tp->packets_out == 0) + goto out; + + BUG_TRAP(!skb_queue_empty(&sk->write_queue)); + + if (tp->snd_wnd == 0 && !sk->dead && + !((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV))) { + /* Receiver dastardly shrinks window. Our retransmits + * become zero probes, but we should not timeout this + * connection. If the socket is an orphan, time it out, + * we cannot allow such beasts to hang infinitely. + */ +#ifdef TCP_DEBUG + if (net_ratelimit()) + printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", + NIPQUAD(sk->daddr), htons(sk->dport), sk->num, + tp->snd_una, tp->snd_nxt); +#endif + if (tcp_time_stamp - tp->rcv_tstamp > TCP_RTO_MAX) { + tcp_write_err(sk); + goto out; + } + tcp_enter_loss(sk, 0); + tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)); + __sk_dst_reset(sk); + goto out_reset_timer; + } + + if (tcp_write_timeout(sk)) + goto out; + + if (tp->retransmits == 0) { + if (tp->ca_state == TCP_CA_Disorder || tp->ca_state == TCP_CA_Recovery) { + if (tp->sack_ok) { + if (tp->ca_state == TCP_CA_Recovery) + NET_INC_STATS_BH(TCPSackRecoveryFail); + else + NET_INC_STATS_BH(TCPSackFailures); + } else { + if (tp->ca_state == TCP_CA_Recovery) + NET_INC_STATS_BH(TCPRenoRecoveryFail); + else + NET_INC_STATS_BH(TCPRenoFailures); + } + } else if (tp->ca_state == TCP_CA_Loss) { + NET_INC_STATS_BH(TCPLossFailures); + } else { + NET_INC_STATS_BH(TCPTimeouts); + } + } + + tcp_enter_loss(sk, 0); + + if (tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)) > 0) { + /* Retransmission failed because of local congestion, + * do not backoff. + */ + if (!tp->retransmits) + tp->retransmits=1; + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, + min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL)); + goto out; + } + + /* Increase the timeout each time we retransmit. Note that + * we do not increase the rtt estimate. rto is initialized + * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests + * that doubling rto each time is the least we can get away with. + * In KA9Q, Karn uses this for the first few times, and then + * goes to quadratic. netBSD doubles, but only goes up to *64, + * and clamps at 1 to 64 sec afterwards. Note that 120 sec is + * defined in the protocol as the maximum possible RTT. I guess + * we'll have to use something other than TCP to talk to the + * University of Mars. + * + * PAWS allows us longer timeouts and large windows, so once + * implemented ftp to mars will work nicely. We will have to fix + * the 120 second clamps though! + */ + tp->backoff++; + tp->retransmits++; + +out_reset_timer: + tp->rto = min(tp->rto << 1, TCP_RTO_MAX); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + if (tp->retransmits > sysctl_tcp_retries1) + __sk_dst_reset(sk); + +out:; +#endif +} + +static void tcp_write_timer(unsigned long data) +{ +#if 0 + struct sock *sk = (struct sock*)data; + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int event; + + bh_lock_sock(sk); + if (sk->lock.users) { + /* Try again later */ + if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20))) + sock_hold(sk); + goto out_unlock; + } + + if (sk->state == TCP_CLOSE || !tp->pending) + goto out; + + if ((long)(tp->timeout - jiffies) > 0) { + if (!mod_timer(&tp->retransmit_timer, tp->timeout)) + sock_hold(sk); + goto out; + } + + event = tp->pending; + tp->pending = 0; + + switch (event) { + case TCP_TIME_RETRANS: + tcp_retransmit_timer(sk); + break; + case TCP_TIME_PROBE0: + tcp_probe_timer(sk); + break; + } + TCP_CHECK_TIMER(sk); + +out: + tcp_mem_reclaim(sk); +out_unlock: + bh_unlock_sock(sk); + sock_put(sk); +#endif +} + +/* + * Timer for listening sockets + */ + +static void tcp_synack_timer(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt = tp->listen_opt; + int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries; + int thresh = max_retries; + unsigned long now = jiffies; + struct open_request **reqp, *req; + int i, budget; + + if (lopt == NULL || lopt->qlen == 0) + return; + + /* Normally all the openreqs are young and become mature + * (i.e. converted to established socket) for first timeout. + * If synack was not acknowledged for 3 seconds, it means + * one of the following things: synack was lost, ack was lost, + * rtt is high or nobody planned to ack (i.e. synflood). + * When server is a bit loaded, queue is populated with old + * open requests, reducing effective size of queue. + * When server is well loaded, queue size reduces to zero + * after several minutes of work. It is not synflood, + * it is normal operation. The solution is pruning + * too old entries overriding normal timeout, when + * situation becomes dangerous. + * + * Essentially, we reserve half of room for young + * embrions; and abort old ones without pity, if old + * ones are about to clog our table. + */ + if (lopt->qlen>>(lopt->max_qlen_log-1)) { + int young = (lopt->qlen_young<<1); + + while (thresh > 2) { + if (lopt->qlen < young) + break; + thresh--; + young <<= 1; + } + } + + if (tp->defer_accept) + max_retries = tp->defer_accept; + + budget = 2*(TCP_SYNQ_HSIZE/(TCP_TIMEOUT_INIT/TCP_SYNQ_INTERVAL)); + i = lopt->clock_hand; + + do { + reqp=&lopt->syn_table[i]; + while ((req = *reqp) != NULL) { + if ((long)(now - req->expires) >= 0) { + if ((req->retrans < thresh || + (req->acked && req->retrans < max_retries)) + && !req->class->rtx_syn_ack(sk, req, NULL)) { + unsigned long timeo; + + if (req->retrans++ == 0) + lopt->qlen_young--; + timeo = min((TCP_TIMEOUT_INIT << req->retrans), + TCP_RTO_MAX); + req->expires = now + timeo; + reqp = &req->dl_next; + continue; + } + + /* Drop this request */ + write_lock(&tp->syn_wait_lock); + *reqp = req->dl_next; + write_unlock(&tp->syn_wait_lock); + lopt->qlen--; + if (req->retrans == 0) + lopt->qlen_young--; + tcp_openreq_free(req); + continue; + } + reqp = &req->dl_next; + } + + i = (i+1)&(TCP_SYNQ_HSIZE-1); + + } while (--budget > 0); + + lopt->clock_hand = i; + + if (lopt->qlen) + tcp_reset_keepalive_timer(sk, TCP_SYNQ_INTERVAL); +#endif +} + +void tcp_delete_keepalive_timer (struct sock *sk) +{ +#if 0 + if (timer_pending(&sk->timer) && del_timer (&sk->timer)) + __sock_put(sk); +#endif +} + +void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len) +{ +#if 0 + if (!mod_timer(&sk->timer, jiffies+len)) + sock_hold(sk); +#endif +} + +void tcp_set_keepalive(struct sock *sk, int val) +{ +#if 0 + if ((1<state)&(TCPF_CLOSE|TCPF_LISTEN)) + return; + + if (val && !sk->keepopen) + tcp_reset_keepalive_timer(sk, keepalive_time_when(&sk->tp_pinfo.af_tcp)); + else if (!val) + tcp_delete_keepalive_timer(sk); +#endif +} + + +static void tcp_keepalive_timer (unsigned long data) +{ +#if 0 + struct sock *sk = (struct sock *) data; + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + __u32 elapsed; + + /* Only process if socket is not in use. */ + bh_lock_sock(sk); + if (sk->lock.users) { + /* Try again later. */ + tcp_reset_keepalive_timer (sk, HZ/20); + goto out; + } + + if (sk->state == TCP_LISTEN) { + tcp_synack_timer(sk); + goto out; + } + + if (sk->state == TCP_FIN_WAIT2 && sk->dead) { + if (tp->linger2 >= 0) { + int tmo = tcp_fin_time(tp) - TCP_TIMEWAIT_LEN; + + if (tmo > 0) { + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto out; + } + } + tcp_send_active_reset(sk, GFP_ATOMIC); + goto death; + } + + if (!sk->keepopen || sk->state == TCP_CLOSE) + goto out; + + elapsed = keepalive_time_when(tp); + + /* It is alive without keepalive 8) */ + if (tp->packets_out || tp->send_head) + goto resched; + + elapsed = tcp_time_stamp - tp->rcv_tstamp; + + if (elapsed >= keepalive_time_when(tp)) { + if ((!tp->keepalive_probes && tp->probes_out >= sysctl_tcp_keepalive_probes) || + (tp->keepalive_probes && tp->probes_out >= tp->keepalive_probes)) { + tcp_send_active_reset(sk, GFP_ATOMIC); + tcp_write_err(sk); + goto out; + } + if (tcp_write_wakeup(sk) <= 0) { + tp->probes_out++; + elapsed = keepalive_intvl_when(tp); + } else { + /* If keepalive was lost due to local congestion, + * try harder. + */ + elapsed = TCP_RESOURCE_PROBE_INTERVAL; + } + } else { + /* It is tp->rcv_tstamp + keepalive_time_when(tp) */ + elapsed = keepalive_time_when(tp) - elapsed; + } + + TCP_CHECK_TIMER(sk); + tcp_mem_reclaim(sk); + +resched: + tcp_reset_keepalive_timer (sk, elapsed); + goto out; + +death: + tcp_done(sk); + +out: + bh_unlock_sock(sk); + sock_put(sk); +#endif +} diff --git a/drivers/net/tcpip/transport/tcp/tcpcore.c b/drivers/net/tcpip/transport/tcp/tcpcore.c new file mode 100755 index 0000000..eead0d6 --- /dev/null +++ b/drivers/net/tcpip/transport/tcp/tcpcore.c @@ -0,0 +1,2783 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: transport/tcp/tcpcore.c + * PURPOSE: Transmission Control Protocol + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 15-01-2003 Imported from linux kernel 2.4.20 + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Implementation of the Transmission Control Protocol(TCP). + * + * Version: $Id$ + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * Mark Evans, + * Corey Minyard + * Florian La Roche, + * Charles Hedrick, + * Linus Torvalds, + * Alan Cox, + * Matthew Dillon, + * Arnt Gulbrandsen, + * Jorge Cwik, + * + * Fixes: + * Alan Cox : Numerous verify_area() calls + * Alan Cox : Set the ACK bit on a reset + * Alan Cox : Stopped it crashing if it closed while + * sk->inuse=1 and was trying to connect + * (tcp_err()). + * Alan Cox : All icmp error handling was broken + * pointers passed where wrong and the + * socket was looked up backwards. Nobody + * tested any icmp error code obviously. + * Alan Cox : tcp_err() now handled properly. It + * wakes people on errors. poll + * behaves and the icmp error race + * has gone by moving it into sock.c + * Alan Cox : tcp_send_reset() fixed to work for + * everything not just packets for + * unknown sockets. + * Alan Cox : tcp option processing. + * Alan Cox : Reset tweaked (still not 100%) [Had + * syn rule wrong] + * Herp Rosmanith : More reset fixes + * Alan Cox : No longer acks invalid rst frames. + * Acking any kind of RST is right out. + * Alan Cox : Sets an ignore me flag on an rst + * receive otherwise odd bits of prattle + * escape still + * Alan Cox : Fixed another acking RST frame bug. + * Should stop LAN workplace lockups. + * Alan Cox : Some tidyups using the new skb list + * facilities + * Alan Cox : sk->keepopen now seems to work + * Alan Cox : Pulls options out correctly on accepts + * Alan Cox : Fixed assorted sk->rqueue->next errors + * Alan Cox : PSH doesn't end a TCP read. Switched a + * bit to skb ops. + * Alan Cox : Tidied tcp_data to avoid a potential + * nasty. + * Alan Cox : Added some better commenting, as the + * tcp is hard to follow + * Alan Cox : Removed incorrect check for 20 * psh + * Michael O'Reilly : ack < copied bug fix. + * Johannes Stille : Misc tcp fixes (not all in yet). + * Alan Cox : FIN with no memory -> CRASH + * Alan Cox : Added socket option proto entries. + * Also added awareness of them to accept. + * Alan Cox : Added TCP options (SOL_TCP) + * Alan Cox : Switched wakeup calls to callbacks, + * so the kernel can layer network + * sockets. + * Alan Cox : Use ip_tos/ip_ttl settings. + * Alan Cox : Handle FIN (more) properly (we hope). + * Alan Cox : RST frames sent on unsynchronised + * state ack error. + * Alan Cox : Put in missing check for SYN bit. + * Alan Cox : Added tcp_select_window() aka NET2E + * window non shrink trick. + * Alan Cox : Added a couple of small NET2E timer + * fixes + * Charles Hedrick : TCP fixes + * Toomas Tamm : TCP window fixes + * Alan Cox : Small URG fix to rlogin ^C ack fight + * Charles Hedrick : Rewrote most of it to actually work + * Linus : Rewrote tcp_read() and URG handling + * completely + * Gerhard Koerting: Fixed some missing timer handling + * Matthew Dillon : Reworked TCP machine states as per RFC + * Gerhard Koerting: PC/TCP workarounds + * Adam Caldwell : Assorted timer/timing errors + * Matthew Dillon : Fixed another RST bug + * Alan Cox : Move to kernel side addressing changes. + * Alan Cox : Beginning work on TCP fastpathing + * (not yet usable) + * Arnt Gulbrandsen: Turbocharged tcp_check() routine. + * Alan Cox : TCP fast path debugging + * Alan Cox : Window clamping + * Michael Riepe : Bug in tcp_check() + * Matt Dillon : More TCP improvements and RST bug fixes + * Matt Dillon : Yet more small nasties remove from the + * TCP code (Be very nice to this man if + * tcp finally works 100%) 8) + * Alan Cox : BSD accept semantics. + * Alan Cox : Reset on closedown bug. + * Peter De Schrijver : ENOTCONN check missing in tcp_sendto(). + * Michael Pall : Handle poll() after URG properly in + * all cases. + * Michael Pall : Undo the last fix in tcp_read_urg() + * (multi URG PUSH broke rlogin). + * Michael Pall : Fix the multi URG PUSH problem in + * tcp_readable(), poll() after URG + * works now. + * Michael Pall : recv(...,MSG_OOB) never blocks in the + * BSD api. + * Alan Cox : Changed the semantics of sk->socket to + * fix a race and a signal problem with + * accept() and async I/O. + * Alan Cox : Relaxed the rules on tcp_sendto(). + * Yury Shevchuk : Really fixed accept() blocking problem. + * Craig I. Hagan : Allow for BSD compatible TIME_WAIT for + * clients/servers which listen in on + * fixed ports. + * Alan Cox : Cleaned the above up and shrank it to + * a sensible code size. + * Alan Cox : Self connect lockup fix. + * Alan Cox : No connect to multicast. + * Ross Biro : Close unaccepted children on master + * socket close. + * Alan Cox : Reset tracing code. + * Alan Cox : Spurious resets on shutdown. + * Alan Cox : Giant 15 minute/60 second timer error + * Alan Cox : Small whoops in polling before an + * accept. + * Alan Cox : Kept the state trace facility since + * it's handy for debugging. + * Alan Cox : More reset handler fixes. + * Alan Cox : Started rewriting the code based on + * the RFC's for other useful protocol + * references see: Comer, KA9Q NOS, and + * for a reference on the difference + * between specifications and how BSD + * works see the 4.4lite source. + * A.N.Kuznetsov : Don't time wait on completion of tidy + * close. + * Linus Torvalds : Fin/Shutdown & copied_seq changes. + * Linus Torvalds : Fixed BSD port reuse to work first syn + * Alan Cox : Reimplemented timers as per the RFC + * and using multiple timers for sanity. + * Alan Cox : Small bug fixes, and a lot of new + * comments. + * Alan Cox : Fixed dual reader crash by locking + * the buffers (much like datagram.c) + * Alan Cox : Fixed stuck sockets in probe. A probe + * now gets fed up of retrying without + * (even a no space) answer. + * Alan Cox : Extracted closing code better + * Alan Cox : Fixed the closing state machine to + * resemble the RFC. + * Alan Cox : More 'per spec' fixes. + * Jorge Cwik : Even faster checksumming. + * Alan Cox : tcp_data() doesn't ack illegal PSH + * only frames. At least one pc tcp stack + * generates them. + * Alan Cox : Cache last socket. + * Alan Cox : Per route irtt. + * Matt Day : poll()->select() match BSD precisely on error + * Alan Cox : New buffers + * Marc Tamsky : Various sk->prot->retransmits and + * sk->retransmits misupdating fixed. + * Fixed tcp_write_timeout: stuck close, + * and TCP syn retries gets used now. + * Mark Yarvis : In tcp_read_wakeup(), don't send an + * ack if state is TCP_CLOSED. + * Alan Cox : Look up device on a retransmit - routes may + * change. Doesn't yet cope with MSS shrink right + * but its a start! + * Marc Tamsky : Closing in closing fixes. + * Mike Shaver : RFC1122 verifications. + * Alan Cox : rcv_saddr errors. + * Alan Cox : Block double connect(). + * Alan Cox : Small hooks for enSKIP. + * Alexey Kuznetsov: Path MTU discovery. + * Alan Cox : Support soft errors. + * Alan Cox : Fix MTU discovery pathological case + * when the remote claims no mtu! + * Marc Tamsky : TCP_CLOSE fix. + * Colin (G3TNE) : Send a reset on syn ack replies in + * window but wrong (fixes NT lpd problems) + * Pedro Roque : Better TCP window handling, delayed ack. + * Joerg Reuter : No modification of locked buffers in + * tcp_do_retransmit() + * Eric Schenk : Changed receiver side silly window + * avoidance algorithm to BSD style + * algorithm. This doubles throughput + * against machines running Solaris, + * and seems to result in general + * improvement. + * Stefan Magdalinski : adjusted tcp_readable() to fix FIONREAD + * Willy Konynenberg : Transparent proxying support. + * Mike McLagan : Routing by source + * Keith Owens : Do proper merging with partial SKB's in + * tcp_do_sendmsg to avoid burstiness. + * Eric Schenk : Fix fast close down bug with + * shutdown() followed by close(). + * Andi Kleen : Make poll agree with SIGIO + * Salvatore Sanfilippo : Support SO_LINGER with linger == 1 and + * lingertime == 0 (RFC 793 ABORT Call) + * + * 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. + * + * Description of States: + * + * TCP_SYN_SENT sent a connection request, waiting for ack + * + * TCP_SYN_RECV received a connection request, sent ack, + * waiting for final ack in three-way handshake. + * + * TCP_ESTABLISHED connection established + * + * TCP_FIN_WAIT1 our side has shutdown, waiting to complete + * transmission of remaining buffered data + * + * TCP_FIN_WAIT2 all buffered data sent, waiting for remote + * to shutdown + * + * TCP_CLOSING both sides have shutdown but we still have + * data we have to finish sending + * + * TCP_TIME_WAIT timeout to catch resent junk before entering + * closed, can only be entered from FIN_WAIT2 + * or CLOSING. Required because the other end + * may not have gotten our last ACK causing it + * to retransmit the data packet (which we ignore) + * + * TCP_CLOSE_WAIT remote side has shutdown and is waiting for + * us to finish writing our data and to shutdown + * (we have to close() to move on to LAST_ACK) + * + * TCP_LAST_ACK out side has shutdown after remote has + * shutdown. There may still be data in our + * buffer that we have to finish sending + * + * TCP_CLOSE socket is finished + */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#else +#include "linux.h" +#include "tcpcore.h" +#endif + +int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT; + +#ifdef ROS_STATISTICS +struct tcp_mib tcp_statistics[NR_CPUS*2]; +#endif + +kmem_cache_t *tcp_openreq_cachep; +kmem_cache_t *tcp_bucket_cachep; +kmem_cache_t *tcp_timewait_cachep; + +#if 0 +atomic_t tcp_orphan_count = ATOMIC_INIT(0); +#endif + +int sysctl_tcp_mem[3]; +int sysctl_tcp_wmem[3] = { 4*1024, 16*1024, 128*1024 }; +int sysctl_tcp_rmem[3] = { 4*1024, 87380, 87380*2 }; + +atomic_t tcp_memory_allocated; /* Current allocated memory. */ +atomic_t tcp_sockets_allocated; /* Current number of TCP sockets. */ + +/* Pressure flag: try to collapse. + * Technical note: it is used by multiple contexts non atomically. + * All the tcp_mem_schedule() is of this nature: accounting + * is strict, actions are advisory and have some latency. */ +int tcp_memory_pressure; + +#define TCP_PAGES(amt) (((amt)+TCP_MEM_QUANTUM-1)/TCP_MEM_QUANTUM) + +int tcp_mem_schedule(struct sock *sk, int size, int kind) +{ + int amt = TCP_PAGES(size); + + sk->forward_alloc += amt*TCP_MEM_QUANTUM; + atomic_add(amt, &tcp_memory_allocated); + + /* Under limit. */ + if (atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + if (tcp_memory_pressure) + tcp_memory_pressure = 0; + return 1; + } + + /* Over hard limit. */ + if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) { + tcp_enter_memory_pressure(); + goto suppress_allocation; + } + + /* Under pressure. */ + if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[1]) + tcp_enter_memory_pressure(); + + if (kind) { + if (atomic_read(&sk->rmem_alloc) < sysctl_tcp_rmem[0]) + return 1; + } else { + if (sk->wmem_queued < sysctl_tcp_wmem[0]) + return 1; + } + + if (!tcp_memory_pressure || + sysctl_tcp_mem[2] > atomic_read(&tcp_sockets_allocated) + * TCP_PAGES(sk->wmem_queued+atomic_read(&sk->rmem_alloc)+ + sk->forward_alloc)) + return 1; + +suppress_allocation: + + if (kind == 0) { + tcp_moderate_sndbuf(sk); + + /* Fail only if socket is _under_ its sndbuf. + * In this case we cannot block, so that we have to fail. + */ + if (sk->wmem_queued+size >= sk->sndbuf) + return 1; + } + + /* Alas. Undo changes. */ + sk->forward_alloc -= amt*TCP_MEM_QUANTUM; + atomic_sub(amt, &tcp_memory_allocated); + return 0; +} + +void __tcp_mem_reclaim(struct sock *sk) +{ + if (sk->forward_alloc >= TCP_MEM_QUANTUM) { + atomic_sub(sk->forward_alloc/TCP_MEM_QUANTUM, &tcp_memory_allocated); + sk->forward_alloc &= (TCP_MEM_QUANTUM-1); + if (tcp_memory_pressure && + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) + tcp_memory_pressure = 0; + } +} + +void tcp_rfree(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + + atomic_sub(skb->truesize, &sk->rmem_alloc); + sk->forward_alloc += skb->truesize; +} + +/* + * LISTEN is a special case for poll.. + */ +static __inline__ unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait) +{ + return sk->tp_pinfo.af_tcp.accept_queue ? (POLLIN | POLLRDNORM) : 0; +} + +/* + * Wait for a TCP event. + * + * Note that we don't need to lock the socket, as the upper poll layers + * take care of normal races (between the test and the event) and we don't + * go look at any of the socket buffers directly. + */ +unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait) +{ +#if 0 + unsigned int mask; + struct sock *sk = sock->sk; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + poll_wait(file, sk->sleep, wait); + if (sk->state == TCP_LISTEN) + return tcp_listen_poll(sk, wait); + + /* Socket is not locked. We are protected from async events + by poll logic and correct handling of state changes + made by another threads is impossible in any case. + */ + + mask = 0; + if (sk->err) + mask = POLLERR; + + /* + * POLLHUP is certainly not done right. But poll() doesn't + * have a notion of HUP in just one direction, and for a + * socket the read side is more interesting. + * + * Some poll() documentation says that POLLHUP is incompatible + * with the POLLOUT/POLLWR flags, so somebody should check this + * all. But careful, it tends to be safer to return too many + * bits than too few, and you can easily break real applications + * if you don't tell them that something has hung up! + * + * Check-me. + * + * Check number 1. POLLHUP is _UNMASKABLE_ event (see UNIX98 and + * our fs/select.c). It means that after we received EOF, + * poll always returns immediately, making impossible poll() on write() + * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP + * if and only if shutdown has been made in both directions. + * Actually, it is interesting to look how Solaris and DUX + * solve this dilemma. I would prefer, if PULLHUP were maskable, + * then we could set it on SND_SHUTDOWN. BTW examples given + * in Stevens' books assume exactly this behaviour, it explains + * why PULLHUP is incompatible with POLLOUT. --ANK + * + * NOTE. Check for TCP_CLOSE is added. The goal is to prevent + * blocking on fresh not-connected or disconnected socket. --ANK + */ + if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE) + mask |= POLLHUP; + if (sk->shutdown & RCV_SHUTDOWN) + mask |= POLLIN | POLLRDNORM; + + /* Connected? */ + if ((1 << sk->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) { + /* Potential race condition. If read of tp below will + * escape above sk->state, we can be illegally awaken + * in SYN_* states. */ + if ((tp->rcv_nxt != tp->copied_seq) && + (tp->urg_seq != tp->copied_seq || + tp->rcv_nxt != tp->copied_seq+1 || + sk->urginline || !tp->urg_data)) + mask |= POLLIN | POLLRDNORM; + + if (!(sk->shutdown & SEND_SHUTDOWN)) { + if (tcp_wspace(sk) >= tcp_min_write_space(sk)) { + mask |= POLLOUT | POLLWRNORM; + } else { /* send SIGIO later */ + set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); + set_bit(SOCK_NOSPACE, &sk->socket->flags); + + /* Race breaker. If space is freed after + * wspace test but before the flags are set, + * IO signal will be lost. + */ + if (tcp_wspace(sk) >= tcp_min_write_space(sk)) + mask |= POLLOUT | POLLWRNORM; + } + } + + if (tp->urg_data & TCP_URG_VALID) + mask |= POLLPRI; + } + return mask; +#else + return 0; +#endif +} + +/* + * TCP socket write_space callback. + */ +void tcp_write_space(struct sock *sk) +{ +#if 0 + struct socket *sock = sk->socket; + + if (tcp_wspace(sk) >= tcp_min_write_space(sk) && sock) { + clear_bit(SOCK_NOSPACE, &sock->flags); + + if (sk->sleep && waitqueue_active(sk->sleep)) + wake_up_interruptible(sk->sleep); + + if (sock->fasync_list && !(sk->shutdown&SEND_SHUTDOWN)) + sock_wake_async(sock, 2, POLL_OUT); + } +#endif +} + +int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int answ; + + switch(cmd) { + case SIOCINQ: + if (sk->state == TCP_LISTEN) + return(-EINVAL); + + lock_sock(sk); + if ((1<state) & (TCPF_SYN_SENT|TCPF_SYN_RECV)) + answ = 0; + else if (sk->urginline || !tp->urg_data || + before(tp->urg_seq,tp->copied_seq) || + !before(tp->urg_seq,tp->rcv_nxt)) { + answ = tp->rcv_nxt - tp->copied_seq; + + /* Subtract 1, if FIN is in queue. */ + if (answ && !skb_queue_empty(&sk->receive_queue)) + answ -= ((struct sk_buff*)sk->receive_queue.prev)->h.th->fin; + } else + answ = tp->urg_seq - tp->copied_seq; + release_sock(sk); + break; + case SIOCATMARK: + { + answ = tp->urg_data && tp->urg_seq == tp->copied_seq; + break; + } + case SIOCOUTQ: + if (sk->state == TCP_LISTEN) + return(-EINVAL); + + if ((1<state) & (TCPF_SYN_SENT|TCPF_SYN_RECV)) + answ = 0; + else + answ = tp->write_seq - tp->snd_una; + break; + default: + return(-ENOIOCTLCMD); + }; + + return put_user(answ, (int *)arg); +#else +return 0; +#endif +} + + +int tcp_listen_start(struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt; + + sk->max_ack_backlog = 0; + sk->ack_backlog = 0; + tp->accept_queue = tp->accept_queue_tail = NULL; + tp->syn_wait_lock = RW_LOCK_UNLOCKED; + tcp_delack_init(tp); + + lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL); + if (!lopt) + return -ENOMEM; + + memset(lopt, 0, sizeof(struct tcp_listen_opt)); + for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++) + if ((1<max_qlen_log) >= sysctl_max_syn_backlog) + break; + + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt = lopt; + write_unlock_bh(&tp->syn_wait_lock); + + /* There is race window here: we announce ourselves listening, + * but this transition is still not validated by get_port(). + * It is OK, because this socket enters to hash table only + * after validation is complete. + */ + sk->state = TCP_LISTEN; + if (sk->prot->get_port(sk, sk->num) == 0) { + sk->sport = htons(sk->num); + + sk_dst_reset(sk); + sk->prot->hash(sk); + + return 0; + } + + sk->state = TCP_CLOSE; + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt = NULL; + write_unlock_bh(&tp->syn_wait_lock); + kfree(lopt); + return -EADDRINUSE; +#endif +} + +/* + * This routine closes sockets which have been at least partially + * opened, but not yet accepted. + */ + +static void tcp_listen_stop (struct sock *sk) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt = tp->listen_opt; + struct open_request *acc_req = tp->accept_queue; + struct open_request *req; + int i; + + tcp_delete_keepalive_timer(sk); + + /* make all the listen_opt local to us */ + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt =NULL; + write_unlock_bh(&tp->syn_wait_lock); + tp->accept_queue = tp->accept_queue_tail = NULL; + + if (lopt->qlen) { + for (i=0; isyn_table[i]) != NULL) { + lopt->syn_table[i] = req->dl_next; + lopt->qlen--; + tcp_openreq_free(req); + + /* Following specs, it would be better either to send FIN + * (and enter FIN-WAIT-1, it is normal close) + * or to send active reset (abort). + * Certainly, it is pretty dangerous while synflood, but it is + * bad justification for our negligence 8) + * To be honest, we are not able to make either + * of the variants now. --ANK + */ + } + } + } + BUG_TRAP(lopt->qlen == 0); + + kfree(lopt); + + while ((req=acc_req) != NULL) { + struct sock *child = req->sk; + + acc_req = req->dl_next; + + local_bh_disable(); + bh_lock_sock(child); + BUG_TRAP(child->lock.users==0); + sock_hold(child); + + tcp_disconnect(child, O_NONBLOCK); + + sock_orphan(child); + + atomic_inc(&tcp_orphan_count); + + tcp_destroy_sock(child); + + bh_unlock_sock(child); + local_bh_enable(); + sock_put(child); + + tcp_acceptq_removed(sk); + tcp_openreq_fastfree(req); + } + BUG_TRAP(sk->ack_backlog == 0); +#endif +} + +/* + * Wait for a socket to get into the connected state + * + * Note: Must be called with the socket locked. + */ +static int wait_for_tcp_connect(struct sock * sk, int flags, long *timeo_p) +{ +#if 0 + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + while((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { + if(sk->err) + return sock_error(sk); + if((1 << sk->state) & + ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) + return -EPIPE; + if(!*timeo_p) + return -EAGAIN; + if(signal_pending(tsk)) + return sock_intr_errno(*timeo_p); + + __set_task_state(tsk, TASK_INTERRUPTIBLE); + add_wait_queue(sk->sleep, &wait); + sk->tp_pinfo.af_tcp.write_pending++; + + release_sock(sk); + *timeo_p = schedule_timeout(*timeo_p); + lock_sock(sk); + + __set_task_state(tsk, TASK_RUNNING); + remove_wait_queue(sk->sleep, &wait); + sk->tp_pinfo.af_tcp.write_pending--; + } + return 0; +#else + return 0; +#endif +} + +static inline int tcp_memory_free(struct sock *sk) +{ + return sk->wmem_queued < sk->sndbuf; +} + +/* + * Wait for more memory for a socket + */ +static int wait_for_tcp_memory(struct sock * sk, long *timeo) +{ +#if 0 + int err = 0; + long vm_wait = 0; + long current_timeo = *timeo; + DECLARE_WAITQUEUE(wait, current); + + if (tcp_memory_free(sk)) + current_timeo = vm_wait = (net_random()%(HZ/5))+2; + + add_wait_queue(sk->sleep, &wait); + for (;;) { + set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); + + set_current_state(TASK_INTERRUPTIBLE); + + if (sk->err || (sk->shutdown & SEND_SHUTDOWN)) + goto do_error; + if (!*timeo) + goto do_nonblock; + if (signal_pending(current)) + goto do_interrupted; + clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); + if (tcp_memory_free(sk) && !vm_wait) + break; + + set_bit(SOCK_NOSPACE, &sk->socket->flags); + sk->tp_pinfo.af_tcp.write_pending++; + release_sock(sk); + if (!tcp_memory_free(sk) || vm_wait) + current_timeo = schedule_timeout(current_timeo); + lock_sock(sk); + sk->tp_pinfo.af_tcp.write_pending--; + + if (vm_wait) { + vm_wait -= current_timeo; + current_timeo = *timeo; + if (current_timeo != MAX_SCHEDULE_TIMEOUT && + (current_timeo -= vm_wait) < 0) + current_timeo = 0; + vm_wait = 0; + } + *timeo = current_timeo; + } +out: + current->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + return err; + +do_error: + err = -EPIPE; + goto out; +do_nonblock: + err = -EAGAIN; + goto out; +do_interrupted: + err = sock_intr_errno(*timeo); + goto out; +#endif +} + +ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags); + +static inline int +can_coalesce(struct sk_buff *skb, int i, struct page *page, int off) +{ +#if 0 + if (i) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; + return page == frag->page && + off == frag->page_offset+frag->size; + } + return 0; +#else +return 0; +#endif +} + +static inline void +fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size) +{ + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + frag->page = page; + frag->page_offset = off; + frag->size = size; + skb_shinfo(skb)->nr_frags = i+1; +} + +static inline void tcp_mark_push(struct tcp_opt *tp, struct sk_buff *skb) +{ + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; + tp->pushed_seq = tp->write_seq; +} + +static inline int forced_push(struct tcp_opt *tp) +{ + return after(tp->write_seq, tp->pushed_seq + (tp->max_window>>1)); +} + +static inline void +skb_entail(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) +{ + skb->csum = 0; + TCP_SKB_CB(skb)->seq = tp->write_seq; + TCP_SKB_CB(skb)->end_seq = tp->write_seq; + TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; + TCP_SKB_CB(skb)->sacked = 0; + __skb_queue_tail(&sk->write_queue, skb); + tcp_charge_skb(sk, skb); + if (tp->send_head == NULL) + tp->send_head = skb; +} + +static inline void +tcp_mark_urg(struct tcp_opt *tp, int flags, struct sk_buff *skb) +{ +#if 0 + if (flags & MSG_OOB) { + tp->urg_mode = 1; + tp->snd_up = tp->write_seq; + TCP_SKB_CB(skb)->sacked |= TCPCB_URG; + } +#endif +} + +static inline void +tcp_push(struct sock *sk, struct tcp_opt *tp, int flags, int mss_now, int nonagle) +{ +#if 0 + if (tp->send_head) { + struct sk_buff *skb = sk->write_queue.prev; + if (!(flags&MSG_MORE) || forced_push(tp)) + tcp_mark_push(tp, skb); + tcp_mark_urg(tp, flags, skb); + __tcp_push_pending_frames(sk, tp, mss_now, (flags&MSG_MORE) ? 2 : nonagle); + } +#endif +} + +static int tcp_error(struct sock *sk, int flags, int err) +{ +#if 0 + if (err == -EPIPE) + err = sock_error(sk) ? : -EPIPE; + if (err == -EPIPE && !(flags&MSG_NOSIGNAL)) + send_sig(SIGPIPE, current, 0); + return err; +#else + return 0; +#endif +} + +ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int mss_now; + int err; + ssize_t copied; + long timeo = sock_sndtimeo(sk, flags&MSG_DONTWAIT); + + /* Wait for a connection to finish. */ + if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) + if((err = wait_for_tcp_connect(sk, 0, &timeo)) != 0) + goto out_err; + + clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); + + mss_now = tcp_current_mss(sk); + copied = 0; + + err = -EPIPE; + if (sk->err || (sk->shutdown & SEND_SHUTDOWN)) + goto do_error; + + while (psize > 0) { + struct sk_buff *skb = sk->write_queue.prev; + int offset, size, copy, i; + struct page *page; + + page = pages[poffset/PAGE_SIZE]; + offset = poffset % PAGE_SIZE; + size = min_t(size_t, psize, PAGE_SIZE-offset); + + if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) { +new_segment: + if (!tcp_memory_free(sk)) + goto wait_for_sndbuf; + + skb = tcp_alloc_pskb(sk, 0, tp->mss_cache, sk->allocation); + if (skb == NULL) + goto wait_for_memory; + + skb_entail(sk, tp, skb); + copy = mss_now; + } + + if (copy > size) + copy = size; + + i = skb_shinfo(skb)->nr_frags; + if (can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += copy; + } else if (i < MAX_SKB_FRAGS) { + get_page(page); + fill_page_desc(skb, i, page, offset, copy); + } else { + tcp_mark_push(tp, skb); + goto new_segment; + } + + skb->len += copy; + skb->data_len += copy; + skb->ip_summed = CHECKSUM_HW; + tp->write_seq += copy; + TCP_SKB_CB(skb)->end_seq += copy; + + if (!copied) + TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH; + + copied += copy; + poffset += copy; + if (!(psize -= copy)) + goto out; + + if (skb->len != mss_now || (flags&MSG_OOB)) + continue; + + if (forced_push(tp)) { + tcp_mark_push(tp, skb); + __tcp_push_pending_frames(sk, tp, mss_now, 1); + } else if (skb == tp->send_head) + tcp_push_one(sk, mss_now); + continue; + +wait_for_sndbuf: + set_bit(SOCK_NOSPACE, &sk->socket->flags); +wait_for_memory: + if (copied) + tcp_push(sk, tp, flags&~MSG_MORE, mss_now, 1); + + if ((err = wait_for_tcp_memory(sk, &timeo)) != 0) + goto do_error; + + mss_now = tcp_current_mss(sk); + } + +out: + if (copied) + tcp_push(sk, tp, flags, mss_now, tp->nonagle); + return copied; + +do_error: + if (copied) + goto out; +out_err: + return tcp_error(sk, flags, err); +#else +return 0; +#endif +} + +ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) +{ +#if 0 + ssize_t res; + struct sock *sk = sock->sk; + +#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) + + if (!(sk->route_caps & NETIF_F_SG) || + !(sk->route_caps & TCP_ZC_CSUM_FLAGS)) + return sock_no_sendpage(sock, page, offset, size, flags); + +#undef TCP_ZC_CSUM_FLAGS + + lock_sock(sk); + TCP_CHECK_TIMER(sk); + res = do_tcp_sendpages(sk, &page, offset, size, flags); + TCP_CHECK_TIMER(sk); + release_sock(sk); + return res; +#else + return 0; +#endif +} + +#define TCP_PAGE(sk) (sk->tp_pinfo.af_tcp.sndmsg_page) +#define TCP_OFF(sk) (sk->tp_pinfo.af_tcp.sndmsg_off) + +static inline int +tcp_copy_to_page(struct sock *sk, char *from, struct sk_buff *skb, + struct page *page, int off, int copy) +{ + int err = 0; + unsigned int csum; + + csum = csum_and_copy_from_user(from, page_address(page)+off, + copy, 0, &err); + if (!err) { + if (skb->ip_summed == CHECKSUM_NONE) + skb->csum = csum_block_add(skb->csum, csum, skb->len); + skb->len += copy; + skb->data_len += copy; + skb->truesize += copy; + sk->wmem_queued += copy; + sk->forward_alloc -= copy; + } + return err; +} + +static inline int +skb_add_data(struct sk_buff *skb, char *from, int copy) +{ +#if 0 + int err = 0; + unsigned int csum; + int off = skb->len; + + csum = csum_and_copy_from_user(from, skb_put(skb, copy), + copy, 0, &err); + if (!err) { + skb->csum = csum_block_add(skb->csum, csum, off); + return 0; + } + + __skb_trim(skb, off); + return -EFAULT; +#else +return 0; +#endif +} + +static inline int select_size(struct sock *sk, struct tcp_opt *tp) +{ +#if 0 + int tmp = tp->mss_cache; + + if (sk->route_caps&NETIF_F_SG) { + int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); + + if (tmp >= pgbreak && tmp <= pgbreak + (MAX_SKB_FRAGS-1)*PAGE_SIZE) + tmp = pgbreak; + } + return tmp; +#else + return 0; +#endif +} + +int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size) +{ +#if 0 + struct iovec *iov; + struct tcp_opt *tp; + struct sk_buff *skb; + int iovlen, flags; + int mss_now; + int err, copied; + long timeo; + + tp = &(sk->tp_pinfo.af_tcp); + + lock_sock(sk); + TCP_CHECK_TIMER(sk); + + flags = msg->msg_flags; + timeo = sock_sndtimeo(sk, flags&MSG_DONTWAIT); + + /* Wait for a connection to finish. */ + if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) + if((err = wait_for_tcp_connect(sk, flags, &timeo)) != 0) + goto out_err; + + /* This should be in poll */ + clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); + + mss_now = tcp_current_mss(sk); + + /* Ok commence sending. */ + iovlen = msg->msg_iovlen; + iov = msg->msg_iov; + copied = 0; + + err = -EPIPE; + if (sk->err || (sk->shutdown&SEND_SHUTDOWN)) + goto do_error; + + while (--iovlen >= 0) { + int seglen=iov->iov_len; + unsigned char * from=iov->iov_base; + + iov++; + + while (seglen > 0) { + int copy; + + skb = sk->write_queue.prev; + + if (tp->send_head == NULL || + (copy = mss_now - skb->len) <= 0) { + +new_segment: + /* Allocate new segment. If the interface is SG, + * allocate skb fitting to single page. + */ + if (!tcp_memory_free(sk)) + goto wait_for_sndbuf; + + skb = tcp_alloc_pskb(sk, select_size(sk, tp), 0, sk->allocation); + if (skb == NULL) + goto wait_for_memory; + + skb_entail(sk, tp, skb); + copy = mss_now; + } + + /* Try to append data to the end of skb. */ + if (copy > seglen) + copy = seglen; + + /* Where to copy to? */ + if (skb_tailroom(skb) > 0) { + /* We have some space in skb head. Superb! */ + if (copy > skb_tailroom(skb)) + copy = skb_tailroom(skb); + if ((err = skb_add_data(skb, from, copy)) != 0) + goto do_fault; + } else { + int merge = 0; + int i = skb_shinfo(skb)->nr_frags; + struct page *page = TCP_PAGE(sk); + int off = TCP_OFF(sk); + + if (can_coalesce(skb, i, page, off) && off != PAGE_SIZE) { + /* We can extend the last page fragment. */ + merge = 1; + } else if (i == MAX_SKB_FRAGS || + (i == 0 && !(sk->route_caps&NETIF_F_SG))) { + /* Need to add new fragment and cannot + * do this because interface is non-SG, + * or because all the page slots are busy. + */ + tcp_mark_push(tp, skb); + goto new_segment; + } else if (page) { + /* If page is cached, align + * offset to L1 cache boundary + */ + off = (off+L1_CACHE_BYTES-1)&~(L1_CACHE_BYTES-1); + if (off == PAGE_SIZE) { + put_page(page); + TCP_PAGE(sk) = page = NULL; + } + } + + if (!page) { + /* Allocate new cache page. */ + if (!(page=tcp_alloc_page(sk))) + goto wait_for_memory; + off = 0; + } + + if (copy > PAGE_SIZE-off) + copy = PAGE_SIZE-off; + + /* Time to copy data. We are close to the end! */ + err = tcp_copy_to_page(sk, from, skb, page, off, copy); + if (err) { + /* If this page was new, give it to the + * socket so it does not get leaked. + */ + if (TCP_PAGE(sk) == NULL) { + TCP_PAGE(sk) = page; + TCP_OFF(sk) = 0; + } + goto do_error; + } + + /* Update the skb. */ + if (merge) { + skb_shinfo(skb)->frags[i-1].size += copy; + } else { + fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { + get_page(page); + } else if (off + copy < PAGE_SIZE) { + get_page(page); + TCP_PAGE(sk) = page; + } + } + + TCP_OFF(sk) = off+copy; + } + + if (!copied) + TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH; + + tp->write_seq += copy; + TCP_SKB_CB(skb)->end_seq += copy; + + from += copy; + copied += copy; + if ((seglen -= copy) == 0 && iovlen == 0) + goto out; + + if (skb->len != mss_now || (flags&MSG_OOB)) + continue; + + if (forced_push(tp)) { + tcp_mark_push(tp, skb); + __tcp_push_pending_frames(sk, tp, mss_now, 1); + } else if (skb == tp->send_head) + tcp_push_one(sk, mss_now); + continue; + +wait_for_sndbuf: + set_bit(SOCK_NOSPACE, &sk->socket->flags); +wait_for_memory: + if (copied) + tcp_push(sk, tp, flags&~MSG_MORE, mss_now, 1); + + if ((err = wait_for_tcp_memory(sk, &timeo)) != 0) + goto do_error; + + mss_now = tcp_current_mss(sk); + } + } + +out: + if (copied) + tcp_push(sk, tp, flags, mss_now, tp->nonagle); + TCP_CHECK_TIMER(sk); + release_sock(sk); + return copied; + +do_fault: + if (skb->len == 0) { + if (tp->send_head == skb) + tp->send_head = NULL; + __skb_unlink(skb, skb->list); + tcp_free_skb(sk, skb); + } + +do_error: + if (copied) + goto out; +out_err: + err = tcp_error(sk, flags, err); + TCP_CHECK_TIMER(sk); + release_sock(sk); + return err; +#else + return 0; +#endif +} + +/* + * Handle reading urgent data. BSD has very simple semantics for + * this, no blocking and very strange errors 8) + */ + +static int tcp_recv_urg(struct sock * sk, long timeo, + struct msghdr *msg, int len, int flags, + int *addr_len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* No URG data to read. */ + if (sk->urginline || !tp->urg_data || tp->urg_data == TCP_URG_READ) + return -EINVAL; /* Yes this is right ! */ + + if (sk->state==TCP_CLOSE && !sk->done) + return -ENOTCONN; + + if (tp->urg_data & TCP_URG_VALID) { + int err = 0; + char c = tp->urg_data; + + if (!(flags & MSG_PEEK)) + tp->urg_data = TCP_URG_READ; + + /* Read urgent data. */ + msg->msg_flags|=MSG_OOB; + + if(len>0) { + if (!(flags & MSG_TRUNC)) + err = memcpy_toiovec(msg->msg_iov, &c, 1); + len = 1; + } else + msg->msg_flags|=MSG_TRUNC; + + return err ? -EFAULT : len; + } + + if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN)) + return 0; + + /* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and + * the available implementations agree in this case: + * this call should never block, independent of the + * blocking state of the socket. + * Mike + */ + return -EAGAIN; +#else +return 0; +#endif +} + +/* + * Release a skb if it is no longer needed. This routine + * must be called with interrupts disabled or with the + * socket locked so that the sk_buff queue operation is ok. + */ + +static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) +{ +#if 0 + __skb_unlink(skb, &sk->receive_queue); + __kfree_skb(skb); +#endif +} + +/* Clean up the receive buffer for full frames taken by the user, + * then send an ACK if necessary. COPIED is the number of bytes + * tcp_recvmsg has given to the user so far, it speeds up the + * calculation of whether or not we must ACK for the sake of + * a window update. + */ +static void cleanup_rbuf(struct sock *sk, int copied) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int time_to_ack = 0; + +#if TCP_DEBUG + struct sk_buff *skb = skb_peek(&sk->receive_queue); + + BUG_TRAP(skb==NULL || before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); +#endif + + if (tcp_ack_scheduled(tp)) { + /* Delayed ACKs frequently hit locked sockets during bulk receive. */ + if (tp->ack.blocked + /* Once-per-two-segments ACK was not sent by tcp_input.c */ + || tp->rcv_nxt - tp->rcv_wup > tp->ack.rcv_mss + /* + * If this read emptied read buffer, we send ACK, if + * connection is not bidirectional, user drained + * receive buffer and there was a small segment + * in queue. + */ + || (copied > 0 && + (tp->ack.pending&TCP_ACK_PUSHED) && + !tp->ack.pingpong && + atomic_read(&sk->rmem_alloc) == 0)) { + time_to_ack = 1; + } + } + + /* We send an ACK if we can now advertise a non-zero window + * which has been raised "significantly". + * + * Even if window raised up to infinity, do not send window open ACK + * in states, where we will not receive more. It is useless. + */ + if(copied > 0 && !time_to_ack && !(sk->shutdown&RCV_SHUTDOWN)) { + __u32 rcv_window_now = tcp_receive_window(tp); + + /* Optimize, __tcp_select_window() is not cheap. */ + if (2*rcv_window_now <= tp->window_clamp) { + __u32 new_window = __tcp_select_window(sk); + + /* Send ACK now, if this read freed lots of space + * in our buffer. Certainly, new_window is new window. + * We can advertise it now, if it is not less than current one. + * "Lots" means "at least twice" here. + */ + if(new_window && new_window >= 2*rcv_window_now) + time_to_ack = 1; + } + } + if (time_to_ack) + tcp_send_ack(sk); +#endif +} + +/* Now socket state including sk->err is changed only under lock, + * hence we may omit checks after joining wait queue. + * We check receive queue before schedule() only as optimization; + * it is very likely that release_sock() added new data. + */ + +static long tcp_data_wait(struct sock *sk, long timeo) +{ +#if 0 + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(sk->sleep, &wait); + + __set_current_state(TASK_INTERRUPTIBLE); + + set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); + release_sock(sk); + + if (skb_queue_empty(&sk->receive_queue)) + timeo = schedule_timeout(timeo); + + lock_sock(sk); + clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); + + remove_wait_queue(sk->sleep, &wait); + __set_current_state(TASK_RUNNING); + return timeo; +#else + return 0; +#endif +} + +static void tcp_prequeue_process(struct sock *sk) +{ +#if 0 + struct sk_buff *skb; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + net_statistics[smp_processor_id()*2+1].TCPPrequeued += skb_queue_len(&tp->ucopy.prequeue); + + /* RX process wants to run with disabled BHs, though it is not necessary */ + local_bh_disable(); + while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) + sk->backlog_rcv(sk, skb); + local_bh_enable(); + + /* Clear memory counter. */ + tp->ucopy.memory = 0; +#endif +} + +static inline +struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) +{ +#if 0 + struct sk_buff *skb; + u32 offset; + + skb_queue_walk(&sk->receive_queue, skb) { + offset = seq - TCP_SKB_CB(skb)->seq; + if (skb->h.th->syn) + offset--; + if (offset < skb->len || skb->h.th->fin) { + *off = offset; + return skb; + } + } + return NULL; +#else + return NULL; +#endif +} + +/* + * This routine provides an alternative to tcp_recvmsg() for routines + * that would like to handle copying from skbuffs directly in 'sendfile' + * fashion. + * Note: + * - It is assumed that the socket was locked by the caller. + * - The routine does not block. + * - At present, there is no support for reading OOB data + * or for 'peeking' the socket using this routine + * (although both would be easy to implement). + */ +int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor) +{ +#if 0 + struct sk_buff *skb; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + u32 seq = tp->copied_seq; + u32 offset; + int copied = 0; + + if (sk->state == TCP_LISTEN) + return -ENOTCONN; + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { + if (offset < skb->len) { + size_t used, len; + + len = skb->len - offset; + /* Stop reading if we hit a patch of urgent data */ + if (tp->urg_data) { + u32 urg_offset = tp->urg_seq - seq; + if (urg_offset < len) + len = urg_offset; + if (!len) + break; + } + used = recv_actor(desc, skb, offset, len); + if (used <= len) { + seq += used; + copied += used; + offset += used; + } + if (offset != skb->len) + break; + } + if (skb->h.th->fin) { + tcp_eat_skb(sk, skb); + ++seq; + break; + } + tcp_eat_skb(sk, skb); + if (!desc->count) + break; + } + tp->copied_seq = seq; + /* Clean up data we have read: This will do ACK frames. */ + if (copied) + cleanup_rbuf(sk, copied); + return copied; +#else +#endif +} + +/* + * This routine copies from a sock struct into the user buffer. + * + * Technical note: in 2.3 we work on _locked_ socket, so that + * tricks with *seq access order and skb->users are not required. + * Probably, code can be easily improved even more. + */ + +int tcp_recvmsg(struct sock *sk, struct msghdr *msg, + int len, int nonblock, int flags, int *addr_len) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int copied = 0; + u32 peek_seq; + u32 *seq; + unsigned long used; + int err; + int target; /* Read at least this many bytes */ + long timeo; + struct task_struct *user_recv = NULL; + + lock_sock(sk); + + TCP_CHECK_TIMER(sk); + + err = -ENOTCONN; + if (sk->state == TCP_LISTEN) + goto out; + + timeo = sock_rcvtimeo(sk, nonblock); + + /* Urgent data needs to be handled specially. */ + if (flags & MSG_OOB) + goto recv_urg; + + seq = &tp->copied_seq; + if (flags & MSG_PEEK) { + peek_seq = tp->copied_seq; + seq = &peek_seq; + } + + target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); + + do { + struct sk_buff * skb; + u32 offset; + + /* Are we at urgent data? Stop if we have read anything. */ + if (copied && tp->urg_data && tp->urg_seq == *seq) + break; + + /* We need to check signals first, to get correct SIGURG + * handling. FIXME: Need to check this doesn't impact 1003.1g + * and move it down to the bottom of the loop + */ + if (signal_pending(current)) { + if (copied) + break; + copied = timeo ? sock_intr_errno(timeo) : -EAGAIN; + break; + } + + /* Next get a buffer. */ + + skb = skb_peek(&sk->receive_queue); + do { + if (!skb) + break; + + /* Now that we have two receive queues this + * shouldn't happen. + */ + if (before(*seq, TCP_SKB_CB(skb)->seq)) { + printk(KERN_INFO "recvmsg bug: copied %X seq %X\n", + *seq, TCP_SKB_CB(skb)->seq); + break; + } + offset = *seq - TCP_SKB_CB(skb)->seq; + if (skb->h.th->syn) + offset--; + if (offset < skb->len) + goto found_ok_skb; + if (skb->h.th->fin) + goto found_fin_ok; + BUG_TRAP(flags&MSG_PEEK); + skb = skb->next; + } while (skb != (struct sk_buff *)&sk->receive_queue); + + /* Well, if we have backlog, try to process it now yet. */ + + if (copied >= target && sk->backlog.tail == NULL) + break; + + if (copied) { + if (sk->err || + sk->state == TCP_CLOSE || + (sk->shutdown & RCV_SHUTDOWN) || + !timeo || + (flags & MSG_PEEK)) + break; + } else { + if (sk->done) + break; + + if (sk->err) { + copied = sock_error(sk); + break; + } + + if (sk->shutdown & RCV_SHUTDOWN) + break; + + if (sk->state == TCP_CLOSE) { + if (!sk->done) { + /* This occurs when user tries to read + * from never connected socket. + */ + copied = -ENOTCONN; + break; + } + break; + } + + if (!timeo) { + copied = -EAGAIN; + break; + } + } + + cleanup_rbuf(sk, copied); + + if (tp->ucopy.task == user_recv) { + /* Install new reader */ + if (user_recv == NULL && !(flags&(MSG_TRUNC|MSG_PEEK))) { + user_recv = current; + tp->ucopy.task = user_recv; + tp->ucopy.iov = msg->msg_iov; + } + + tp->ucopy.len = len; + + BUG_TRAP(tp->copied_seq == tp->rcv_nxt || (flags&(MSG_PEEK|MSG_TRUNC))); + + /* Ugly... If prequeue is not empty, we have to + * process it before releasing socket, otherwise + * order will be broken at second iteration. + * More elegant solution is required!!! + * + * Look: we have the following (pseudo)queues: + * + * 1. packets in flight + * 2. backlog + * 3. prequeue + * 4. receive_queue + * + * Each queue can be processed only if the next ones + * are empty. At this point we have empty receive_queue. + * But prequeue _can_ be not empty after second iteration, + * when we jumped to start of loop because backlog + * processing added something to receive_queue. + * We cannot release_sock(), because backlog contains + * packets arrived _after_ prequeued ones. + * + * Shortly, algorithm is clear --- to process all + * the queues in order. We could make it more directly, + * requeueing packets from backlog to prequeue, if + * is not empty. It is more elegant, but eats cycles, + * unfortunately. + */ + if (skb_queue_len(&tp->ucopy.prequeue)) + goto do_prequeue; + + /* __ Set realtime policy in scheduler __ */ + } + + if (copied >= target) { + /* Do not sleep, just process backlog. */ + release_sock(sk); + lock_sock(sk); + } else { + timeo = tcp_data_wait(sk, timeo); + } + + if (user_recv) { + int chunk; + + /* __ Restore normal policy in scheduler __ */ + + if ((chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromBacklog += chunk; + len -= chunk; + copied += chunk; + } + + if (tp->rcv_nxt == tp->copied_seq && + skb_queue_len(&tp->ucopy.prequeue)) { +do_prequeue: + tcp_prequeue_process(sk); + + if ((chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk; + len -= chunk; + copied += chunk; + } + } + } + if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) { + if (net_ratelimit()) + printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", + current->comm, current->pid); + peek_seq = tp->copied_seq; + } + continue; + + found_ok_skb: + /* Ok so how much can we use? */ + used = skb->len - offset; + if (len < used) + used = len; + + /* Do we have urgent data here? */ + if (tp->urg_data) { + u32 urg_offset = tp->urg_seq - *seq; + if (urg_offset < used) { + if (!urg_offset) { + if (!sk->urginline) { + ++*seq; + offset++; + used--; + if (!used) + goto skip_copy; + } + } else + used = urg_offset; + } + } + + if (!(flags&MSG_TRUNC)) { + err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, used); + if (err) { + /* Exception. Bailout! */ + if (!copied) + copied = -EFAULT; + break; + } + } + + *seq += used; + copied += used; + len -= used; + +skip_copy: + if (tp->urg_data && after(tp->copied_seq,tp->urg_seq)) { + tp->urg_data = 0; + tcp_fast_path_check(sk, tp); + } + if (used + offset < skb->len) + continue; + + if (skb->h.th->fin) + goto found_fin_ok; + if (!(flags & MSG_PEEK)) + tcp_eat_skb(sk, skb); + continue; + + found_fin_ok: + /* Process the FIN. */ + ++*seq; + if (!(flags & MSG_PEEK)) + tcp_eat_skb(sk, skb); + break; + } while (len > 0); + + if (user_recv) { + if (skb_queue_len(&tp->ucopy.prequeue)) { + int chunk; + + tp->ucopy.len = copied > 0 ? len : 0; + + tcp_prequeue_process(sk); + + if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk; + len -= chunk; + copied += chunk; + } + } + + tp->ucopy.task = NULL; + tp->ucopy.len = 0; + } + + /* According to UNIX98, msg_name/msg_namelen are ignored + * on connected socket. I was just happy when found this 8) --ANK + */ + + /* Clean up data we have read: This will do ACK frames. */ + cleanup_rbuf(sk, copied); + + TCP_CHECK_TIMER(sk); + release_sock(sk); + return copied; + +out: + TCP_CHECK_TIMER(sk); + release_sock(sk); + return err; + +recv_urg: + err = tcp_recv_urg(sk, timeo, msg, len, flags, addr_len); + goto out; +#else + return 0; +#endif +} + +/* + * State processing on a close. This implements the state shift for + * sending our FIN frame. Note that we only send a FIN for some + * states. A shutdown() may have already sent the FIN, or we may be + * closed. + */ + +static unsigned char new_state[16] = { + /* current state: new state: action: */ + /* (Invalid) */ TCP_CLOSE, + /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN, + /* TCP_SYN_SENT */ TCP_CLOSE, + /* TCP_SYN_RECV */ TCP_FIN_WAIT1 | TCP_ACTION_FIN, + /* TCP_FIN_WAIT1 */ TCP_FIN_WAIT1, + /* TCP_FIN_WAIT2 */ TCP_FIN_WAIT2, + /* TCP_TIME_WAIT */ TCP_CLOSE, + /* TCP_CLOSE */ TCP_CLOSE, + /* TCP_CLOSE_WAIT */ TCP_LAST_ACK | TCP_ACTION_FIN, + /* TCP_LAST_ACK */ TCP_LAST_ACK, + /* TCP_LISTEN */ TCP_CLOSE, + /* TCP_CLOSING */ TCP_CLOSING, +}; + +static int tcp_close_state(struct sock *sk) +{ +#if 0 + int next = (int) new_state[sk->state]; + int ns = (next & TCP_STATE_MASK); + + tcp_set_state(sk, ns); + + return (next & TCP_ACTION_FIN); +#else + return 0; +#endif +} + +/* + * Shutdown the sending side of a connection. Much like close except + * that we don't receive shut down or set sk->dead. + */ + +void tcp_shutdown(struct sock *sk, int how) +{ +#if 0 + /* We need to grab some memory, and put together a FIN, + * and then put it into the queue to be sent. + * Tim MacKenzie(tym@dibbler.cs.monash.edu.au) 4 Dec '92. + */ + if (!(how & SEND_SHUTDOWN)) + return; + + /* If we've already sent a FIN, or it's a closed state, skip this. */ + if ((1 << sk->state) & + (TCPF_ESTABLISHED|TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE_WAIT)) { + /* Clear out any half completed packets. FIN if needed. */ + if (tcp_close_state(sk)) + tcp_send_fin(sk); + } +#endif +} + + +/* + * Return 1 if we still have things to send in our buffers. + */ + +static inline int closing(struct sock * sk) +{ +#if 0 + return ((1 << sk->state) & (TCPF_FIN_WAIT1|TCPF_CLOSING|TCPF_LAST_ACK)); +#else + return 0; +#endif +} + +static __inline__ void tcp_kill_sk_queues(struct sock *sk) +{ +#if 0 + /* First the read buffer. */ + __skb_queue_purge(&sk->receive_queue); + + /* Next, the error queue. */ + __skb_queue_purge(&sk->error_queue); + + /* Next, the write queue. */ + BUG_TRAP(skb_queue_empty(&sk->write_queue)); + + /* Account for returned memory. */ + tcp_mem_reclaim(sk); + + BUG_TRAP(sk->wmem_queued == 0); + BUG_TRAP(sk->forward_alloc == 0); + + /* It is _impossible_ for the backlog to contain anything + * when we get here. All user references to this socket + * have gone away, only the net layer knows can touch it. + */ +#endif +} + +/* + * At this point, there should be no process reference to this + * socket, and thus no user references at all. Therefore we + * can assume the socket waitqueue is inactive and nobody will + * try to jump onto it. + */ +void tcp_destroy_sock(struct sock *sk) +{ +#if 0 + BUG_TRAP(sk->state==TCP_CLOSE); + BUG_TRAP(sk->dead); + + /* It cannot be in hash table! */ + BUG_TRAP(sk->pprev==NULL); + + /* If it has not 0 sk->num, it must be bound */ + BUG_TRAP(!sk->num || sk->prev!=NULL); + +#ifdef TCP_DEBUG + if (sk->zapped) { + printk(KERN_DEBUG "TCP: double destroy sk=%p\n", sk); + sock_hold(sk); + } + sk->zapped = 1; +#endif + + sk->prot->destroy(sk); + + tcp_kill_sk_queues(sk); + +#ifdef INET_REFCNT_DEBUG + if (atomic_read(&sk->refcnt) != 1) { + printk(KERN_DEBUG "Destruction TCP %p delayed, c=%d\n", sk, atomic_read(&sk->refcnt)); + } +#endif + + atomic_dec(&tcp_orphan_count); + sock_put(sk); +#endif +} + +void tcp_close(struct sock *sk, long timeout) +{ +#if 0 + struct sk_buff *skb; + int data_was_unread = 0; + + lock_sock(sk); + sk->shutdown = SHUTDOWN_MASK; + + if(sk->state == TCP_LISTEN) { + tcp_set_state(sk, TCP_CLOSE); + + /* Special case. */ + tcp_listen_stop(sk); + + goto adjudge_to_death; + } + + /* We need to flush the recv. buffs. We do this only on the + * descriptor close, not protocol-sourced closes, because the + * reader process may not have drained the data yet! + */ + while((skb=__skb_dequeue(&sk->receive_queue))!=NULL) { + u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq - skb->h.th->fin; + data_was_unread += len; + __kfree_skb(skb); + } + + tcp_mem_reclaim(sk); + + /* As outlined in draft-ietf-tcpimpl-prob-03.txt, section + * 3.10, we send a RST here because data was lost. To + * witness the awful effects of the old behavior of always + * doing a FIN, run an older 2.1.x kernel or 2.0.x, start + * a bulk GET in an FTP client, suspend the process, wait + * for the client to advertise a zero window, then kill -9 + * the FTP client, wheee... Note: timeout is always zero + * in such a case. + */ + if(data_was_unread != 0) { + /* Unread data was tossed, zap the connection. */ + NET_INC_STATS_USER(TCPAbortOnClose); + tcp_set_state(sk, TCP_CLOSE); + tcp_send_active_reset(sk, GFP_KERNEL); + } else if (sk->linger && sk->lingertime==0) { + /* Check zero linger _after_ checking for unread data. */ + sk->prot->disconnect(sk, 0); + NET_INC_STATS_USER(TCPAbortOnData); + } else if (tcp_close_state(sk)) { + /* We FIN if the application ate all the data before + * zapping the connection. + */ + + /* RED-PEN. Formally speaking, we have broken TCP state + * machine. State transitions: + * + * TCP_ESTABLISHED -> TCP_FIN_WAIT1 + * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible) + * TCP_CLOSE_WAIT -> TCP_LAST_ACK + * + * are legal only when FIN has been sent (i.e. in window), + * rather than queued out of window. Purists blame. + * + * F.e. "RFC state" is ESTABLISHED, + * if Linux state is FIN-WAIT-1, but FIN is still not sent. + * + * The visible declinations are that sometimes + * we enter time-wait state, when it is not required really + * (harmless), do not send active resets, when they are + * required by specs (TCP_ESTABLISHED, TCP_CLOSE_WAIT, when + * they look as CLOSING or LAST_ACK for Linux) + * Probably, I missed some more holelets. + * --ANK + */ + tcp_send_fin(sk); + } + + if (timeout) { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(sk->sleep, &wait); + + do { + set_current_state(TASK_INTERRUPTIBLE); + if (!closing(sk)) + break; + release_sock(sk); + timeout = schedule_timeout(timeout); + lock_sock(sk); + } while (!signal_pending(tsk) && timeout); + + tsk->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + } + +adjudge_to_death: + /* It is the last release_sock in its life. It will remove backlog. */ + release_sock(sk); + + + /* Now socket is owned by kernel and we acquire BH lock + to finish close. No need to check for user refs. + */ + local_bh_disable(); + bh_lock_sock(sk); + BUG_TRAP(sk->lock.users==0); + + sock_hold(sk); + sock_orphan(sk); + + /* This is a (useful) BSD violating of the RFC. There is a + * problem with TCP as specified in that the other end could + * keep a socket open forever with no application left this end. + * We use a 3 minute timeout (about the same as BSD) then kill + * our end. If they send after that then tough - BUT: long enough + * that we won't make the old 4*rto = almost no time - whoops + * reset mistake. + * + * Nope, it was not mistake. It is really desired behaviour + * f.e. on http servers, when such sockets are useless, but + * consume significant resources. Let's do it with special + * linger2 option. --ANK + */ + + if (sk->state == TCP_FIN_WAIT2) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + if (tp->linger2 < 0) { + tcp_set_state(sk, TCP_CLOSE); + tcp_send_active_reset(sk, GFP_ATOMIC); + NET_INC_STATS_BH(TCPAbortOnLinger); + } else { + int tmo = tcp_fin_time(tp); + + if (tmo > TCP_TIMEWAIT_LEN) { + tcp_reset_keepalive_timer(sk, tcp_fin_time(tp)); + } else { + atomic_inc(&tcp_orphan_count); + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto out; + } + } + } + if (sk->state != TCP_CLOSE) { + tcp_mem_reclaim(sk); + if (atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans || + (sk->wmem_queued > SOCK_MIN_SNDBUF && + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + if (net_ratelimit()) + printk(KERN_INFO "TCP: too many of orphaned sockets\n"); + tcp_set_state(sk, TCP_CLOSE); + tcp_send_active_reset(sk, GFP_ATOMIC); + NET_INC_STATS_BH(TCPAbortOnMemory); + } + } + atomic_inc(&tcp_orphan_count); + + if (sk->state == TCP_CLOSE) + tcp_destroy_sock(sk); + /* Otherwise, socket is reprieved until protocol close. */ + +out: + bh_unlock_sock(sk); + local_bh_enable(); + sock_put(sk); +#endif +} + +/* These states need RST on ABORT according to RFC793 */ + +extern __inline__ int tcp_need_reset(int state) +{ +#if 0 + return ((1 << state) & + (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1| + TCPF_FIN_WAIT2|TCPF_SYN_RECV)); +#else + return 0; +#endif +} + +int tcp_disconnect(struct sock *sk, int flags) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int old_state; + int err = 0; + + old_state = sk->state; + if (old_state != TCP_CLOSE) + tcp_set_state(sk, TCP_CLOSE); + + /* ABORT function of RFC793 */ + if (old_state == TCP_LISTEN) { + tcp_listen_stop(sk); + } else if (tcp_need_reset(old_state) || + (tp->snd_nxt != tp->write_seq && + (1<err = ECONNRESET; + } else if (old_state == TCP_SYN_SENT) + sk->err = ECONNRESET; + + tcp_clear_xmit_timers(sk); + __skb_queue_purge(&sk->receive_queue); + tcp_writequeue_purge(sk); + __skb_queue_purge(&tp->out_of_order_queue); + + sk->dport = 0; + + if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) { + sk->rcv_saddr = 0; + sk->saddr = 0; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + memset(&sk->net_pinfo.af_inet6.saddr, 0, 16); + memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16); +#endif + } + + sk->shutdown = 0; + sk->done = 0; + tp->srtt = 0; + if ((tp->write_seq += tp->max_window+2) == 0) + tp->write_seq = 1; + tp->backoff = 0; + tp->snd_cwnd = 2; + tp->probes_out = 0; + tp->packets_out = 0; + tp->snd_ssthresh = 0x7fffffff; + tp->snd_cwnd_cnt = 0; + tp->ca_state = TCP_CA_Open; + tcp_clear_retrans(tp); + tcp_delack_init(tp); + tp->send_head = NULL; + tp->saw_tstamp = 0; + tcp_sack_reset(tp); + __sk_dst_reset(sk); + + BUG_TRAP(!sk->num || sk->prev); + + sk->error_report(sk); + return err; +#else + return 0; +#endif +} + +/* + * Wait for an incoming connection, avoid race + * conditions. This must be called with the socket locked. + */ +static int wait_for_connect(struct sock * sk, long timeo) +{ +#if 0 + DECLARE_WAITQUEUE(wait, current); + int err; + + /* + * True wake-one mechanism for incoming connections: only + * one process gets woken up, not the 'whole herd'. + * Since we do not 'race & poll' for established sockets + * anymore, the common case will execute the loop only once. + * + * Subtle issue: "add_wait_queue_exclusive()" will be added + * after any current non-exclusive waiters, and we know that + * it will always _stay_ after any new non-exclusive waiters + * because all non-exclusive waiters are added at the + * beginning of the wait-queue. As such, it's ok to "drop" + * our exclusiveness temporarily when we get woken up without + * having to remove and re-insert us on the wait queue. + */ + add_wait_queue_exclusive(sk->sleep, &wait); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + release_sock(sk); + if (sk->tp_pinfo.af_tcp.accept_queue == NULL) + timeo = schedule_timeout(timeo); + lock_sock(sk); + err = 0; + if (sk->tp_pinfo.af_tcp.accept_queue) + break; + err = -EINVAL; + if (sk->state != TCP_LISTEN) + break; + err = sock_intr_errno(timeo); + if (signal_pending(current)) + break; + err = -EAGAIN; + if (!timeo) + break; + } + current->state = TASK_RUNNING; + remove_wait_queue(sk->sleep, &wait); + return err; +#else + return 0; +#endif +} + +/* + * This will accept the next outstanding connection. + */ + +struct sock *tcp_accept(struct sock *sk, int flags, int *err) +{ +#if 0 + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct open_request *req; + struct sock *newsk; + int error; + + lock_sock(sk); + + /* We need to make sure that this socket is listening, + * and that it has something pending. + */ + error = -EINVAL; + if (sk->state != TCP_LISTEN) + goto out; + + /* Find already established connection */ + if (!tp->accept_queue) { + long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); + + /* If this is a non blocking socket don't sleep */ + error = -EAGAIN; + if (!timeo) + goto out; + + error = wait_for_connect(sk, timeo); + if (error) + goto out; + } + + req = tp->accept_queue; + if ((tp->accept_queue = req->dl_next) == NULL) + tp->accept_queue_tail = NULL; + + newsk = req->sk; + tcp_acceptq_removed(sk); + tcp_openreq_fastfree(req); + BUG_TRAP(newsk->state != TCP_SYN_RECV); + release_sock(sk); + return newsk; + +out: + release_sock(sk); + *err = error; + return NULL; +#else + return NULL; +#endif +} + +/* + * Socket option code for TCP. + */ + +int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval, + int optlen) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int val; + int err = 0; + + if (level != SOL_TCP) + return tp->af_specific->setsockopt(sk, level, optname, + optval, optlen); + + if(optlen MAX_TCP_WINDOW) { + err = -EINVAL; + break; + } + tp->user_mss = val; + break; + + case TCP_NODELAY: + /* You cannot try to use this and TCP_CORK in + * tandem, so let the user know. + */ + if (tp->nonagle == 2) { + err = -EINVAL; + break; + } + tp->nonagle = (val == 0) ? 0 : 1; + if (val) + tcp_push_pending_frames(sk, tp); + break; + + case TCP_CORK: + /* When set indicates to always queue non-full frames. + * Later the user clears this option and we transmit + * any pending partial frames in the queue. This is + * meant to be used alongside sendfile() to get properly + * filled frames when the user (for example) must write + * out headers with a write() call first and then use + * sendfile to send out the data parts. + * + * You cannot try to use TCP_NODELAY and this mechanism + * at the same time, so let the user know. + */ + if (tp->nonagle == 1) { + err = -EINVAL; + break; + } + if (val != 0) { + tp->nonagle = 2; + } else { + tp->nonagle = 0; + + tcp_push_pending_frames(sk, tp); + } + break; + + case TCP_KEEPIDLE: + if (val < 1 || val > MAX_TCP_KEEPIDLE) + err = -EINVAL; + else { + tp->keepalive_time = val * HZ; + if (sk->keepopen && !((1<state)&(TCPF_CLOSE|TCPF_LISTEN))) { + __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; + if (tp->keepalive_time > elapsed) + elapsed = tp->keepalive_time - elapsed; + else + elapsed = 0; + tcp_reset_keepalive_timer(sk, elapsed); + } + } + break; + case TCP_KEEPINTVL: + if (val < 1 || val > MAX_TCP_KEEPINTVL) + err = -EINVAL; + else + tp->keepalive_intvl = val * HZ; + break; + case TCP_KEEPCNT: + if (val < 1 || val > MAX_TCP_KEEPCNT) + err = -EINVAL; + else + tp->keepalive_probes = val; + break; + case TCP_SYNCNT: + if (val < 1 || val > MAX_TCP_SYNCNT) + err = -EINVAL; + else + tp->syn_retries = val; + break; + + case TCP_LINGER2: + if (val < 0) + tp->linger2 = -1; + else if (val > sysctl_tcp_fin_timeout/HZ) + tp->linger2 = 0; + else + tp->linger2 = val*HZ; + break; + + case TCP_DEFER_ACCEPT: + tp->defer_accept = 0; + if (val > 0) { + /* Translate value in seconds to number of retransmits */ + while (tp->defer_accept < 32 && val > ((TCP_TIMEOUT_INIT/HZ)<defer_accept)) + tp->defer_accept++; + tp->defer_accept++; + } + break; + + case TCP_WINDOW_CLAMP: + if (val==0) { + if (sk->state != TCP_CLOSE) { + err = -EINVAL; + break; + } + tp->window_clamp = 0; + } else { + tp->window_clamp = valack.pingpong = 1; + } else { + tp->ack.pingpong = 0; + if ((1<state)&(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT) && + tcp_ack_scheduled(tp)) { + tp->ack.pending |= TCP_ACK_PUSHED; + cleanup_rbuf(sk, 1); + if (!(val & 1)) + tp->ack.pingpong = 1; + } + } + break; + + default: + err = -ENOPROTOOPT; + break; + }; + release_sock(sk); + return err; +#else + return 0; +#endif +} + +int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, + int *optlen) +{ +#if 0 + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int val, len; + + if(level != SOL_TCP) + return tp->af_specific->getsockopt(sk, level, optname, + optval, optlen); + + if(get_user(len,optlen)) + return -EFAULT; + + len = min_t(unsigned int, len, sizeof(int)); + + if(len < 0) + return -EINVAL; + + switch(optname) { + case TCP_MAXSEG: + val = tp->mss_cache; + if (val == 0 && ((1<state)&(TCPF_CLOSE|TCPF_LISTEN))) + val = tp->user_mss; + break; + case TCP_NODELAY: + val = (tp->nonagle == 1); + break; + case TCP_CORK: + val = (tp->nonagle == 2); + break; + case TCP_KEEPIDLE: + val = (tp->keepalive_time ? : sysctl_tcp_keepalive_time)/HZ; + break; + case TCP_KEEPINTVL: + val = (tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl)/HZ; + break; + case TCP_KEEPCNT: + val = tp->keepalive_probes ? : sysctl_tcp_keepalive_probes; + break; + case TCP_SYNCNT: + val = tp->syn_retries ? : sysctl_tcp_syn_retries; + break; + case TCP_LINGER2: + val = tp->linger2; + if (val >= 0) + val = (val ? : sysctl_tcp_fin_timeout)/HZ; + break; + case TCP_DEFER_ACCEPT: + val = tp->defer_accept == 0 ? 0 : ((TCP_TIMEOUT_INIT/HZ)<<(tp->defer_accept-1)); + break; + case TCP_WINDOW_CLAMP: + val = tp->window_clamp; + break; + case TCP_INFO: + { + struct tcp_info info; + u32 now = tcp_time_stamp; + + if(get_user(len,optlen)) + return -EFAULT; + info.tcpi_state = sk->state; + info.tcpi_ca_state = tp->ca_state; + info.tcpi_retransmits = tp->retransmits; + info.tcpi_probes = tp->probes_out; + info.tcpi_backoff = tp->backoff; + info.tcpi_options = 0; + if (tp->tstamp_ok) + info.tcpi_options |= TCPI_OPT_TIMESTAMPS; + if (tp->sack_ok) + info.tcpi_options |= TCPI_OPT_SACK; + if (tp->wscale_ok) { + info.tcpi_options |= TCPI_OPT_WSCALE; + info.tcpi_snd_wscale = tp->snd_wscale; + info.tcpi_rcv_wscale = tp->rcv_wscale; + } else { + info.tcpi_snd_wscale = 0; + info.tcpi_rcv_wscale = 0; + } + if (tp->ecn_flags&TCP_ECN_OK) + info.tcpi_options |= TCPI_OPT_ECN; + + info.tcpi_rto = (1000000*tp->rto)/HZ; + info.tcpi_ato = (1000000*tp->ack.ato)/HZ; + info.tcpi_snd_mss = tp->mss_cache; + info.tcpi_rcv_mss = tp->ack.rcv_mss; + + info.tcpi_unacked = tp->packets_out; + info.tcpi_sacked = tp->sacked_out; + info.tcpi_lost = tp->lost_out; + info.tcpi_retrans = tp->retrans_out; + info.tcpi_fackets = tp->fackets_out; + + info.tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ; + info.tcpi_last_ack_sent = 0; + info.tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ; + info.tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ; + + info.tcpi_pmtu = tp->pmtu_cookie; + info.tcpi_rcv_ssthresh = tp->rcv_ssthresh; + info.tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3; + info.tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2; + info.tcpi_snd_ssthresh = tp->snd_ssthresh; + info.tcpi_snd_cwnd = tp->snd_cwnd; + info.tcpi_advmss = tp->advmss; + info.tcpi_reordering = tp->reordering; + + len = min_t(unsigned int, len, sizeof(info)); + if(put_user(len, optlen)) + return -EFAULT; + if(copy_to_user(optval, &info,len)) + return -EFAULT; + return 0; + } + case TCP_QUICKACK: + val = !tp->ack.pingpong; + break; + default: + return -ENOPROTOOPT; + }; + + if(put_user(len, optlen)) + return -EFAULT; + if(copy_to_user(optval, &val,len)) + return -EFAULT; + return 0; +#else + return 0; +#endif +} + + +//extern void __skb_cb_too_small_for_tcp(int, int); +//extern void tcpdiag_init(void); + +void /* __init */ tcp_init(void) +{ +#if 0 + struct sk_buff *skb = NULL; + unsigned long goal; + int order, i; + + if(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)) + __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb), + sizeof(skb->cb)); + + tcp_openreq_cachep = kmem_cache_create("tcp_open_request", + sizeof(struct open_request), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if(!tcp_openreq_cachep) + panic("tcp_init: Cannot alloc open_request cache."); + + tcp_bucket_cachep = kmem_cache_create("tcp_bind_bucket", + sizeof(struct tcp_bind_bucket), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if(!tcp_bucket_cachep) + panic("tcp_init: Cannot alloc tcp_bind_bucket cache."); + + tcp_timewait_cachep = kmem_cache_create("tcp_tw_bucket", + sizeof(struct tcp_tw_bucket), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if(!tcp_timewait_cachep) + panic("tcp_init: Cannot alloc tcp_tw_bucket cache."); + + /* Size and allocate the main established and bind bucket + * hash tables. + * + * The methodology is similar to that of the buffer cache. + */ + if (num_physpages >= (128 * 1024)) + goal = num_physpages >> (21 - PAGE_SHIFT); + else + goal = num_physpages >> (23 - PAGE_SHIFT); + + for(order = 0; (1UL << order) < goal; order++) + ; + do { + tcp_ehash_size = (1UL << order) * PAGE_SIZE / + sizeof(struct tcp_ehash_bucket); + tcp_ehash_size >>= 1; + while (tcp_ehash_size & (tcp_ehash_size-1)) + tcp_ehash_size--; + tcp_ehash = (struct tcp_ehash_bucket *) + __get_free_pages(GFP_ATOMIC, order); + } while (tcp_ehash == NULL && --order > 0); + + if (!tcp_ehash) + panic("Failed to allocate TCP established hash table\n"); + for (i = 0; i < (tcp_ehash_size<<1); i++) { + tcp_ehash[i].lock = RW_LOCK_UNLOCKED; + tcp_ehash[i].chain = NULL; + } + + do { + tcp_bhash_size = (1UL << order) * PAGE_SIZE / + sizeof(struct tcp_bind_hashbucket); + if ((tcp_bhash_size > (64 * 1024)) && order > 0) + continue; + tcp_bhash = (struct tcp_bind_hashbucket *) + __get_free_pages(GFP_ATOMIC, order); + } while (tcp_bhash == NULL && --order >= 0); + + if (!tcp_bhash) + panic("Failed to allocate TCP bind hash table\n"); + for (i = 0; i < tcp_bhash_size; i++) { + tcp_bhash[i].lock = SPIN_LOCK_UNLOCKED; + tcp_bhash[i].chain = NULL; + } + + /* Try to be a bit smarter and adjust defaults depending + * on available memory. + */ + if (order > 4) { + sysctl_local_port_range[0] = 32768; + sysctl_local_port_range[1] = 61000; + sysctl_tcp_max_tw_buckets = 180000; + sysctl_tcp_max_orphans = 4096<<(order-4); + sysctl_max_syn_backlog = 1024; + } else if (order < 3) { + sysctl_local_port_range[0] = 1024*(3-order); + sysctl_tcp_max_tw_buckets >>= (3-order); + sysctl_tcp_max_orphans >>= (3-order); + sysctl_max_syn_backlog = 128; + } + tcp_port_rover = sysctl_local_port_range[0] - 1; + + sysctl_tcp_mem[0] = 768< 512) + sysctl_tcp_mem[1] = sysctl_tcp_mem[2] - 512; + if (sysctl_tcp_mem[1] - sysctl_tcp_mem[0] > 512) + sysctl_tcp_mem[0] = sysctl_tcp_mem[1] - 512; + + if (order < 3) { + sysctl_tcp_wmem[2] = 64*1024; + sysctl_tcp_rmem[0] = PAGE_SIZE; + sysctl_tcp_rmem[1] = 43689; + sysctl_tcp_rmem[2] = 2*43689; + } + + printk(KERN_INFO "TCP: Hash tables configured (established %d bind %d)\n", + tcp_ehash_size<<1, tcp_bhash_size); + + tcpdiag_init(); +#endif +} diff --git a/drivers/net/tcpip/transport/udp/.cvsignore b/drivers/net/tcpip/transport/udp/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tcpip/transport/udp/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tdi/.cvsignore b/drivers/net/tdi/.cvsignore new file mode 100644 index 0000000..07e60d4 --- /dev/null +++ b/drivers/net/tdi/.cvsignore @@ -0,0 +1,3 @@ +*.sym +*.sys +*.o diff --git a/drivers/net/tdi/cte/.cvsignore b/drivers/net/tdi/cte/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tdi/cte/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/net/tdi/misc/.cvsignore b/drivers/net/tdi/misc/.cvsignore index 3775129..6dd71d1 100644 --- a/drivers/net/tdi/misc/.cvsignore +++ b/drivers/net/tdi/misc/.cvsignore @@ -1 +1,2 @@ -tdi.coff \ No newline at end of file +*.o +*.coff diff --git a/drivers/net/tdi/tdi/.cvsignore b/drivers/net/tdi/tdi/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/drivers/net/tdi/tdi/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/drivers/storage/atapi/.cvsignore b/drivers/storage/atapi/.cvsignore index b44c068..d604900 100644 --- a/drivers/storage/atapi/.cvsignore +++ b/drivers/storage/atapi/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp atapi.coff -atapi.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/storage/atapi/atapi.c b/drivers/storage/atapi/atapi.c index be4eaff..d85ba3a 100644 --- a/drivers/storage/atapi/atapi.c +++ b/drivers/storage/atapi/atapi.c @@ -41,6 +41,7 @@ */ #define ENABLE_PCI +#define ENABLE_NATIVE_PCI #define ENABLE_ISA // ------------------------------------------------------------------------- @@ -75,6 +76,10 @@ typedef struct _ATAPI_MINIPORT_EXTENSION IDE_DRIVE_IDENTIFY DeviceParams[2]; BOOLEAN DevicePresent[2]; BOOLEAN DeviceAtapi[2]; + ULONG TransferSize[2]; + BOOLEAN MultiSectorCommand[2]; + BOOLEAN DWordIo[2]; + ULONG CommandPortBase; ULONG ControlPortBase; @@ -83,7 +88,9 @@ typedef struct _ATAPI_MINIPORT_EXTENSION BOOLEAN ExpectingInterrupt; PSCSI_REQUEST_BLOCK CurrentSrb; - PUSHORT DataBuffer; + + PUCHAR DataBuffer; + ULONG DataTransferLength; } ATAPI_MINIPORT_EXTENSION, *PATAPI_MINIPORT_EXTENSION; @@ -92,6 +99,29 @@ typedef struct _UNIT_EXTENSION ULONG Dummy; } UNIT_EXTENSION, *PUNIT_EXTENSION; +PCI_SLOT_NUMBER LastSlotNumber; + +#ifdef ENABLE_NATIVE_PCI +typedef struct _PCI_NATIVE_CONTROLLER +{ + USHORT VendorID; + USHORT DeviceID; +} +PCI_NATIVE_CONTROLLER, *PPCI_NATIVE_CONTROLLER; + +PCI_NATIVE_CONTROLLER const PciNativeController[] = +{ + { + 0x105A, // Promise + 0x4D68, // PDC20268, Ultra100TX2 + }, + { + 0x105A, // Promise + 0x4D30, // PDC20267, Ultra100 + } +}; +#endif + // ----------------------------------------------- Discardable Declarations @@ -203,6 +233,9 @@ static ULONG AtapiReadWrite(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb); +static ULONG +AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, + PSCSI_REQUEST_BLOCK Srb); static UCHAR AtapiErrorToScsi(PVOID DeviceExtension, @@ -271,6 +304,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, InitData.MapBuffers = TRUE; + /* Search the PCI bus for compatibility mode ide controllers */ #ifdef ENABLE_PCI InitData.HwFindAdapter = AtapiFindCompatiblePciController; @@ -290,30 +324,33 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, // statusToReturn = newStatus; #endif - /* Search the ISA bus for ide controllers */ -#ifdef ENABLE_ISA - InitData.HwFindAdapter = AtapiFindIsaBusController; - InitData.NumberOfAccessRanges = 2; - InitData.AdapterInterfaceType = Isa; + /* Search the PCI bus for all ide controllers */ +#ifdef ENABLE_NATIVE_PCI - InitData.VendorId = NULL; + InitData.HwFindAdapter = AtapiFindNativePciController; + InitData.NumberOfAccessRanges = 3; + InitData.AdapterInterfaceType = PCIBus; + + InitData.VendorId = 0; InitData.VendorIdLength = 0; - InitData.DeviceId = NULL; + InitData.DeviceId = 0; InitData.DeviceIdLength = 0; + LastSlotNumber.u.AsULONG = 0xFFFFFFFF; + Status = ScsiPortInitialize(DriverObject, RegistryPath, &InitData, NULL); -// if (newStatus < statusToReturn) -// statusToReturn = newStatus; +// if (newStatus < statusToReturn) +// statusToReturn = newStatus; #endif - /* Search the PCI bus for native mode ide controllers */ -#if 0 - InitData.HwFindAdapter = AtapiFindNativePciController; + /* Search the ISA bus for ide controllers */ +#ifdef ENABLE_ISA + InitData.HwFindAdapter = AtapiFindIsaBusController; InitData.NumberOfAccessRanges = 2; - InitData.AdapterInterfaceType = PCIBus; + InitData.AdapterInterfaceType = Isa; InitData.VendorId = NULL; InitData.VendorIdLength = 0; @@ -323,9 +360,9 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, Status = ScsiPortInitialize(DriverObject, RegistryPath, &InitData, - (PVOID)i); -// if (newStatus < statusToReturn) -// statusToReturn = newStatus; + NULL); +// if (newStatus < statusToReturn) +// statusToReturn = newStatus; #endif DPRINT("Returning from DriverEntry\n"); @@ -334,6 +371,90 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, } +BOOLEAN +AtapiClaimHwResources(PATAPI_MINIPORT_EXTENSION DevExt, + PPORT_CONFIGURATION_INFORMATION ConfigInfo, + INTERFACE_TYPE InterfaceType, + ULONG CommandPortBase, + ULONG ControlPortBase, + ULONG BusMasterPortBase, + ULONG InterruptVector) +{ + SCSI_PHYSICAL_ADDRESS IoAddress; + PVOID IoBase; + + IoAddress = ScsiPortConvertUlongToPhysicalAddress(CommandPortBase); + IoBase = ScsiPortGetDeviceBase((PVOID)DevExt, + InterfaceType, + ConfigInfo->SystemIoBusNumber, + IoAddress, + 8, + TRUE); + if (IoBase == NULL) + { + return FALSE; + } + DevExt->CommandPortBase = (ULONG)IoBase; + ConfigInfo->AccessRanges[0].RangeStart = IoAddress; + ConfigInfo->AccessRanges[0].RangeLength = 8; + ConfigInfo->AccessRanges[0].RangeInMemory = FALSE; + + if (ControlPortBase) + { + IoAddress = ScsiPortConvertUlongToPhysicalAddress(ControlPortBase + 2); + IoBase = ScsiPortGetDeviceBase((PVOID)DevExt, + InterfaceType, + ConfigInfo->SystemIoBusNumber, + IoAddress, + 1, + TRUE); + if (IoBase == NULL) + { + ScsiPortFreeDeviceBase((PVOID)DevExt, + (PVOID)DevExt->CommandPortBase); + return FALSE; + } + DevExt->ControlPortBase = (ULONG)IoBase; + ConfigInfo->AccessRanges[1].RangeStart = IoAddress; + ConfigInfo->AccessRanges[1].RangeLength = 1; + ConfigInfo->AccessRanges[1].RangeInMemory = FALSE; + } + if (BusMasterPortBase) + { + IoAddress = ScsiPortConvertUlongToPhysicalAddress(BusMasterPortBase); + IoBase = ScsiPortGetDeviceBase((PVOID)DevExt, + InterfaceType, + ConfigInfo->SystemIoBusNumber, + IoAddress, + 8, + TRUE); + if (IoBase == NULL) + { + ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->CommandPortBase); + ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->ControlPortBase); + return FALSE; + } + ConfigInfo->AccessRanges[2].RangeStart = IoAddress; + ConfigInfo->AccessRanges[2].RangeLength = 8; + ConfigInfo->AccessRanges[2].RangeInMemory = FALSE; + } + ConfigInfo->BusInterruptLevel = InterruptVector; + ConfigInfo->BusInterruptVector = InterruptVector; + ConfigInfo->InterruptMode = (InterfaceType == Isa) ? Latched : LevelSensitive; + + if ((CommandPortBase == 0x1F0 || ControlPortBase == 0x3F4) && !ConfigInfo->AtdiskPrimaryClaimed) + { + ConfigInfo->AtdiskPrimaryClaimed = TRUE; + } + if ((CommandPortBase == 0x170 || ControlPortBase == 0x374) && !ConfigInfo->AtdiskSecondaryClaimed) + { + ConfigInfo->AtdiskSecondaryClaimed = TRUE; + } + return TRUE; +} + + +#ifdef ENABLE_PCI static ULONG STDCALL AtapiFindCompatiblePciController(PVOID DeviceExtension, PVOID HwContext, @@ -346,9 +467,13 @@ AtapiFindCompatiblePciController(PVOID DeviceExtension, PCI_SLOT_NUMBER SlotNumber; PCI_COMMON_CONFIG PciConfig; ULONG DataSize; + ULONG StartDeviceNumber; + ULONG DeviceNumber; + ULONG StartFunctionNumber; ULONG FunctionNumber; BOOLEAN ChannelFound; BOOLEAN DeviceFound; + ULONG BusMasterBasePort = 0; DPRINT("AtapiFindCompatiblePciController() Bus: %lu Slot: %lu\n", ConfigInfo->SystemIoBusNumber, @@ -361,155 +486,116 @@ AtapiFindCompatiblePciController(PVOID DeviceExtension, ConfigInfo->AtdiskSecondaryClaimed == TRUE) return(SP_RETURN_NOT_FOUND); - - SlotNumber.u.AsULONG = 0; - for (FunctionNumber = 0 /*ConfigInfo->SlotNumber*/; FunctionNumber < 256; FunctionNumber++) - { - SlotNumber.u.AsULONG = FunctionNumber; - - ChannelFound = FALSE; - DeviceFound = FALSE; - - DataSize = ScsiPortGetBusData(DeviceExtension, - PCIConfiguration, - 0, - SlotNumber.u.AsULONG, - &PciConfig, - sizeof(PCI_COMMON_CONFIG)); -// if (DataSize != sizeof(PCI_COMMON_CONFIG) || -// PciConfig.VendorID == PCI_INVALID_VENDORID) - if (DataSize == 0) + SlotNumber.u.AsULONG = ConfigInfo->SlotNumber; + StartDeviceNumber = SlotNumber.u.bits.DeviceNumber; + StartFunctionNumber = SlotNumber.u.bits.FunctionNumber; + for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++) + { + SlotNumber.u.bits.DeviceNumber = DeviceNumber; + for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++) + { + SlotNumber.u.bits.FunctionNumber = FunctionNumber; + ChannelFound = FALSE; + DeviceFound = FALSE; + + DataSize = ScsiPortGetBusData(DeviceExtension, + PCIConfiguration, + ConfigInfo->SystemIoBusNumber, + SlotNumber.u.AsULONG, + &PciConfig, + PCI_COMMON_HDR_LENGTH); + if (DataSize != PCI_COMMON_HDR_LENGTH) { -// if ((SlotNumber.u.AsULONG & 0x07) == 0) -// return(SP_RETURN_ERROR); /* No bus found */ - - continue; -// return(SP_RETURN_ERROR); + if (FunctionNumber == 0) + { + break; + } + else + { + continue; + } } - - if (PciConfig.BaseClass == 0x01 && - PciConfig.SubClass == 0x01) // && -// (PciConfig.ProgIf & 0x05) == 0) + + DPRINT("%x %x\n", PciConfig.BaseClass, PciConfig.SubClass); + if (PciConfig.BaseClass == 0x01 && + PciConfig.SubClass == 0x01) // && +// (PciConfig.ProgIf & 0x05) == 0) { - /* both channels are in compatibility mode */ - DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n", - ConfigInfo->SystemIoBusNumber, - SlotNumber.u.bits.DeviceNumber, - SlotNumber.u.bits.FunctionNumber, - PciConfig.VendorID, - PciConfig.DeviceID); - DPRINT("ProgIF 0x%02hx\n", PciConfig.ProgIf); - - DPRINT("Found IDE controller in compatibility mode!\n"); - - ConfigInfo->NumberOfBuses = 1; - ConfigInfo->MaximumNumberOfTargets = 2; - ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */ - - if (PciConfig.ProgIf & 0x80) - { + /* both channels are in compatibility mode */ + DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n", + ConfigInfo->SystemIoBusNumber, + SlotNumber.u.bits.DeviceNumber, + SlotNumber.u.bits.FunctionNumber, + PciConfig.VendorID, + PciConfig.DeviceID); + DPRINT("ProgIF 0x%02hx\n", PciConfig.ProgIf); + + DPRINT("Found IDE controller in compatibility mode!\n"); + + ConfigInfo->NumberOfBuses = 1; + ConfigInfo->MaximumNumberOfTargets = 2; + ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */ + + if (PciConfig.ProgIf & 0x80) + { DPRINT("Found IDE Bus Master controller!\n"); - if (PciConfig.u.type0.BaseAddresses[4] & 0x00000001) - { - DPRINT(" IDE Bus Master Registers at IO %lx\n", - PciConfig.u.type0.BaseAddresses[4] & ~0x00000003); - } - } - - if (ConfigInfo->AtdiskPrimaryClaimed == FALSE) - { + if (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE) + { + BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK; + DPRINT(" IDE Bus Master Registers at IO %lx\n", BusMasterBasePort); + } + } + if (ConfigInfo->AtdiskPrimaryClaimed == FALSE) + { /* Both channels unclaimed: Claim primary channel */ DPRINT("Primary channel!\n"); - - DevExt->CommandPortBase = 0x01F0; - DevExt->ControlPortBase = 0x03F6; - - ConfigInfo->BusInterruptLevel = 14; - ConfigInfo->BusInterruptVector = 14; - ConfigInfo->InterruptMode = LevelSensitive; - - ConfigInfo->AccessRanges[0].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(0x01F0); - ConfigInfo->AccessRanges[0].RangeLength = 8; - ConfigInfo->AccessRanges[0].RangeInMemory = FALSE; - - ConfigInfo->AccessRanges[1].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(0x03F6); - ConfigInfo->AccessRanges[1].RangeLength = 1; - ConfigInfo->AccessRanges[1].RangeInMemory = FALSE; - - /* Claim bus master registers */ - if (PciConfig.ProgIf & 0x80) - { - DevExt->BusMasterRegisterBase = - PciConfig.u.type0.BaseAddresses[4] & ~0x00000003; - - ConfigInfo->AccessRanges[2].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(DevExt->BusMasterRegisterBase); - ConfigInfo->AccessRanges[2].RangeLength = 8; - ConfigInfo->AccessRanges[2].RangeInMemory = FALSE; - } - - ConfigInfo->AtdiskPrimaryClaimed = TRUE; - ChannelFound = TRUE; - *Again = TRUE; - } - else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE) - { + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + PCIBus, + 0x1F0, + 0x3F4, + BusMasterBasePort, + 14); + *Again = TRUE; + } + else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE) + { /* Primary channel already claimed: claim secondary channel */ DPRINT("Secondary channel!\n"); - DevExt->CommandPortBase = 0x0170; - DevExt->ControlPortBase = 0x0376; - - ConfigInfo->BusInterruptLevel = 15; - ConfigInfo->BusInterruptVector = 15; - ConfigInfo->InterruptMode = LevelSensitive; - - ConfigInfo->AccessRanges[0].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(0x0170); - ConfigInfo->AccessRanges[0].RangeLength = 8; - ConfigInfo->AccessRanges[0].RangeInMemory = FALSE; - - ConfigInfo->AccessRanges[1].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(0x0376); - ConfigInfo->AccessRanges[1].RangeLength = 1; - ConfigInfo->AccessRanges[1].RangeInMemory = FALSE; - - /* Claim bus master registers */ - if (PciConfig.ProgIf & 0x80) - { - DevExt->BusMasterRegisterBase = - (PciConfig.u.type0.BaseAddresses[4] & ~0x00000003) + 8; - - ConfigInfo->AccessRanges[2].RangeStart = - ScsiPortConvertUlongToPhysicalAddress(DevExt->BusMasterRegisterBase); - ConfigInfo->AccessRanges[2].RangeLength = 8; - ConfigInfo->AccessRanges[2].RangeInMemory = FALSE; - } - - ConfigInfo->AtdiskSecondaryClaimed = TRUE; - ChannelFound = TRUE; + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + PCIBus, + 0x170, + 0x374, + BusMasterBasePort ? BusMasterBasePort + 8 : 0, + 15); *Again = FALSE; - } - - /* Find attached devices */ - if (ChannelFound == TRUE) - { - DeviceFound = AtapiFindDevices(DevExt, - ConfigInfo); - } - DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_FOUND\n"); - return(SP_RETURN_FOUND); - } - } - + } + /* Find attached devices */ + if (ChannelFound) + { + DeviceFound = AtapiFindDevices(DevExt, ConfigInfo); + ConfigInfo->SlotNumber = SlotNumber.u.AsULONG; + DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_FOUND\n"); + return(SP_RETURN_FOUND); + } + } + if (FunctionNumber == 0 && !(PciConfig.HeaderType & PCI_MULTIFUNCTION)) + { + break; + } + } + StartFunctionNumber = 0; + } DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_NOT_FOUND\n"); return(SP_RETURN_NOT_FOUND); } +#endif +#ifdef ENABLE_ISA static ULONG STDCALL AtapiFindIsaBusController(PVOID DeviceExtension, PVOID HwContext, @@ -535,47 +621,27 @@ AtapiFindIsaBusController(PVOID DeviceExtension, /* Both channels unclaimed: Claim primary channel */ DPRINT("Primary channel!\n"); - DevExt->CommandPortBase = 0x01F0; - DevExt->ControlPortBase = 0x03F6; - - ConfigInfo->BusInterruptLevel = 14; - ConfigInfo->BusInterruptVector = 14; - ConfigInfo->InterruptMode = LevelSensitive; - - ConfigInfo->AccessRanges[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0x01F0); - ConfigInfo->AccessRanges[0].RangeLength = 8; - ConfigInfo->AccessRanges[0].RangeInMemory = FALSE; - - ConfigInfo->AccessRanges[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0x03F6); - ConfigInfo->AccessRanges[1].RangeLength = 1; - ConfigInfo->AccessRanges[1].RangeInMemory = FALSE; - - ConfigInfo->AtdiskPrimaryClaimed = TRUE; - ChannelFound = TRUE; - *Again = FALSE/*TRUE*/; + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + Isa, + 0x1F0, + 0x3F4, + 0, + 14); + *Again = TRUE; } else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE) { /* Primary channel already claimed: claim secondary channel */ DPRINT("Secondary channel!\n"); - DevExt->CommandPortBase = 0x0170; - DevExt->ControlPortBase = 0x0376; - - ConfigInfo->BusInterruptLevel = 15; - ConfigInfo->BusInterruptVector = 15; - ConfigInfo->InterruptMode = LevelSensitive; - - ConfigInfo->AccessRanges[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0x0170); - ConfigInfo->AccessRanges[0].RangeLength = 8; - ConfigInfo->AccessRanges[0].RangeInMemory = FALSE; - - ConfigInfo->AccessRanges[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0x0376); - ConfigInfo->AccessRanges[1].RangeLength = 1; - ConfigInfo->AccessRanges[1].RangeInMemory = FALSE; - - ConfigInfo->AtdiskSecondaryClaimed = TRUE; - ChannelFound = TRUE; + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + Isa, + 0x170, + 0x374, + 0, + 15); *Again = FALSE; } else @@ -590,13 +656,16 @@ AtapiFindIsaBusController(PVOID DeviceExtension, { DeviceFound = AtapiFindDevices(DevExt, ConfigInfo); + DPRINT("AtapiFindIsaBusController() returns: SP_RETURN_FOUND\n"); + return(SP_RETURN_FOUND); } - - DPRINT("AtapiFindIsaBusController() returns: SP_RETURN_FOUND\n"); - return(SP_RETURN_FOUND); + *Again = FALSE; + return SP_RETURN_NOT_FOUND; } +#endif +#ifdef ENABLE_NATIVE_PCI static ULONG STDCALL AtapiFindNativePciController(PVOID DeviceExtension, PVOID HwContext, @@ -606,15 +675,129 @@ AtapiFindNativePciController(PVOID DeviceExtension, PBOOLEAN Again) { PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension; + PCI_COMMON_CONFIG PciConfig; + PCI_SLOT_NUMBER SlotNumber; + ULONG DataSize; + ULONG DeviceNumber; + ULONG StartDeviceNumber; + ULONG FunctionNumber; + ULONG StartFunctionNumber; + ULONG BusMasterBasePort; + ULONG Count; + BOOLEAN ChannelFound; DPRINT("AtapiFindNativePciController() called!\n"); + SlotNumber.u.AsULONG = ConfigInfo->SlotNumber; + StartDeviceNumber = SlotNumber.u.bits.DeviceNumber; + StartFunctionNumber = SlotNumber.u.bits.FunctionNumber; + for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++) + { + SlotNumber.u.bits.DeviceNumber = DeviceNumber; + for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++) + { + SlotNumber.u.bits.FunctionNumber = FunctionNumber; + DataSize = ScsiPortGetBusData(DeviceExtension, + PCIConfiguration, + ConfigInfo->SystemIoBusNumber, + SlotNumber.u.AsULONG, + &PciConfig, + PCI_COMMON_HDR_LENGTH); + if (DataSize != PCI_COMMON_HDR_LENGTH) + { + break; + } + for (Count = 0; Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER); Count++) + { + if (PciConfig.VendorID == PciNativeController[Count].VendorID && + PciConfig.DeviceID == PciNativeController[Count].DeviceID) + { + break; + } + } + if (Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER)) + { + /* We have found a known native pci ide controller */ + if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE)) + { + DPRINT("Found IDE Bus Master controller!\n"); + BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK; + DPRINT(" IDE Bus Master Registers at IO %lx\n", BusMasterBasePort); + } + else + { + BusMasterBasePort = 0; + } + + DPRINT("VendorID: %04x, DeviceID: %04x\n", PciConfig.VendorID, PciConfig.DeviceID); + ConfigInfo->NumberOfBuses = 1; + ConfigInfo->MaximumNumberOfTargets = 2; + ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */ + + /* FIXME: + We must not store and use the last tested slot number. If there is a recall + to the some device and we will claim the primary channel again than the call + to ScsiPortGetDeviceBase in AtapiClaimHwResource will fail and we can try to + claim the secondary channel. + */ + ChannelFound = FALSE; + if (LastSlotNumber.u.AsULONG != SlotNumber.u.AsULONG) + { + /* try to claim primary channel */ + if ((PciConfig.u.type0.BaseAddresses[0] & PCI_ADDRESS_IO_SPACE) && + (PciConfig.u.type0.BaseAddresses[1] & PCI_ADDRESS_IO_SPACE)) + { + /* primary channel is enabled */ + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + PCIBus, + PciConfig.u.type0.BaseAddresses[0] & PCI_ADDRESS_IO_ADDRESS_MASK, + PciConfig.u.type0.BaseAddresses[1] & PCI_ADDRESS_IO_ADDRESS_MASK, + BusMasterBasePort, + PciConfig.u.type0.InterruptLine); + if (ChannelFound) + { + AtapiFindDevices(DevExt, ConfigInfo); + *Again = TRUE; + ConfigInfo->SlotNumber = LastSlotNumber.u.AsULONG = SlotNumber.u.AsULONG; + return SP_RETURN_FOUND; + } + } + } + if (!ChannelFound) + { + /* try to claim secondary channel */ + if ((PciConfig.u.type0.BaseAddresses[2] & PCI_ADDRESS_IO_SPACE) && + (PciConfig.u.type0.BaseAddresses[3] & PCI_ADDRESS_IO_SPACE)) + { + /* secondary channel is enabled */ + ChannelFound = AtapiClaimHwResources(DevExt, + ConfigInfo, + PCIBus, + PciConfig.u.type0.BaseAddresses[2] & PCI_ADDRESS_IO_ADDRESS_MASK, + PciConfig.u.type0.BaseAddresses[3] & PCI_ADDRESS_IO_ADDRESS_MASK, + BusMasterBasePort ? BusMasterBasePort + 8 : 0, + PciConfig.u.type0.InterruptLine); + if (ChannelFound) + { + AtapiFindDevices(DevExt, ConfigInfo); + *Again = FALSE; + LastSlotNumber.u.AsULONG = 0xFFFFFFFF; + return SP_RETURN_FOUND; + } + } + } + } + } + StartFunctionNumber = 0; + } *Again = FALSE; - + LastSlotNumber.u.AsULONG = 0xFFFFFFFF; DPRINT("AtapiFindNativePciController() done!\n"); return(SP_RETURN_NOT_FOUND); } +#endif static BOOLEAN STDCALL @@ -700,23 +883,36 @@ AtapiInterrupt(IN PVOID DeviceExtension) BOOLEAN IsAtapi; ULONG Retries; PUCHAR TargetAddress; - ULONG SectorSize; ULONG TransferSize; DPRINT("AtapiInterrupt() called!\n"); DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension; + + CommandPortBase = DevExt->CommandPortBase; + ControlPortBase = DevExt->ControlPortBase; + if (DevExt->ExpectingInterrupt == FALSE) { - DPRINT("AtapiInterrupt(): Unexpected interrupt\n"); + DeviceStatus = IDEReadStatus(CommandPortBase); + DPRINT("AtapiInterrupt(): Unexpected interrupt (port=%x)\n", CommandPortBase); return(FALSE); } + /* check if it was our irq */ + if ((DeviceStatus = IDEReadAltStatus(ControlPortBase)) & IDE_SR_BUSY) + { + ScsiPortStallExecution(1); + if ((DeviceStatus = IDEReadAltStatus(ControlPortBase) & IDE_SR_BUSY)) + { + DPRINT("AtapiInterrupt(): Unexpected interrupt (port=%x)\n", CommandPortBase); + return(FALSE); + } + } + Srb = DevExt->CurrentSrb; DPRINT("Srb: %p\n", Srb); - CommandPortBase = DevExt->CommandPortBase; - ControlPortBase = DevExt->ControlPortBase; DPRINT("CommandPortBase: %lx ControlPortBase: %lx\n", CommandPortBase, ControlPortBase); IsAtapi = DevExt->DeviceAtapi[Srb->TargetId]; @@ -727,25 +923,6 @@ AtapiInterrupt(IN PVOID DeviceExtension) DeviceStatus = IDEReadStatus(CommandPortBase); DPRINT("DeviceStatus: %x\n", DeviceStatus); - if (DeviceStatus & IDE_SR_BUSY) - { - /* Wait for BUSY to drop */ - for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) - { - DeviceStatus = IDEReadStatus(CommandPortBase); - if (!(DeviceStatus & IDE_SR_BUSY)) - { - break; - } - ScsiPortStallExecution(10); - } - if (Retries >= IDE_MAX_BUSY_RETRIES) - { - DPRINT1("Drive is BUSY for too long\n"); - /* FIXME: handle timeout */ - } - } - if ((DeviceStatus & IDE_SR_ERR) && (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) { @@ -760,7 +937,7 @@ AtapiInterrupt(IN PVOID DeviceExtension) DPRINT("Read data\n"); /* Update controller/device state variables */ - TargetAddress = Srb->DataBuffer; + TargetAddress = DevExt->DataBuffer; if (IsAtapi) { @@ -769,23 +946,27 @@ AtapiInterrupt(IN PVOID DeviceExtension) } else { - TransferSize = DevExt->DeviceParams[Srb->TargetId].BytesPerSector; + TransferSize = DevExt->TransferSize[Srb->TargetId]; } DPRINT("TransferLength: %lu\n", Srb->DataTransferLength); DPRINT("TransferSize: %lu\n", TransferSize); - if (Srb->DataTransferLength <= TransferSize) + if (DevExt->DataTransferLength <= TransferSize) { - Srb->DataTransferLength = 0; + if (!IsAtapi) + { + TransferSize = DevExt->DataTransferLength; + } + DevExt->DataTransferLength = 0; IsLastBlock = TRUE; } else { - Srb->DataTransferLength -= TransferSize; + DevExt->DataTransferLength -= TransferSize; IsLastBlock = FALSE; } - Srb->DataBuffer += TransferSize; + DevExt->DataBuffer += TransferSize; DPRINT("IsLastBlock == %s\n", (IsLastBlock) ? "TRUE" : "FALSE"); /* Wait for DRQ assertion */ @@ -797,10 +978,18 @@ AtapiInterrupt(IN PVOID DeviceExtension) } /* Copy the block of data */ - IDEReadBlock(CommandPortBase, - TargetAddress, - TransferSize); - + if (DevExt->DWordIo[Srb->TargetId]) + { + IDEReadBlock32(CommandPortBase, + TargetAddress, + TransferSize); + } + else + { + IDEReadBlock(CommandPortBase, + TargetAddress, + TransferSize); + } /* check DRQ */ if (IsLastBlock) { @@ -812,10 +1001,10 @@ AtapiInterrupt(IN PVOID DeviceExtension) } /* Check for data overrun */ - if (IDEReadStatus(CommandPortBase) & IDE_SR_DRQ) + while (IDEReadStatus(CommandPortBase) & IDE_SR_DRQ) { - /* FIXME: Handle error! */ - DPRINT1("AtapiInterrupt(): data overrun error!"); + DPRINT1("AtapiInterrupt(): reading overrun data!\n"); + IDEReadWord(CommandPortBase); } } @@ -825,39 +1014,47 @@ AtapiInterrupt(IN PVOID DeviceExtension) { DPRINT("Write data\n"); - if (Srb->DataTransferLength == 0) + if (DevExt->DataTransferLength == 0) { - - for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES && - (IDEReadStatus(CommandPortBase) & IDE_SR_BUSY); - Retries++) - { - KeStallExecutionProcessor(10); - } - /* Check for data overrun */ - if (IDEReadStatus(CommandPortBase) & IDE_SR_DRQ) + if (DeviceStatus & IDE_SR_DRQ) { /* FIXME: Handle error! */ - DPRINT1("AtapiInterrupt(): data overrun error!"); + /* This can occure if the irq is shared with an other and if the + ide controller has a write buffer. We have write the last sectors + and the other device has a irq before ours. The isr is called but + we haven't a interrupt. The controller writes the sector buffer + and the status register shows DRQ because the write is not ended. */ + DPRINT("AtapiInterrupt(): data overrun error!\n"); } - - DevExt->ExpectingInterrupt = FALSE; IsLastBlock = TRUE; } else { - /* Update SRB data */ - SectorSize = DevExt->DeviceParams[Srb->TargetId].BytesPerSector; - - TargetAddress = Srb->DataBuffer; - Srb->DataBuffer += SectorSize; - Srb->DataTransferLength -= SectorSize; + /* Update DevExt data */ + TransferSize = DevExt->TransferSize[Srb->TargetId]; + if (DevExt->DataTransferLength < TransferSize) + { + TransferSize = DevExt->DataTransferLength; + } + + TargetAddress = DevExt->DataBuffer; + DevExt->DataBuffer += TransferSize; + DevExt->DataTransferLength -= TransferSize; /* Write the sector */ - IDEWriteBlock(CommandPortBase, - TargetAddress, - SectorSize); + if (DevExt->DWordIo[Srb->TargetId]) + { + IDEWriteBlock32(CommandPortBase, + TargetAddress, + TransferSize); + } + else + { + IDEWriteBlock(CommandPortBase, + TargetAddress, + TransferSize); + } } Srb->SrbStatus = SRB_STATUS_SUCCESS; @@ -897,11 +1094,6 @@ AtapiInterrupt(IN PVOID DeviceExtension) return(TRUE); } - - - - - // ---------------------------------------------------- Discardable statics @@ -958,8 +1150,22 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, IDE_DC_nIEN); ScsiPortStallExecution(500); + /* Check if a device is attached to the interface */ + IDEWriteCylinderHigh(CommandPortBase, 0xaa); + IDEWriteCylinderLow(CommandPortBase, 0x55); + + High = IDEReadCylinderHigh(CommandPortBase); + Low = IDEReadCylinderLow(CommandPortBase); + IDEWriteCylinderHigh(CommandPortBase, 0); IDEWriteCylinderLow(CommandPortBase, 0); + + if (Low != 0x55 || High != 0xaa) + { + DPRINT("No Drive found. UnitNumber %d CommandPortBase %x\n", UnitNumber, CommandPortBase); + continue; + } + IDEWriteCommand(CommandPortBase, IDE_CMD_RESET); for (Retries = 0; Retries < 20000; Retries++) @@ -996,6 +1202,9 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, DPRINT(" ATAPI drive found!\n"); DeviceExtension->DevicePresent[UnitNumber] = TRUE; DeviceExtension->DeviceAtapi[UnitNumber] = TRUE; + DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector; + DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE; + DeviceExtension->DWordIo[UnitNumber] = FALSE; DeviceFound = TRUE; } else @@ -1014,6 +1223,20 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, DPRINT(" IDE drive found!\n"); DeviceExtension->DevicePresent[UnitNumber] = TRUE; DeviceExtension->DeviceAtapi[UnitNumber] = FALSE; + DeviceExtension->TransferSize[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].BytesPerSector; + if ((DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0x8000) && + (DeviceExtension->DeviceParams[UnitNumber].RWMultImplemented & 0xff) && + (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0x100) && + (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff)) + { + DeviceExtension->TransferSize[UnitNumber] *= (DeviceExtension->DeviceParams[UnitNumber].RWMultCurrent & 0xff); + DeviceExtension->MultiSectorCommand[UnitNumber] = TRUE; + } + else + { + DeviceExtension->MultiSectorCommand[UnitNumber] = FALSE; + } + DeviceExtension->DWordIo[UnitNumber] = DeviceExtension->DeviceParams[UnitNumber].DWordIo ? TRUE : FALSE; DeviceFound = TRUE; } else @@ -1023,6 +1246,14 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension, } } + /* Reset pending interrupts */ + IDEReadStatus(CommandPortBase); + /* Reenable interrupts */ + IDEWriteDriveControl(ControlPortBase, 0); + ScsiPortStallExecution(500); + /* Return with drive 0 selected */ + IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED); + ScsiPortStallExecution(500); DPRINT("AtapiFindDrives() done (DeviceFound %s)\n", (DeviceFound) ? "TRUE" : "FALSE"); @@ -1152,8 +1383,9 @@ AtapiIdentifyDevice(IN ULONG CommandPort, DrvParms->ECCByteCnt, DrvParms->FirmwareRev); DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber); - DPRINT("RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n", - (DrvParms->RWMultImplemented) & 0xff, + DPRINT("RWMultMax?:%04x RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n", + (DrvParms->RWMultImplemented), + (DrvParms->RWMultCurrent) & 0xff, (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0, (DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0, DrvParms->MinPIOTransTime, @@ -1168,21 +1400,29 @@ AtapiIdentifyDevice(IN ULONG CommandPort, DrvParms->TMSectorCountLo, (ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo)); - DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector); - if (DrvParms->BytesPerSector == 0) + if (! Atapi && 0 != (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED)) { + /* LBA ATA drives always have a sector size of 512 */ DrvParms->BytesPerSector = 512; } else { - for (i = 15; i >= 0; i--) - { - if (DrvParms->BytesPerSector & (1 << i)) - { - DrvParms->BytesPerSector = 1 << i; - break; - } - } + DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector); + if (DrvParms->BytesPerSector == 0) + { + DrvParms->BytesPerSector = 512; + } + else + { + for (i = 15; i >= 0; i--) + { + if (DrvParms->BytesPerSector & (1 << i)) + { + DrvParms->BytesPerSector = 1 << i; + break; + } + } + } } DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector); @@ -1229,7 +1469,6 @@ AtapiPolledRead(IN ULONG CommandPort, ULONG RetryCount; BOOLEAN Junk = FALSE; UCHAR Status; - UCHAR Control; //#if 0 /* Wait for BUSY to clear */ @@ -1256,8 +1495,7 @@ AtapiPolledRead(IN ULONG CommandPort, ScsiPortStallExecution(500); /* Disable interrupts */ - Control = IDEReadAltStatus(ControlPort); - IDEWriteDriveControl(ControlPort, Control | IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, IDE_DC_nIEN); ScsiPortStallExecution(500); #if 0 @@ -1318,7 +1556,10 @@ AtapiPolledRead(IN ULONG CommandPort, { if (Status & IDE_SR_ERR) { - IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, 0); + ScsiPortStallExecution(50); + IDEReadStatus(CommandPort); + return(IDE_ER_ABRT); } if (Status & IDE_SR_DRQ) @@ -1327,7 +1568,10 @@ AtapiPolledRead(IN ULONG CommandPort, } else { - IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, 0); + ScsiPortStallExecution(50); + IDEReadStatus(CommandPort); + return(IDE_ER_ABRT); } } @@ -1337,7 +1581,10 @@ AtapiPolledRead(IN ULONG CommandPort, /* timed out */ if (RetryCount >= IDE_MAX_POLL_RETRIES) { - IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, 0); + ScsiPortStallExecution(50); + IDEReadStatus(CommandPort); + return(IDE_ER_ABRT); } @@ -1364,7 +1611,10 @@ AtapiPolledRead(IN ULONG CommandPort, { if (Status & IDE_SR_ERR) { - IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, 0); + ScsiPortStallExecution(50); + IDEReadStatus(CommandPort); + return(IDE_ER_ABRT); } if (Status & IDE_SR_DRQ) @@ -1383,7 +1633,10 @@ AtapiPolledRead(IN ULONG CommandPort, DPRINT("Read %lu sectors of junk!\n", SectorCount - SectorCnt); } - IDEWriteDriveControl(ControlPort, Control & ~IDE_DC_nIEN); + IDEWriteDriveControl(ControlPort, 0); + ScsiPortStallExecution(50); + IDEReadStatus(CommandPort); + return(0); } } @@ -1438,7 +1691,8 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, Srb)); /* Set pointer to data buffer. */ - DeviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer; + DeviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer; + DeviceExtension->DataTransferLength = Srb->DataTransferLength; DeviceExtension->CurrentSrb = Srb; /* Wait for BUSY to clear */ @@ -1485,10 +1739,10 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, } #endif - if (Srb->DataTransferLength < 0x10000) + if (DeviceExtension->DataTransferLength < 0x10000) { - ByteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF); - ByteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8); + ByteCountLow = (UCHAR)(DeviceExtension->DataTransferLength & 0xFF); + ByteCountHigh = (UCHAR)(DeviceExtension->DataTransferLength >> 8); } else { @@ -1504,7 +1758,7 @@ AtapiSendAtapiCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, IDEWriteCylinderLow(DeviceExtension->CommandPortBase, ByteCountLow); /* Issue command to drive */ - IDEWriteCommand(DeviceExtension->CommandPortBase, 0xA0); /* Packet command */ + IDEWriteCommand(DeviceExtension->CommandPortBase, IDE_CMD_PACKET); /* Wait for DRQ to assert */ for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) @@ -1564,6 +1818,11 @@ AtapiSendIdeCommand(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, Srb); break; + case SCSIOP_SYNCHRONIZE_CACHE: + SrbStatus = AtapiFlushCache(DeviceExtension, + Srb); + break; + case SCSIOP_MODE_SENSE: case SCSIOP_TEST_UNIT_READY: case SCSIOP_VERIFY: @@ -1827,11 +2086,11 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) { - Command = IDE_CMD_READ; + Command = DeviceExtension->MultiSectorCommand[Srb->TargetId] ? IDE_CMD_READ_MULTIPLE : IDE_CMD_READ; } else { - Command = IDE_CMD_WRITE; + Command = DeviceExtension->MultiSectorCommand[Srb->TargetId] ? IDE_CMD_WRITE_MULTIPLE : IDE_CMD_WRITE; } if (DrvHead & IDE_DH_LBA) @@ -1860,12 +2119,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, } /* Set pointer to data buffer. */ - DeviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer; + DeviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer; + DeviceExtension->DataTransferLength = Srb->DataTransferLength; DeviceExtension->CurrentSrb = Srb; - DeviceExtension->ExpectingInterrupt = TRUE; - - /* wait for BUSY to clear */ for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) @@ -1883,24 +2140,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, { DPRINT ("Drive is BUSY for too long\n"); return(SRB_STATUS_BUSY); -#if 0 - if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES) - { - DbgPrint ("Max Retries on Drive reset reached, returning failure\n"); - Irp = ControllerExtension->CurrentIrp; - Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED; - Irp->IoStatus.Information = 0; - - return FALSE; - } - else - { - DPRINT ("Beginning drive reset sequence\n"); - IDEBeginControllerReset(ControllerExtension); - - return TRUE; - } -#endif } /* Select the desired drive */ @@ -1924,30 +2163,9 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, { DPRINT("Drive is BUSY for too long after drive select\n"); return(SRB_STATUS_BUSY); -#if 0 - if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES) - { - DbgPrint ("Max Retries on Drive reset reached, returning failure\n"); - Irp = ControllerExtension->CurrentIrp; - Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED; - Irp->IoStatus.Information = 0; - - return FALSE; - } - else - { - DPRINT("Beginning drive reset sequence\n"); - IDEBeginControllerReset(ControllerExtension); - - return TRUE; - } -#endif } #endif - /* Indicate expecting an interrupt. */ - DeviceExtension->ExpectingInterrupt = TRUE; - /* Setup command parameters */ IDEWritePrecomp(DeviceExtension->CommandPortBase, 0); IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount); @@ -1960,10 +2178,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, IDEWriteCommand(DeviceExtension->CommandPortBase, Command); /* Write data block */ - if (Command == IDE_CMD_WRITE) + if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT) { PUCHAR TargetAddress; - ULONG SectorSize; + ULONG TransferSize; /* Wait for controller ready */ for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) @@ -1975,40 +2193,39 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, } KeStallExecutionProcessor(10); } - if (Retries >= IDE_MAX_BUSY_RETRIES) + if (Retries >= IDE_MAX_WRITE_RETRIES) { - DPRINT("Drive is BUSY for too long after sending write command\n"); + DPRINT1("Drive is BUSY for too long after sending write command\n"); return(SRB_STATUS_BUSY); -#if 0 - if (DeviceExtension->Retries++ > IDE_MAX_CMD_RETRIES) - { - Irp = ControllerExtension->CurrentIrp; - Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED; - Irp->IoStatus.Information = 0; - - return FALSE; - } - else - { - IDEBeginControllerReset(ControllerExtension); - - return TRUE; - } -#endif } - /* Update SRB data */ - SectorSize = DeviceExtension->DeviceParams[Srb->TargetId].BytesPerSector; - TargetAddress = Srb->DataBuffer; - Srb->DataBuffer += SectorSize; - Srb->DataTransferLength -= SectorSize; + /* Update DeviceExtension data */ + TransferSize = DeviceExtension->TransferSize[Srb->TargetId]; + if (DeviceExtension->DataTransferLength < TransferSize) + { + TransferSize = DeviceExtension->DataTransferLength; + } + + TargetAddress = DeviceExtension->DataBuffer; + DeviceExtension->DataBuffer += TransferSize; + DeviceExtension->DataTransferLength -= TransferSize; /* Write data block */ - IDEWriteBlock(DeviceExtension->CommandPortBase, - TargetAddress, - SectorSize); + if (DeviceExtension->DWordIo[Srb->TargetId]) + { + IDEWriteBlock32(DeviceExtension->CommandPortBase, + TargetAddress, + TransferSize); + } + else + { + IDEWriteBlock(DeviceExtension->CommandPortBase, + TargetAddress, + TransferSize); + } } - + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; DPRINT("AtapiReadWrite() done!\n"); @@ -2017,6 +2234,94 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, } +static ULONG +AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, + PSCSI_REQUEST_BLOCK Srb) +{ + ULONG Retries; + UCHAR Status; + + DPRINT1("AtapiFlushCache() called!\n"); + + if (Srb->PathId != 0) + { + Srb->SrbStatus = SRB_STATUS_INVALID_PATH_ID; + return(SRB_STATUS_INVALID_PATH_ID); + } + + if (Srb->TargetId > 1) + { + Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID; + return(SRB_STATUS_INVALID_TARGET_ID); + } + + if (Srb->Lun != 0) + { + Srb->SrbStatus = SRB_STATUS_INVALID_LUN; + return(SRB_STATUS_INVALID_LUN); + } + + if (DeviceExtension->DevicePresent[Srb->TargetId] == FALSE) + { + Srb->SrbStatus = SRB_STATUS_NO_DEVICE; + return(SRB_STATUS_NO_DEVICE); + } + + DPRINT1("SCSIOP_SYNCRONIZE_CACHE: TargetId: %lu\n", + Srb->TargetId); + + /* Wait for BUSY to clear */ + for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) + { + Status = IDEReadStatus(DeviceExtension->CommandPortBase); + if (!(Status & IDE_SR_BUSY)) + { + break; + } + ScsiPortStallExecution(10); + } + DPRINT1("Status=%02x\n", Status); + DPRINT1("Waited %ld usecs for busy to clear\n", Retries * 10); + if (Retries >= IDE_MAX_BUSY_RETRIES) + { + DPRINT1("Drive is BUSY for too long\n"); + return(SRB_STATUS_BUSY); + } + + /* Select the desired drive */ + IDEWriteDriveHead(DeviceExtension->CommandPortBase, + IDE_DH_FIXED | (Srb->TargetId ? IDE_DH_DRV1 : 0)); + ScsiPortStallExecution(10); + + /* Issue command to drive */ + IDEWriteCommand(DeviceExtension->CommandPortBase, IDE_CMD_FLUSH_CACHE); + + /* Wait for controller ready */ + for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) + { + BYTE Status = IDEReadStatus(DeviceExtension->CommandPortBase); + if (!(Status & IDE_SR_BUSY) || (Status & IDE_SR_ERR)) + { + break; + } + KeStallExecutionProcessor(10); + } + if (Retries >= IDE_MAX_WRITE_RETRIES) + { + DPRINT1("Drive is BUSY for too long after sending write command\n"); + return(SRB_STATUS_BUSY); + } + + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; + + DPRINT1("AtapiFlushCache() done!\n"); + + /* Wait for interrupt. */ + return(SRB_STATUS_PENDING); +} + + static UCHAR AtapiErrorToScsi(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb) diff --git a/drivers/storage/atapi/atapi.h b/drivers/storage/atapi/atapi.h index 9ccac81..6688b4c 100644 --- a/drivers/storage/atapi/atapi.h +++ b/drivers/storage/atapi/atapi.h @@ -61,13 +61,21 @@ extern "C" { #define IDE_SR_DRQ 0x08 #define IDE_SR_ERR 0x01 #define IDE_REG_COMMAND 0x0007 + +/* IDE/ATA commands */ #define IDE_CMD_RESET 0x08 #define IDE_CMD_READ 0x20 #define IDE_CMD_READ_RETRY 0x21 #define IDE_CMD_WRITE 0x30 #define IDE_CMD_WRITE_RETRY 0x31 +#define IDE_CMD_PACKET 0xA0 +#define IDE_CMD_READ_MULTIPLE 0xC4 +#define IDE_CMD_WRITE_MULTIPLE 0xC5 +#define IDE_CMD_FLUSH_CACHE 0xE7 +#define IDE_CMD_FLUSH_CACHE_EXT 0xEA #define IDE_CMD_IDENT_ATA_DRV 0xEC #define IDE_CMD_IDENT_ATAPI_DRV 0xA1 + // // Access macros for command registers // Each macro takes an address of the command port block, and data @@ -110,6 +118,14 @@ extern "C" { #define IDEWriteBlock(Address, Buffer, Count) \ (ScsiPortWritePortBufferUshort((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) +#define IDEReadBlock32(Address, Buffer, Count) \ + (ScsiPortReadPortBufferUlong((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) +#define IDEWriteBlock32(Address, Buffer, Count) \ + (ScsiPortWritePortBufferUlong((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) + +#define IDEReadWord(Address) \ + (ScsiPortReadPortUshort((PUSHORT)((Address) + IDE_REG_DATA_PORT))) + // // Access macros for control registers // Each macro takes an address of the control port blank and data @@ -144,7 +160,7 @@ typedef struct _IDE_DRIVE_IDENTIFY char FirmwareRev[8]; /*23*/ char ModelNumber[40]; /*27*/ WORD RWMultImplemented; /*47*/ - WORD Reserved48; /*48*/ + WORD DWordIo; /*48*/ WORD Capabilities; /*49*/ #define IDE_DRID_STBY_SUPPORTED 0x2000 #define IDE_DRID_IORDY_SUPPORTED 0x0800 @@ -160,14 +176,13 @@ typedef struct _IDE_DRIVE_IDENTIFY WORD TMSectorsPerTrk; /*56*/ WORD TMCapacityLo; /*57*/ WORD TMCapacityHi; /*58*/ - WORD Reserved59; /*59*/ + WORD RWMultCurrent; /*59*/ WORD TMSectorCountLo; /*60*/ WORD TMSectorCountHi; /*61*/ WORD Reserved62[193]; /*62*/ WORD Checksum; /*255*/ } IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY; - #ifdef __cplusplus } #endif diff --git a/drivers/storage/atapi/atapi.rc b/drivers/storage/atapi/atapi.rc index 407833a..e137d88 100644 --- a/drivers/storage/atapi/atapi.rc +++ b/drivers/storage/atapi/atapi.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/storage/cdrom/.cvsignore b/drivers/storage/cdrom/.cvsignore index 6ab709c..e893a67 100644 --- a/drivers/storage/cdrom/.cvsignore +++ b/drivers/storage/cdrom/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp cdrom.coff -cdrom.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/storage/cdrom/cdrom.c b/drivers/storage/cdrom/cdrom.c index 08440ca..886bd42 100644 --- a/drivers/storage/cdrom/cdrom.c +++ b/drivers/storage/cdrom/cdrom.c @@ -275,7 +275,6 @@ CdromClassFindDevices(IN PDRIVER_OBJECT DriverObject, DPRINT("CdromClassFindDevices() done\n"); return(FoundDevice); -// return(TRUE); } @@ -462,6 +461,10 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, return(STATUS_INSUFFICIENT_RESOURCES); } + /* Initialize lookaside list for SRBs */ + ScsiClassInitializeSrbLookasideList(DiskDeviceExtension, + 4); + /* Get disk geometry */ DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool, sizeof(DISK_GEOMETRY)); @@ -469,6 +472,8 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, { DPRINT1("Failed to allocate geometry buffer!\n"); + ExDeleteNPagedLookasideList(&DiskDeviceExtension->SrbLookasideListHead); + IoDeleteDevice(DiskDeviceObject); /* Release (unclaim) the disk */ @@ -511,6 +516,7 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, return(STATUS_SUCCESS); } + /********************************************************************** * NAME * CdromClassReadTocEntry @@ -543,14 +549,15 @@ CdromClassReadTocEntry(PDEVICE_OBJECT DeviceObject, UINT TrackNo, PVOID Buffer, Cdb->READ_TOC.AllocationLength[0] = Length >> 8; Cdb->READ_TOC.AllocationLength[1] = Length & 0xff; Cdb->READ_TOC.Msf = 1; - - return ScsiClassSendSrbSynchronous(DeviceObject, + + return(ScsiClassSendSrbSynchronous(DeviceObject, &Srb, Buffer, Length, - FALSE); + FALSE)); } + static NTSTATUS CdromClassReadLastSession(PDEVICE_OBJECT DeviceObject, UINT TrackNo, PVOID Buffer, UINT Length) { @@ -569,14 +576,15 @@ CdromClassReadLastSession(PDEVICE_OBJECT DeviceObject, UINT TrackNo, PVOID Buffe Cdb->READ_TOC.AllocationLength[0] = Length >> 8; Cdb->READ_TOC.AllocationLength[1] = Length & 0xff; Cdb->READ_TOC.Msf = 0; - - return ScsiClassSendSrbSynchronous(DeviceObject, + + return(ScsiClassSendSrbSynchronous(DeviceObject, &Srb, Buffer, Length, - FALSE); + FALSE)); } + /********************************************************************** * NAME EXPORTED * CdromClassDeviceControl @@ -649,62 +657,73 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, } } break; + case IOCTL_CDROM_READ_TOC: - DPRINT("IOCTL_CDROM_READ_TOC\n"); - if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC)) + DPRINT("IOCTL_CDROM_READ_TOC\n"); + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC)) { - Status = STATUS_INFO_LENGTH_MISMATCH; + Status = STATUS_INFO_LENGTH_MISMATCH; } - else + else { - PCDROM_TOC TocBuffer; - USHORT Length; - - TocBuffer = Irp->AssociatedIrp.SystemBuffer; + PCDROM_TOC TocBuffer; + USHORT Length; - /* First read the lead out */ - Length = 4 + sizeof(TRACK_DATA); - Status = CdromClassReadTocEntry(DeviceObject, 0xaa, TocBuffer, Length); + TocBuffer = Irp->AssociatedIrp.SystemBuffer; - if (NT_SUCCESS(Status)) + /* First read the lead out */ + Length = 4 + sizeof(TRACK_DATA); + Status = CdromClassReadTocEntry(DeviceObject, + 0xAA, + TocBuffer, + Length); + if (NT_SUCCESS(Status)) { - if (TocBuffer->FirstTrack == 0xaa) - { + if (TocBuffer->FirstTrack == 0xaa) + { /* there is an empty cd */ - Information = Length; - } - else - { + Information = Length; + } + else + { /* read the toc */ Length = 4 + sizeof(TRACK_DATA) * (TocBuffer->LastTrack - TocBuffer->FirstTrack + 2); - Status = CdromClassReadTocEntry(DeviceObject, TocBuffer->FirstTrack, TocBuffer, Length); - if (NT_SUCCESS(Status)) - { - Information = Length; - } - } + Status = CdromClassReadTocEntry(DeviceObject, + TocBuffer->FirstTrack, + TocBuffer, Length); + if (NT_SUCCESS(Status)) + { + Information = Length; + } + } } } - break; + break; + case IOCTL_CDROM_GET_LAST_SESSION: - DPRINT("IOCTL_CDROM_GET_LAST_SESSION\n"); - if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < 4 + sizeof(TRACK_DATA)) + DPRINT("IOCTL_CDROM_GET_LAST_SESSION\n"); + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < 4 + sizeof(TRACK_DATA)) { - Status = STATUS_INFO_LENGTH_MISMATCH; + Status = STATUS_INFO_LENGTH_MISMATCH; } - else + else { - USHORT Length; - PCDROM_TOC TocBuffer = Irp->AssociatedIrp.SystemBuffer; - - Length = 4 + sizeof(TRACK_DATA); - Status = CdromClassReadLastSession(DeviceObject, 0, TocBuffer, Length); - if (NT_SUCCESS(Status)) + PCDROM_TOC TocBuffer; + USHORT Length; + + TocBuffer = Irp->AssociatedIrp.SystemBuffer; + Length = 4 + sizeof(TRACK_DATA); + Status = CdromClassReadLastSession(DeviceObject, + 0, + TocBuffer, + Length); + if (NT_SUCCESS(Status)) { - Information = Length; + Information = Length; } } - break; + break; + default: /* Call the common device control function */ return(ScsiClassDeviceControl(DeviceObject, Irp)); diff --git a/drivers/storage/cdrom/cdrom.rc b/drivers/storage/cdrom/cdrom.rc index 87a1ca0..52002fa 100644 --- a/drivers/storage/cdrom/cdrom.rc +++ b/drivers/storage/cdrom/cdrom.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/storage/class2/.cvsignore b/drivers/storage/class2/.cvsignore index f815d77..18454ea 100644 --- a/drivers/storage/class2/.cvsignore +++ b/drivers/storage/class2/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp class2.coff -class2.sys.unstripped +*.o +*.sys +*.sym diff --git a/drivers/storage/class2/class2.c b/drivers/storage/class2/class2.c index 0b01fca..c36b07e 100644 --- a/drivers/storage/class2/class2.c +++ b/drivers/storage/class2/class2.c @@ -69,9 +69,7 @@ ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, static VOID ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PSCSI_REQUEST_BLOCK Srb, - BOOLEAN Associated); + PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated); /* FUNCTIONS ****************************************************************/ @@ -160,9 +158,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, DPRINT("Logical block address: %lu\n", LogicalBlockAddress); /* Allocate and initialize an SRB */ - /* FIXME: use lookaside list instead */ - Srb = ExAllocatePool(NonPagedPool, - sizeof(SCSI_REQUEST_BLOCK)); + Srb = ExAllocateFromNPagedLookasideList(&DeviceExtension->SrbLookasideListHead); Srb->SrbFlags = 0; Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE; @@ -171,6 +167,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, Srb->TargetId = DeviceExtension->TargetId; Srb->Lun = DeviceExtension->Lun; Srb->Function = SRB_FUNCTION_EXECUTE_SCSI; + //FIXME: NT4 DDK sample uses MmGetMdlVirtualAddress! Why shouldn't we? Srb->DataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Srb->DataTransferLength = CurrentIrpStack->Parameters.Read.Length; Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST; @@ -240,10 +237,9 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, /* Initialize next stack location */ NextIrpStack->MajorFunction = IRP_MJ_SCSI; NextIrpStack->Parameters.Scsi.Srb = Srb; - NextIrpStack->DeviceObject = DeviceObject; /* Set retry count */ - NextIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES; + CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES; DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb); IoSetCompletionRoutine(Irp, @@ -420,7 +416,7 @@ ScsiClassDeviceControl(PDEVICE_OBJECT DeviceObject, ULONG IoControlCode; ULONG OutputBufferLength; - DPRINT1("ScsiClassDeviceControl() called\n"); + DPRINT("ScsiClassDeviceControl() called\n"); DeviceExtension = DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); @@ -775,7 +771,7 @@ ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject, DPRINT("ScsiClassInterpretSenseInfo() called\n"); DPRINT("Srb->SrbStatus %lx\n", Srb->SrbStatus); - + if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING) { *Status = STATUS_SUCCESS; @@ -899,10 +895,16 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject, DeviceObject, Irp, Context); DeviceExtension = DeviceObject->DeviceExtension; - Srb = (PSCSI_REQUEST_BLOCK)Context; - DPRINT("Srb %p\n", Srb); IrpStack = IoGetCurrentIrpStackLocation(Irp); + + //BUGBUG -> Srb = IrpStack->Parameters.Scsi.Srb; + //Must pass Srb as Context arg!! See comment about Completion routines in + //IofCallDriver for more info. + + Srb = (PSCSI_REQUEST_BLOCK)Context; + + DPRINT("Srb %p\n", Srb); if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS) { @@ -916,22 +918,24 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject, 0, MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4), &Status); - if ((Retry == TRUE) && + if ((Retry) && ((ULONG)IrpStack->Parameters.Others.Argument4 > 0)) { ((ULONG)IrpStack->Parameters.Others.Argument4)--; - ScsiClassRetryRequest(DeviceObject, - Irp, - Srb, - FALSE); + ScsiClassRetryRequest( + DeviceObject, + Irp, + Srb, + FALSE); + return(STATUS_MORE_PROCESSING_REQUIRED); } } - /* FIXME: use lookaside list instead */ - DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb); - ExFreePool(IrpStack->Parameters.Scsi.Srb); + /* Free the SRB */ + ExFreeToNPagedLookasideList(&DeviceExtension->SrbLookasideListHead, + Srb); Irp->IoStatus.Status = Status; if (!NT_SUCCESS(Status)) @@ -977,11 +981,17 @@ ScsiClassIoCompleteAssociated(PDEVICE_OBJECT DeviceObject, MasterIrp = Irp->AssociatedIrp.MasterIrp; DeviceExtension = DeviceObject->DeviceExtension; - Srb = (PSCSI_REQUEST_BLOCK)Context; - DPRINT("Srb %p\n", Srb); IrpStack = IoGetCurrentIrpStackLocation(Irp); + //BUGBUG -> Srb = Srb = IrpStack->Parameters.Scsi.Srb; + //Must pass Srb as Context arg!! See comment about Completion routines in + //IofCallDriver for more info. + + Srb = (PSCSI_REQUEST_BLOCK)Context; + + DPRINT("Srb %p\n", Srb); + if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS) { Status = STATUS_SUCCESS; @@ -996,24 +1006,24 @@ ScsiClassIoCompleteAssociated(PDEVICE_OBJECT DeviceObject, MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4), &Status); - DPRINT1("Retry count: %lu\n", (ULONG)IrpStack->Parameters.Others.Argument4); - - if ((Retry == TRUE) && + if ((Retry) && ((ULONG)IrpStack->Parameters.Others.Argument4 > 0)) { ((ULONG)IrpStack->Parameters.Others.Argument4)--; - ScsiClassRetryRequest(DeviceObject, - Irp, - Srb, - TRUE); + ScsiClassRetryRequest( + DeviceObject, + Irp, + Srb, + TRUE); + return(STATUS_MORE_PROCESSING_REQUIRED); } } - /* FIXME: use lookaside list instead */ - DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb); - ExFreePool(IrpStack->Parameters.Scsi.Srb); + /* Free the SRB */ + ExFreeToNPagedLookasideList(&DeviceExtension->SrbLookasideListHead, + Srb); Irp->IoStatus.Status = Status; @@ -1618,14 +1628,17 @@ ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, static VOID -ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PSCSI_REQUEST_BLOCK Srb, - BOOLEAN Associated) +ScsiClassRetryRequest( + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PSCSI_REQUEST_BLOCK Srb, + BOOLEAN Associated + ) { PDEVICE_EXTENSION DeviceExtension; PIO_STACK_LOCATION CurrentIrpStack; PIO_STACK_LOCATION NextIrpStack; + ULONG TransferLength; DPRINT("ScsiPortRetryRequest() called\n"); @@ -1634,21 +1647,23 @@ ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject, CurrentIrpStack = IoGetCurrentIrpStackLocation(Irp); NextIrpStack = IoGetNextIrpStackLocation(Irp); - if (CurrentIrpStack->MajorFunction == IRP_MJ_READ || - CurrentIrpStack->MajorFunction == IRP_MJ_WRITE) + if (CurrentIrpStack->MajorFunction != IRP_MJ_READ && + CurrentIrpStack->MajorFunction != IRP_MJ_WRITE) { - TransferLength = CurrentIrpStack->Parameters.Read.Length; - } - else if (Irp->MdlAddress != NULL) - { - TransferLength = Irp->MdlAddress->ByteCount; - } - else - { - TransferLength = 0; + /* We shouldn't setup the buffer pointer and transfer length on read/write requests. */ + if (Irp->MdlAddress != NULL) + { + TransferLength = Irp->MdlAddress->ByteCount; + } + else + { + TransferLength = 0; + } + + Srb->DataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress); + Srb->DataTransferLength = TransferLength; } - Srb->DataTransferLength = TransferLength; Srb->SrbStatus = 0; Srb->ScsiStatus = 0; @@ -1660,23 +1675,24 @@ ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject, NextIrpStack->Parameters.Scsi.Srb = Srb; if (Associated == FALSE) - { - IoSetCompletionRoutine(Irp, - ScsiClassIoComplete, - Srb, - TRUE, - TRUE, - TRUE); - } - else - { - IoSetCompletionRoutine(Irp, - ScsiClassIoCompleteAssociated, - Srb, - TRUE, - TRUE, - TRUE); - } + { + IoSetCompletionRoutine(Irp, + ScsiClassIoComplete, + Srb, + TRUE, + TRUE, + TRUE); + } + else + { + IoSetCompletionRoutine(Irp, + ScsiClassIoCompleteAssociated, + Srb, + TRUE, + TRUE, + TRUE); + } + IoCallDriver(DeviceExtension->PortDeviceObject, Irp); diff --git a/drivers/storage/class2/class2.rc b/drivers/storage/class2/class2.rc index 99c1875..bb45fd0 100644 --- a/drivers/storage/class2/class2.rc +++ b/drivers/storage/class2/class2.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/storage/disk/.cvsignore b/drivers/storage/disk/.cvsignore index 0449f28..9f9fab5 100644 --- a/drivers/storage/disk/.cvsignore +++ b/drivers/storage/disk/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp disk.coff -disk.sys.unstripped \ No newline at end of file +*.sym +*.sys +*.o diff --git a/drivers/storage/disk/disk.c b/drivers/storage/disk/disk.c index 682ae7c..2e54035 100644 --- a/drivers/storage/disk/disk.c +++ b/drivers/storage/disk/disk.c @@ -491,6 +491,10 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, DiskDeviceExtension->TargetId = InquiryData->TargetId; DiskDeviceExtension->Lun = InquiryData->Lun; + /* Initialize the lookaside list for SRBs */ + ScsiClassInitializeSrbLookasideList(DiskDeviceExtension, + 4); + /* zero-out disk data */ DiskData = (PDISK_DATA)(DiskDeviceExtension + 1); RtlZeroMemory(DiskData, @@ -503,6 +507,8 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, { DPRINT("Failed to allocate geometry buffer!\n"); + ExDeleteNPagedLookasideList(&DiskDeviceExtension->SrbLookasideListHead); + IoDeleteDevice(DiskDeviceObject); /* Release (unclaim) the disk */ @@ -552,41 +558,41 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, } else { - /* Read partition table */ - Status = IoReadPartitionTable(DiskDeviceObject, - DiskDeviceExtension->DiskGeometry->BytesPerSector, - TRUE, - &PartitionList); + /* Read partition table */ + Status = IoReadPartitionTable(DiskDeviceObject, + DiskDeviceExtension->DiskGeometry->BytesPerSector, + TRUE, + &PartitionList); - DPRINT("IoReadPartitionTable(): Status: %lx\n", Status); + DPRINT("IoReadPartitionTable(): Status: %lx\n", Status); - if ((!NT_SUCCESS(Status) || PartitionList->PartitionCount == 0) && - DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) - { - if (!NT_SUCCESS(Status)) + if ((!NT_SUCCESS(Status) || PartitionList->PartitionCount == 0) && + DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) { - /* Drive is not ready. */ - DPRINT("Drive not ready\n"); - DiskData->DriveNotReady = TRUE; - } - else - { - ExFreePool(PartitionList); - } + if (!NT_SUCCESS(Status)) + { + /* Drive is not ready. */ + DPRINT("Drive not ready\n"); + DiskData->DriveNotReady = TRUE; + } + else + { + ExFreePool(PartitionList); + } - /* Allocate a partition list for a single entry. */ - PartitionList = ExAllocatePool(NonPagedPool, - sizeof(DRIVE_LAYOUT_INFORMATION)); - if (PartitionList != NULL) - { - RtlZeroMemory(PartitionList, - sizeof(DRIVE_LAYOUT_INFORMATION)); - PartitionList->PartitionCount = 1; + /* Allocate a partition list for a single entry. */ + PartitionList = ExAllocatePool(NonPagedPool, + sizeof(DRIVE_LAYOUT_INFORMATION)); + if (PartitionList != NULL) + { + RtlZeroMemory(PartitionList, + sizeof(DRIVE_LAYOUT_INFORMATION)); + PartitionList->PartitionCount = 1; - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; + } } } - } if (NT_SUCCESS(Status)) { @@ -642,6 +648,10 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, PartitionDeviceExtension->Lun = InquiryData->Lun; PartitionDeviceExtension->SectorShift = DiskDeviceExtension->SectorShift; + /* Initialize lookaside list for SRBs */ + ScsiClassInitializeSrbLookasideList(PartitionDeviceExtension, + 8); + DiskData = (PDISK_DATA)(PartitionDeviceExtension + 1); DiskData->PartitionType = PartitionEntry->PartitionType; DiskData->PartitionNumber = PartitionNumber + 1; @@ -969,14 +979,20 @@ DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, Srb->TargetId = DeviceExtension->TargetId; Srb->Lun = DeviceExtension->Lun; - - /* FIXME: Flush write cache */ - + /* Flush write cache */ + Srb->Function = SRB_FUNCTION_EXECUTE_SCSI; + Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER; + Srb->CdbLength = 10; + Srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE; + ScsiClassSendSrbSynchronous(DeviceObject, + Srb, + NULL, + 0, + TRUE); /* Get current stack location */ IrpStack = IoGetCurrentIrpStackLocation(Irp); - /* FIXME: Unlock removable media upon shutdown */ diff --git a/drivers/storage/disk/disk.rc b/drivers/storage/disk/disk.rc index 5a97ec3..5969b3b 100644 --- a/drivers/storage/disk/disk.rc +++ b/drivers/storage/disk/disk.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/drivers/storage/scsiport/.cvsignore b/drivers/storage/scsiport/.cvsignore index 71e1e21..c9246a8 100644 --- a/drivers/storage/scsiport/.cvsignore +++ b/drivers/storage/scsiport/.cvsignore @@ -2,4 +2,6 @@ base.tmp junk.tmp temp.exp scsiport.coff -scsiport.sys.unstripped +*.o +*.sym +*.sys diff --git a/drivers/storage/scsiport/scsiport.c b/drivers/storage/scsiport/scsiport.c index 8269d0f..3592b24 100644 --- a/drivers/storage/scsiport/scsiport.c +++ b/drivers/storage/scsiport/scsiport.c @@ -41,7 +41,12 @@ /* TYPES *********************************************************************/ - +/* + * SCSI_PORT_TIMER_STATES + * + * DESCRIPTION + * An enumeration containing the states in the timer DFA + */ typedef enum _SCSI_PORT_TIMER_STATES { IDETimerIdle, @@ -51,6 +56,17 @@ typedef enum _SCSI_PORT_TIMER_STATES } SCSI_PORT_TIMER_STATES; +typedef struct _SCSI_PORT_DEVICE_BASE +{ + LIST_ENTRY List; + + PVOID MappedAddress; + ULONG NumberOfBytes; + SCSI_PHYSICAL_ADDRESS IoAddress; + ULONG SystemIoBusNumber; +} SCSI_PORT_DEVICE_BASE, *PSCSI_PORT_DEVICE_BASE; + + /* * SCSI_PORT_DEVICE_EXTENSION * @@ -65,46 +81,39 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION ULONG MiniPortExtensionSize; PORT_CONFIGURATION_INFORMATION PortConfig; ULONG PortNumber; - + KSPIN_LOCK IrpLock; KSPIN_LOCK SpinLock; PKINTERRUPT Interrupt; PIRP CurrentIrp; ULONG IrpFlags; - + SCSI_PORT_TIMER_STATES TimerState; LONG TimerCount; - + BOOLEAN Initializing; - + + LIST_ENTRY DeviceBaseListHead; + ULONG PortBusInfoSize; PSCSI_ADAPTER_BUS_INFO PortBusInfo; - + PIO_SCSI_CAPABILITIES PortCapabilities; - + PDEVICE_OBJECT DeviceObject; PCONTROLLER_OBJECT ControllerObject; - + PHW_STARTIO HwStartIo; PHW_INTERRUPT HwInterrupt; - + PSCSI_REQUEST_BLOCK OriginalSrb; SCSI_REQUEST_BLOCK InternalSrb; SENSE_DATA InternalSenseData; - + UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */ } SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION; -/* - * SCSI_PORT_TIMER_STATES - * - * DESCRIPTION - * An enumeration containing the states in the timer DFA - */ - - - #define IRP_FLAG_COMPLETE 0x00000001 #define IRP_FLAG_NEXT 0x00000002 @@ -139,7 +148,8 @@ ScsiPortStartPacket(IN OUT PVOID Context); static NTSTATUS ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension, - IN ULONG PortCount); + IN ULONG PortCount, + IN OUT PSCSI_PORT_DEVICE_EXTENSION *RealDeviceExtension); static VOID ScsiPortInquire(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); @@ -162,6 +172,11 @@ static PSCSI_REQUEST_BLOCK ScsiPortInitSenseRequestSrb(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PSCSI_REQUEST_BLOCK OriginalSrb); +static NTSTATUS +ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, + PUNICODE_STRING RegistryPath); + + /* FUNCTIONS *****************************************************************/ /********************************************************************** @@ -246,6 +261,7 @@ ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, IN UCHAR Lun, IN UCHAR SrbStatus) { + DPRINT("ScsiPortCompleteRequest()\n"); UNIMPLEMENTED; } @@ -253,6 +269,7 @@ ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, ULONG STDCALL ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address) { + DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n"); return(Address.u.LowPart); } @@ -260,6 +277,7 @@ ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address) VOID STDCALL ScsiPortFlushDma(IN PVOID HwDeviceExtension) { + DPRINT("ScsiPortFlushDma()\n"); UNIMPLEMENTED; } @@ -268,7 +286,36 @@ VOID STDCALL ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress) { - UNIMPLEMENTED; + PSCSI_PORT_DEVICE_EXTENSION DeviceExtension; + PSCSI_PORT_DEVICE_BASE DeviceBase; + PLIST_ENTRY Entry; + + DPRINT("ScsiPortFreeDeviceBase() called\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + SCSI_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + if (IsListEmpty(&DeviceExtension->DeviceBaseListHead)) + return; + + Entry = DeviceExtension->DeviceBaseListHead.Flink; + while (Entry != &DeviceExtension->DeviceBaseListHead) + { + DeviceBase = CONTAINING_RECORD(Entry, + SCSI_PORT_DEVICE_BASE, + List); + if (DeviceBase->MappedAddress == MappedAddress) + { + MmUnmapIoSpace(DeviceBase->MappedAddress, + DeviceBase->NumberOfBytes); + RemoveEntryList(Entry); + ExFreePool(DeviceBase); + + return; + } + + Entry = Entry->Flink; + } } @@ -296,34 +343,48 @@ ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace) { - ULONG AddressSpace; + PSCSI_PORT_DEVICE_EXTENSION DeviceExtension; PHYSICAL_ADDRESS TranslatedAddress; - PVOID VirtualAddress; - PVOID Buffer; - BOOLEAN rc; + PSCSI_PORT_DEVICE_BASE DeviceBase; + ULONG AddressSpace; + PVOID MappedAddress; - AddressSpace = (ULONG)InIoSpace; + DPRINT("ScsiPortGetDeviceBase() called\n"); - if (!HalTranslateBusAddress(BusType, - SystemIoBusNumber, - IoAddress, - &AddressSpace, - &TranslatedAddress)) + AddressSpace = (ULONG)InIoSpace; + if (HalTranslateBusAddress(BusType, + SystemIoBusNumber, + IoAddress, + &AddressSpace, + &TranslatedAddress) == FALSE) return NULL; /* i/o space */ if (AddressSpace != 0) - return (PVOID)TranslatedAddress.u.LowPart; + return((PVOID)TranslatedAddress.u.LowPart); + + MappedAddress = MmMapIoSpace(TranslatedAddress, + NumberOfBytes, + FALSE); + + DeviceBase = ExAllocatePool(NonPagedPool, + sizeof(SCSI_PORT_DEVICE_BASE)); + if (DeviceBase == NULL) + return(MappedAddress); - VirtualAddress = MmMapIoSpace(TranslatedAddress, - NumberOfBytes, - FALSE); + DeviceBase->MappedAddress = MappedAddress; + DeviceBase->NumberOfBytes = NumberOfBytes; + DeviceBase->IoAddress = IoAddress; + DeviceBase->SystemIoBusNumber = SystemIoBusNumber; - Buffer = ExAllocatePool(NonPagedPool,0x20); - if (Buffer == NULL) - return VirtualAddress; + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + SCSI_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); - return NULL; /* ?? */ + InsertHeadList(&DeviceExtension->DeviceBaseListHead, + &DeviceBase->List); + + return(MappedAddress); } @@ -333,6 +394,7 @@ ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension, IN UCHAR TargetId, IN UCHAR Lun) { + DPRINT("ScsiPortGetLogicalUnit()\n"); UNIMPLEMENTED; } @@ -343,6 +405,7 @@ ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension, IN PVOID VirtualAddress, OUT ULONG *Length) { + DPRINT("ScsiPortGetPhysicalAddress()\n"); UNIMPLEMENTED; } @@ -354,6 +417,7 @@ ScsiPortGetSrb(IN PVOID DeviceExtension, IN UCHAR Lun, IN LONG QueueTag) { + DPRINT("ScsiPortGetSrb()\n"); UNIMPLEMENTED; } @@ -363,6 +427,7 @@ ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG NumberOfBytes) { + DPRINT("ScsiPortGetUncachedExtension()\n"); UNIMPLEMENTED; } @@ -371,6 +436,7 @@ PVOID STDCALL ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension, IN SCSI_PHYSICAL_ADDRESS PhysicalAddress) { + DPRINT("ScsiPortGetVirtualAddress()\n"); UNIMPLEMENTED; } @@ -411,6 +477,7 @@ ScsiPortInitialize(IN PVOID Argument1, PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Argument1; PUNICODE_STRING RegistryPath = (PUNICODE_STRING)Argument2; PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension; + PSCSI_PORT_DEVICE_EXTENSION RealDeviceExtension; PCONFIGURATION_INFORMATION SystemConfig; PPORT_CONFIGURATION_INFORMATION PortConfig; BOOLEAN Again; @@ -464,6 +531,8 @@ ScsiPortInitialize(IN PVOID Argument1, ExAllocatePool(PagedPool, sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges); + for (i = 0; i < SCSI_MAXIMUM_BUSES; i++) + PortConfig->InitiatorBusId[i] = 255; PortConfig->SystemIoBusNumber = 0; PortConfig->SlotNumber = 0; @@ -476,6 +545,8 @@ ScsiPortInitialize(IN PVOID Argument1, { DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber); + InitializeListHead(&PseudoDeviceExtension->DeviceBaseListHead); + // RtlZeroMemory(AccessRanges, // sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges); @@ -497,7 +568,8 @@ ScsiPortInitialize(IN PVOID Argument1, Status = ScsiPortCreatePortDevice(DriverObject, PseudoDeviceExtension, - SystemConfig->ScsiPortCount); + SystemConfig->ScsiPortCount, + &RealDeviceExtension); if (!NT_SUCCESS(Status)) { @@ -509,6 +581,10 @@ ScsiPortInitialize(IN PVOID Argument1, return(Status); } + /* Build the registry device map */ + ScsiPortBuildDeviceMap(RealDeviceExtension, + (PUNICODE_STRING)Argument2); + /* Update the configuration info */ SystemConfig->AtDiskPrimaryAddressClaimed = PortConfig->AtdiskPrimaryClaimed; SystemConfig->AtDiskSecondaryAddressClaimed = PortConfig->AtdiskSecondaryClaimed; @@ -544,6 +620,7 @@ ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension, IN ULONG LogicalAddress, IN ULONG Length) { + DPRINT("ScsiPortIoMapTransfer()\n"); UNIMPLEMENTED; } @@ -557,6 +634,7 @@ ScsiPortLogError(IN PVOID HwDeviceExtension, IN ULONG ErrorCode, IN ULONG UniqueId) { + DPRINT("ScsiPortLogError()\n"); UNIMPLEMENTED; } @@ -619,6 +697,7 @@ ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension, IN ULONG Offset, IN ULONG Length) { + DPRINT("ScsiPortSetBusDataByOffset()\n"); return(HalSetBusDataByOffset(BusDataType, SystemIoBusNumber, SlotNumber, @@ -636,6 +715,7 @@ ScsiPortValidateRange(IN PVOID HwDeviceExtension, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace) { + DPRINT("ScsiPortValidateRange()\n"); return(TRUE); } @@ -1050,7 +1130,8 @@ ScsiPortStartPacket(IN OUT PVOID Context) static NTSTATUS ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension, - IN ULONG PortNumber) + IN ULONG PortNumber, + IN OUT PSCSI_PORT_DEVICE_EXTENSION *RealDeviceExtension) { PSCSI_PORT_DEVICE_EXTENSION PortDeviceExtension; PIO_SCSI_CAPABILITIES PortCapabilities; @@ -1061,23 +1142,20 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, UNICODE_STRING DosDeviceName; NTSTATUS Status; ULONG AccessRangeSize; - -#if 0 ULONG MappedIrq; KIRQL Dirql; KAFFINITY Affinity; -#endif DPRINT("ScsiPortCreatePortDevice() called\n"); -#if 0 + *RealDeviceExtension = NULL; + MappedIrq = HalGetInterruptVector(PseudoDeviceExtension->PortConfig.AdapterInterfaceType, PseudoDeviceExtension->PortConfig.SystemIoBusNumber, - 0, PseudoDeviceExtension->PortConfig.BusInterruptLevel, + PseudoDeviceExtension->PortConfig.BusInterruptVector, &Dirql, &Affinity); -#endif /* Create a unicode device name */ swprintf(NameBuffer, @@ -1124,6 +1202,23 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, PseudoDeviceExtension->PortConfig.AccessRanges, AccessRangeSize); + /* Copy device base list */ + if (IsListEmpty(&PseudoDeviceExtension->DeviceBaseListHead)) + { + InitializeListHead(&PortDeviceExtension->DeviceBaseListHead); + } + else + { + PseudoDeviceExtension->DeviceBaseListHead.Flink = + PortDeviceExtension->DeviceBaseListHead.Flink; + PseudoDeviceExtension->DeviceBaseListHead.Blink = + PortDeviceExtension->DeviceBaseListHead.Blink; + PortDeviceExtension->DeviceBaseListHead.Blink->Flink = + &PortDeviceExtension->DeviceBaseListHead; + PortDeviceExtension->DeviceBaseListHead.Flink->Blink = + &PortDeviceExtension->DeviceBaseListHead; + } + PortDeviceExtension->DeviceObject = PortDeviceObject; PortDeviceExtension->PortNumber = PortNumber; @@ -1136,12 +1231,12 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, ScsiPortIsr, PortDeviceExtension, &PortDeviceExtension->SpinLock, - PortDeviceExtension->PortConfig.BusInterruptVector, // MappedIrq, - PortDeviceExtension->PortConfig.BusInterruptLevel, // Dirql, - 15, //Dirql, + MappedIrq, + Dirql, + Dirql, PortDeviceExtension->PortConfig.InterruptMode, - FALSE, - 0xFFFF, //Affinity, + TRUE, + Affinity, FALSE); if (!NT_SUCCESS(Status)) { @@ -1189,6 +1284,7 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, /* FIXME: Copy more configuration data? */ + /* Create the dos device link */ swprintf(DosNameBuffer, L"\\??\\Scsi%lu:", @@ -1199,6 +1295,8 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject, IoCreateSymbolicLink(&DosDeviceName, &DeviceName); + *RealDeviceExtension = PortDeviceExtension; + DPRINT("ScsiPortCreatePortDevice() done\n"); return(STATUS_SUCCESS); @@ -1241,9 +1339,10 @@ ScsiPortInquire(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) { Srb.PathId = Bus; - AdapterInfo->BusData[Bus].InitiatorBusId = 0; /* ? */ + AdapterInfo->BusData[Bus].InitiatorBusId = + DeviceExtension->PortConfig.InitiatorBusId[Bus]; AdapterInfo->BusData[Bus].InquiryDataOffset = - (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo); + (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo); PrevUnit = NULL; UnitCount = 0; @@ -1499,31 +1598,71 @@ ScsiPortFreeSenseRequestSrb(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) } -#if 0 +/********************************************************************** + * NAME INTERNAL + * ScsiPortBuildDeviceMap + * + * DESCRIPTION + * Builds the registry device map of all device which are attached + * to the given SCSI HBA port. The device map is located at: + * \Registry\Machine\DeviceMap\Scsi + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DeviceExtension + * ... + * + * RegistryPath + * Name of registry driver service key. + * + * RETURNS + * NTSTATUS + */ + static NTSTATUS -ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) +ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, + PUNICODE_STRING RegistryPath) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; - WCHAR NameBuffer[32]; + UNICODE_STRING ValueName; + WCHAR NameBuffer[64]; ULONG Disposition; HANDLE ScsiKey; HANDLE ScsiPortKey; HANDLE ScsiBusKey; + HANDLE ScsiInitiatorKey; HANDLE ScsiTargetKey; - HANDLE ScsiUnitKey; + HANDLE ScsiLunKey; ULONG BusNumber; + UCHAR CurrentTarget; + PSCSI_ADAPTER_BUS_INFO AdapterInfo; + PSCSI_INQUIRY_DATA UnitInfo; + PINQUIRYDATA InquiryData; + PWCHAR DriverName; + ULONG UlongData; + PWCHAR TypeName; NTSTATUS Status; + DPRINT("ScsiPortBuildDeviceMap() called\n"); + + if (DeviceExtension == NULL || RegistryPath == NULL) + { + DPRINT1("Invalid parameter\n"); + return(STATUS_INVALID_PARAMETER); + } + /* Open or create the 'Scsi' subkey */ RtlInitUnicodeStringFromLiteral(&KeyName, - L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi"); + L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_OPENIF, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 0, NULL); - Status = NtCreateKey(&ScsiKey, + Status = ZwCreateKey(&ScsiKey, KEY_ALL_ACCESS, &ObjectAttributes, 0, @@ -1531,9 +1670,15 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) REG_OPTION_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + return(Status); + } /* Create new 'Scsi Port X' subkey */ + DPRINT("Scsi Port %lu\n", + DeviceExtension->PortNumber); + swprintf(NameBuffer, L"Scsi Port %lu", DeviceExtension->PortNumber); @@ -1544,73 +1689,345 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) 0, ScsiKey, NULL); - Status = NtCreateKey(&ScsiPortKey, + Status = ZwCreateKey(&ScsiPortKey, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, &Disposition); + ZwClose(ScsiKey); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + return(Status); + } + + /* + * Create port-specific values + */ + + /* Set 'DMA Enabled' (REG_DWORD) value */ + UlongData = (ULONG)!DeviceExtension->PortCapabilities->AdapterUsesPio; + DPRINT(" DMA Enabled = %s\n", (UlongData) ? "TRUE" : "FALSE"); + RtlInitUnicodeString(&ValueName, + L"DMA Enabled"); + Status = ZwSetValueKey(ScsiPortKey, + &ValueName, + 0, + REG_DWORD, + &UlongData, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status); + ZwClose(ScsiPortKey); + return(Status); + } + + /* Set 'Driver' (REG_SZ) value */ + DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1; + DPRINT(" Driver = '%S'\n", DriverName); + RtlInitUnicodeString(&ValueName, + L"Driver"); + Status = ZwSetValueKey(ScsiPortKey, + &ValueName, + 0, + REG_SZ, + DriverName, + wcslen(DriverName) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status); + ZwClose(ScsiPortKey); + return(Status); + } + + /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */ + UlongData = (ULONG)DeviceExtension->PortConfig.BusInterruptLevel; + DPRINT(" Interrupt = %lu\n", UlongData); + RtlInitUnicodeString(&ValueName, + L"Interrupt"); + Status = ZwSetValueKey(ScsiPortKey, + &ValueName, + 0, + REG_DWORD, + &UlongData, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status); + ZwClose(ScsiPortKey); + return(Status); + } + + /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */ + UlongData = ScsiPortConvertPhysicalAddressToUlong(DeviceExtension->PortConfig.AccessRanges[0].RangeStart); + DPRINT(" IOAddress = %lx\n", UlongData); + RtlInitUnicodeString(&ValueName, + L"IOAddress"); + Status = ZwSetValueKey(ScsiPortKey, + &ValueName, + 0, + REG_DWORD, + &UlongData, + sizeof(ULONG)); if (!NT_SUCCESS(Status)) { - NtClose(ScsiKey); + DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status); + ZwClose(ScsiPortKey); return(Status); } - /* Add port-specific values */ + /* Enumerate buses */ + for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig.NumberOfBuses; BusNumber++) + { + /* Create 'Scsi Bus X' key */ + DPRINT(" Scsi Bus %lu\n", BusNumber); + swprintf(NameBuffer, + L"Scsi Bus %lu", + BusNumber); + RtlInitUnicodeString(&KeyName, + NameBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + 0, + ScsiPortKey, + NULL); + Status = ZwCreateKey(&ScsiBusKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + ZwClose(ScsiPortKey); + return(Status); + } - /* 'DMA Enabled' (REG_DWORD) */ - DPRINT1("DMA Enabled = %s\n", - (DeviceExtension->PortCapabilities->AdapterUsesPio)?"TRUE":"FALSE"); + /* Create 'Initiator Id X' key */ + DPRINT(" Initiator Id %u\n", + DeviceExtension->PortConfig.InitiatorBusId[BusNumber]); + swprintf(NameBuffer, + L"Initiator Id %u", + DeviceExtension->PortConfig.InitiatorBusId[BusNumber]); + RtlInitUnicodeString(&KeyName, + NameBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + 0, + ScsiBusKey, + NULL); + Status = ZwCreateKey(&ScsiInitiatorKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + ZwClose(ScsiBusKey); + ZwClose(ScsiPortKey); + return(Status); + } - /* 'Driver' (REG_SZ) */ + /* FIXME: Are there any initiator values (??) */ - /* 'Interrupt' (REG_DWORD) (NT4 only) */ - DPRINT1("Interrupt = %lx\n", DeviceExtension->PortConfig.BusInterruptLevel); + ZwClose(ScsiInitiatorKey); - /* 'IOAddress' (REG_DWORD) (NT4 only) */ - DPRINT1("IOAddress = %lx\n", - ScsiPortConvertPhysicalAddressToUlong(DeviceExtension->PortConfig.AccessRanges[0].RangeStart)); + /* Enumerate targets */ + CurrentTarget = (UCHAR)-1; + ScsiTargetKey = NULL; + AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo; + if (AdapterInfo->BusData[BusNumber].NumberOfLogicalUnits != 0) + { + UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + + AdapterInfo->BusData[BusNumber].InquiryDataOffset); - /* Create 'Scsi Bus X' keys */ - for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig.NumberOfBuses; BusNumber++) - { - swprintf(NameBuffer, - L"Scsi Bus %lu", - DeviceExtension->PortNumber); - RtlInitUnicodeString(&KeyName, - NameBuffer); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, + while (AdapterInfo->BusData[BusNumber].InquiryDataOffset) + { + if (UnitInfo->TargetId != CurrentTarget) + { + /* Close old target key */ + if (ScsiTargetKey != NULL) + { + ZwClose(ScsiTargetKey); + ScsiTargetKey = NULL; + } + + /* Create 'Target Id X' key */ + DPRINT(" Target Id %u\n", + UnitInfo->TargetId); + swprintf(NameBuffer, + L"Target Id %u", + UnitInfo->TargetId); + RtlInitUnicodeString(&KeyName, + NameBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + 0, + ScsiBusKey, + NULL); + Status = ZwCreateKey(&ScsiTargetKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + ZwClose(ScsiBusKey); + ZwClose(ScsiPortKey); + return(Status); + } + + CurrentTarget = UnitInfo->TargetId; + } + + /* Create 'Logical Unit Id X' key */ + DPRINT(" Logical Unit Id %u\n", + UnitInfo->Lun); + swprintf(NameBuffer, + L"Logical Unit Id %u", + UnitInfo->Lun); + RtlInitUnicodeString(&KeyName, + NameBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + 0, + ScsiTargetKey, + NULL); + Status = ZwCreateKey(&ScsiLunKey, + KEY_ALL_ACCESS, + &ObjectAttributes, 0, - ScsiPortKey, - NULL); - Status = NtCreateKey(&ScsiBusKey, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - NtClose(ScsiPortKey); - NtClose(ScsiKey); - return(Status); - } + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed (Status %lx)\n", Status); + ZwClose(ScsiTargetKey); + ZwClose(ScsiBusKey); + ZwClose(ScsiPortKey); + return(Status); + } - /* Create target keys */ + /* Set values for logical unit */ + InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData; + + /* Set 'Identifier' (REG_SZ) value */ + swprintf(NameBuffer, + L"%.8S%.16S%.4S", + InquiryData->VendorId, + InquiryData->ProductId, + InquiryData->ProductRevisionLevel); + DPRINT(" Identifier = '%S'\n", + NameBuffer); + RtlInitUnicodeString(&ValueName, + L"Identifier"); + Status = ZwSetValueKey(ScsiLunKey, + &ValueName, + 0, + REG_SZ, + NameBuffer, + wcslen(NameBuffer) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status); + ZwClose(ScsiLunKey); + ZwClose(ScsiTargetKey); + ZwClose(ScsiBusKey); + ZwClose(ScsiPortKey); + return(Status); + } + /* Set 'Type' (REG_SZ) value */ + switch (InquiryData->DeviceType) + { + case 0: + TypeName = L"DiskPeripheral"; + break; + case 1: + TypeName = L"TapePeripheral"; + break; + case 2: + TypeName = L"PrinterPeripheral"; + break; + case 4: + TypeName = L"WormPeripheral"; + break; + case 5: + TypeName = L"CdRomPeripheral"; + break; + case 6: + TypeName = L"ScannerPeripheral"; + break; + case 7: + TypeName = L"OpticalDiskPeripheral"; + break; + case 8: + TypeName = L"MediumChangerPeripheral"; + break; + case 9: + TypeName = L"CommunicationPeripheral"; + break; + default: + TypeName = L"OtherPeripheral"; + break; + } + DPRINT(" Type = '%S'\n", TypeName); + RtlInitUnicodeString(&ValueName, + L"Type"); + Status = ZwSetValueKey(ScsiLunKey, + &ValueName, + 0, + REG_SZ, + TypeName, + wcslen(TypeName) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status); + ZwClose(ScsiLunKey); + ZwClose(ScsiTargetKey); + ZwClose(ScsiBusKey); + ZwClose(ScsiPortKey); + return(Status); + } - NtClose(ScsiBusKey); + ZwClose(ScsiLunKey); + + if (UnitInfo->NextInquiryDataOffset == 0) + break; + + UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + + UnitInfo->NextInquiryDataOffset); + } + + /* Close old target key */ + if (ScsiTargetKey != NULL) + { + ZwClose(ScsiTargetKey); + ScsiTargetKey = NULL; + } + } + + ZwClose(ScsiBusKey); } - NtClose(ScsiPortKey); - NtClose(ScsiKey); + ZwClose(ScsiPortKey); + + DPRINT("ScsiPortBuildDeviceMap() done\n"); return(Status); } -#endif /* EOF */ diff --git a/drivers/storage/scsiport/scsiport.rc b/drivers/storage/scsiport/scsiport.rc index 8450f6f..a4939b8 100644 --- a/drivers/storage/scsiport/scsiport.rc +++ b/drivers/storage/scsiport/scsiport.rc @@ -1,4 +1,3 @@ - #include #include diff --git a/hal/halx86/bus.c b/hal/halx86/bus.c index da974ef..8c2dec6 100644 --- a/hal/halx86/bus.c +++ b/hal/halx86/bus.c @@ -170,6 +170,8 @@ HalpInitBusHandlers(VOID) if (BusHandler == NULL) return; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetIsaInterruptVector; BusHandler->TranslateBusAddress = (pTranslateBusAddress)HalpTranslateIsaBusAddress; diff --git a/hal/halx86/include/bus.h b/hal/halx86/include/bus.h index d77a470..b566a81 100644 --- a/hal/halx86/include/bus.h +++ b/hal/halx86/include/bus.h @@ -86,6 +86,14 @@ HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler, PPHYSICAL_ADDRESS TranslatedAddress); /* isa.c */ +ULONG STDCALL +HalpGetIsaInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity); + BOOLEAN STDCALL HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler, ULONG BusNumber, diff --git a/hal/halx86/irql.c b/hal/halx86/irql.c index a18a5aa..578432c 100644 --- a/hal/halx86/irql.c +++ b/hal/halx86/irql.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/hal/x86/irql.c @@ -26,6 +27,29 @@ */ static KIRQL CurrentIrql = HIGH_LEVEL; +typedef union +{ + USHORT both; + struct + { + BYTE master; + BYTE slave; + }; +} +PIC_MASK; + +/* + * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt + * - At startup enable timer and cascade + */ +static PIC_MASK pic_mask = {.both = 0xFFFA}; + + +/* + * PURPOSE: Mask for disabling of acknowledged interrupts + */ +static PIC_MASK pic_mask_intr = {.both = 0x0000}; + extern IMPORTED ULONG DpcQueueSize; static ULONG HalpPendingInterruptCount[NR_IRQS]; @@ -64,14 +88,36 @@ VOID HalpInitPICs(VOID) /* 8086 mode */ WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); - /* Enable all interrupts from PICs */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x0); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x0); + /* Enable interrupts */ + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave); /* We can now enable interrupts */ __asm__ __volatile__ ("sti\n\t"); } +VOID HalpEndSystemInterrupt(KIRQL Irql) +/* + * FUNCTION: Enable all irqs with higher priority. + */ +{ + 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 */ + __asm__("pushf\n\t"); + __asm__("cli\n\t"); + pic_mask_intr.both &= mask[Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master|pic_mask_intr.master); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave|pic_mask_intr.slave); + __asm__("popf\n\t"); +} + VOID STATIC HalpExecuteIrqs(KIRQL NewIrql) { @@ -85,22 +131,29 @@ HalpExecuteIrqs(KIRQL NewIrql) */ for (i = 0; i < IrqLimit; i++) { - while (HalpPendingInterruptCount[i] > 0) + if (HalpPendingInterruptCount[i] > 0) { - /* - * For each deferred interrupt execute all the handlers at DIRQL. - */ - CurrentIrql = IRQ_TO_DIRQL(i); - KiInterruptDispatch2(i, NewIrql); - HalpPendingInterruptCount[i]--; + CurrentIrql = IRQ_TO_DIRQL(i); + + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + KiInterruptDispatch2(i, NewIrql); + HalpPendingInterruptCount[i]--; + } + CurrentIrql--; + HalpEndSystemInterrupt(CurrentIrql); } } + } VOID STATIC HalpLowerIrql(KIRQL NewIrql) { - if (NewIrql > PROFILE_LEVEL) + if (NewIrql >= PROFILE_LEVEL) { CurrentIrql = NewIrql; return; @@ -116,12 +169,11 @@ HalpLowerIrql(KIRQL NewIrql) { KiDispatchInterrupt(); } + CurrentIrql = APC_LEVEL; if (NewIrql == APC_LEVEL) { - CurrentIrql = NewIrql; return; } - CurrentIrql = APC_LEVEL; if (KeGetCurrentThread() != NULL && KeGetCurrentThread()->ApcState.KernelApcPending) { @@ -304,21 +356,30 @@ HalBeginSystemInterrupt (ULONG Vector, KIRQL Irql, PKIRQL OldIrql) { - if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS) + ULONG irq; + if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) { return(FALSE); } - - /* Send EOI to the PICs */ - WRITE_PORT_UCHAR((PUCHAR)0x20,0x20); - if ((Vector-IRQ_BASE)>=8) - { - WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20); - } + 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, pic_mask.master|pic_mask_intr.master); + WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20); + } + else + { + WRITE_PORT_UCHAR((PUCHAR)0xa1, 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 (CurrentIrql >= Irql) { - HalpPendingInterruptCount[Vector - IRQ_BASE]++; + HalpPendingInterruptCount[irq]++; return(FALSE); } *OldIrql = CurrentIrql; @@ -334,26 +395,26 @@ VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) */ { HalpLowerIrql(Irql); + HalpEndSystemInterrupt(Irql); } - + BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, ULONG Unknown2) { ULONG irq; - if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS) + 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, - READ_PORT_UCHAR((PUCHAR)0x21)|(1< IRQ_BASE + NR_IRQS) + 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, - READ_PORT_UCHAR((PUCHAR)0x21)&(~(1<> 4) | 0xf0) /* GLOBALS ******************************************************************/ static ULONG BusConfigType = 0; /* undetermined config type */ - +static KSPIN_LOCK PciLock; /* FUNCTIONS ****************************************************************/ @@ -58,18 +51,24 @@ ReadPciConfigUchar(UCHAR Bus, 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, 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; @@ -82,23 +81,29 @@ ReadPciConfigUshort(UCHAR Bus, UCHAR Offset, PUSHORT Value) { + KIRQL oldIrql; + if ((Offset & 1) != 0) { - return PCIBIOS_BAD_REGISTER_NUMBER; + 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 & 1)); + KeReleaseSpinLock(&PciLock, oldIrql); return STATUS_SUCCESS; case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); WRITE_PORT_UCHAR((PUCHAR)0xCF8, 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; @@ -111,23 +116,29 @@ ReadPciConfigUlong(UCHAR Bus, UCHAR Offset, PULONG Value) { + KIRQL oldIrql; + if ((Offset & 3) != 0) { - return PCIBIOS_BAD_REGISTER_NUMBER; + 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, 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; @@ -140,18 +151,24 @@ WritePciConfigUchar(UCHAR Bus, 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, 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; @@ -164,23 +181,29 @@ WritePciConfigUshort(UCHAR Bus, UCHAR Offset, USHORT Value) { + KIRQL oldIrql; + if ((Offset & 1) != 0) { - return PCIBIOS_BAD_REGISTER_NUMBER; + 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 & 1), Value); + KeReleaseSpinLock(&PciLock, oldIrql); return STATUS_SUCCESS; case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); WRITE_PORT_UCHAR((PUCHAR)0xCF8, 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; @@ -193,23 +216,29 @@ WritePciConfigUlong(UCHAR Bus, UCHAR Offset, ULONG Value) { + KIRQL oldIrql; + if ((Offset & 3) != 0) { - return PCIBIOS_BAD_REGISTER_NUMBER; + 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, 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; @@ -239,21 +268,49 @@ HalpGetPciData(PBUS_HANDLER BusHandler, if ((Length == 0) || (BusConfigType == 0)) return 0; + ReadPciConfigUlong(BusNumber, + 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(BusNumber, - SlotNumber & 0xF8, + SlotNumber & 0x1F, 0x0E, &HeaderType); - if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0)) + if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0)) + { + if (Offset == 0 && Length >= 2) + { + *(PUSHORT)Buffer = PCI_INVALID_VENDORID; + return 2; + } return 0; - + } ReadPciConfigUlong(BusNumber, 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)) { @@ -337,12 +394,21 @@ HalpSetPciData(PBUS_HANDLER BusHandler, if ((Length == 0) || (BusConfigType == 0)) return 0; + ReadPciConfigUlong(BusNumber, + 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(BusNumber, - SlotNumber & 0xF8, + SlotNumber & 0x1F, 0x0E, &HeaderType); - if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0)) + if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0)) return 0; ReadPciConfigUlong(BusNumber, @@ -416,9 +482,12 @@ 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); @@ -426,6 +495,7 @@ GetBusConfigType(VOID) if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000) { WRITE_PORT_ULONG((PULONG)0xCF8, Value); + KeReleaseSpinLock(&PciLock, oldIrql); DPRINT(" Success!\n"); return 1; } @@ -439,9 +509,11 @@ GetBusConfigType(VOID) 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"); @@ -457,11 +529,39 @@ HalpGetPciInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { - *Irql = HIGH_LEVEL - BusInterruptVector; + *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; } +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; +} + VOID HalpInitPciBus(VOID) @@ -470,6 +570,8 @@ HalpInitPciBus(VOID) DPRINT("HalpInitPciBus() called.\n"); + KeInitializeSpinLock (&PciLock); + BusConfigType = GetBusConfigType(); if (BusConfigType == 0) return; @@ -484,6 +586,8 @@ HalpInitPciBus(VOID) BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData; BusHandler->GetInterruptVector = (pGetInterruptVector)HalpGetPciInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslatePciAddress; // BusHandler->AdjustResourceList = // (pGetSetBusData)HalpAdjustPciResourceList; // BusHandler->AssignSlotResources = @@ -498,6 +602,8 @@ HalpInitPciBus(VOID) BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData; BusHandler->GetInterruptVector = (pGetInterruptVector)HalpGetPciInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslatePciAddress; // BusHandler->AdjustResourceList = // (pGetSetBusData)HalpAdjustPciResourceList; // BusHandler->AssignSlotResources = diff --git a/hal/halx86/sysbus.c b/hal/halx86/sysbus.c index 6a2b7de..5b1b95f 100644 --- a/hal/halx86/sysbus.c +++ b/hal/halx86/sysbus.c @@ -25,7 +25,7 @@ HalpGetSystemInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { - *Irql = HIGH_LEVEL - BusInterruptVector; + *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; } diff --git a/hal/halx86/time.c b/hal/halx86/time.c index 57a4015..7691431 100644 --- a/hal/halx86/time.c +++ b/hal/halx86/time.c @@ -32,6 +32,9 @@ #define RTC_REGISTER_CENTURY 0x32 +/* GLOBALS ******************************************************************/ + +static KSPIN_LOCK CmosLock = {0}; /* FUNCTIONS *****************************************************************/ @@ -105,9 +108,12 @@ HalpSetECMOS(USHORT Reg, 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) - ; + while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP); Time->Second = BCD_INT(HalpQueryCMOS (0)); Time->Minute = BCD_INT(HalpQueryCMOS (2)); @@ -127,6 +133,8 @@ HalQueryRealTimeClock(PTIME_FIELDS Time) 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, @@ -145,9 +153,12 @@ HalQueryRealTimeClock(PTIME_FIELDS Time) 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) - ; + while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP); HalpSetCMOS (0, INT_BCD(Time->Second)); HalpSetCMOS (2, INT_BCD(Time->Minute)); @@ -161,6 +172,8 @@ HalSetRealTimeClock(PTIME_FIELDS Time) /* Century */ HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100)); #endif + KeReleaseSpinLock(&CmosLock, oldIrql); + } @@ -169,11 +182,15 @@ 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); @@ -182,6 +199,7 @@ HalGetEnvironmentVariable(PCH Name, { strncpy(Value, "TRUE", ValueLength); } + KeReleaseSpinLock(&CmosLock, oldIrql); return TRUE; } @@ -192,10 +210,14 @@ 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) @@ -203,9 +225,11 @@ HalSetEnvironmentVariable(PCH Name, else if (_stricmp(Value, "FALSE") == 0) HalpSetCMOS(RTC_REGISTER_B, Val & ~0x01); else - return FALSE; + result = FALSE; - return TRUE; + KeReleaseSpinLock(&CmosLock, oldIrql); + + return result; } @@ -220,6 +244,7 @@ HalpGetCmosData(PBUS_HANDLER BusHandler, PUCHAR Ptr = Buffer; ULONG Address = SlotNumber; ULONG Len = Length; + KIRQL oldIrql; DPRINT("HalpGetCmosData() called.\n"); DPRINT(" BusNumber %lu\n", BusNumber); @@ -233,6 +258,7 @@ HalpGetCmosData(PBUS_HANDLER BusHandler, if (BusNumber == 0) { /* CMOS */ + KeAcquireSpinLock(&CmosLock, &oldIrql); while ((Len > 0) && (Address < 0x100)) { *Ptr = HalpQueryCMOS((UCHAR)Address); @@ -240,10 +266,12 @@ HalpGetCmosData(PBUS_HANDLER BusHandler, Address++; Len--; } + KeReleaseSpinLock(&CmosLock, oldIrql); } else if (BusNumber == 1) { /* Extended CMOS */ + KeAcquireSpinLock(&CmosLock, &oldIrql); while ((Len > 0) && (Address < 0x1000)) { *Ptr = HalpQueryECMOS((USHORT)Address); @@ -251,6 +279,7 @@ HalpGetCmosData(PBUS_HANDLER BusHandler, Address++; Len--; } + KeReleaseSpinLock(&CmosLock, oldIrql); } return(Length - Len); @@ -268,6 +297,7 @@ HalpSetCmosData(PBUS_HANDLER BusHandler, PUCHAR Ptr = (PUCHAR)Buffer; ULONG Address = SlotNumber; ULONG Len = Length; + KIRQL oldIrql; DPRINT("HalpSetCmosData() called.\n"); DPRINT(" BusNumber %lu\n", BusNumber); @@ -281,6 +311,7 @@ HalpSetCmosData(PBUS_HANDLER BusHandler, if (BusNumber == 0) { /* CMOS */ + KeAcquireSpinLock(&CmosLock, &oldIrql); while ((Len > 0) && (Address < 0x100)) { HalpSetCMOS((UCHAR)Address, *Ptr); @@ -288,10 +319,12 @@ HalpSetCmosData(PBUS_HANDLER BusHandler, Address++; Len--; } + KeReleaseSpinLock(&CmosLock, oldIrql); } else if (BusNumber == 1) { /* Extended CMOS */ + KeAcquireSpinLock(&CmosLock, &oldIrql); while ((Len > 0) && (Address < 0x1000)) { HalpSetECMOS((USHORT)Address, *Ptr); @@ -299,6 +332,7 @@ HalpSetCmosData(PBUS_HANDLER BusHandler, Address++; Len--; } + KeReleaseSpinLock(&CmosLock, oldIrql); } return(Length - Len); diff --git a/iface/native/genntdll.c b/iface/native/genntdll.c index 5d72e90..be3d71c 100644 --- a/iface/native/genntdll.c +++ b/iface/native/genntdll.c @@ -29,7 +29,7 @@ /* FUNCTIONS ****************************************************************/ void write_syscall_stub(FILE* out, FILE* out3, char* name, char* name2, - unsigned int nr_args, unsigned int sys_call_idx) + char* nr_args, unsigned int sys_call_idx) { #ifdef PARAMETERIZED_LIBS fprintf(out,"__asm__(\"\\n\\t.global _%s@%s\\n\\t\"\n",name,nr_args); diff --git a/include/ascii.h b/include/ascii.h index 50b0dc8..be57851 100644 --- a/include/ascii.h +++ b/include/ascii.h @@ -640,6 +640,17 @@ CopyFileA( WINBOOL STDCALL +CopyFileExA( + LPCSTR lpExistingFileName, + LPCSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + LPBOOL pbCancel, + DWORD dwCopyFlags + ); + +WINBOOL +STDCALL MoveFileA( LPCSTR lpExistingFileName, LPCSTR lpNewFileName @@ -653,6 +664,16 @@ MoveFileExA( DWORD dwFlags ); +WINBOOL +STDCALL +MoveFileWithProgressA( + LPCSTR lpExistingFileName, + LPCSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + DWORD dwFlags + ); + HANDLE STDCALL CreateNamedPipeA( @@ -2114,7 +2135,7 @@ FindNextFileA( WINBOOL STDCALL GetVersionExA( - LPOSVERSIONINFO lpVersionInformation + LPOSVERSIONINFOA lpVersionInformation ); #define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\ @@ -2415,7 +2436,7 @@ InitiateSystemShutdownA( WINBOOL STDCALL AbortSystemShutdownA( - LPSTR lpMachineName + LPCSTR lpMachineName ); int diff --git a/include/base.h b/include/base.h index d57906e..e8b39f4 100644 --- a/include/base.h +++ b/include/base.h @@ -56,17 +56,6 @@ typedef long LONG; #define CONST const -#ifdef i386 -#define STDCALL __attribute__ ((stdcall)) -#define CDECL __attribute((cdecl)) -#define CALLBACK WINAPI -#define PASCAL WINAPI -#else -#define STDCALL -#define CDECL -#define CALLBACK -#define PASCAL -#endif #define WINAPI STDCALL #define APIENTRY STDCALL #define WINGDIAPI @@ -74,8 +63,8 @@ typedef long LONG; #ifdef UNICODE -typedef unsigned short *LPTCH; -typedef unsigned short *LPTSTR; +typedef wchar_t *LPTCH; +typedef wchar_t *LPTSTR; #else typedef char *LPTCH; typedef char *LPTSTR; @@ -165,12 +154,12 @@ typedef CHAR *LPCH; typedef COLORREF *LPCOLORREF; #ifdef UNICODE -typedef const unsigned short *LPCTSTR; +typedef const wchar_t *LPCTSTR; #else typedef const char *LPCTSTR; #endif /* UNICODE */ -typedef const unsigned short *LPCWCH; +typedef const wchar_t *LPCWCH; typedef DWORD *LPDWORD; /* typedef LPFRHOOKPROC; */ typedef HANDLE *LPHANDLE; @@ -179,14 +168,14 @@ typedef PINT LPINT; typedef PLONG LPLONG; typedef long LRESULT; -typedef unsigned short *LPWCH; +typedef wchar_t *LPWCH; typedef unsigned short *LPWORD; /* typedef NPSTR; */ -typedef unsigned short *NWPSTR; +typedef wchar_t *NWPSTR; typedef WINBOOL *PWINBOOL; typedef const CHAR *PCCH; typedef const char *PCSTR; -typedef const unsigned short *PCWCH; +typedef const wchar_t *PCWCH; /* typedef PHKEY; */ /* typedef LCID *PLCID; */ typedef short *PSHORT; @@ -195,10 +184,10 @@ typedef char *PSTR; typedef char *PSZ; #ifdef UNICODE -typedef unsigned short *PTBYTE; -typedef unsigned short *PTCH; -typedef unsigned short *PTCHAR; -typedef unsigned short *PTSTR; +typedef wchar_t *PTBYTE; +typedef wchar_t *PTCH; +typedef wchar_t *PTCHAR; +typedef wchar_t *PTSTR; #else typedef unsigned char *PTBYTE; typedef char *PTCH; @@ -221,12 +210,12 @@ typedef DWORD SERVICE_STATUS_HANDLE; /* typedef SPHANDLE; */ #ifdef UNICODE -typedef unsigned short TBYTE; +typedef wchar_t TBYTE; #ifndef _TCHAR_DEFINED #define _TCHAR_DEFINED -typedef unsigned short TCHAR; +typedef wchar_t TCHAR; #endif /* _TCHAR_DEFINED */ -typedef unsigned short BCHAR; +typedef wchar_t BCHAR; #else typedef unsigned char TBYTE; #ifndef _TCHAR_DEFINED @@ -359,12 +348,21 @@ typedef enum _SID_NAME_USE { #define INDEXTOSTATEIMAGEMASK(i) ((i) << 12) #ifdef UNICODE +#ifndef _T #define _T(quote) L##quote +#endif +#ifndef _TEXT #define TEXT(quote) L##quote +#endif #else +#ifndef _T #define _T(quote) quote +#endif +#ifndef _TEXT #define TEXT(quote) quote #endif +#endif + #ifndef RC_INVOKED @@ -381,7 +379,7 @@ typedef UINT CALLBACK (*LPPRINTHOOKPROC) (HWND, UINT, WPARAM, LPARAM); typedef UINT CALLBACK (*LPSETUPHOOKPROC) (HWND, UINT, WPARAM, LPARAM); typedef WINBOOL CALLBACK (*DLGPROC) (HWND, UINT, WPARAM, LPARAM); typedef int CALLBACK (*PFNPROPSHEETCALLBACK) (HWND, UINT, LPARAM); -typedef VOID CALLBACK (*LPSERVICE_MAIN_FUNCTION) (DWORD, LPTSTR); +typedef VOID CALLBACK (*LPSERVICE_MAIN_FUNCTION) (DWORD, LPTSTR*); typedef int CALLBACK (*PFNTVCOMPARE) (LPARAM, LPARAM, LPARAM); typedef LRESULT CALLBACK (*WNDPROC) (HWND, UINT, WPARAM, LPARAM); typedef int CALLBACK (*FARPROC)(void); diff --git a/include/basetsd.h b/include/basetsd.h new file mode 100644 index 0000000..d9c375d --- /dev/null +++ b/include/basetsd.h @@ -0,0 +1,119 @@ +#ifndef _BASETSD_H +#define _BASETSD_H +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __GNUC__ +#ifndef __int64 +#define __int64 long long +#endif +#endif + +#if defined(_WIN64) +#define __int3264 __int64 +#define ADDRESS_TAG_BIT 0x40000000000UI64 +#else /* !_WIN64 */ +#define __int3264 __int32 +#define ADDRESS_TAG_BIT 0x80000000UL +#define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) +#define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) +#define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) +#define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) +#define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) +#define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) +#define PtrToInt( p ) ((INT)(INT_PTR) (p) ) +#define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) +#define PtrToShort( p ) ((short)(LONG_PTR)(p) ) +#define IntToPtr( i ) ((VOID*)(INT_PTR)((int)i)) +#define UIntToPtr( ui ) ((VOID*)(UINT_PTR)((unsigned int)ui)) +#define LongToPtr( l ) ((VOID*)(LONG_PTR)((long)l)) +#define ULongToPtr( ul ) ((VOID*)(ULONG_PTR)((unsigned long)ul)) +#endif /* !_WIN64 */ + +#define UlongToPtr(ul) ULongToPtr(ul) +#define UintToPtr(ui) UIntToPtr(ui) +#define MAXUINT_PTR (~((UINT_PTR)0)) +#define MAXINT_PTR ((INT_PTR)(MAXUINT_PTR >> 1)) +#define MININT_PTR (~MAXINT_PTR) +#define MAXULONG_PTR (~((ULONG_PTR)0)) +#define MAXLONG_PTR ((LONG_PTR)(MAXULONG_PTR >> 1)) +#define MINLONG_PTR (~MAXLONG_PTR) +#define MAXUHALF_PTR ((UHALF_PTR)~0) +#define MAXHALF_PTR ((HALF_PTR)(MAXUHALF_PTR >> 1)) +#define MINHALF_PTR (~MAXHALF_PTR) + +#ifndef RC_INVOKED +#ifdef __cplusplus +extern "C" { +#endif +typedef int LONG32, *PLONG32; +#ifndef XFree86Server +typedef int INT32, *PINT32; +#endif /* ndef XFree86Server */ +typedef unsigned int ULONG32, *PULONG32; +typedef unsigned int DWORD32, *PDWORD32; +typedef unsigned int UINT32, *PUINT32; + +#if defined(_WIN64) +typedef __int64 INT_PTR, *PINT_PTR; +typedef unsigned __int64 UINT_PTR, *PUINT_PTR; +typedef __int64 LONG_PTR, *PLONG_PTR; +typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; +typedef unsigned __int64 HANDLE_PTR; +typedef unsigned int UHALF_PTR, *PUHALF_PTR; +typedef int HALF_PTR, *PHALF_PTR; + +#if 0 /* TODO when WIN64 is here */ +inline unsigned long HandleToUlong(const void* h ) + { return((unsigned long) h ); } +inline long HandleToLong( const void* h ) + { return((long) h ); } +inline void* LongToHandle( const long h ) + { return((void*) (INT_PTR) h ); } +inline unsigned long PtrToUlong( const void* p) + { return((unsigned long) p ); } +inline unsigned int PtrToUint( const void* p ) + { return((unsigned int) p ); } +inline unsigned short PtrToUshort( const void* p ) + { return((unsigned short) p ); } +inline long PtrToLong( const void* p ) + { return((long) p ); } +inline int PtrToInt( const void* p ) + { return((int) p ); } +inline short PtrToShort( const void* p ) + { return((short) p ); } +inline void* IntToPtr( const int i ) + { return( (void*)(INT_PTR)i ); } +inline void* UIntToPtr(const unsigned int ui) + { return( (void*)(UINT_PTR)ui ); } +inline void* LongToPtr( const long l ) + { return( (void*)(LONG_PTR)l ); } +inline void* ULongToPtr( const unsigned long ul ) + { return( (void*)(ULONG_PTR)ul ); } +#endif /* 0_ */ + +#else /* !_WIN64 */ +typedef int INT_PTR, *PINT_PTR; +typedef unsigned int UINT_PTR, *PUINT_PTR; +typedef long LONG_PTR, *PLONG_PTR; +typedef unsigned long ULONG_PTR, *PULONG_PTR; +typedef unsigned short UHALF_PTR, *PUHALF_PTR; +typedef short HALF_PTR, *PHALF_PTR; +typedef unsigned long HANDLE_PTR; +#endif /* !_WIN64 */ + +typedef ULONG_PTR SIZE_T, *PSIZE_T; +typedef LONG_PTR SSIZE_T, *PSSIZE_T; +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; +typedef __int64 LONG64, *PLONG64; +typedef __int64 INT64, *PINT64; +typedef unsigned __int64 ULONG64, *PULONG64; +typedef unsigned __int64 DWORD64, *PDWORD64; +typedef unsigned __int64 UINT64, *PUINT64; +#ifdef __cplusplus +} +#endif +#endif /* !RC_INVOKED */ + +#endif /* _BASETSD_H */ diff --git a/include/crtdll/alloc.h b/include/crtdll/alloc.h deleted file mode 100644 index a351fde..0000000 --- a/include/crtdll/alloc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * alloc.h - * - * Memory management functions. Because most of these functions are - * actually declared in stdlib.h I have decided to simply include that - * header file. This file is included by malloc.h. My head hurts... - * - * NOTE: In the version of the Standard C++ Library from Cygnus there - * is also an alloc.h which needs to be on your include path. Most of - * the time I think the most sensible option would be to get rid of - * this file. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _ALLOC_H_ -#define _ALLOC_H_ - -#include - -#ifndef RC_INVOKED - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The structure used to walk through the heap with _heapwalk. - * TODO: This is a guess at the internals of this structure. - */ -typedef struct _heapinfo -{ - void* ptr; - unsigned int size; - int in_use; -} _HEAPINFO; - -int _heapwalk (_HEAPINFO* pHeapinfo); -void * _alloca(size_t size); - - - -#ifndef _NO_OLDNAMES -#define heapwalk(x) _heapwalk(x) -#define alloca(s) _alloca(s) -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not RC_INVOKED */ - -#endif /* Not _ALLOC_H_ */ - -#endif /* Not __STRICT_ANSI__ */ - diff --git a/include/crtdll/assert.h b/include/crtdll/assert.h deleted file mode 100644 index 8d85fcf..0000000 --- a/include/crtdll/assert.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * assert.h - * - * Define the assert macro for debug output. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _ASSERT_H_ -#define _ASSERT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef NDEBUG - -/* - * If not debugging, assert does nothing. - */ -#define assert(x) ((void)0); - -#else /* debugging enabled */ - -/* - * CRTDLL nicely supplies a function which does the actual output and - * call to abort. - */ -#ifndef __ATTRIB_NORETURN -#ifdef __GNUC__ -#define _ATTRIB_NORETURN __attribute__ ((noreturn)) -#else /* Not __GNUC__ */ -#define _ATTRIB_NORETURN -#endif /* __GNUC__ */ -#endif - -void _assert (const char* szExpression, const char* szFileName, int nLine) -_ATTRIB_NORETURN -; - -/* - * Definition of the assert macro. - */ -#define assert(x) if(!(x)) _assert( #x , __FILE__, __LINE__); -#endif /* NDEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/conio.h b/include/crtdll/conio.h deleted file mode 100644 index db012be..0000000 --- a/include/crtdll/conio.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * conio.h - * - * Low level console I/O functions. Pretty please try to use the ANSI - * standard ones if you are writing new code. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _CONIO_H_ -#define _CONIO_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -char* _cgets (char* szBuffer); -int _cprintf (const char* szFormat, ...); -int _cputs (const char* szString); -int _cscanf (char* szFormat, ...); - -int _getch (void); -int _getche (void); -int _kbhit (void); -int _putch (int cPut); -int _ungetch (int cUnget); - - -#ifndef _NO_OLDNAMES - -#define getch _getch -#define getche _getche -#define kbhit _kbhit -#define putch(cPut) _putch(cPut) -#define ungetch(cUnget) _ungetch(cUnget) - -#endif /* Not _NO_OLDNAMES */ - - -#ifdef __cplusplus -} -#endif - -#endif /* Not _CONIO_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/crtdll.h b/include/crtdll/crtdll.h deleted file mode 100644 index fb1f1ad..0000000 --- a/include/crtdll/crtdll.h +++ /dev/null @@ -1 +0,0 @@ -void debug_printf(char* fmt, ...); diff --git a/include/crtdll/ctype.h b/include/crtdll/ctype.h deleted file mode 100644 index 7a11bdf..0000000 --- a/include/crtdll/ctype.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * ctype.h - * - * Functions for testing character types and converting characters. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -#ifndef _LINUX_CTYPE_H -#define _LINUX_CTYPE_H - -#ifndef _CTYPE_H_ -#define _CTYPE_H_ - -#define __need_wchar_t -#define __need_wint_t -#include - - -/* - * The following flags are used to tell iswctype and _isctype what character - * types you are looking for. - */ -#define _UPPER 0x0001 -#define _LOWER 0x0002 -#define _DIGIT 0x0004 -#define _SPACE 0x0008 -#define _PUNCT 0x0010 -#define _CONTROL 0x0020 -#define _BLANK 0x0040 -#define _HEX 0x0080 - -#define _ALPHA 0x0103 -#define _LEADBYTE 0x8000 - - -#ifdef __cplusplus -extern "C" { -#endif - -int isalnum(int c); -int isalpha(int c); -int iscntrl(int c); -int isdigit(int c); -int isgraph(int c); -int islower(int c); -int isprint(int c); -int ispunct(int c); -int isspace(int c); -int isupper(int c); -int isxdigit(int c); - -#ifndef __STRICT_ANSI__ -int _isctype (unsigned int c, int ctypeFlags); -#endif - -int tolower(int c); -int toupper(int c); - -/* - * NOTE: The above are not old name type wrappers, but functions exported - * explicitly by CRTDLL. However, underscored versions are also exported. - */ -#ifndef __STRICT_ANSI__ -int _tolower(int c); -int _toupper(int c); -#endif - -#ifndef WEOF -#define WEOF (wchar_t)(0xFFFF) -#endif - -/* - * TODO: MB_CUR_MAX should be defined here (if not already defined, since - * it should also be defined in stdlib.h). It is supposed to be the - * maximum number of bytes in a multi-byte character in the current - * locale. Perhaps accessible through the __mb_curr_max_dll entry point, - * but I think (again) that that is a variable pointer, which leads to - * problems under the current Cygwin compiler distribution. - */ - -typedef int wctype_t; - -/* Wide character equivalents */ -int iswalnum(wint_t wc); -int iswalpha(wint_t wc); -int iswascii(wint_t wc); -int iswcntrl(wint_t wc); -int iswctype(wint_t wc, wctype_t wctypeFlags); -int is_wctype(wint_t wc, wctype_t wctypeFlags); /* Obsolete! */ -int iswdigit(wint_t wc); -int iswgraph(wint_t wc); -int iswlower(wint_t wc); -int iswprint(wint_t wc); -int iswpunct(wint_t wc); -int iswspace(wint_t wc); -int iswupper(wint_t wc); -int iswxdigit(wint_t wc); - -wchar_t towlower(wchar_t c); -wchar_t towupper(wchar_t c); - -int isleadbyte (int c); - -#ifndef __STRICT_ANSI__ -int __isascii (int c); -int __toascii (int c); -int __iscsymf (int c); /* Valid first character in C symbol */ -int __iscsym (int c); /* Valid character in C symbol (after first) */ - -#ifndef _NO_OLDNAMES -#define isascii(c) __isascii(c) -#define toascii(c) _toascii(c) -#define iscsymf(c) __iscsymf(c) -#define iscsym(c) __iscsym(c) -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __cplusplus -} -#endif - -#endif -#endif diff --git a/include/crtdll/dir.h b/include/crtdll/dir.h deleted file mode 100644 index 0cb14eb..0000000 --- a/include/crtdll/dir.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * dir.h - * - * Functions for working with directories and path names. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _DIR_H_ -#define _DIR_H_ - -#include /* To get FILENAME_MAX... ugly. */ -#include /* To get time_t. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Attributes of files as returned by _findfirst et al. - */ -#define _A_NORMAL 0x00000000 -#define _A_RDONLY 0x00000001 -#define _A_HIDDEN 0x00000002 -#define _A_SYSTEM 0x00000004 -#define _A_VOLID 0x00000008 -#define _A_SUBDIR 0x00000010 -#define _A_ARCH 0x00000020 - -#ifndef _FSIZE_T_DEFINED -typedef unsigned long _fsize_t; -#define _FSIZE_T_DEFINED -#endif - -/* - * The following structure is filled in by _findfirst or _findnext when - * they succeed in finding a match. - */ -struct _finddata_t -{ - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - _fsize_t size; - char name[FILENAME_MAX]; /* may include spaces. */ -}; - -/* - * Functions for searching for files. _findfirst returns -1 if no match - * is found. Otherwise it returns a handle to be used in _findnext and - * _findclose calls. _findnext also returns -1 if no match could be found, - * and 0 if a match was found. Call _findclose when you are finished. - */ -int _findfirst (const char* szFilespec, struct _finddata_t* find); -int _findnext (int nHandle, struct _finddata_t* find); -int _findclose (int nHandle); - -int _chdir (const char* szPath); -char* _getcwd (char* caBuffer, int nBufferSize); -int _mkdir (const char* szPath); -char* _mktemp (char* szTemplate); -int _rmdir (const char* szPath); - - -#ifndef _NO_OLDNAMES - -int chdir (const char* szPath); -char* getcwd (char* caBuffer, int nBufferSize); -int mkdir (const char* szPath); -char* mktemp (char* szTemplate); -int rmdir (const char* szPath); - -#endif /* Not _NO_OLDNAMES */ - - -#ifdef __cplusplus -} -#endif - -#endif /* Not _DIR_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/direct.h b/include/crtdll/direct.h deleted file mode 100644 index 49dc129..0000000 --- a/include/crtdll/direct.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __include_direct_h_ -#define __include_direct_h_ - -struct _diskfree_t { - unsigned short total_clusters; - unsigned short avail_clusters; - unsigned short sectors_per_cluster; - unsigned short bytes_per_sector; -}; - - -int _chdrive( int drive ); -int _getdrive( void ); -char *_getcwd( char *buffer, int maxlen ); - -int _chdir(const char *_path); -char *_getcwd(char *, int); -int _mkdir(const char *_path); -int _rmdir(const char *_path); -unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace); -#define chdir _chdir -#define getcwd _getcwd -#define mkdir _mkdir -#define rmdir _rmdir - - -#endif diff --git a/include/crtdll/dirent.h b/include/crtdll/dirent.h deleted file mode 100644 index 26d6aba..0000000 --- a/include/crtdll/dirent.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * DIRENT.H (formerly DIRLIB.H) - * - * by M. J. Weinstein Released to public domain 1-Jan-89 - * - * Because I have heard that this feature (opendir, readdir, closedir) - * it so useful for programmers coming from UNIX or attempting to port - * UNIX code, and because it is reasonably light weight, I have included - * it in the Mingw32 package. - * - Colin Peters - * - * This code is distributed in the hope that is will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includeds but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _STRICT_ANSI - -#ifndef _DIRENT_H_ -#define _DIRENT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct dirent -{ - long d_ino; - unsigned short d_reclen; - unsigned short d_namlen; - char d_name[FILENAME_MAX+1]; -}; - -typedef struct -{ - struct _finddata_t dd_dta; /* disk transfer area for this dir */ - struct dirent dd_dir; /* dirent struct to return from dir */ - long dd_handle; /* _findnext handle */ - short dd_stat; /* status return from last lookup */ - char dd_name[1]; /* full name of file (struct is extended */ -} DIR; - -DIR* opendir (const char* szPath); -struct dirent* readdir (DIR* dir); -int closedir (DIR* dir); - -#ifdef __cplusplus -} -#endif - -#endif _DIRENT_H_ - -#endif /* Not _STRICT_ANSI */ diff --git a/include/crtdll/dos.h b/include/crtdll/dos.h deleted file mode 100644 index f31ecb1..0000000 --- a/include/crtdll/dos.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#ifndef __dj_include_h_ -#define __dj_include_h_ - -#ifndef __dj_ENFORCE_ANSI_FREESTANDING - -#ifndef __STRICT_ANSI__ - -#ifndef _POSIX_SOURCE - - - -struct ftime { - unsigned ft_tsec:5; /* 0-29, double to get real seconds */ - unsigned ft_min:6; /* 0-59 */ - unsigned ft_hour:5; /* 0-23 */ - unsigned ft_day:5; /* 1-31 */ - unsigned ft_month:4; /* 1-12 */ - unsigned ft_year:7; /* since 1980 */ -}; - -struct date { - short da_year; - char da_day; - char da_mon; -}; - -struct time { - unsigned char ti_min; - unsigned char ti_hour; - unsigned char ti_hund; - unsigned char ti_sec; -}; - -struct dfree { - unsigned df_avail; - unsigned df_total; - unsigned df_bsec; - unsigned df_sclus; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned short _osmajor, _osminor; -extern const char * _os_flavor; - -unsigned short _get_version(int); - - - - -int getftime(int handle, struct ftime *ftimep); -int setftime(int handle, struct ftime *ftimep); - -int getcbrk(void); -int setcbrk(int new_value); - -void getdate(struct date *); -void gettime(struct time *); -void setdate(struct date *); -void settime(struct time *); - -void getdfree(unsigned char drive, struct dfree *ptr); - -void delay(unsigned msec); -/* int _get_default_drive(void); -void _fixpath(const char *, char *); */ - - -/* - * For compatibility with other DOS C compilers. - */ - -#define _A_NORMAL 0x00 /* Normal file - No read/write restrictions */ -#define _A_RDONLY 0x01 /* Read only file */ -#define _A_HIDDEN 0x02 /* Hidden file */ -#define _A_SYSTEM 0x04 /* System file */ -#define _A_VOLID 0x08 /* Volume ID file */ -#define _A_SUBDIR 0x10 /* Subdirectory */ -#define _A_ARCH 0x20 /* Archive file */ - -#define _enable enable -#define _disable disable - -struct date_t { - unsigned char day; /* 1-31 */ - unsigned char month; /* 1-12 */ - unsigned short year; /* 1980-2099 */ - unsigned char dayofweek; /* 0-6, 0=Sunday */ -}; -#define dosdate_t date_t - -struct time_t { - unsigned char hour; /* 0-23 */ - unsigned char minute; /* 0-59 */ - unsigned char second; /* 0-59 */ - unsigned char hsecond; /* 0-99 */ -}; -#define dostime_t time_t - - - -#define finddata_t _finddata_t - - -#define diskfree_t _diskfree_t - -struct _DOSERROR { - int exterror; - #ifdef __cplusplus - char errclass; - #else - char class; - #endif - char action; - char locus; -}; -#define DOSERROR _DOSERROR - - - - -void _getdate(struct date_t *_date); -unsigned int _setdate(struct date_t *_date); -void _gettime(struct time_t *_time); -unsigned int _settime(struct time_t *_time); - -unsigned int _getftime(int _handle, unsigned int *_p_date, unsigned int *_p_time); -unsigned int _setftime(int _handle, unsigned int _date, unsigned int _time); -unsigned int _getfileattr(const char *_filename, unsigned int *_p_attr); -unsigned int _setfileattr(const char *_filename, unsigned int _attr); - - -void _setdrive(unsigned int _drive, unsigned int *_p_drives); - - -int exterr(struct _DOSERROR *_p_error); -#define dosexterr(_ep) exterr(_ep) - -#include - -#define int386(_i, _ir, _or) int86(_i, _ir, _or) -#define int386x(_i, _ir, _or, _sr) int86x(_i, _ir, _or, _sr) - -#ifdef __cplusplus -} -#endif - -#endif /* !_POSIX_SOURCE */ -#endif /* !__STRICT_ANSI__ */ -#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */ - -#ifndef __dj_ENFORCE_FUNCTION_CALLS -#endif /* !__dj_ENFORCE_FUNCTION_CALLS */ - -#endif /* !__dj_include_h_ */ diff --git a/include/crtdll/errno.h b/include/crtdll/errno.h deleted file mode 100644 index a69c3c5..0000000 --- a/include/crtdll/errno.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * errno.h - * - * Error numbers and access to error reporting. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _ERRNO_H_ -#define _ERRNO_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Error numbers. - * TODO: Can't be sure of some of these assignments, I guessed from the - * names given by strerror and the defines in the Cygnus errno.h. A lot - * of the names from the Cygnus errno.h are not represented, and a few - * of the descriptions returned by strerror do not obviously match - * their error naming. - */ -#define EPERM 1 /* Operation not permitted */ -#define ENOFILE 2 /* No such file or directory */ -#define ENOENT 2 -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted function call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Resource temporarily unavailable */ -#define ENOMEM 12 /* Not enough space */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -/* 15 - Unknown Error */ -#define EBUSY 16 /* strerror reports "Resource device" */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Improper link (cross-device link?) */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate I/O control operation */ -/* 26 - Unknown Error */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Domain error (math functions) */ -#define ERANGE 34 /* Result too large (possibly too small) */ -/* 35 - Unknown Error */ -#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */ -#define EDEADLK 36 -/* 37 - Unknown Error */ -#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */ -#define ENOLCK 39 /* No locks available (46 in Cyg?) */ -#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */ -#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ -#define EILSEQ 42 /* Illegal byte sequence */ - -/* - * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the - * sockets.h header provided with windows32api-0.1.2. - * You should go and put an #if 0 ... #endif around the whole block - * of errors (look at the comment above them). - */ - -/* - * Definitions of macros for the 'variables' errno, _doserrno, sys_nerr and - * sys_errlist. - */ -int* _errno(void); -#define errno (*_errno()) - -int* __doserrno(void); -#define _doserrno (*__doserrno()) - -#if __MSVCRT__ -/* One of the MSVCRTxx libraries */ - -extern int* __imp__sys_nerr; -#define sys_nerr (*__imp__sys_nerr) - -extern char** __imp__sys_errlist; -#ifndef sys_errlist -#define sys_errlist (__imp__sys_errlist) -#endif - -#else -/* CRTDLL run time library */ - - -#define _sys_nerr (*_sys_nerr_dll) -extern int* _sys_nerr_dll; -#define sys_nerr (*_sys_nerr_dll) - -extern const char* __sys_errlist[]; -#define sys_errlist (__sys_errlist) - -#endif - - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/excpt.h b/include/crtdll/excpt.h deleted file mode 100644 index a10c909..0000000 --- a/include/crtdll/excpt.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * excpt.h - * - * Support for operating system level structured exception handling. - * - * NOTE: This is very preliminary stuff. I am also pretty sure it is - * completely Intel specific. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * Based on code by Mikey - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _EXCPT_H_ -#define _EXCPT_H_ - -#ifndef __STRICT_ANSI__ - -#include - -/* - * NOTE: The constants structs and typedefs below should be defined in the - * Win32 API headers. - */ -#define EH_NONCONTINUABLE 0x01 -#define EH_UNWINDING 0x02 -#define EH_EXIT_UNWIND 0x04 -#define EH_STACK_INVALID 0x08 -#define EH_NESTED_CALL 0x10 - -#ifndef RC_INVOKED - -typedef enum { - ExceptionContinueExecution, - ExceptionContinueSearch, - ExceptionNestedException, - ExceptionCollidedUnwind -} EXCEPTION_DISPOSITION; - - -/* - * End of stuff that should be in the Win32 API files. - */ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The type of function that is expected as an exception handler to be - * installed with _try1. - */ -typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) - (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); - -/* - * This is not entirely necessary, but it is the structure installed by - * the _try1 primitive below. - */ -typedef struct _EXCEPTION_REGISTRATION -{ - struct _EXCEPTION_REGISTRATION* prev; - PEXCEPTION_HANDLER handler; -} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION; - -typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD; -typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; - -/* - * A macro which installs the supplied exception handler. - * Push the pointer to the new handler onto the stack, - * then push the pointer to the old registration structure (at fs:0) - * onto the stack, then put a pointer to the new registration - * structure (i.e. the current stack pointer) at fs:0. - */ -#define __try1(pHandler) \ - __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (pHandler)); - - -/* - * A macro which (dispite its name) *removes* an installed - * exception handler. Should be used only in conjunction with the above - * install routine __try1. - * Move the pointer to the old reg. struct (at the current stack - * position) to fs:0, replacing the pointer we installed above, - * then add 8 to the stack pointer to get rid of the space we - * used when we pushed on our new reg. struct above. Notice that - * the stack must be in the exact state at this point that it was - * after we did _try1 or this will smash things. - */ -#define __except1 \ - __asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" \ - : : : "%eax"); - -#ifdef __cplusplus -} -#endif - -#endif /* Not RC_INVOKED */ - -#endif /* Not strict ANSI */ - -#endif /* _EXCPT_H_ not defined */ diff --git a/include/crtdll/fcntl.h b/include/crtdll/fcntl.h deleted file mode 100644 index ccb674a..0000000 --- a/include/crtdll/fcntl.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * fcntl.h - * - * Access constants for _open. Note that the permissions constants are - * in sys/stat.h (ick). - * - * This code is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* added _O_RANDOM_O_SEQUENTIAL _O_SHORT_LIVED*/ -/* changed fmode_dll */ - -#ifndef _FCNTL_H_ -#define _FCNTL_H_ - -/* - * It appears that fcntl.h should include io.h for compatibility... - */ -#include - -/* - * This variable determines the default file mode. - * TODO: Which flags work? - */ -#if 0 -#if __MSVCRT__ -extern unsigned int* __imp__fmode; -#define _fmode (*__imp__fmode) -#else -/* CRTDLL */ -extern unsigned int* _fmode_dll; -#define _fmode (*_fmode_dll) -#endif -#endif /* 0 */ - -/* - * NOTE: This is the correct definition to build crtdll. - * It is NOT valid outside of crtdll. - */ -extern unsigned int* _fmode_dll; -extern unsigned int _fmode; - - -/* Specifiy one of these flags to define the access mode. */ -#define _O_RDONLY 0 -#define _O_WRONLY 1 -#define _O_RDWR 2 - -/* Mask for access mode bits in the _open flags. */ -#define _O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) - -#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */ -#define _O_CREAT 0x0100 /* Create the file if it does not exist. */ -#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */ -#define _O_EXCL 0x0400 /* Open only if the file does not exist. */ - -/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */ -#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */ -#define _O_BINARY 0x8000 /* Input and output is not translated. */ -#define _O_RAW _O_BINARY - -#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing. - * WARNING: Even if not created by _open! */ - - -#define _O_RANDOM 0x0010 -#define _O_SEQUENTIAL _O_RANDOM -#define _O_SHORT_LIVED 0x1000 - -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES - -/* POSIX/Non-ANSI names for increased portability */ -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_RDWR _O_RDWR -#define O_ACCMODE _O_ACCMODE -#define O_APPEND _O_APPEND -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC -#define O_EXCL _O_EXCL -#define O_TEXT _O_TEXT -#define O_BINARY _O_BINARY -#define O_TEMPORARY _O_TEMPORARY - -#define O_RANDOM _O_RANDOM -#define O_SEQUENTIAL _O_RANDOM -#define O_SHORT_LIVED _O_SHORT_LIVED - -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -extern "C" { -#endif - -int _setmode (int nHandle, int nAccessMode); - -#ifndef _NO_OLDNAMES -int setmode (int nHandle, int nAccessMode); -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not __STRICT_ANSI__ */ -#endif /* Not _FCNTL_H_ */ diff --git a/include/crtdll/float.h b/include/crtdll/float.h deleted file mode 100644 index 87f8b1c..0000000 --- a/include/crtdll/float.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * float.h - * - * Constants related to floating point arithmetic. - * - * Also included here are some non-ANSI bits for accessing the floating - * point controller. - * - * NOTE: GCC provides float.h, and it is probably more accurate than this, - * but it doesn't include the non-standard stuff for accessing the - * fp controller. (TODO: Move those bits elsewhere?) Thus it is - * probably not a good idea to use the GCC supplied version instead - * of this header. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _FLOAT_H_ -#define _FLOAT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLT_ROUNDS 1 -#define FLT_GUARD 1 -#define FLT_NORMALIZE 1 - -/* - * The characteristics of float. - */ - -/* The radix for floating point representation. */ -#define FLT_RADIX 2 - -/* Decimal digits of precision. */ -#define FLT_DIG 6 - -/* Smallest number such that 1+x != 1 */ -#define FLT_EPSILON 1.19209290e-07F - -/* The number of base FLT_RADIX digits in the mantissa. */ -#define FLT_MANT_DIG 24 - -/* The maximum floating point number. */ -#define FLT_MAX 3.40282347e+38F - -/* Maximum n such that FLT_RADIX^n - 1 is representable. */ -#define FLT_MAX_EXP 128 - -/* Maximum n such that 10^n is representable. */ -#define FLT_MAX_10_EXP 38 - -/* Minimum normalized floating-point number. */ -#define FLT_MIN 1.17549435e-38F - -/* Minimum n such that FLT_RADIX^n is a normalized number. */ -#define FLT_MIN_EXP (-125) - -/* Minimum n such that 10^n is a normalized number. */ -#define FLT_MIN_10_EXP (-37) - - -/* - * The characteristics of double. - */ -#define DBL_DIG 15 -#define DBL_EPSILON 1.1102230246251568e-16 -#define DBL_MANT_DIG 53 -#define DBL_MAX 1.7976931348623157e+308 -#define DBL_MAX_EXP 1024 -#define DBL_MAX_10_EXP 308 -#define DBL_MIN 2.2250738585072014e-308 -#define DBL_MIN_EXP (-1021) -#define DBL_MIN_10_EXP (-307) - - -/* - * The characteristics of long double. - * NOTE: long double is the same as double. - */ -#define LDBL_DIG 15 -#define LDBL_EPSILON 1.1102230246251568e-16L -#define LDBL_MANT_DIG 53 -#define LDBL_MAX 1.7976931348623157e+308L -#define LDBL_MAX_EXP 1024 -#define LDBL_MAX_10_EXP 308 -#define LDBL_MIN 2.2250738585072014e-308L -#define LDBL_MIN_EXP (-1021) -#define LDBL_MIN_10_EXP (-307) - - -/* - * Functions and definitions for controlling the FPU. - */ -#ifndef __STRICT_ANSI__ - -/* TODO: These constants are only valid for x86 machines */ - -/* Control word masks for unMask */ -#define _MCW_EM 0x0008001F /* Error masks */ -#define _MCW_IC 0x00040000 /* Infinity */ -#define _MCW_RC 0x00000300 /* Rounding */ -#define _MCW_PC 0x00030000 /* Precision */ - -/* Control word values for unNew (use with related unMask above) */ -#define _EM_INVALID 0x00000010 -#define _EM_DENORMAL 0x00080000 -#define _EM_ZERODIVIDE 0x00000008 -#define _EM_OVERFLOW 0x00000004 -#define _EM_UNDERFLOW 0x00000002 -#define _EM_INEXACT 0x00000001 -#define _IC_AFFINE 0x00040000 -#define _IC_PROJECTIVE 0x00000000 -#define _RC_CHOP 0x00000300 -#define _RC_UP 0x00000200 -#define _RC_DOWN 0x00000100 -#define _RC_NEAR 0x00000000 -#define _PC_24 0x00020000 -#define _PC_53 0x00010000 -#define _PC_64 0x00000000 - - -/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), - * i.e. change the bits in unMask to have the values they have in unNew, - * leaving other bits unchanged. */ -unsigned int _controlfp (unsigned int unNew, unsigned int unMask); -unsigned int _control87 (unsigned int unNew, unsigned int unMask); - - -unsigned int _clearfp (void); /* Clear the FPU status word */ -unsigned int _statusfp (void); /* Report the FPU status word */ -#define _clear87 _clearfp -#define _status87 _statusfp - -void _fpreset (void); /* Reset the FPU */ - -/* Global 'variable' for the current floating point error code. */ -int * __fpecode(void); -#define _fpecode (*(__fpecode())) - -/* - * IEEE recommended functions - */ - -double _chgsign (double x); -double _copysign (double dTo, double dFrom); -double _logb (double x); -double _nextafter (double x, double y); -double _scalb (double x, long n); - -/* Return values for fpclass. */ -#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ -#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ -#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ -#define _FPCLASS_NN 0x0008 /* Negative Normal */ -#define _FPCLASS_ND 0x0010 /* Negative Denormal */ -#define _FPCLASS_NZ 0x0020 /* Negative Zero */ -#define _FPCLASS_PZ 0x0040 /* Positive Zero */ -#define _FPCLASS_PD 0x0080 /* Positive Denormal */ -#define _FPCLASS_PN 0x0100 /* Positive Normal */ -#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ - -int _finite (double x); -int _fpclass (double x); -int _isnan (double x); -int _isinf (double x); // not exported - -int _isnanl (long double x); // not exported -int _isinfl (long double x); // not exported - -#define isnan(x) _isnan(x) -#define isinf(x) _isinf(x) - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _FLOAT_H_ */ diff --git a/include/crtdll/internal/atexit.h b/include/crtdll/internal/atexit.h deleted file mode 100644 index b3a9f01..0000000 --- a/include/crtdll/internal/atexit.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#ifndef __dj_include_libc_atexit_h__ -#define __dj_include_libc_dosexec_h__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __dj_ENFORCE_ANSI_FREESTANDING - -#ifndef __STRICT_ANSI__ - -#ifndef _POSIX_SOURCE - -struct __atexit { - struct __atexit *__next; - void (*__function)(void); -}; - -extern struct __atexit *__atexit_ptr; - -#endif /* !_POSIX_SOURCE */ -#endif /* !__STRICT_ANSI__ */ -#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */ - -#ifndef __dj_ENFORCE_FUNCTION_CALLS -#endif /* !__dj_ENFORCE_FUNCTION_CALLS */ - -#ifdef __cplusplus -} -#endif - -#endif /* __dj_include_libc_dosexec_h__ */ diff --git a/include/crtdll/internal/file.h b/include/crtdll/internal/file.h deleted file mode 100644 index b058381..0000000 --- a/include/crtdll/internal/file.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ - -#ifndef __dj_include_libc_file_h__ -#define __dj_include_libc_file_h__ - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __dj_ENFORCE_ANSI_FREESTANDING - -#ifndef __STRICT_ANSI__ - -#ifndef _POSIX_SOURCE - -#ifndef _IORMONCL -#define _IORMONCL 004000 /* remove on close, for temp files */ -#endif -/* if _flag & _IORMONCL, ._name_to_remove needs freeing */ - -#ifndef _IOUNGETC -#define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */ -#endif - - -// might need check for IO_APPEND aswell -#define OPEN4WRITING(f) ((((f)->_flag & _IOWRT) == _IOWRT ) ) - -#define OPEN4READING(f) ((((f)->_flag & _IOREAD) == _IOREAD ) ) - -// might need check for IO_APPEND aswell -#define WRITE_STREAM(f) ((((f)->_flag & _IOWRT) == _IOWRT ) ) - -#define READ_STREAM(f) ((((f)->_flag & _IOREAD) == _IOREAD ) ) - - -char __validfp (FILE *f); - -int __set_errno(int err); -void *filehnd(int fn); - -char __is_text_file(FILE *p); - -int __fileno_alloc(void *hFile, int mode); - -int _doprnt(const char *fmt, va_list args, FILE *f); -int _doscan(FILE *iop, const char *fmt, va_list argp); - - -int __fileno_dup2( int handle1, int handle2 ); -int __fileno_setmode(int _fd, int _newmode); -int __fileno_close(int _fd); - -void sigabort_handler(int sig); - -#include - -void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder ); -time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ); - - -#endif /* !_POSIX_SOURCE */ -#endif /* !__STRICT_ANSI__ */ -#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */ - -#ifndef __dj_ENFORCE_FUNCTION_CALLS -#endif /* !__dj_ENFORCE_FUNCTION_CALLS */ - - -#define __FILE_REC_MAX 20 -typedef struct __file_rec -{ - struct __file_rec *next; - int count; - FILE *files[__FILE_REC_MAX]; -} __file_rec; - -extern __file_rec *__file_rec_list; - - -#ifdef __cplusplus -} -#endif - - -#endif /* __dj_include_libc_file_h__ */ - - - diff --git a/include/crtdll/internal/ieee.h b/include/crtdll/internal/ieee.h deleted file mode 100644 index 788908b..0000000 --- a/include/crtdll/internal/ieee.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _IEEE_H -#define _IEEE_H - -typedef struct { - unsigned int mantissa:23; - unsigned int exponent:8; - unsigned int sign:1; -} float_t; - -typedef struct { - unsigned int mantissal:32; - unsigned int mantissah:20; - unsigned int exponent:11; - unsigned int sign:1; -} double_t; - -typedef struct { - unsigned int mantissal:32; - unsigned int mantissah:32; - unsigned int exponent:15; - unsigned int sign:1; - unsigned int empty:16; -} long_double_t; - -#endif diff --git a/include/crtdll/internal/quad.h b/include/crtdll/internal/quad.h deleted file mode 100644 index 339b6db..0000000 --- a/include/crtdll/internal/quad.h +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)quad.h 8.1 (Berkeley) 6/4/93 - * $Id$ - */ - -/* - * Quad arithmetic. - * - * This library makes the following assumptions: - * - * - The type long long (aka quad_t) exists. - * - * - A quad variable is exactly twice as long as `long'. - * - * - The machine's arithmetic is two's complement. - * - * This library can provide 128-bit arithmetic on a machine with 128-bit - * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines - * with 48-bit longs. - */ -#include -//#include - - -typedef unsigned long long u_quad_t; /* quads */ -typedef long long quad_t; -typedef unsigned long u_long; - - - -/* - * Define the order of 32-bit words in 64-bit words. - */ -#define _QUAD_HIGHWORD 1 -#define _QUAD_LOWWORD 0 - -//#include -#include -#include - -/* - * Depending on the desired operation, we view a `long long' (aka quad_t) in - * one or more of the following formats. - */ -union uu { - quad_t q; /* as a (signed) quad */ - quad_t uq; /* as an unsigned quad */ - long sl[2]; /* as two signed longs */ - u_long ul[2]; /* as two unsigned longs */ -}; - -/* - * Define high and low longwords. - */ -#define H _QUAD_HIGHWORD -#define L _QUAD_LOWWORD - -/* - * Total number of bits in a quad_t and in the pieces that make it up. - * These are used for shifting, and also below for halfword extraction - * and assembly. - */ -#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT) -#define LONG_BITS (sizeof(long) * CHAR_BIT) -#define HALF_BITS (sizeof(long) * CHAR_BIT / 2) - -/* - * Extract high and low shortwords from longword, and move low shortword of - * longword to upper half of long, i.e., produce the upper longword of - * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.) - * - * These are used in the multiply code, to split a longword into upper - * and lower halves, and to reassemble a product as a quad_t, shifted left - * (sizeof(long)*CHAR_BIT/2). - */ -#define HHALF(x) ((x) >> HALF_BITS) -#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) -#define LHUP(x) ((x) << HALF_BITS) - -quad_t __divdi3(quad_t a, quad_t b); -quad_t __moddi3(quad_t a, quad_t b); -u_quad_t __qdivrem(u_quad_t u, u_quad_t v, u_quad_t *rem); -u_quad_t __udivdi3(u_quad_t a, u_quad_t b); -u_quad_t __umoddi3(u_quad_t a, u_quad_t b); - -/* - * XXX - * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument - * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use - * both compilers. - */ -#if __GNUC__ >= 2 -typedef unsigned int qshift_t; -#else -typedef u_quad_t qshift_t; -#endif diff --git a/include/crtdll/io.h b/include/crtdll/io.h deleted file mode 100644 index ab0a88f..0000000 --- a/include/crtdll/io.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * io.h - * - * System level I/O functions and types. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* added D_OK */ -/* changed get_osfhandle and open_osfhandle */ -/* added fileno as macro */ -#ifndef _IO_H_ -#define _IO_H_ - -#ifndef __STRICT_ANSI__ - -#include - -#include - - -/* We need the definition of FILE anyway... */ -#include - -/* MSVC's io.h contains the stuff from dir.h, so I will too. - * NOTE: This also defines off_t, the file offset type, through - * and inclusion of sys/types.h */ -#include - -/* TODO: Maximum number of open handles has not been tested, I just set - * it the same as FOPEN_MAX. */ -#define HANDLE_MAX FOPEN_MAX - - -/* Some defines for _access nAccessMode (MS doesn't define them, but - * it doesn't seem to hurt to add them). */ -#define F_OK 0 /* Check for file existence */ -#define W_OK 2 /* Check for write permission */ -#define R_OK 4 /* Check for read permission */ -/* TODO: Is this safe? X_OK not supported directly... */ -#define X_OK R_OK /* Check for execute permission */ -#define D_OK 0x10 - - - -#ifdef __cplusplus -extern "C" { -#endif - -int _access (const char* szFileName, int nAccessMode); -int _chsize (int nHandle, long lnNewSize); -int _close (int nHandle); -int _commit(int _fd); -int _creat (const char* szFileName, int nAccessMode); -int _dup (int nHandle); -int _dup2 (int nOldHandle, int nNewHandle); -long _filelength (int nHandle); -int _fileno (FILE* fileGetHandle); -void* _get_osfhandle (int nHandle); -int _isatty (int nHandle); - -/* In a very odd turn of events this function is excluded from those - * files which define _STREAM_COMPAT. This is required in order to - * build GNU libio because of a conflict with _eof in streambuf.h - * line 107. Actually I might just be able to change the name of - * the enum member in streambuf.h... we'll see. TODO */ -#ifndef _STREAM_COMPAT -int _eof (int nHandle); -#endif - -/* LK_... locking commands defined in sys/locking.h. */ -int _locking (int nHandle, int nCmd, long lnLockRegionLength); - -off_t _lseek(int _fd, off_t _offset, int _whence); -int _open (const char* szFileName, int nFlags, ...); -int _open_osfhandle (void *lnOSHandle, int nFlags); -int _pipe (int *naHandles, unsigned int unSize, int nMode); -size_t _read(int _fd, void *_buf, size_t _nbyte); - -/* SH_... flags for nFlag defined in share.h */ -int _sopen (char* szFileName, int nAccess, int nFlag, int nMode); - -long _tell (int nHandle); -unsigned _umask (unsigned unMode); -int _unlink (const char* szFileName); -size_t _write(int _fd, const void *_buf, size_t _nbyte); - -#ifndef _NO_OLDNAMES -/* - * Non-underscored versions of non-ANSI functions to improve portability. - * These functions live in libmoldname.a. - */ - -#define access _access -#define chsize _chsize -#define close _close -#define creat _creat -#define dup _dup -#define dup2 _dup2 -#define eof _eof -#define filelength _filelength -#define fileno(f) ((f)->_file) -#define isatty _isatty -#define lseek _lseek -#define open _open -#define read _read -#define sopen(path,access,shflag,mode) _open((path), (access)|(shflag), (mode)) -#define tell(file) _lseek(_file, 0, SEEK_CUR) -#define umask _umask -#define unlink _unlink -#define write _write - - -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not strict ANSI */ - -#endif /* _IO_H_ not defined */ diff --git a/include/crtdll/locale.h b/include/crtdll/locale.h deleted file mode 100644 index 8a6e7d4..0000000 --- a/include/crtdll/locale.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * locale.h - * - * Functions and types for localization (ie. changing the appearance of - * output based on the standards of a certain country). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _LOCALE_H_ -#define _LOCALE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * NOTE: I have tried to test this, but I am limited by my knowledge of - * locale issues. The structure does not bomb if you look at the - * values, and 'decimal_point' even seems to be correct. But the - * rest of the values are, by default, not particularly useful - * (read meaningless and not related to the international settings - * of the system). - */ - -#define LC_ALL 0 -#define LC_COLLATE 1 -#define LC_CTYPE 2 -#define LC_MONETARY 3 -#define LC_NUMERIC 4 -#define LC_TIME 5 - -/* - * The structure returned by 'localeconv'. - */ -struct lconv -{ - char* decimal_point; - char* thousands_sep; - char* grouping; - char* int_curr_symbol; - char* currency_symbol; - char* mon_decimal_point; - char* mon_thousands_sep; - char* mon_grouping; - char* positive_sign; - char* negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -}; - -char* setlocale (int nCategory, const char* locale); -struct lconv* localeconv (void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/include/crtdll/malloc.h b/include/crtdll/malloc.h deleted file mode 100644 index 1535929..0000000 --- a/include/crtdll/malloc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * malloc.h - * - * Support for programs which want to use malloc.h to get memory management - * functions. Unless you absolutely need some of these functions and they are - * not in the ANSI headers you should use the ANSI standard header files - * instead. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _MALLOC_H_ -#define _MALLOC_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void * _expand( void *memblock, size_t size ); -int _heapchk (void); /* Verify heap integrety. */ -int _heapmin (void); /* Return unused heap to the OS. */ -int _heapset (unsigned int unFill); -size_t _msize (void* pBlock); - -#ifdef __cplusplus -} -#endif - -#endif /* Not _MALLOC_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/math.h b/include/crtdll/math.h deleted file mode 100644 index 9afe1df..0000000 --- a/include/crtdll/math.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * math.h - * - * Mathematical functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -// added modfl - -#ifndef _MATH_H_ -#define _MATH_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * HUGE_VAL is returned by strtod when the value would overflow the - * representation of 'double'. There are other uses as well. - * - * __imp__HUGE is a pointer to the actual variable _HUGE in - * MSVCRT.DLL. If we used _HUGE directly we would get a pointer - * to a thunk function. - * - * NOTE: The CRTDLL version uses _HUGE_dll instead. - */ -#if __MSVCRT__ -extern double* __imp__HUGE; -#define HUGE_VAL (*__imp__HUGE) -#else -/* CRTDLL */ -extern double* _HUGE_dll; -#define HUGE_VAL (*_HUGE_dll) -#endif - - -struct _exception -{ - int type; - char *name; - double arg1; - double arg2; - double retval; -}; - -/* - * Types for the above _exception structure. - */ - -#define _DOMAIN 1 /* domain error in argument */ -#define _SING 2 /* singularity */ -#define _OVERFLOW 3 /* range overflow */ -#define _UNDERFLOW 4 /* range underflow */ -#define _TLOSS 5 /* total loss of precision */ -#define _PLOSS 6 /* partial loss of precision */ - -/* - * Exception types with non-ANSI names for compatibility. - */ - -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES - -#define DOMAIN _DOMAIN -#define SING _SING -#define OVERFLOW _OVERFLOW -#define UNDERFLOW _UNDERFLOW -#define TLOSS _TLOSS -#define PLOSS _PLOSS - -#endif /* Not _NO_OLDNAMES */ -#endif /* Not __STRICT_ANSI__ */ - - -double sin (double x); -double cos (double x); -double tan (double x); -double sinh (double x); -double cosh (double x); -double tanh (double x); -double asin (double x); -double acos (double x); -double atan (double x); -double atan2 (double y, double x); -double exp (double x); -double log (double x); -double log10 (double x); -double pow (double x, double y); -long double powl (long double x,long double y); -double sqrt (double x); -double ceil (double x); -double floor (double x); -double fabs (double x); -double ldexp (double x, int n); -double frexp (double x, int* exp); -double modf (double x, double* ip); -long double modfl (long double x,long double* ip); -double fmod (double x, double y); - - -#ifndef __STRICT_ANSI__ - -/* Complex number (for cabs) */ -struct _complex -{ - double x; /* Real part */ - double y; /* Imaginary part */ -}; - -double _cabs (struct _complex x); -double _hypot (double x, double y); -double _j0 (double x); -double _j1 (double x); -double _jn (int n, double x); -double _y0 (double x); -double _y1 (double x); -double _yn (int n, double x); - -#ifndef _NO_OLDNAMES - -/* - * Non-underscored versions of non-ANSI functions. These reside in - * liboldnames.a. Provided for extra portability. - */ -double cabs (struct _complex x); -double hypot (double x, double y); -double j0 (double x); -double j1 (double x); -double jn (int n, double x); -double y0 (double x); -double y1 (double x); -double yn (int n, double x); - -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not _MATH_H_ */ - diff --git a/include/crtdll/mbctype.h b/include/crtdll/mbctype.h deleted file mode 100644 index dc34d13..0000000 --- a/include/crtdll/mbctype.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _MBCTYPE_H -#define _MBCTYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -//#define _MS 0x01 -//#define _MP 0x02 -//#define _M1 0x04 -//#define _M2 0x08 - -#define _MBC_SINGLE 0 -#define _MBC_LEAD 1 -#define _MBC_TRAIL 2 -#define _MBC_ILLEGAL -1 - -#define _MB_CP_SBCS 0 -#define _MB_CP_OEM -2 -#define _MB_CP_ANSI -3 -#define _MB_CP_LOCALE -4 - -#define _KNJ_M ((char)0x01) /* Non-punctuation of Kana-set */ -#define _KNJ_P ((char)0x02) /* Punctuation of Kana-set */ -#define _KNJ_1 ((char)0x04) /* Legal 1st byte of double byte stream */ -#define _KNJ_2 ((char)0x08) /* Legal 2nd btye of double byte stream */ - - -#define ___ 0 -#define _1_ _KNJ_1 /* Legal 1st byte of double byte code */ -#define __2 _KNJ_2 /* Legal 2nd byte of double byte code */ -#define _M_ _KNJ_M /* Non-puntuation in Kana-set */ -#define _P_ _KNJ_P /* Punctuation of Kana-set */ -#define _12 (_1_|__2) -#define _M2 (_M_|__2) -#define _P2 (_P_|__2) - -extern char _jctype[257]; - -int _ismbbkana( unsigned char c ); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/mbstring.h b/include/crtdll/mbstring.h deleted file mode 100644 index c0dd474..0000000 --- a/include/crtdll/mbstring.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _MBSTRING_H_ -#define _MBSTRING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -size_t _mbstrlen(const char *str); - - - - -int _mbbtype(unsigned char c, int type); -int _mbsbtype( const unsigned char *str, size_t n ); - -unsigned int _mbbtombc(unsigned int c); -unsigned int _mbctombb(unsigned int c); - -unsigned char * _mbscat(unsigned char *dst, const unsigned char *src); -unsigned char * _mbschr(unsigned char *str, unsigned char* c); -int _mbscmp(const unsigned char *, const unsigned char *); -int _mbscoll(const unsigned char *, const unsigned char *); -unsigned char * _mbscpy(unsigned char *, const unsigned char *); -size_t _mbscspn(const unsigned char *, const unsigned char *); -unsigned char * _mbsdup(const unsigned char *str); -int _mbsicmp(const unsigned char *, const unsigned char *); -int _mbsicoll(const unsigned char *, const unsigned char *); -size_t _mbslen(const unsigned char *str); - -unsigned char * _mbsncat(unsigned char *, const unsigned char *, size_t); -unsigned char * _mbsnbcat(unsigned char *, const unsigned char *, size_t); - - -int _mbsncmp(const unsigned char *, const unsigned char *, size_t); -int _mbsnbcmp(const unsigned char *, const unsigned char *, size_t); - -int _mbsncoll(const unsigned char *, const unsigned char *, size_t); -int _mbsnbcoll(const unsigned char *, const unsigned char *, size_t); - - -unsigned char * _mbsncpy(unsigned char *, const unsigned char *, size_t); -unsigned char * _mbsnbcpy(unsigned char *, const unsigned char *, size_t); - -int _mbsnicmp(const unsigned char *, const unsigned char *, size_t); -int _mbsnbicmp(const unsigned char *, const unsigned char *, size_t); - -int _mbsnicoll(const unsigned char *, const unsigned char *, size_t); -int _mbsnbicoll(const unsigned char *, const unsigned char *, size_t); - -unsigned char * _mbsnset(unsigned char *, unsigned int, size_t); -unsigned char * _mbsnbset(unsigned char *, unsigned int, size_t); - -size_t _mbsnccnt(const unsigned char *, size_t); - - -unsigned char * _mbspbrk(const unsigned char *, const unsigned char *); -unsigned char * _mbsrchr(const unsigned char *, unsigned int); -unsigned char * _mbsrev(unsigned char *); -unsigned char * _mbsset(unsigned char *, unsigned int); -size_t _mbsspn(const unsigned char *, const unsigned char *); - -unsigned char * _mbsstr(const unsigned char *, const unsigned char *); -unsigned char * _mbstok(unsigned char *, unsigned char *); - -unsigned char * _mbslwr(unsigned char *str); -unsigned char * _mbsupr(unsigned char *str); - -size_t _mbclen(const unsigned char *); -void _mbccpy(unsigned char *, const unsigned char *); - -/* tchar routines */ - -unsigned char * _mbsdec(const unsigned char *, const unsigned char *); -unsigned char * _mbsinc(const unsigned char *); -size_t _mbsnbcnt(const unsigned char *, size_t); -unsigned int _mbsnextc (const unsigned char *); -unsigned char * _mbsninc(const unsigned char *, size_t); -unsigned char * _mbsspnp(const unsigned char *, const unsigned char *); - -/* character routines */ - -int _ismbcalnum(unsigned int c); -int _ismbcalpha(unsigned int c); -int _ismbcdigit(unsigned int c); -int _ismbcgraph(unsigned int c); -int _ismbclegal(unsigned int c); -int _ismbclower(unsigned int c); -int _ismbcprint(unsigned int c); -int _ismbcpunct(unsigned int c); -int _ismbcspace(unsigned int c); -int _ismbcupper(unsigned int c); - -unsigned int _mbctolower(unsigned int); -unsigned int _mbctoupper(unsigned int); - - -int _ismbblead( unsigned int c); -int _ismbbtrail( unsigned int c); -int _ismbslead( const unsigned char *s, const unsigned char *c); -int _ismbstrail( const unsigned char *s, const unsigned char *c); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/process.h b/include/crtdll/process.h deleted file mode 100644 index 56f649b..0000000 --- a/include/crtdll/process.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * process.h - * - * Function calls for spawning child processes. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* changed second argument of cwait from nPID to hProc */ - -#ifndef _PROCESS_H_ -#define _PROCESS_H_ - -#ifndef __STRICT_ANSI__ - -#ifdef __cplusplus -extern "C" { -#endif - -void _cexit(void); -void _c_exit(void); - -/* - * Constants for cwait actions. - * Obsolete for Win32. - */ -#define _WAIT_CHILD 0 -#define _WAIT_GRANDCHILD 1 - -#ifndef _NO_OLDNAMES -#define WAIT_CHILD _WAIT_CHILD -#define WAIT_GRANDCHILD _WAIT_GRANDCHILD -#endif /* Not _NO_OLDNAMES */ - -int _cwait (int* pnStatus, int hProc, int nAction); - -int _getpid(void); - -int _execl (const char* szPath, const char* szArgv0, ...); -int _execle (const char* szPath, const char* szArgv0, ...); -int _execlp (const char* szPath, const char* szArgv0, ...); -int _execlpe (const char* szPath, const char* szArgv0, ...); -int _execv (const char* szPath, char* const* szaArgv); -int _execve (const char* szPath, char* const* szaArgv, char* const* szaEnv); -int _execvp (const char* szPath, char* const* szaArgv); -int _execvpe (const char* szPath, char* const* szaArgv, char* const* szaEnv); - - -/* - * Mode constants for spawn functions. - */ -#define _P_WAIT 0 -#define _P_NOWAIT 1 -#define _P_OVERLAY 2 -#define _OLD_P_OVERLAY _P_OVERLAY -#define _P_NOWAITO 3 -#define _P_DETACH 4 - -#ifndef _NO_OLDNAMES -#define P_WAIT _P_WAIT -#define P_NOWAIT _P_NOWAIT -#define P_OVERLAY _P_OVERLAY -#define OLD_P_OVERLAY _OLD_P_OVERLAY -#define P_NOWAITO _P_NOWAITO -#define P_DETACH _P_DETACH -#endif /* Not _NO_OLDNAMES */ - -int _spawnl (int nMode, const char* szPath, const char* szArgv0, ...); -int _spawnle (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnlp (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnlpe (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnv (int nMode, const char* szPath, char* const* szaArgv); -int _spawnve (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); -int _spawnvp (int nMode, const char* szPath, char* const* szaArgv); -int _spawnvpe (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); -/* - * The functions _beginthreadex and _endthreadex are not provided by CRTDLL. - * They are provided by MSVCRT. - * - * NOTE: Apparently _endthread calls CloseHandle on the handle of the thread, - * making for race conditions if you are not careful. Basically you have to - * make sure that no-one is going to do *anything* with the thread handle - * after the thread calls _endthread or returns from the thread function. - * - * NOTE: No old names for these functions. Use the underscore. - */ -unsigned long - _beginthread (void (*pfuncStart)(void *), - unsigned unStackSize, void* pArgList); -void _endthread (void); - -#if __MSVCRT__ -unsigned long - _beginthreadex (void *pSecurity, unsigned unStackSize, - unsigned (*pfuncStart)(void*), void* pArgList, - unsigned unInitFlags, unsigned* pThreadAddr); -void _endthreadex (unsigned unExitCode); -#endif - - -void *_loaddll (char *name); -int _unloaddll(void *handle); - -unsigned long __threadid(void); -#define _threadid __threadid() -void * __threadhandle(void); - - -#ifndef _NO_OLDNAMES - -#define cwait _cwait -#define getpid _getpid -#define execl _execl -#define execle _execle -#define execlp _execlp -#define execlpe _execlpe - -#define execv _execv -#define execve _execve -#define execvp _execvp -#define execvpe _execvpe - -#define spawnl _spawnl -#define spawnle _spawnle -#define spawnlp _spawnlp -#define spawnlpe _spawnlpe - -#define spawnv _spawnv -#define spawnve _spawnve -#define spawnvp _spawnvp -#define spawnvpe _spawnvpe - - -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not __STRICT_ANSI__ */ - -#endif /* _PROCESS_H_ not defined */ diff --git a/include/crtdll/search.h b/include/crtdll/search.h deleted file mode 100644 index c8242c6..0000000 --- a/include/crtdll/search.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef _SEARCH_H_ -#define _SEARCH_H_ - -//char *key -//void *data - -//enum { FIND, ENTER } ACTION; -//enum { preorder, postorder, endorder, leaf } VISIT; - -#include -#include - - -//The Single UNIX ® Specification, Version 2 Copyright © 1997 The Open Group - -//int hcreate(size_t); -//void hdestroy(void); -//ENTRY *hsearch(ENTRY, ACTION); -//void insque(void *, void *); -void *_lfind(const void *, const void *, size_t *, - size_t, int (*)(const void *, const void *)); -void *_lsearch(const void *, void *, size_t *, - size_t, int (*)(const void *, const void *)); -//void remque(void *); -//void *tdelete(const void *, void **, -// int(*)(const void *, const void *)); -//void *tfind(const void *, void *const *, -// int(*)(const void *, const void *)); -//void *tsearch(const void *, void **, -// int(*)(const void *, const void *)); -//void twalk(const void *, -// void (*)(const void *, VISIT, int )); - -#endif diff --git a/include/crtdll/setjmp.h b/include/crtdll/setjmp.h deleted file mode 100644 index 60335dd..0000000 --- a/include/crtdll/setjmp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954 -** -** This file is distributed under the terms listed in the document -** "copying.dj", available from DJ Delorie at the address above. -** A copy of "copying.dj" should accompany this file; if not, a copy -** should be available from where this file was obtained. This file -** may not be distributed without a verbatim copy of "copying.dj". -** -** This file is distributed WITHOUT ANY WARRANTY; without even the implied -** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -*/ - -#ifndef _SETJMP_H_ -#define _SETJMP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned long eax; - unsigned long ebx; - unsigned long ecx; - unsigned long edx; - unsigned long esi; - unsigned long edi; - unsigned long ebp; - unsigned long esp; - unsigned long eip; - unsigned short es; - unsigned short fs; - unsigned short gs; - unsigned short ss; -} jmp_buf[1]; - -extern int _setjmp(jmp_buf); -extern void longjmp(jmp_buf, int); - -#define setjmp(jmp_buf) _setjmp(jmp_buf) - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/crtdll/share.h b/include/crtdll/share.h deleted file mode 100644 index 8e3af3f..0000000 --- a/include/crtdll/share.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _include_share_h_ -#define _include_share_h_ - - -#define SH_COMPAT 0x0000 -#define SH_DENYRW 0x0010 -#define SH_DENYWR 0x0020 -#define SH_DENYRD 0x0030 -#define SH_DENYNO 0x0040 - -#define _SH_COMPAT SH_COMPAT -#define _SH_DENYRW SH_DENYRW -#define _SH_DENYWR SH_DENYWR -#define _SH_DENYRD SH_DENYRD -#define _SH_DENYNO SH_DENYNO - -#endif diff --git a/include/crtdll/signal.h b/include/crtdll/signal.h deleted file mode 100644 index 05b2aac..0000000 --- a/include/crtdll/signal.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * signal.h - * - * A way to set handlers for exceptional conditions (also known as signals). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* added some extra signal constants */ -#ifndef _SIGNAL_H_ -#define _SIGNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The prototypes (below) are the easy part. The hard part is figuring - * out what signals are available and what numbers they are assigned - * along with appropriate values of SIG_DFL and SIG_IGN. - */ - -/* - * A pointer to a signal handler function. A signal handler takes a - * single int, which is the signal it handles. - */ -typedef void (*_p_sig_fn_t)(int nSig); - -/* - * These are special values of signal handler pointers which are - * used to send a signal to the default handler (SIG_DFL), ignore - * the signal (SIG_IGN), or indicate an error return (SIG_ERR). - */ -#define SIG_DFL ((_p_sig_fn_t) 0) -#define SIG_IGN ((_p_sig_fn_t) 1) -#define SIG_ERR ((_p_sig_fn_t) -1) - -/* - * The actual signal values. Using other values with signal - * produces a SIG_ERR return value. - * - * NOTE: SIGINT is produced when the user presses Ctrl-C. - * SIGILL has not been tested. - * SIGFPE doesn't seem to work? - * SIGSEGV does not catch writing to a NULL pointer (that shuts down - * your app; can you say "segmentation violation core dump"?). - * SIGTERM comes from what kind of termination request exactly? - * SIGBREAK is indeed produced by pressing Ctrl-Break. - * SIGABRT is produced by calling abort. - * TODO: The above results may be related to not installing an appropriate - * structured exception handling frame. Results may be better if I ever - * manage to get the SEH stuff down. - */ -#define SIGINT 2 /* Interactive attention */ -#define SIGILL 4 /* Illegal instruction */ -#define SIGFPE 8 /* Floating point error */ -#define SIGSEGV 11 /* Segmentation violation */ -#define SIGTERM 15 /* Termination request */ -#define SIGBREAK 21 /* Control-break */ -#define SIGABRT 22 /* Abnormal termination (abort) */ - -#define SIGALRM 293 -#define SIGHUP 294 -/* SIGINT is ansi */ -#define SIGKILL 296 -#define SIGPIPE 297 -#define SIGQUIT 298 -#define SIGUSR1 299 -#define SIGUSR2 300 - -#define SIGNOFP 301 -#define SIGTRAP 302 -#define SIGTIMR 303 /* Internal for setitimer (SIGALRM, SIGPROF) */ -#define SIGPROF 304 -#define SIGMAX 320 - -/* - * Call signal to set the signal handler for signal sig to the - * function pointed to by handler. Returns a pointer to the - * previous handler, or SIG_ERR if an error occurs. Initially - * unhandled signals defined above will return SIG_DFL. - */ -_p_sig_fn_t signal(int sig, _p_sig_fn_t func); - -/* - * Raise the signal indicated by sig. Returns non-zero on success. - */ -int raise (int sig); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/stdarg.h b/include/crtdll/stdarg.h deleted file mode 100644 index 82656c6..0000000 --- a/include/crtdll/stdarg.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * stdarg.h - * - * Provides facilities for stepping through a list of function arguments of - * an unknown number and type. - * - * NOTE: Gcc should provide stdarg.h, and I believe their version will work - * with crtdll. If necessary I think you can replace this with the GCC - * stdarg.h (or is it vararg.h). - * - * Note that the type used in va_arg is supposed to match the actual type - * *after default promotions*. Thus, va_arg (..., short) is not valid. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ - -#ifndef _STDARG_H_ -#define _STDARG_H_ - -/* - * Don't do any of this stuff for the resource compiler. - */ -#ifndef RC_INVOKED - -/* - * I was told that Win NT likes this. - */ -#ifndef _VA_LIST_DEFINED -#define _VA_LIST_DEFINED -#endif - -#ifndef _VA_LIST -#define _VA_LIST -typedef char* va_list; -#endif - - -/* - * Amount of space required in an argument list (ie. the stack) for an - * argument of type t. - */ -#define __va_argsiz(t) \ - (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) - - -/* - * Start variable argument list processing by setting AP to point to the - * argument after pN. - */ -#ifdef __GNUC__ -/* - * In GNU the stack is not necessarily arranged very neatly in order to - * pack shorts and such into a smaller argument list. Fortunately a - * neatly arranged version is available through the use of __builtin_next_arg. - */ -#define va_start(ap, pN) \ - ((ap) = ((va_list) __builtin_next_arg(pN))) -#else -/* - * For a simple minded compiler this should work (it works in GNU too for - * vararg lists that don't follow shorts and such). - */ -#define va_start(ap, pN) \ - ((ap) = ((va_list) (&pN) + __va_argsiz(pN))) -#endif - - -/* - * End processing of variable argument list. In this case we do nothing. - */ -#define va_end(ap) ((void)0) - - -/* - * Increment ap to the next argument in the list while returing a - * pointer to what ap pointed to first, which is of type t. - * - * We cast to void* and then to t* because this avoids a warning about - * increasing the alignment requirement. - */ - -#define va_arg(ap, t) \ - (((ap) = (ap) + __va_argsiz(t)), \ - *((t*) (void*) ((ap) - __va_argsiz(t)))) - -#endif /* Not RC_INVOKED */ - -#endif /* not _STDARG_H_ */ diff --git a/include/crtdll/stddef.h b/include/crtdll/stddef.h deleted file mode 100644 index 6a614b7..0000000 --- a/include/crtdll/stddef.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * stddef.h - * - * Standard type definitions provided by the C library. - * - * NOTE: Actually supplied by the compiler (correct?). As such, GCC - * supplies a version of this header file. Unfortunately, GCC's - * version is all tied up with the way other headers for the - * GNU C library are implemented (or vice-versa), in a similar - * way to how the other Mingw32 headers are dependent on - * certain internals of this file. It is not clear to me whether - * you can safely use the GCC version in place of this version. - * TODO: Line up usage in other header files to work with GCC - * stddef.h. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - - -#ifndef __CRTDLL_STDDEF_H_ - -/* - * Any one of these symbols __need_* means that a standard header file - * wants us just to define one data type. So don't define - * the symbols that indicate this file's entire job has been done. - */ -#if (!defined(__need_wchar_t) && !defined(__need_wint_t) \ - && !defined(__need_size_t) && !defined(__need_ptrdiff_t) \ - && !defined(__need_NULL)) -#define __CRTDLL_STDDEF_H_ -#endif - -/* - * NOTE: The following typedefs are done using __xxx_TYPE__ defines followed - * by typedefs using those defines. I have chosen to do it this way because - * GCC supplies definitions for __xxx_TYPE__ macros and if, for example, your - * size_t is typedef'ed differently from what GCC expects it will give you - * warnings when you prototype functions like memcmp and memcpy. The values - * for __xxx_TYPE__ in this header file are the same as those given by GCC. - * Those values appear to work with the CRTDLL functions. - */ - -/* - * Signed type of difference of two pointers. - */ - -/* Define this type if we are doing the whole job, or if we want this type - * in particular. */ -#if defined (__CRTDLL_STDDEF_H_) || defined (__need_ptrdiff_t) - -#ifndef _PTRDIFF_T_ -#define _PTRDIFF_T_ -#ifndef __PTRDIFF_TYPE__ -#define __PTRDIFF_TYPE__ int -#endif -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#endif - -/* If this symbol has done its job, get rid of it. */ -#undef __need_ptrdiff_t - -#endif /* __CRTDLL_STDDEF_H_ or __need_ptrdiff_t. */ - -/* - * Unsigned type of `sizeof' something. - */ - - -/* Define this type if we are doing the whole job, - * or if we want this type in particular. */ -#if defined (__CRTDLL_STDDEF_H_) || defined (__need_size_t) - -#ifndef _SIZE_T_ -#define _SIZE_T_ -#define SIZE_T_DEFINED -#define _SIZE_T -#ifndef __SIZE_TYPE__ -#define __SIZE_TYPE__ unsigned int -#endif -typedef __SIZE_TYPE__ size_t; -#endif - -#undef __need_size_t - -#endif /* __CRTDLL_STDDEF_H_ or __need_size_t. */ - -/* Wide character type. - Locale-writers should change this as necessary to - be big enough to hold unique values not between 0 and 127, - and not (wchar_t) -1, for each defined multibyte character. */ - -/* Define this type if we are doing the whole job, - or if we want this type in particular. */ -#if defined (__CRTDLL_STDDEF_H_) || defined (__need_wchar_t) - -#ifndef _WCHAR_T_ -#define _WCHAR_T_ -#define _WCHAR_T -#ifndef __WCHAR_TYPE__ -#define __WCHAR_TYPE__ short unsigned int -#endif -#ifndef __cplusplus -typedef __WCHAR_TYPE__ wchar_t; -#endif /* C++ */ -#endif /* wchar_t not already defined */ - -#undef __need_wchar_t - -#endif /* __CRTDLL_STDDEF_H_ or __need_wchar_t. */ - -/* - * wint_t, the equivalent of int in wchar ctype functions. - */ -#if defined (__CRTDLL_STDDEF_H_) || defined (__need_wint_t) - -#ifndef _WINT_T_ -#define _WINT_T_ -#define _WINT_T /* To satisfy libstdc++ */ -#ifndef __WINT_TYPE__ -#define __WINT_TYPE__ short int -#endif /* Not defined __WINT_TYPE__ */ - -typedef __WINT_TYPE__ wint_t; -#endif /* Not defined _WINT_T_ */ - -#undef __need_wint_t - -#endif /* __CRTDLL_STDDEF_H_ or __need_wint_t. */ - - -/* - * A null pointer constant. - */ - -#if defined (__CRTDLL_STDDEF_H_) || defined (__need_NULL) - -#undef NULL -#define NULL (0) -#endif /* __CRTDLL_STDDEF_H_ or __need_NULL */ - -#undef __need_NULL - - -/* - * Offsetof, a macro for finding the offset of a member in a structure. - * Works by returning the 'address' of the MEMBER of a TYPE struct at address - * zero. - */ - -#if defined (__CRTDLL_STDDEF_H_) -#define offsetof(TYPE, MEMBER) ((size_t) &( ((TYPE *) 0)->MEMBER )) -#endif /* __CRTDLL_STDDEF_H_ */ - - -#endif /* not __CRTDLL__CRTDLL_STDDEF_H_ */ diff --git a/include/crtdll/stdio.h b/include/crtdll/stdio.h deleted file mode 100644 index acdc2e4..0000000 --- a/include/crtdll/stdio.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * stdio.h - * - * Definitions of types and prototypes of functions for standard input and - * output. - * - * NOTE: The file manipulation functions provided by Microsoft seem to - * work with either slash (/) or backslash (\) as the path separator. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* implemented clearerr feof ferror perror as macros */ -/* added _IOCOMMIT */ -/* added filbuf and flsbuf and fwalk */ - -#ifndef _STDIO_H_ -#define _STDIO_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define __need_size_t -#define __need_NULL -#define __need_wchar_t -#define __need_wint_t -#include - - -/* Some flags for the iobuf structure provided by djgpp stdio.h */ -#define _IOREAD 0x000010 -#define _IOWRT 0x000020 -#define _IOMYBUF 0x000040 -#define _IOEOF 0x000100 -#define _IOERR 0x000200 -#define _IOSTRG 0x000400 - -#define _IOAPPEND 0x002000 -#define _IORMONCL 0x004000 /* remove on close, for temp files */ -/* if _flag & _IORMONCL, ._name_to_remove needs freeing */ -#define _IOUNGETC 0x010000 /* there is an ungetc'ed character in the buffer */ -#define _IOCOMMIT 0x008000 - -#define _IODIRTY 0x000080 -#define _IOAHEAD 0x000008 -#define _IORW (_IOREAD | _IOWRITE ) - - -/* - * I used to include stdarg.h at this point, in order to allow for the - * functions later on in the file which use va_list. That conflicts with - * using stdio.h and varargs.h in the same file, so I do the typedef myself. - */ -//#ifndef _VA_LIST -//#define _VA_LIST -//typedef char* va_list; -//#endif -#include - -/* - * FILE should be used as a pointer to an opaque data type. Do not rely on - * anything else, especially the size or contents of this structure! - */ -#ifndef _FILE_DEFINED -typedef struct { - char *_ptr; - int _cnt; - char *_base; - int _flag; - int _file; - int _ungotchar; - int _bufsiz; - char *_name_to_remove; -} FILE; -#define _FILE_DEFINED -#endif - -//#define _fillsize _bufsiz - -/* - * The three standard file pointers provided by the run time library. - * NOTE: These will go to the bit-bucket silently in GUI applications! - */ -extern FILE _iob[]; /* an array of FILE */ -#define stdin (&_iob[0]) -#define stdout (&_iob[1]) -#define stderr (&_iob[2]) -#define stdaux (&_iob[3]) -#define stdprn (&_iob[4]) - -/* Returned by various functions on end of file condition or error. */ -#define EOF (-1) - - -/* - * The maximum length of a file name. You should use GetVolumeInformation - * instead of this constant. But hey, this works. - * - * NOTE: This is used in the structure _finddata_t (see dir.h) so changing it - * is probably not a good idea. - */ -#define FILENAME_MAX (260) - -/* - * The maximum number of files that may be open at once. I have set this to - * a conservative number. The actual value may be higher. - */ -#define FOPEN_MAX (20) - - -/* - * File Operations - */ - -FILE* fopen (const char* szFileName, const char* szMode); -FILE* freopen (const char* szNewFileName, const char* szNewMode, - FILE* fileChangeAssociation); -int fflush (FILE* fileFlush); -int fclose (FILE* fileClose); -#define fcloseall _fcloseall -int remove (const char* szFileName); -int rename (const char* szOldFileName, const char* szNewFileName); -FILE* tmpfile (void); - -int _filbuf(FILE *f); -int _flsbuf(int c, FILE *f); -void _fwalk(void (*func)(FILE *)); // not exported -int _fcloseall( void ); - - -/* - * The maximum size of name (including NUL) that will be put in the user - * supplied buffer caName. - * NOTE: This has not been determined by experiment, but based on the - * maximum file name length above it is probably reasonable. I could be - * wrong... - */ -#define L_tmpnam (260) - -char* tmpnam (char caName[]); -char* _tempnam (const char *szDir, const char *szPfx); - -#ifndef _NO_OLDNAMES -#define tempnam _tempnam -#endif /* Not _NO_OLDNAMES */ - -/* - * The three possible buffering mode (nMode) values for setvbuf. - * NOTE: _IOFBF works, but _IOLBF seems to work like unbuffered... - * maybe I'm testing it wrong? - */ -#define _IOFBF 0 /* fully buffered */ -#define _IOLBF 1 /* line buffered */ -#define _IONBF 2 /* unbuffered */ - -int setvbuf (FILE* fileSetBuffer, char* caBuffer, int nMode, - size_t sizeBuffer); - - -/* - * The buffer size as used by setbuf such that it is equivalent to - * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ). - */ -#define BUFSIZ 512 - -void setbuf (FILE* fileSetBuffer, char* caBuffer); - -/* - * Pipe Operations - */ - -int _pclose (FILE* pipeClose); -FILE* _popen (const char* szPipeName, const char* szMode); - -#define popen _popen -#define pclose _pclose - -/* Wide character version */ -FILE* _wpopen (const wchar_t* szPipeName, const wchar_t* szMode); - -/* - * Formatted Output - */ - -int fprintf (FILE* filePrintTo, const char* szFormat, ...); -int printf (const char* szFormat, ...); -int sprintf (char* caBuffer, const char* szFormat, ...); -int vfprintf (FILE* filePrintTo, const char* szFormat, va_list varg); -int vprintf (const char* szFormat, va_list varg); -int vsprintf (char* caBuffer, const char* szFormat, va_list varg); - -/* Wide character versions */ -int fwprintf (FILE* filePrintTo, const wchar_t* wsFormat, ...); -int wprintf (const wchar_t* wsFormat, ...); -int swprintf (wchar_t* wcaBuffer, const wchar_t* wsFormat, ...); -int vfwprintf (FILE* filePrintTo, const wchar_t* wsFormat, va_list varg); -int vwprintf (const wchar_t* wsFormat, va_list varg); -int vswprintf (wchar_t* wcaBuffer, const wchar_t* wsFormat, va_list varg); - -/* - * Formatted Input - */ - -int fscanf (FILE* fileReadFrom, const char* szFormat, ...); -int scanf (const char* szFormat, ...); -int sscanf (const char* szReadFrom, const char* szFormat, ...); - -/* Wide character versions */ -int fwscanf (FILE* fileReadFrom, const wchar_t* wsFormat, ...); -int wscanf (const wchar_t* wsFormat, ...); -int swscanf (const wchar_t* wsReadFrom, const wchar_t* wsFormat, ...); - -/* - * Character Input and Output Functions - */ - -int fgetc (FILE* fileRead); -char* fgets (char* caBuffer, int nBufferSize, FILE* fileRead); -int fputc (int c, FILE* fileWrite); -int fputs (const char* szOutput, FILE* fileWrite); -int getc (FILE* fileRead); -int getchar (void); -char* gets (char* caBuffer); /* Unsafe: how does gets know how long the - * buffer is? */ -int putc (int c, FILE* fileWrite); -int putchar (int c); -int puts (const char* szOutput); -int ungetc (int c, FILE* fileWasRead); - -/* Wide character versions */ -wint_t fgetwc (FILE* fileRead); -wint_t fputwc (wchar_t wc, FILE* fileWrite); -wint_t getwc(FILE *fileRead); // not exported -wint_t ungetwc (wchar_t wc, FILE* fileWasRead); - -wint_t _filwbuf(FILE *f); -wint_t _flswbuf(wchar_t c, FILE *f); - -/* - * Not exported by CRTDLL.DLL included for reference purposes. - */ -#if 0 -wchar_t* fgetws (wchar_t* wcaBuffer, int nBufferSize, FILE* fileRead); -int fputws (const wchar_t* wsOutput, FILE* fileWrite); -int getwc (FILE* fileRead); -int getwchar (); -wchar_t* getws (wchar_t* wcaBuffer); -int putwc (wchar_t wc, FILE* fileWrite); -int putws (const wchar_t* wsOutput); -#endif /* 0 */ - -/* NOTE: putchar has no wide char equivalent even in tchar.h */ - - -/* - * Direct Input and Output Functions - */ - -size_t fread (void* pBuffer, size_t sizeObject, size_t sizeObjCount, - FILE* fileRead); -size_t fwrite (const void* pObjArray, size_t sizeObject, size_t sizeObjCount, - FILE* fileWrite); - - -/* - * File Positioning Functions - */ - -/* Constants for nOrigin indicating the position relative to which fseek - * sets the file position. Enclosed in ifdefs because io.h could also - * define them. (Though not anymore since io.h includes this file now.) */ -#ifndef SEEK_SET -#define SEEK_SET (0) -#endif - -#ifndef SEEK_CUR -#define SEEK_CUR (1) -#endif - -#ifndef SEEK_END -#define SEEK_END (2) -#endif - -int fseek (FILE* fileSetPosition, long lnOffset, int nOrigin); -long ftell (FILE* fileGetPosition); -void rewind (FILE* fileRewind); - -/* - * An opaque data type used for storing file positions... The contents of - * this type are unknown, but we (the compiler) need to know the size - * because the programmer using fgetpos and fsetpos will be setting aside - * storage for fpos_t structres. Actually I tested using a byte array and - * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). - * Perhaps an unsigned long? TODO? - */ -typedef long fpos_t; - -int fgetpos (FILE* fileGetPosition, fpos_t* pfpos); -int fsetpos (FILE* fileSetPosition, const fpos_t* pfpos); - - -/* - * Error Functions - */ -#if 0 -void clearerr (FILE* fileClearErrors); -int feof (FILE* fileIsAtEnd); -int ferror (FILE* fileIsError); -void perror (const char* szErrorMessage); - -#endif - -#define clearerr(f) (((f)->_flag) &= ~(_IOERR|_IOEOF)) -#define feof(f) (((f)->_flag&_IOEOF)!=0) -#define ferror(f) (((f)->_flag&_IOERR)!=0) -#define perror(s) (fprintf(stderr, "%s: %s\n", (s), _strerror(NULL))) -/* - * Non ANSI functions - */ - -#ifndef __STRICT_ANSI__ -int _fgetchar (void); -int _fputchar (int c); -FILE* _fdopen (int nHandle, char* szMode); - -#ifndef _NO_OLDNAMES -#define fgetchar _fgetchar -#define fputchar _fputchar -#define fdopen _fdopen -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _STDIO_H_ */ diff --git a/include/crtdll/stdlib.h b/include/crtdll/stdlib.h deleted file mode 100644 index 22bfede..0000000 --- a/include/crtdll/stdlib.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * stdlib.h - * - * Definitions for common types, variables, and functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* added splitpath */ -/* changed definition of environ and argc */ -/* moved prototype for swab from string.h to stdlib.h */ -#ifndef _STDLIB_H_ -#define _STDLIB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This seems like a convenient place to declare these variables, which - * give programs using WinMain (or main for that matter) access to main-ish - * argc and argv. environ is a pointer to a table of environment variables. - * NOTE: Strings in _argv and environ are ANSI strings. - */ -extern int* __argc_dll; -extern char*** __argv_dll; -extern char*** _environ_dll; -#define __argc (*__argc_dll) -#define __argv (*__argv_dll) -#define _environ (*_environ_dll) - - -#define __need_size_t -#define __need_wchar_t -#define __need_NULL -#include - -#include - -#ifndef __ATTRIB_NORETURN -#ifdef __GNUC__ -#define _ATTRIB_NORETURN __attribute__ ((noreturn)) -#else /* Not __GNUC__ */ -#define _ATTRIB_NORETURN -#endif /* __GNUC__ */ -#endif - -double atof (const char* szNumber); -int atoi (const char* szNumber); -long atol (const char* szNumber); - - -double strtod (const char* szNumber, char** pszAfterNumber); -double wcstod (const wchar_t* wsNumber, wchar_t** pwsAfterNumber); -long strtol (const char* szNumber, char** pszAfterNumber, int nBase); -long wcstol (const wchar_t* wsNumber, wchar_t** pwsAfterNumber, int nBase); - -unsigned long strtoul (const char* szNumber, char** pszAfterNumber, - int nBase); -unsigned long wcstoul (const wchar_t* wsNumber, wchar_t** pwsAfterNumber, - int nBase); - -size_t wcstombs (char* mbsDest, const wchar_t* wsConvert, size_t size); -int wctomb (char* mbDest, wchar_t wc); - -int mblen (const char* mbs, size_t sizeString); -size_t mbstowcs (wchar_t* wcaDest, const char* mbsConvert, - size_t size); -int mbtowc (wchar_t* wcDest, const char* mbConvert, size_t size); - - -/* - * RAND_MAX is the maximum value that may be returned by rand. - * The minimum is zero. - */ -#define RAND_MAX 0x7FFF - -int rand (void); -void srand (unsigned int nSeed); - - -void* calloc (size_t sizeObjCnt, size_t sizeObject); -void* malloc (size_t sizeObject); -void* realloc (void* pObject, size_t sizeNew); -void free (void* pObject); - -/* These values may be used as exit status codes. */ -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE -1 - -void abort (void) _ATTRIB_NORETURN; -void exit (int nStatus) _ATTRIB_NORETURN; -int atexit (void (*pfuncExitProcessing)(void)); - -int system (const char* szCommand); // impl in process -char* getenv (const char* szVarName); // impl in stdio - -typedef int (*_pfunccmp_t)(const void*, const void*); - -void* bsearch (const void* pKey, const void* pBase, size_t cntObjects, - size_t sizeObject, _pfunccmp_t pfuncCmp); -void qsort (const void* pBase, size_t cntObjects, size_t sizeObject, - _pfunccmp_t pfuncCmp); - -int abs (int n); -long labs (long n); - -/* - * div_t and ldiv_t are structures used to return the results of div and - * ldiv. - * - * NOTE: div and ldiv appear not to work correctly unless - * -fno-pcc-struct-return is specified. This is included in the - * mingw32 specs file. - */ -typedef struct { int quot, rem; } div_t; -typedef struct { long quot, rem; } ldiv_t; -typedef struct { long long quot, rem; } lldiv_t; - -div_t div (int nNumerator, int nDenominator); -ldiv_t ldiv (long lNumerator, long lDenominator); -lldiv_t lldiv (long long lNumerator, long long lDenominator); - - -#ifndef __STRICT_ANSI__ - -/* - * NOTE: Officially the three following functions are obsolete. The Win32 API - * functions SetErrorMode, Beep and Sleep are their replacements. - */ -void _beep (unsigned int, unsigned int); -void _seterrormode (int nMode); -void _sleep (unsigned long ulTime); - -void _exit (int nStatus) _ATTRIB_NORETURN; - -int _putenv (const char* szNameEqValue); -void _searchenv (const char* szFileName, const char* szVar, - char* szFullPathBuf); - -void _splitpath( const char *path, char *drive, char *dir, - char *fname, char *ext ); - -char* _itoa (int nValue, char* sz, int nRadix); -char* _ltoa (long lnValue, char* sz, int nRadix); - -char* _ecvt (double dValue, int nDig, int* pnDec, int* pnSign); -char* _fcvt (double dValue, int nDig, int* pnDec, int* pnSign); -char* _gcvt (double dValue, int nDec, char* caBuf); - -char* _fullpath (char* caBuf, const char* szPath, size_t sizeMax); - -void _swab (const char* caFrom, char* caTo, size_t sizeToCopy); - -unsigned int _rotl( unsigned int value, int shift ); -unsigned int _rotr( unsigned int value, int shift ); -unsigned long _lrotl( unsigned long value, int shift ); -unsigned long _lrotr( unsigned long value, int shift ); - - - - -#ifndef _NO_OLDNAMES -#define beep _beep -#define seterrormode _seterrormode -#define sleep _sleep -#define putenv _putenv -#define searchenv _searchenv -#define splitpath _splitpath - -#define itoa _itoa -#define ltoa _ltoa - -#define ecvt _ecvt -#define fcvt _fcvt -#define gcvt _gcvt - -#define swab _swab -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ - -/* - * Undefine the no return attribute used in some function definitions - */ -#undef _ATTRIB_NORETURN - -#ifdef __cplusplus -} -#endif - -#endif /* _STDLIB_H_ */ diff --git a/include/crtdll/string.h b/include/crtdll/string.h deleted file mode 100644 index 77dab36..0000000 --- a/include/crtdll/string.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * string.h - * - * Definitions for memory and string functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -/* changed prototype for _strerror */ -/* moved prototype for swab from string.h to stdlib.h */ - - -#ifndef _STRING_H_ -#define _STRING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Define size_t, wchar_t and NULL - */ -#define __need_size_t -#define __need_wchar_t -#define __need_NULL -#include - -char * ___strtok; // removed extern specifier 02-06-98, BD - -/* - * Prototypes of the ANSI Standard C library string functions. - */ -void* memchr (const void* p, int cSearchFor, size_t sizeSearch); -int memcmp (const void* p1, const void* p2, size_t sizeSearch); -void* memcpy (void* pCopyTo, const void* pSource, size_t sizeSource); -void* memmove (void* pMoveTo, const void* pSource, size_t sizeSource); -void* memset (void* p, int cFill, size_t sizeRepeatCount); -char* strcat (char* szAddTo, const char* szAdd); -char* strchr (const char* szSearch, int cFor); -int strcmp (const char* sz1, const char* sz2); -int strcoll (const char* sz1, const char* sz2); /* Compare using locale */ -char* strcpy (char* szCopyTo, const char* szSource); -size_t strcspn (const char* szGetPrefix, const char* szNotIncluding); -char* strerror (int nError); /* NOTE: NOT an old name wrapper. */ -char * _strerror(const char *s); -size_t strlen (const char* sz); -size_t strnlen (const char* sz, size_t count); // not exported -char* strncat (char* szAddTo, const char* szAdd, size_t sizeMaxAdd); -int strncmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -char* strncpy (char* szCopyTo, const char* szSource, size_t sizeMaxCopy); -char* strpbrk (const char* szSearch, const char* szAnyOf); -char* strrchr (const char* szSearch, int cFor); -size_t strspn (const char* szGetPrefix, const char *szIncluding); -char* strstr (const char* szSearch, const char *szFor); -char* strtok (char* szTokenize, const char* szDelimiters); -size_t strxfrm (char* szTransformed, const char *szSource, - size_t sizeTransform); - -#ifndef __STRICT_ANSI__ -/* - * Extra non-ANSI functions provided by the CRTDLL library - */ -void* _memccpy (void* pCopyTo, const void* pSource, int cTerminator, - size_t sizeMaxCopy); -int _memicmp (const void* p1, const void* p2, size_t sizeSearch); -char* _strdup (const char *szDuplicate); -int _strcmpi (const char* sz1, const char* sz2); -int _stricmp (const char* sz1, const char* sz2); -int _stricoll (const char* sz1, const char* sz2); -char* _strlwr (char* szToConvert); -int _strnicmp (const char* sz1, const char* sz2, - size_t sizeMaxCompare); -char* _strnset (char* szToFill, int cFill, size_t sizeMaxFill); -char* _strrev (char* szToReverse); -char* _strset (char* szToFill, int cFill); -char* _strupr (char* szToConvert); - - -#endif /* Not __STRICT_ANSI__ */ - - -/* - * Unicode versions of the standard calls. - */ -wchar_t* wcscat (wchar_t* wsAddTo, const wchar_t* wsAdd); -wchar_t* wcschr (const wchar_t* wsSearch, wchar_t wcFor); -int wcscmp (const wchar_t* ws1, const wchar_t* ws2); -int wcscoll (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcscpy (wchar_t* wsCopyTo, const wchar_t* wsSource); -size_t wcscspn (const wchar_t* wsGetPrefix, const wchar_t* wsNotIncluding); -/* Note: No wcserror in CRTDLL. */ -size_t wcslen (const wchar_t* ws); -wchar_t* wcsncat (wchar_t* wsAddTo, const wchar_t* wsAdd, size_t sizeMaxAdd); -int wcsncmp(const wchar_t* ws1, const wchar_t* ws2, size_t sizeMaxCompare); -wchar_t* wcsncpy(wchar_t* wsCopyTo, const wchar_t* wsSource, - size_t sizeMaxCopy); -wchar_t* wcspbrk(const wchar_t* wsSearch, const wchar_t* wsAnyOf); -wchar_t* wcsrchr(const wchar_t* wsSearch, wchar_t wcFor); -size_t wcsspn(const wchar_t* wsGetPrefix, const wchar_t* wsIncluding); -wchar_t* wcsstr(const wchar_t* wsSearch, const wchar_t* wsFor); -wchar_t* wcstok(wchar_t* wsTokenize, const wchar_t* wsDelimiters); -size_t wcsxfrm(wchar_t* wsTransformed, const wchar_t *wsSource, - size_t sizeTransform); - - -#ifndef __STRICT_ANSI__ -/* - * Unicode versions of non-ANSI functions provided by CRTDLL. - */ - -/* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */ -#define _wcscmpi _wcsicmp - -wchar_t* _wcsdup (const wchar_t* wsToDuplicate); -int _wcsicmp (const wchar_t* ws1, const wchar_t* ws2); -int _wcsicoll (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* _wcslwr (wchar_t* wsToConvert); -int _wcsnicmp (const wchar_t* ws1, const wchar_t* ws2, - size_t sizeMaxCompare); -wchar_t* _wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); -wchar_t* _wcsrev (wchar_t* wsToReverse); -wchar_t* _wcsset (wchar_t* wsToFill, wchar_t wcToFill); -wchar_t* _wcsupr (wchar_t* wsToConvert); - -#endif /* Not __STRICT_ANSI__ */ - - -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES - -/* - * Non-underscored versions of non-ANSI functions. They live in liboldnames.a - * and provide a little extra portability. Also a few extra UNIX-isms like - * strcasecmp. - */ - -void* memccpy (void* pCopyTo, const void* pSource, int cTerminator, - size_t sizeMaxCopy); -int memicmp (const void* p1, const void* p2, size_t sizeSearch); -#define strdup(szDuplicate) _strdup(szDuplicate) -int strcmpi (const char* sz1, const char* sz2); -int stricmp (const char* sz1, const char* sz2); -int strcasecmp (const char* sz1, const char* sz2); -int stricoll (const char* sz1, const char* sz2); -char* strlwr (char* szToConvert); -int strnicmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -int strncasecmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -char* strnset (char* szToFill, int cFill, size_t sizeMaxFill); -char* strrev (char* szToReverse); -char* strset (char* szToFill, int cFill); -char* strupr (char* szToConvert); - - -/* NOTE: There is no _wcscmpi, but this is for compatibility. */ -int wcscmpi (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcsdup (const wchar_t* wsToDuplicate); -int wcsicmp (const wchar_t* ws1, const wchar_t* ws2); -int wcsicoll (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcslwr (wchar_t* wsToConvert); -int wcsnicmp (const wchar_t* ws1, const wchar_t* ws2, - size_t sizeMaxCompare); -wchar_t* wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); -wchar_t* wcsrev (wchar_t* wsToReverse); -wchar_t* wcsset (wchar_t* wsToFill, wchar_t wcToFill); -wchar_t* wcsupr (wchar_t* wsToConvert); - -#endif /* Not _NO_OLDNAMES */ -#endif /* Not strict ANSI */ - -#endif - -#ifdef __cplusplus -}; /* extern "c" */ -#endif diff --git a/include/crtdll/sys/fcntl.h b/include/crtdll/sys/fcntl.h deleted file mode 100644 index 4f83933..0000000 --- a/include/crtdll/sys/fcntl.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * This file is part of the Mingw32 package. - * - * This fcntl.h maps to the root fcntl.h - */ -#ifndef __STRICT_ANSI__ -#include -#endif diff --git a/include/crtdll/sys/file.h b/include/crtdll/sys/file.h deleted file mode 100644 index 4497725..0000000 --- a/include/crtdll/sys/file.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * This file is part of the Mingw32 package. - * - * This file.h maps to the root fcntl.h - * TODO? - */ -#ifndef __STRICT_ANSI__ -#include -#endif diff --git a/include/crtdll/sys/locking.h b/include/crtdll/sys/locking.h deleted file mode 100644 index d279c6d..0000000 --- a/include/crtdll/sys/locking.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * locking.h - * - * Constants for the mode parameter of the locking function. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _LOCKING_H_ -#define _LOCKING_H_ - -/* - * TODO: Define LK_... constants. - */ - -#endif /* Not _LOCKING_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/sys/stat.h b/include/crtdll/sys/stat.h deleted file mode 100644 index 8ea94f2..0000000 --- a/include/crtdll/sys/stat.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * stat.h - * - * Symbolic constants for opening and creating files, also stat, fstat and - * chmod functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _STAT_H_ -#define _STAT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Constants for the stat st_mode member. - */ -#define S_IFIFO 0x1000 /* FIFO */ -#define S_IFCHR 0x2000 /* Character */ -#define S_IFBLK 0x3000 /* Block */ -#define S_IFDIR 0x4000 /* Directory */ -#define S_IFREG 0x8000 /* Regular */ - -#define S_IFMT 0xF000 /* File type mask */ - -#define S_IEXEC 0x0040 -#define S_IWRITE 0x0080 -#define S_IREAD 0x0100 - -#define S_ISDIR(m) ((m) & S_IFDIR) -#define S_ISFIFO(m) ((m) & S_IFIFO) -#define S_ISCHR(m) ((m) & S_IFCHR) -#define S_ISBLK(m) ((m) & S_IFBLK) -#define S_ISREG(m) ((m) & S_IFREG) - -#define S_IRWXU (S_IREAD | S_IWRITE | S_IEXEC) -#define S_IXUSR S_IEXEC -#define S_IWUSR S_IWRITE -#define S_IRUSR S_IREAD - -#define _S_IEXEC S_IEXEC -#define _S_IREAD S_IREAD -#define _S_IWRITE S_IWRITE - -/* - * The structure manipulated and returned by stat and fstat. - * - * NOTE: If called on a directory the values in the time fields are not only - * invalid, they will cause localtime et. al. to return NULL. And calling - * asctime with a NULL pointer causes an Invalid Page Fault. So watch it! - */ -struct stat -{ - short st_dev; /* Equivalent to drive number 0=A 1=B ... */ - short st_ino; /* Always zero ? */ - short st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - int st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - short st_rdev; /* Seems useless (not even filled in) */ - long st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ -}; - - -int _fstat (int nFileNo, struct stat* pstat); -int _chmod (const char* szPath, int nMode); -int _stat (const char* szPath, struct stat* pstat); - - -#ifndef _NO_OLDNAMES - -#define fstat(nFileNo, pstat) _fstat(nFileNo, pstat) -#define chmod(szPath,nMode) _chmod(szPath,nMode) -#define stat(szPath,pstat) _stat(szPath,pstat) - -#endif /* Not _NO_OLDNAMES */ - - -#ifdef __cplusplus -} -#endif - -#endif /* Not _STAT_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/sys/time.h b/include/crtdll/sys/time.h deleted file mode 100644 index deffe97..0000000 --- a/include/crtdll/sys/time.h +++ /dev/null @@ -1,3 +0,0 @@ - -#include - diff --git a/include/crtdll/sys/timeb.h b/include/crtdll/sys/timeb.h deleted file mode 100644 index 85e57ed..0000000 --- a/include/crtdll/sys/timeb.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * timeb.h - * - * Support for the UNIX System V ftime system call. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _TIMEB_H_ -#define _TIMEB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * TODO: Structure not tested. - */ -struct timeb -{ - long time; - short millitm; - short _timezone; - short dstflag; -}; - -/* TODO: Not tested. */ -void _ftime (struct timeb* timebBuffer); - -#ifndef _NO_OLDNAMES -void ftime (struct timeb* timebBuffer); -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not _TIMEB_H_ */ - -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/sys/types.h b/include/crtdll/sys/types.h deleted file mode 100644 index bafdbac..0000000 --- a/include/crtdll/sys/types.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * types.h - * - * The definition of constants, data types and global variables. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warrenties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _TYPES_H_ -#define _TYPES_H_ - -#ifndef _TIME_T_ -#define _TIME_T_ -typedef long time_t; -#endif - - -#ifndef __STRICT_ANSI__ - -#ifndef _OFF_T_DEFINED -typedef long _off_t; - -#ifndef _NO_OLDNAMES -#define off_t _off_t -#endif - -#define _OFF_T_DEFINED - -#endif /* Not _OFF_T_DEFINED */ - - -#ifndef _DEV_T_DEFINED -typedef short _dev_t; - -#ifndef _NO_OLDNAMES -#define dev_t _dev_t -#endif - -#define _DEV_T_DEFINED - -#endif /* Not _DEV_T_DEFINED */ - - -#ifndef _INO_T_DEFINED -typedef short _ino_t; - -#ifndef _NO_OLDNAMES -#define ino_t _ino_t -#endif - -#define _INO_T_DEFINED - -#endif /* Not _INO_T_DEFINED */ - - -#endif /* Not __STRICT_ANSI__ */ - - -#endif /* Not _TYPES_H_ */ diff --git a/include/crtdll/sys/unistd.h b/include/crtdll/sys/unistd.h deleted file mode 100644 index 63cbb45..0000000 --- a/include/crtdll/sys/unistd.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * This file is part of the Mingw32 package. - * - * unistd.h maps (roughly) to io.h - */ -#ifndef __STRICT_ANSI__ -#include -#endif - diff --git a/include/crtdll/sys/utime.h b/include/crtdll/sys/utime.h deleted file mode 100644 index f355e7e..0000000 --- a/include/crtdll/sys/utime.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * utime.h - * - * Support for the utime function. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef __STRICT_ANSI__ - -#ifndef _UTIME_H_ -#define _UTIME_H_ - -#define __need_wchar_t -#define __need_size_t -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Structure used by _utime function. - */ -struct _utimbuf -{ - time_t actime; /* Access time */ - time_t modtime; /* Modification time */ -}; - -int _utime (const char* szFileName, struct _utimbuf* pTimes); -int _futime (int nHandle, struct _utimbuf *pTimes); - -/* Wide character version */ -int _wutime (const wchar_t *szFileName, struct _utimbuf *times); - -#ifndef _NO_OLDNAMES - -/* NOTE: Must be the same as _utimbuf above. */ -struct utimbuf -{ - time_t actime; - time_t modtime; -}; - -int utime (const char* szFileName, struct utimbuf* pTimes); - -#endif /* Not _NO_OLDNAMES */ - - -#ifdef __cplusplus -} -#endif - -#endif /* Not _UTIME_H_ */ -#endif /* Not __STRICT_ANSI__ */ diff --git a/include/crtdll/tchar.h b/include/crtdll/tchar.h deleted file mode 100644 index 9dc3ab4..0000000 --- a/include/crtdll/tchar.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * tchar.h - * - * Unicode mapping layer for the standard C library. By including this - * file and using the 't' names for string functions - * (eg. _tprintf) you can make code which can be easily adapted to both - * Unicode and non-unicode environments. In a unicode enabled compile define - * _UNICODE before including tchar.h, otherwise the standard non-unicode - * library functions will be used. - * - * Note that you still need to include string.h or stdlib.h etc. to define - * the appropriate functions. Also note that there are several defines - * included for non-ANSI functions which are commonly available (but using - * the convention of prepending an underscore to non-ANSI library function - * names). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _TCHAR_H_ -#define _TCHAR_H_ - -/* - * NOTE: This tests _UNICODE, which is different from the UNICODE define - * used to differentiate Win32 API calls. - */ -#ifdef _UNICODE - - -/* - * Use TCHAR instead of char or wchar_t. It will be appropriately translated - * if _UNICODE is correctly defined (or not). - */ -#ifndef _TCHAR_DEFINED -#ifndef RC_INVOKED -typedef wchar_t TCHAR; -#endif /* Not RC_INVOKED */ -#define _TCHAR_DEFINED -#endif - - -/* - * Enclose constant strings and literal characters in the _TEXT and _T macro to make - * them unicode constant strings when _UNICODE is defined. - */ -#define _TEXT(x) L ## x -#define _T(x) L ## x - -/* - * Unicode functions - */ - -#define _tprintf wprintf -#define _ftprintf fwprintf -#define _stprintf swprintf -#define _sntprintf _snwprintf -#define _vtprintf vwprintf -#define _vftprintf vfwprintf -#define _vstprintf vswprintf -#define _vsntprintf _vsnwprintf -#define _tscanf wscanf -#define _ftscanf fwscanf -#define _stscanf swscanf -#define _fgettc fgetwc -#define _fgettchar _fgetwchar -#define _fgetts fgetws -#define _fputtc fputwc -#define _fputtchar _fputwchar -#define _fputts fputws -#define _gettc getwc -#define _getts getws -#define _puttc putwc -#define _putts putws -#define _ungettc ungetwc -#define _tcstod wcstod -#define _tcstol wcstol -#define _tcstoul wcstoul -#define _tcscat wcscat -#define _tcschr wcschr -#define _tcscmp wcscmp -#define _tcscpy wcscpy -#define _tcscspn wcscspn -#define _tcslen wcslen -#define _tcsncat wcsncat -#define _tcsncmp wcsncmp -#define _tcsncpy wcsncpy -#define _tcspbrk wcspbrk -#define _tcsrchr wcsrchr -#define _tcsspn wcsspn -#define _tcsstr wcsstr -#define _tcstok wcstok -#define _tcsdup _wcsdup -#define _tcsicmp _wcsicmp -#define _tcsnicmp _wcsnicmp -#define _tcsnset _wcsnset -#define _tcsrev _wcsrev -#define _tcsset _wcsset -#define _tcslwr _wcslwr -#define _tcsupr _wcsupr -#define _tcsxfrm wcsxfrm -#define _tcscoll wcscoll -#define _tcsicoll _wcsicoll -#define _istalpha iswalpha -#define _istupper iswupper -#define _istlower iswlower -#define _istdigit iswdigit -#define _istxdigit iswxdigit -#define _istspace iswspace -#define _istpunct iswpunct -#define _istalnum iswalnum -#define _istprint iswprint -#define _istgraph iswgraph -#define _istcntrl iswcntrl -#define _istascii iswascii -#define _totupper towupper -#define _totlower towlower -#define _ttoi _wtoi -#define _tcsftime wcsftime - -#else /* Not _UNICODE */ - -/* - * TCHAR, the type you should use instead of char. - */ -#ifndef _TCHAR_DEFINED -#ifndef RC_INVOKED -typedef char TCHAR; -#endif -#define _TCHAR_DEFINED -#endif - -/* - * Enclose constant strings and characters in the _TEXT and _T macro. - */ -#define _TEXT(x) x -#define _T(x) x - - -/* - * Non-unicode (standard) functions - */ - -#define _tprintf printf -#define _ftprintf fprintf -#define _stprintf sprintf -#define _sntprintf _snprintf -#define _vtprintf vprintf -#define _vftprintf vfprintf -#define _vstprintf vsprintf -#define _vsntprintf _vsnprintf -#define _tscanf scanf -#define _ftscanf fscanf -#define _stscanf sscanf -#define _fgettc fgetc -#define _fgettchar _fgetchar -#define _fgetts fgets -#define _fputtc fputc -#define _fputtchar _fputchar -#define _fputts fputs -#define _gettc getc -#define _getts gets -#define _puttc putc -#define _putts puts -#define _ungettc ungetc -#define _tcstod strtod -#define _tcstol strtol -#define _tcstoul strtoul -#define _tcscat strcat -#define _tcschr strchr -#define _tcscmp strcmp -#define _tcscpy strcpy -#define _tcscspn strcspn -#define _tcslen strlen -#define _tcsncat strncat -#define _tcsncmp strncmp -#define _tcsncpy strncpy -#define _tcspbrk strpbrk -#define _tcsrchr strrchr -#define _tcsspn strspn -#define _tcsstr strstr -#define _tcstok strtok -#define _tcsdup _strdup -#define _tcsicmp _stricmp -#define _tcsnicmp _strnicmp -#define _tcsnset _strnset -#define _tcsrev _strrev -#define _tcsset _strset -#define _tcslwr _strlwr -#define _tcsupr _strupr -#define _tcsxfrm strxfrm -#define _tcscoll strcoll -#define _tcsicoll _stricoll -#define _istalpha isalpha -#define _istupper isupper -#define _istlower islower -#define _istdigit isdigit -#define _istxdigit isxdigit -#define _istspace isspace -#define _istpunct ispunct -#define _istalnum isalnum -#define _istprint isprint -#define _istgraph isgraph -#define _istcntrl iscntrl -#define _istascii isascii -#define _totupper toupper -#define _totlower tolower -#define _ttoi atoi -#define _tcsftime strftime - -#endif /* Not _UNICODE */ - -#endif /* Not _TCHAR_H_ */ - diff --git a/include/crtdll/time.h b/include/crtdll/time.h deleted file mode 100644 index ede0f82..0000000 --- a/include/crtdll/time.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * time.h - * - * Date and time functions and types. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ -/* Appropriated for Reactos Crtdll by Ariadne */ -#ifndef _TIME_H_ -#define _TIME_H_ - -#define __need_wchar_t -#define __need_size_t -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Number of clock ticks per second. A clock tick is the unit by which - * processor time is measured and is returned by 'clock'. - */ -#define CLOCKS_PER_SEC 1000.0 -#define CLK_TICK CLOCKS_PER_SEC - -/* - * A type for measuring processor time (in clock ticks). - */ -#ifndef _CLOCK_T_ -#define _CLOCK_T_ -typedef long clock_t; -#endif - -/* - * Need a definition of time_t. - */ -#include - -/* - * A type for storing the current time and date. This is the number of - * seconds since midnight Jan 1, 1970. - * NOTE: Normally this is defined by the above include of sys/types.h - */ -#ifndef _TIME_T_ -#define _TIME_T_ -typedef long time_t; -#endif - -/* - * A structure for storing all kinds of useful information about the - * current (or another) time. - */ -struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - char *tm_zone; - int tm_gmtoff; -}; - - - -clock_t clock (void); -time_t time (time_t* tp); -double difftime (time_t t2, time_t t1); -time_t mktime (struct tm* tmsp); - -/* - * These functions write to and return pointers to static buffers that may - * be overwritten by other function calls. Yikes! - * - * NOTE: localtime, and perhaps the others of the four functions grouped - * below may return NULL if their argument is not 'acceptable'. Also note - * that calling asctime with a NULL pointer will produce an Invalid Page - * Fault and crap out your program. Guess how I know. Hint: stat called on - * a directory gives 'invalid' times in st_atime etc... - */ -char* asctime (const struct tm* tmsp); -char* ctime (const time_t* tp); -struct tm* gmtime (const time_t* tm); -struct tm* localtime (const time_t* tm); - - -size_t strftime (char* caBuffer, size_t sizeMax, const char* szFormat, - const struct tm* tpPrint); - -size_t wcsftime (wchar_t* wcaBuffer, size_t sizeMax, - const wchar_t* wsFormat, const struct tm* tpPrint); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/crtdll/wchar.h b/include/crtdll/wchar.h deleted file mode 100644 index eadb63d..0000000 --- a/include/crtdll/wchar.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * wchar.h - * - * Defines of all functions for supporting wide characters. Actually it - * just includes all those headers, which is not a good thing to do from a - * processing time point of view, but it does mean that everything will be - * in sync. - * - * This file is part of the Mingw32 package. - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#include -#include -#include -#include -#include - diff --git a/include/csrss/csrss.h b/include/csrss/csrss.h index 4b1115a..d13ece7 100644 --- a/include/csrss/csrss.h +++ b/include/csrss/csrss.h @@ -311,6 +311,31 @@ typedef struct DWORD Length; } CSRSS_PEEK_CONSOLE_INPUT_REPLY, *PCSRSS_PEEK_CONSOLE_INPUT_REPLY; +typedef struct +{ + HANDLE ConsoleHandle; + COORD BufferSize; + COORD BufferCoord; + SMALL_RECT ReadRegion; + CHAR_INFO* CharInfo; +} CSRSS_READ_CONSOLE_OUTPUT_REQUEST, *PCSRSS_READ_CONSOLE_OUTPUT_REQUEST; + +typedef struct +{ + SMALL_RECT ReadRegion; +} CSRSS_READ_CONSOLE_OUTPUT_REPLY, *PCSRSS_READ_CONSOLE_OUTPUT_REPLY; + +typedef struct +{ + HANDLE ConsoleHandle; + DWORD Length; + INPUT_RECORD* InputRecord; +} CSRSS_WRITE_CONSOLE_INPUT_REQUEST, *PCSRSS_WRITE_CONSOLE_INPUT_REQUEST; + +typedef struct +{ + DWORD Length; +} CSRSS_WRITE_CONSOLE_INPUT_REPLY, *PCSRSS_WRITE_CONSOLE_INPUT_REPLY; #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \ (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST)) @@ -364,7 +389,8 @@ typedef struct #define CSRSS_GET_SHUTDOWN_PARAMETERS (0x1F) #define CSRSS_SET_SHUTDOWN_PARAMETERS (0x20) #define CSRSS_PEEK_CONSOLE_INPUT (0x21) - +#define CSRSS_READ_CONSOLE_OUTPUT (0x22) +#define CSRSS_WRITE_CONSOLE_INPUT (0x23) /* Keep in sync with definition below. */ #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE) + sizeof(ULONG)) @@ -406,6 +432,8 @@ typedef struct CSRSS_EXIT_REACTOS_REQUEST ExitReactosRequest; CSRSS_SHUTDOWN_PARAMETERS SetShutdownParametersRequest; CSRSS_PEEK_CONSOLE_INPUT_REQUEST PeekConsoleInputRequest; + CSRSS_READ_CONSOLE_OUTPUT_REQUEST ReadConsoleOutputRequest; + CSRSS_WRITE_CONSOLE_INPUT_REQUEST WriteConsoleInputRequest; } Data; } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST; @@ -434,6 +462,8 @@ typedef struct CSRSS_GET_NUM_INPUT_EVENTS_REPLY GetNumInputEventsReply; CSRSS_SHUTDOWN_PARAMETERS GetShutdownParametersReply; CSRSS_PEEK_CONSOLE_INPUT_REPLY PeekConsoleInputReply; + CSRSS_READ_CONSOLE_OUTPUT_REPLY ReadConsoleOutputReply; + CSRSS_WRITE_CONSOLE_INPUT_REPLY WriteConsoleInputReply; } Data; } CSRSS_API_REPLY, *PCSRSS_API_REPLY; diff --git a/include/ddk/af_irda.h b/include/ddk/af_irda.h new file mode 100644 index 0000000..0a6433f --- /dev/null +++ b/include/ddk/af_irda.h @@ -0,0 +1,221 @@ +/* + * af_irda.h + * + * IrDa ports interface + * + * This file is part of the MinGW package. + * + * Contributors: + * Created by Robert Dickenson + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __AF_IRDA_H +#define __AF_IRDA_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + + +/* GUIDs */ + +#ifdef DEFINE_GUID +DEFINE_GUID(GUID_DEVINTERFACE_IRDAPORT, + 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x74); +DEFINE_GUID(GUID_DEVINTERFACE_IRDAENUM_BUS_ENUMERATOR, + 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x19); +#endif // DEFINE_GUID + +#define WINDOWS_AF_IRDA 26 +#define WINDOWS_PF_IRDA WINDOWS_AF_IRDA + +#ifndef AF_IRDA +#define AF_IRDA WINDOWS_AF_IRDA +#endif + +#define IRDA_PROTO_SOCK_STREAM 1 +#define PF_IRDA AF_IRDA +#define SOL_IRLMP 0x00FF +#define SIO_LAZY_DISCOVERY _IOR('t', 127, ULONG) + + +#define IAS_MAX_USER_STRING 256 +#define IAS_MAX_OCTET_STRING 1024 +#define IAS_MAX_CLASSNAME 64 +#define IAS_MAX_ATTRIBNAME 256 + +#define IAS_ATTRIB_NO_CLASS ((ULONG)0x10) +#define IAS_ATTRIB_NO_ATTRIB ((ULONG)0x00) +#define IAS_ATTRIB_INT ((ULONG)0x01) +#define IAS_ATTRIB_OCTETSEQ ((ULONG)0x02) +#define IAS_ATTRIB_STR ((ULONG)0x03) + +#define IRLMP_ENUMDEVICES ((ULONG)0x10) +#define IRLMP_IAS_SET ((ULONG)0x11) +#define IRLMP_IAS_QUERY ((ULONG)0x12) +#define IRLMP_SEND_PDU_LEN ((ULONG)0x13) +#define IRLMP_EXCLUSIVE_MODE ((ULONG)0x14) +#define IRLMP_IRLPT_MODE ((ULONG)0x15) +#define IRLMP_9WIRE_MODE ((ULONG)0x16) + +#if 0 +// Available/Used on Windows 98 only ??? +#define IRLMP_TINYTP_MODE ((ULONG)0x17) +#define IRLMP_PARAMETERS ((ULONG)0x18) +#define IRLMP_DISCOVERY_MODE ((ULONG)0x19) +// Available/Used on Windows CE only ??? +#define IRLMP_SHARP_MODE ((ULONG)0x20) +#endif + +enum { +// First hint byte + LM_HB1_PnP = 0x01, + LM_HB1_PDA_Palmtop = 0x02, + LM_HB1_Computer = 0x04, + LM_HB1_Printer = 0x08, + LM_HB1_Modem = 0x10, + LM_HB1_Fax = 0x20, + LM_HB1_LANAccess = 0x40, +// Second hint byte + LM_HB2_Telephony = 0x01, + LM_HB2_FileServer = 0x02, +// Any hint byte + LM_HB_Extension = 0x80, +}; + +#define LmCharSetASCII 0x00 +#define LmCharSetISO_8859_1 0x01 +#define LmCharSetISO_8859_2 0x02 +#define LmCharSetISO_8859_3 0x03 +#define LmCharSetISO_8859_4 0x04 +#define LmCharSetISO_8859_5 0x05 +#define LmCharSetISO_8859_6 0x06 +#define LmCharSetISO_8859_7 0x07 +#define LmCharSetISO_8859_8 0x08 +#define LmCharSetISO_8859_9 0x09 +#define LmCharSetUNICODE 0xFF + +#define LM_BAUD_1200 1200 +#define LM_BAUD_2400 2400 +#define LM_BAUD_9600 9600 +#define LM_BAUD_19200 19200 +#define LM_BAUD_38400 38400 +#define LM_BAUD_57600 57600 +#define LM_BAUD_115200 115200 +#define LM_BAUD_576K 576000 +#define LM_BAUD_1152K 1152000 +#define LM_BAUD_4M 4000000 + +#if 0 // Available/Used on Windows 98 only ??? +typedef ULONG LM_BAUD_RATE; +typedef struct { + ULONG nTXDataBytes; // packet transmit receive bytes + ULONG nRXDataBytes; // packet maximum receive bytes + LM_BAUD_RATE nBaudRate; // link negotiated baud + ULONG thresholdTime; // milliseconds for threshold time + ULONG discTime; // milliseconds for disconnect time + USHORT nMSLinkTurn; // milliseconds for link turn around time + UCHAR nTXPackets; // transmit window packets + UCHAR nRXPackets; // receive window packets +} LM_IRPARMS; +typedef LM_IRPARMS *PLM_IRPARMS; +#endif + +typedef struct _SOCKADDR_IRDA { + USHORT irdaAddressFamily; + UCHAR irdaDeviceID[4]; + char irdaServiceName[25]; +} SOCKADDR_IRDA; + +typedef struct _WINDOWS_IRDA_DEVICE_INFO { + UCHAR irdaDeviceID[4]; + char irdaDeviceName[22]; + UCHAR irdaDeviceHints1; + UCHAR irdaDeviceHints2; + UCHAR irdaCharSet; +} WINDOWS_IRDA_DEVICE_INFO; + +typedef struct _WINDOWS_IAS_SET { + char irdaClassName[IAS_MAX_CLASSNAME]; + char irdaAttribName[IAS_MAX_ATTRIBNAME]; + ULONG irdaAttribType; + union { + LONG irdaAttribInt; + struct { + USHORT Len; + UCHAR OctetSeq[IAS_MAX_OCTET_STRING]; + } irdaAttribOctetSeq; + struct { + UCHAR Len; + UCHAR CharSet; + UCHAR UsrStr[IAS_MAX_USER_STRING]; + } irdaAttribUsrStr; + } irdaAttribute; +} WINDOWS_IAS_SET; + +typedef struct _WINDOWS_IAS_QUERY { + UCHAR irdaDeviceID[4]; + char irdaClassName[IAS_MAX_CLASSNAME]; + char irdaAttribName[IAS_MAX_ATTRIBNAME]; + ULONG irdaAttribType; + union { + LONG irdaAttribInt; + struct { + ULONG Len; + UCHAR OctetSeq[IAS_MAX_OCTET_STRING]; + } irdaAttribOctetSeq; + struct { + ULONG Len; + ULONG CharSet; + UCHAR UsrStr[IAS_MAX_USER_STRING]; + } irdaAttribUsrStr; + } irdaAttribute; +} WINDOWS_IAS_QUERY; + +typedef struct _WINDOWS_DEVICELIST { + ULONG numDevice; + WINDOWS_IRDA_DEVICE_INFO Device[1]; +} WINDOWS_DEVICELIST; + +typedef WINDOWS_DEVICELIST DEVICELIST; +typedef WINDOWS_DEVICELIST *PDEVICELIST; +typedef WINDOWS_DEVICELIST *PWINDOWS_DEVICELIST; + +typedef WINDOWS_IRDA_DEVICE_INFO IRDA_DEVICE_INFO; +typedef WINDOWS_IRDA_DEVICE_INFO *PIRDA_DEVICE_INFO; +typedef WINDOWS_IRDA_DEVICE_INFO *PWINDOWS_IRDA_DEVICE_INFO; + +typedef WINDOWS_IAS_SET IAS_SET; +typedef WINDOWS_IAS_SET *PIAS_SET; +typedef WINDOWS_IAS_SET *PWINDOWS_IAS_SET; + +typedef WINDOWS_IAS_QUERY IAS_QUERY; +typedef WINDOWS_IAS_QUERY *PIAS_QUERY; +typedef WINDOWS_IAS_QUERY *PWINDOWS_IAS_QUERY; + +typedef SOCKADDR_IRDA *PSOCKADDR_IRDA; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __AF_IRDA_H */ diff --git a/include/ddk/cctypes.h b/include/ddk/cctypes.h index bd3f0ac..4d61ef8 100644 --- a/include/ddk/cctypes.h +++ b/include/ddk/cctypes.h @@ -15,7 +15,7 @@ typedef struct _CC_FILE_SIZES } CC_FILE_SIZES, *PCC_FILE_SIZES; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PCC_POST_DEFERRED_WRITE)(IN PVOID Context1, IN PVOID Context2); @@ -37,18 +37,18 @@ typedef VOID (*PDIRTY_PAGE_ROUTINE) ( IN PVOID Context2 ); -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PACQUIRE_FOR_LAZY_WRITE)(IN PVOID Context, IN BOOLEAN Wait); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PRELEASE_FROM_LAZY_WRITE)(IN PVOID Context); -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PACQUIRE_FOR_READ_AHEAD)(IN PVOID Context, IN BOOLEAN Wait); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PRELEASE_FROM_READ_AHEAD)(IN PVOID Context); typedef struct _CACHE_MANAGER_CALLBACKS @@ -69,7 +69,7 @@ typedef struct _SECTION_OBJECT_POINTERS } SECTION_OBJECT_POINTERS, *PSECTION_OBJECT_POINTERS; */ -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PFLUSH_TO_LSN)(IN PVOID LogHandle, IN LARGE_INTEGER Lsn); diff --git a/include/ddk/cmfuncs.h b/include/ddk/cmfuncs.h deleted file mode 100644 index fee65aa..0000000 --- a/include/ddk/cmfuncs.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * FUNCTION: Creates a registry key - * ARGUMENTS: - * KeyHandle (OUT) = Caller supplied storage for the resulting handle - * DesiredAccess = Specifies the allowed or desired access to the key - * It can have a combination of the following values: - * KEY_READ | KEY_WRITE | KEY_EXECUTE | KEY_ALL_ACCESS - * or - * KEY_QUERY_VALUE The values of the key can be queried. - * KEY_SET_VALUE The values of the key can be modified. - * KEY_CREATE_SUB_KEYS The key may contain subkeys. - * KEY_ENUMERATE_SUB_KEYS Subkeys can be queried. - * KEY_NOTIFY - * KEY_CREATE_LINK A symbolic link to the key can be created. - * ObjectAttributes = The name of the key may be specified directly in the name field - * of object attributes or relative to a key in rootdirectory. - * TitleIndex = Might specify the position in the sequential order of subkeys. - * Class = Specifies the kind of data, for example REG_SZ for string data. [ ??? ] - * CreateOptions = Specifies additional options with which the key is created - * REG_OPTION_VOLATILE The key is not preserved across boots. - * REG_OPTION_NON_VOLATILE The key is preserved accross boots. - * REG_OPTION_CREATE_LINK The key is a symbolic link to another key. - * REG_OPTION_BACKUP_RESTORE Key is being opened or created for backup/restore operations. - * Disposition = Indicates if the call to NtCreateKey resulted in the creation of a key it - * can have the following values: REG_CREATED_NEW_KEY | REG_OPENED_EXISTING_KEY - * RETURNS: - * Status - */ - -NTSTATUS STDCALL -NtCreateKey(OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class OPTIONAL, - IN ULONG CreateOptions, - IN PULONG Disposition OPTIONAL); - -NTSTATUS STDCALL -ZwCreateKey(OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class OPTIONAL, - IN ULONG CreateOptions, - IN PULONG Disposition OPTIONAL); - diff --git a/include/ddk/cmtypes.h b/include/ddk/cmtypes.h index a9af321..e1c1ac4 100644 --- a/include/ddk/cmtypes.h +++ b/include/ddk/cmtypes.h @@ -1,4 +1,5 @@ - +#ifndef __INCLUDE_DDK_CMTYPES_H +#define __INCLUDE_DDK_CMTYPES_H /* * Object Manager structures and typedefs */ @@ -98,3 +99,4 @@ typedef struct _KEY_VALUE_ENTRY ULONG Type; } KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY; +#endif /* __INCLUDE_DDK_CMTYPES_H */ diff --git a/include/ddk/defines.h b/include/ddk/defines.h index ea65d82..392afe0 100644 --- a/include/ddk/defines.h +++ b/include/ddk/defines.h @@ -7,7 +7,7 @@ #define _WIN32_WINNT 0x0400 -#include +#include #include #define EXPORTED __declspec(dllexport) @@ -40,130 +40,7 @@ enum PagedPool, PagedPoolCacheAligned, }; - -/* - * This is a list of bug check types (not MS's) - */ -enum -{ - APC_INDEX_MISMATCH = 1, - DEVICE_QUEUE_NOT_BUSY, - INVALID_AFFINITY_SET, - INVALID_DATA_ACCESS_TRAP, - INVALID_PROCESS_ATTACH_ATTEMPT, - INVALID_PROCESS_DEATTACH_ATTEMPT, - INVALID_SOFTWARE_INTERRUPT, - IRQL_NOT_DISPATCH_LEVEL, - IRQL_NOT_GREATER_OR_EQUAL, - NO_EXCEPTION_HANDLING_SUPPORT, - MAXIMUM_WAIT_OBJECTS_EXCEEDED, - MUTEX_LEVEL_NUMBER_VIOLATION, - NO_USER_MODE_CONTEXT, - SPIN_LOCK_ALREADY_OWNED, - SPIN_LOCK_NOT_OWNED, - THREAD_NOT_MUTEX_OWNER, - TRAP_CAUSE_UNKNOWN, - EMPTY_THREAD_REAPER_LIST, - CREATE_DELETE_LOCK_NOT_LOCKED, - LAST_CHANCE_CALLED_FROM_KMODE, - CID_HANDLE_CREATION, - CID_HANDLE_DELETION, - REFERENCE_BY_POINTER, - BAD_POOL_HEADER, - MEMORY_MANAGMENT, - PFN_SHARE_COUNT, - PFN_REFERENCE_COUNT, - NO_SPIN_LOCK_AVAILABLE, - KMODE_EXCEPTION_NOT_HANDLED, - SHARED_RESOURCE_CONV_ERROR, - KERNEL_APC_PENDING_DURING_EXIT, - QUOTA_UNDERFLOW, - FILE_SYSTEM, - FAT_FILE_SYSTEM, - NTFS_FILE_SYSTEM, - NPFS_FILE_SYSTEM, - CDFS_FILE_SYSTEM, - RDR_FILE_SYSTEM, - CORRUPT_ACCESS_TOKEN, - SECURITY_SYSTEM, - INCONSISTENT_IRP, - PANIC_STACK_SWITCH, - PORT_DRIVER_INTERNAL, - SCSI_DISK_DRIVER_INTERNAL, - INSTRUCTION_BUS_ERROR, - SET_OF_INVALID_CONTEXT, - PHASE0_INITIALIZATION_FAILED, - PHASE1_INITIALIZATION_FAILED, - UNEXPECTED_INITIALIZATION_CALL, - CACHE_MANAGER, - NO_MORE_IRP_STACK_LOCATIONS, - DEVICE_REFERENCE_COUNT_NOT_ZERO, - FLOPPY_INTERNAL_ERROR, - SERIAL_DRIVER_INTERNAL, - SYSTEM_EXIT_OWNED_MUTEX, - SYSTEM_UNWIND_PREVIOUS_USER, - SYSTEN_SERVICE_EXCEPTION, - INTERRUPT_UNWIND_ATTEMPTED, - INTERRUPT_EXCEPTION_NOT_HANDLED, - MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED, - NO_MORE_SYSTEM_PTES, - TARGET_MDL_TOO_SMALL, - MUST_SUCCEED_POOL_EMPTY, - ATDISK_DRIVER_INTERNAL, - NO_SUCH_PARTITION, - MULTIPLE_IRP_COMPLETE_REQUESTS, - INSUFFICENT_SYSTEM_MAP_PAGES, - DEREF_UNKNOWN_LOGON_SERVICE, - REF_UNKNOWN_LOGON_SERVICE, - CANCEL_STATE_IN_COMPLETED_IRP, - PAGE_FAULT_WITH_INTERRUPTS_OFF, - IRQL_GT_ZERO_AT_SYSTEM_SERVICE, - STREAMS_INTERNAL_ERROR, - FATAL_UNHANDLED_HARD_ERROR, - NO_PAGES_AVAILABLE, - PFN_LIST_CORRUPT, - NDIS_INTERNAL_ERROR, - PAGE_FAULT_IN_NONPAGED_AREA, - REGISTRY_ERROR, - MAILSLOT_FILE_SYSTEM, - NO_BOOT_DEVICE, - LM_SERVER_INTERNAL_ERROR, - DATA_COHERENCY_EXCEPTION, - INSTRUCTION_COHERENCY_EXCEPTION, - XNS_INTERNAL_ERROR, - FTDISK_INTERNAL_ERROR, - PINBALL_FILE_SYSTEM, - CRITICAL_SERVICE_FAILED, - SET_ENV_VAR_FAILED, - HAL_INITIALIZED_FAILED, - UNSUPPORTED_PROCESSOR, - OBJECT_INITIALIZATION_FAILED, - SECURITY_INITIALIZATION_FAILED, - PROCESS_INITIALIZATION_FAILED, - HAL1_INITIALIZATION_FAILED, -}; -enum -{ - KBUG_NONE, - KBUG_ORPHANED_IRP, - KBUG_IO_STACK_OVERFLOW, - KBUG_OUT_OF_MEMORY, - KBUG_POOL_FREE_LIST_CORRUPT, - - /* - * These are well known but the actual value is unknown - */ -// NO_PAGES_AVAILABLE, - - /* - * These are well known (MS) bug types - * (Reference: NT Insider 1997 - http://www.osr.com) - */ - IRQL_NOT_LESS_OR_EQUAL = 0xa, -// KMODE_EXCEPTION_NOT_HANDLED = 0x1e, - UNEXPECTED_KERNEL_MODE_TRAP = 0x7f, - PAGE_FAULT_IN_NON_PAGED_AREA = 0x50, -}; + /* * PURPOSE: Object attributes @@ -175,19 +52,19 @@ enum OBJ_EXCLUSIVE = 0x20, OBJ_CASE_INSENSITIVE = 0x40, OBJ_OPENIF = 0x80, - OBJ_OPENLINK = 0x100, - OBJ_VALID_ATTRIBUTES = 0x1F2, + OBJ_OPENLINK = 0x100, + OBJ_VALID_ATTRIBUTES = 0x1F2, }; /* * PURPOSE: Timer types */ enum - { - NotificationTimer, - SynchronizationTimer, - }; - +{ + NotificationTimer, + SynchronizationTimer, +}; + /* * PURPOSE: Some drivers use these */ diff --git a/include/ddk/extypes.h b/include/ddk/extypes.h index ee53a99..6093fc5 100644 --- a/include/ddk/extypes.h +++ b/include/ddk/extypes.h @@ -78,7 +78,7 @@ typedef struct _ZONE_ENTRY } ZONE_ENTRY, *PZONE_ENTRY; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PWORKER_THREAD_ROUTINE)(PVOID Parameter); typedef struct _WORK_QUEUE_ITEM @@ -88,12 +88,12 @@ typedef struct _WORK_QUEUE_ITEM PVOID Context; } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM; -typedef PVOID STDCALL +typedef PVOID STDCALL_FUNC (*PALLOCATE_FUNCTION)(POOL_TYPE PoolType, ULONG NumberOfBytes, ULONG Tag); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PFREE_FUNCTION)(PVOID Buffer); typedef union _SLIST_HEADER @@ -153,7 +153,7 @@ typedef struct _PAGED_LOOKASIDE_LIST typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PCALLBACK_FUNCTION)(PVOID CallbackContext, PVOID Argument1, PVOID Argument2); @@ -166,11 +166,11 @@ typedef enum _TRAVERSE_METHOD { TraverseMethodPostorder } TRAVERSE_METHOD; -typedef LONG STDCALL +typedef LONG STDCALL_FUNC (*PKEY_COMPARATOR)(IN PVOID Key1, IN PVOID Key2); -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PTRAVERSE_ROUTINE)(IN PVOID Context, IN PVOID Key, IN PVOID Value); diff --git a/include/ddk/fstypes.h b/include/ddk/fstypes.h index 8b77390..f782424 100644 --- a/include/ddk/fstypes.h +++ b/include/ddk/fstypes.h @@ -18,6 +18,8 @@ typedef struct _FILE_LOCK_TOC { KSPIN_LOCK SpinLock; LIST_ENTRY GrantedListHead; LIST_ENTRY PendingListHead; + LIST_ENTRY CompletedListHead; + LIST_ENTRY UnlockedListHead; } FILE_LOCK_TOC, *PFILE_LOCK_TOC; typedef struct _FILE_LOCK_GRANTED { @@ -25,27 +27,6 @@ typedef struct _FILE_LOCK_GRANTED { FILE_LOCK_INFO Lock; } FILE_LOCK_GRANTED, *PFILE_LOCK_GRANTED; -typedef struct _FILE_LOCK_PENDING { - LIST_ENTRY ListEntry; - PIRP Irp; - PVOID Context; -} FILE_LOCK_PENDING, *PFILE_LOCK_PENDING; - -// raw internal file lock struct returned from FsRtlGetNextFileLock -typedef struct _FILE_SHARED_LOCK_ENTRY { - PVOID Unknown1; - PVOID Unknown2; - FILE_LOCK_INFO FileLock; -} FILE_SHARED_LOCK_ENTRY, *PFILE_SHARED_LOCK_ENTRY; - -// raw internal file lock struct returned from FsRtlGetNextFileLock -typedef struct _FILE_EXCLUSIVE_LOCK_ENTRY { - LIST_ENTRY ListEntry; - PVOID Unknown1; - PVOID Unknown2; - FILE_LOCK_INFO FileLock; -} FILE_EXCLUSIVE_LOCK_ENTRY, *PFILE_EXCLUSIVE_LOCK_ENTRY; - typedef NTSTATUS (*PCOMPLETE_LOCK_IRP_ROUTINE) ( IN PVOID Context, IN PIRP Irp diff --git a/include/ddk/haltypes.h b/include/ddk/haltypes.h index 2ccf398..2256e25 100644 --- a/include/ddk/haltypes.h +++ b/include/ddk/haltypes.h @@ -164,7 +164,7 @@ typedef struct _PCI_COMMON_CONFIG #define PCI_INVALID_VENDORID 0xFFFF -/* Bit encodings for PCI_COMMON_CONFIG.HeaderType */ +/* Bit encodings for PCI_COMMON_CONFIG.HeaderType */ #define PCI_MULTIFUNCTION 0x80 #define PCI_DEVICE_TYPE 0x00 @@ -197,12 +197,43 @@ typedef struct _PCI_COMMON_CONFIG #define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000 +/* PCI device classes */ + +#define PCI_CLASS_PRE_20 0x00 +#define PCI_CLASS_MASS_STORAGE_CTLR 0x01 +#define PCI_CLASS_NETWORK_CTLR 0x02 +#define PCI_CLASS_DISPLAY_CTLR 0x03 +#define PCI_CLASS_MULTIMEDIA_DEV 0x04 +#define PCI_CLASS_MEMORY_CTLR 0x05 +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_CLASS_SIMPLE_COMMS_CTLR 0x07 +#define PCI_CLASS_BASE_SYSTEM_DEV 0x08 +#define PCI_CLASS_INPUT_DEV 0x09 +#define PCI_CLASS_DOCKING_STATION 0x0a +#define PCI_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_SERIAL_BUS_CTLR 0x0c + + +/* PCI device subclasses for class 1 (mass storage controllers)*/ + +#define PCI_SUBCLASS_MSC_SCSI_BUS_CTLR 0x00 +#define PCI_SUBCLASS_MSC_IDE_CTLR 0x01 +#define PCI_SUBCLASS_MSC_FLOPPY_CTLR 0x02 +#define PCI_SUBCLASS_MSC_IPI_CTLR 0x03 +#define PCI_SUBCLASS_MSC_RAID_CTLR 0x04 +#define PCI_SUBCLASS_MSC_OTHER 0x80 + + /* Bit encodes for PCI_COMMON_CONFIG.u.type0.BaseAddresses */ #define PCI_ADDRESS_IO_SPACE 0x00000001 #define PCI_ADDRESS_MEMORY_TYPE_MASK 0x00000006 #define PCI_ADDRESS_MEMORY_PREFETCHABLE 0x00000008 +#define PCI_ADDRESS_IO_ADDRESS_MASK 0xfffffffc +#define PCI_ADDRESS_MEMORY_ADDRESS_MASK 0xfffffff0 +#define PCI_ADDRESS_ROM_ADDRESS_MASK 0xfffff800 + #define PCI_TYPE_32BIT 0 #define PCI_TYPE_20BIT 2 #define PCI_TYPE_64BIT 4 @@ -213,6 +244,7 @@ typedef struct _PCI_COMMON_CONFIG #define PCI_ROMADDRESS_ENABLED 0x00000001 + typedef struct _PCI_SLOT_NUMBER { union @@ -270,23 +302,23 @@ typedef struct _BUS_HANDLER *PBUS_HANDLER; typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT; -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PHAL_RESET_DISPLAY_PARAMETERS)(ULONG Columns, ULONG Rows); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*pHalQuerySystemInformation)(IN HAL_QUERY_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN OUT PVOID Buffer, OUT PULONG ReturnedLength); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*pHalSetSystemInformation)(IN HAL_SET_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN PVOID Buffer); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*pHalQueryBusSlots)(IN PBUS_HANDLER BusHandler, IN ULONG BufferSize, OUT PULONG SlotNumbers, @@ -329,11 +361,11 @@ typedef struct _DEVICE_CONTROL_CONTEXT } DEVICE_CONTROL_CONTEXT, *PDEVICE_CONTROL_CONTEXT; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PDEVICE_CONTROL_COMPLETION)(IN PDEVICE_CONTROL_CONTEXT ControlContext); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*pHalDeviceControl)(IN PDEVICE_HANDLER_OBJECT DeviceHandler, IN PDEVICE_OBJECT DeviceObject, IN ULONG ControlCode, diff --git a/include/ddk/iofuncs.h b/include/ddk/iofuncs.h index 08b8797..595b33e 100644 --- a/include/ddk/iofuncs.h +++ b/include/ddk/iofuncs.h @@ -613,6 +613,9 @@ IoGetConfigurationInformation ( #define IoGetCurrentIrpStackLocation(Irp) \ ((Irp)->Tail.Overlay.CurrentStackLocation) +#define IoGetPreviousIrpStackLocation(Irp) \ + ((Irp)->Tail.Overlay.CurrentStackLocation+1) + #define IoSetNextIrpStackLocation(Irp) { \ (Irp)->CurrentLocation--; \ (Irp)->Tail.Overlay.CurrentStackLocation--; } @@ -630,6 +633,12 @@ IoGetConfigurationInformation ( (Irp)->CurrentLocation++; \ (Irp)->Tail.Overlay.CurrentStackLocation++; +#define IoSetPreviousIrpStackLocation(Irp) \ + IoSkipCurrentIrpStackLocation(Irp) + +#define IoRetardCurrentIrpStackLocation(Irp) \ + IoSkipCurrentIrpStackLocation(Irp) + struct _EPROCESS* STDCALL IoGetCurrentProcess ( @@ -928,7 +937,7 @@ IoReportResourceUsage ( #define IoSetCancelRoutine(Irp,NewCancelRoutine) \ ((PDRIVER_CANCEL)InterlockedExchange((PULONG)&(Irp)->CancelRoutine, \ - (ULONG)(NewCancelRoutine))); + (ULONG)(NewCancelRoutine))) #define IoSetCompletionRoutine(Irp,Routine,Context,Success,Error,Cancel) \ { \ diff --git a/include/ddk/iotypes.h b/include/ddk/iotypes.h index 3d6b27a..e6f6fa7 100644 --- a/include/ddk/iotypes.h +++ b/include/ddk/iotypes.h @@ -62,12 +62,12 @@ typedef struct _SHARE_ACCESS /* FUNCTION TYPES ************************************************************/ -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PDRIVER_REINITIALIZE)(struct _DRIVER_OBJECT* DriverObject, PVOID Context, ULONG Count); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PIO_QUERY_DEVICE_ROUTINE)(PVOID Context, PUNICODE_STRING Pathname, INTERFACE_TYPE BusType, @@ -80,12 +80,12 @@ typedef NTSTATUS STDCALL ULONG PeripheralNumber, PKEY_VALUE_FULL_INFORMATION* PI); -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PIO_COMPLETION_ROUTINE)(struct _DEVICE_OBJECT* DeviceObject, struct _IRP* Irp, PVOID Context); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PIO_APC_ROUTINE)(PVOID ApcContext, struct _IO_STATUS_BLOCK* IoStatusBlock, ULONG Reserved); @@ -489,14 +489,14 @@ typedef struct _IO_MAILSLOT_CREATE_BUFFER /* * Driver entry point declaration */ -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PDRIVER_INITIALIZE)(struct _DRIVER_OBJECT* DriverObject, PUNICODE_STRING RegistryPath); /* * Driver cancel declaration */ -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PDRIVER_CANCEL)(struct _DEVICE_OBJECT* DeviceObject, struct _IRP* RegistryPath); @@ -689,7 +689,7 @@ typedef struct _DEVICE_OBJECT */ //typedef NTSTATUS (*PFAST_IO_DISPATCH)(struct _DEVICE_OBJECT*, IRP*); //FIXME : this type is ok for read and write, but not for all routines -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PFAST_IO_ROUTINE)(IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, @@ -733,27 +733,27 @@ typedef struct _FAST_IO_DISPATCH { /* * Dispatch routine type declaration */ -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PDRIVER_DISPATCH)(IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp); /* * StartIo routine type declaration */ -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PDRIVER_STARTIO)(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); /* * Unload routine type declaration */ -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PDRIVER_UNLOAD)(IN struct _DRIVER_OBJECT *DriverObject); /* * AddDevice routine type declaration */ -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PDRIVER_ADD_DEVICE)(IN struct _DRIVER_OBJECT *DriverObject, IN struct _DEVICE_OBJECT *PhysicalDeviceObject); @@ -813,13 +813,13 @@ typedef struct _CONFIGURATION_INFORMATION BOOLEAN AtDiskSecondaryAddressClaimed; } CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PIO_DPC_ROUTINE)(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PIO_TIMER_ROUTINE)(PDEVICE_OBJECT DeviceObject, PVOID Context); @@ -848,13 +848,13 @@ typedef struct _DRIVER_LAYOUT_INFORMATION } DRIVER_LAYOUT_INFORMATION, *PDRIVER_LAYOUT_INFORMATION; -typedef IO_ALLOCATION_ACTION STDCALL +typedef IO_ALLOCATION_ACTION STDCALL_FUNC (*PDRIVER_CONTROL)(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context); #if (_WIN32_WINNT >= 0x0400) -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PFSDNOTIFICATIONPROC)(IN PDEVICE_OBJECT PtrTargetFileSystemDeviceObject, IN BOOLEAN DriverActive); #endif // (_WIN32_WINNT >= 0x0400) diff --git a/include/ddk/ketypes.h b/include/ddk/ketypes.h index abb87b2..be4b6e4 100644 --- a/include/ddk/ketypes.h +++ b/include/ddk/ketypes.h @@ -69,28 +69,27 @@ struct _KMUTANT; typedef LONG KPRIORITY; -typedef VOID STDCALL -(*PKBUGCHECK_CALLBACK_ROUTINE)(PVOID Buffer, - ULONG Length); +typedef VOID STDCALL_FUNC +(*PKBUGCHECK_CALLBACK_ROUTINE)(PVOID Buffer, ULONG Length); -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PKSYNCHRONIZE_ROUTINE)(PVOID SynchronizeContext); struct _KAPC; -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PKNORMAL_ROUTINE)(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PKKERNEL_ROUTINE)(struct _KAPC* Apc, PKNORMAL_ROUTINE* NormalRoutine, PVOID* NormalContext, PVOID* SystemArgument1, PVOID* SystemArgument2); -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PKRUNDOWN_ROUTINE)(struct _KAPC* Apc); struct _DISPATCHER_HEADER; @@ -222,7 +221,7 @@ struct _KDPC; * SystemArgument[1-2] = Undocumented. * */ -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PKDEFERRED_ROUTINE)(struct _KDPC* Dpc, PVOID DeferredContext, PVOID SystemArgument1, @@ -255,11 +254,12 @@ typedef struct _KDEVICE_QUEUE_ENTRY typedef struct _WAIT_CONTEXT_BLOCK { + int unknown; } WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK; struct _KINTERRUPT; -typedef BOOLEAN STDCALL +typedef BOOLEAN STDCALL_FUNC (*PKSERVICE_ROUTINE)(struct _KINTERRUPT* Interrupt, PVOID ServiceContext); diff --git a/include/ddk/ntddbeep.h b/include/ddk/ntddbeep.h index 2663ecd..1fa4630 100644 --- a/include/ddk/ntddbeep.h +++ b/include/ddk/ntddbeep.h @@ -31,6 +31,7 @@ extern "C" { #endif +#pragma pack(push,4) #define IOCTL_BEEP_SET \ CTL_CODE(FILE_DEVICE_BEEP,0,METHOD_BUFFERED,FILE_ANY_ACCESS) @@ -43,6 +44,8 @@ typedef struct tagBEEP_SET_PARAMETERS { #define BEEP_FREQUENCY_MINIMUM 0x25 #define BEEP_FREQUENCY_MAXIMUM 0x7FFF +#pragma pack(pop) + #ifdef __cplusplus } #endif diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index fd8d199..11610af 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -56,18 +56,17 @@ extern "C" #include #include #include -#include -#include +#include +#include #include -#include +#include #include #include -#include -#include +#include +#include #include #include -#include #if defined(__NTOSKRNL__) || defined(__NTDRIVER__) || defined(__NTHAL__) #include #include diff --git a/include/ddk/ntddkbd.h b/include/ddk/ntddkbd.h index 527392c..fa903f3 100644 --- a/include/ddk/ntddkbd.h +++ b/include/ddk/ntddkbd.h @@ -1,5 +1,38 @@ -#ifndef _NTDDKBD_ -#define _NTDDKBD_ +/* + * ntddkbd.h + * + * Keyboard IOCTL interface + * + * This file is part of the MinGW package. + * + * Contributors: + * Created by Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __NTDDKBD_H +#define __NTDDKBD_H + +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push,4) + typedef struct _KEYBOARD_INPUT_DATA { @@ -16,4 +49,11 @@ typedef struct _KEYBOARD_INPUT_DATA { } KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA; -#endif // _NTDDKBD_ + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif /* __NTDDKBD_H */ diff --git a/include/ddk/ntdef.h b/include/ddk/ntdef.h index 264adc1..e56b777 100644 --- a/include/ddk/ntdef.h +++ b/include/ddk/ntdef.h @@ -5,9 +5,16 @@ struct _KTHREAD; struct _ETHREAD; struct _EPROCESS; -#define NTKERNELAPI -#define NTSYSAPI -#define NTAPI +#ifndef NTKERNELAPI +#define NTKERNELAPI STDCALL +#endif + +#ifndef NTSYSAPI +#define NTSYSAPI STDCALL +#endif +#ifndef NTAPI +#define NTAPI STDCALL +#endif #endif diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index ca81c9b..e5b8290 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -3,33 +3,13 @@ struct _BCB; -typedef struct _BCB* PBCB; - -struct _MEMORY_AREA; - -struct _CACHE_SEGMENT; - -typedef struct _CACHE_SEGMENT* PCACHE_SEGMENT; - -NTSTATUS STDCALL -CcRosReleaseCacheSegment (struct _BCB* Bcb, - struct _CACHE_SEGMENT* CacheSeg, - BOOLEAN Valid, - BOOLEAN Dirty, - BOOLEAN Mapped); -NTSTATUS STDCALL -CcRosRequestCacheSegment (struct _BCB* Bcb, - ULONG FileOffset, - PVOID* BaseAddress, - PBOOLEAN UptoDate, - struct _CACHE_SEGMENT** CacheSeg); NTSTATUS STDCALL CcRosInitializeFileCache (PFILE_OBJECT FileObject, - struct _BCB** Bcb, - ULONG CacheSegmentSize); + struct _BCB** Bcb, + ULONG CacheSegmentSize); NTSTATUS STDCALL CcRosReleaseFileCache (PFILE_OBJECT FileObject, - struct _BCB* Bcb); + struct _BCB* Bcb); #include diff --git a/include/ddk/obtypes.h b/include/ddk/obtypes.h index bd55d80..5e5480d 100644 --- a/include/ddk/obtypes.h +++ b/include/ddk/obtypes.h @@ -62,24 +62,24 @@ typedef struct _OBJECT_TYPE * PURPOSE: Dumps the object * NOTE: To be defined */ - VOID STDCALL (*Dump)(VOID); + VOID STDCALL_FUNC (*Dump)(VOID); /* * PURPOSE: Opens the object * NOTE: To be defined */ - VOID STDCALL (*Open)(VOID); + VOID STDCALL_FUNC (*Open)(VOID); /* * PURPOSE: Called to close an object if OkayToClose returns true */ - VOID STDCALL (*Close)(PVOID ObjectBody, + VOID STDCALL_FUNC (*Close)(PVOID ObjectBody, ULONG HandleCount); /* * PURPOSE: Called to delete an object when the last reference is removed */ - VOID STDCALL (*Delete)(PVOID ObjectBody); + VOID STDCALL_FUNC (*Delete)(PVOID ObjectBody); /* * PURPOSE: Called when an open attempts to open a file apparently @@ -89,7 +89,7 @@ typedef struct _OBJECT_TYPE * STATUS_UNSUCCESSFUL NextObject not found * STATUS_REPARSE Path changed, restart parsing the path */ - NTSTATUS STDCALL (*Parse)(PVOID ParsedObject, + NTSTATUS STDCALL_FUNC (*Parse)(PVOID ParsedObject, PVOID *NextObject, PUNICODE_STRING FullPath, PWSTR *Path, @@ -97,26 +97,26 @@ typedef struct _OBJECT_TYPE /* */ - NTSTATUS STDCALL (*Security)(PVOID Object, + NTSTATUS STDCALL_FUNC (*Security)(PVOID Object, ULONG InfoClass, PVOID Info, PULONG InfoLength); /* */ - VOID STDCALL (*QueryName)(VOID); + VOID STDCALL_FUNC (*QueryName)(VOID); /* * PURPOSE: Called when a process asks to close the object */ - VOID STDCALL (*OkayToClose)(VOID); + VOID STDCALL_FUNC (*OkayToClose)(VOID); - NTSTATUS STDCALL (*Create)(PVOID ObjectBody, + NTSTATUS STDCALL_FUNC (*Create)(PVOID ObjectBody, PVOID Parent, PWSTR RemainingPath, struct _OBJECT_ATTRIBUTES* ObjectAttributes); - VOID STDCALL (*DuplicationNotify)(PEPROCESS DuplicateTo, + VOID STDCALL_FUNC (*DuplicationNotify)(PEPROCESS DuplicateTo, PEPROCESS DuplicateFrom, PVOID Object); } OBJECT_TYPE, *POBJECT_TYPE; diff --git a/include/ddk/pnptypes.h b/include/ddk/pnptypes.h index 2ba5453..b402bae 100644 --- a/include/ddk/pnptypes.h +++ b/include/ddk/pnptypes.h @@ -148,13 +148,13 @@ typedef enum _IO_NOTIFICATION_EVENT_CATEGORY { } IO_NOTIFICATION_EVENT_CATEGORY; // CallbackRoutine for IoRegisterPlugPlayNotification -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)( IN PVOID NotificationStructure, IN PVOID Context); // Callback for IoReportTargetDeviceChangeAsynchronous -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PDEVICE_CHANGE_COMPLETE_CALLBACK)( IN PVOID Context); diff --git a/include/ddk/potypes.h b/include/ddk/potypes.h index ee720e7..06ede74 100644 --- a/include/ddk/potypes.h +++ b/include/ddk/potypes.h @@ -59,7 +59,7 @@ typedef enum _POWER_STATE_TYPE { } POWER_STATE_TYPE, *PPOWER_STATE_TYPE; // CompletionFunction for PoRequestPowerIrp -typedef VOID STDCALL +typedef VOID STDCALL_FUNC (*PREQUEST_POWER_COMPLETE) ( IN struct _DEVICE_OBJECT *DeviceObject, IN UCHAR MinorFunction, @@ -74,8 +74,8 @@ typedef struct _POWER_SEQUENCE { ULONG SequenceD3; } POWER_SEQUENCE, *PPOWER_SEQUENCE; -typedef VOID STDCALL (*PINTERFACE_REFERENCE)(PVOID Context); -typedef VOID STDCALL (*PINTERFACE_DEREFERENCE)(PVOID Context); +typedef VOID STDCALL_FUNC (*PINTERFACE_REFERENCE)(PVOID Context); +typedef VOID STDCALL_FUNC (*PINTERFACE_DEREFERENCE)(PVOID Context); typedef struct _INTERFACE { USHORT Size; diff --git a/include/ddk/pstypes.h b/include/ddk/pstypes.h index 9aae408..25113b8 100644 --- a/include/ddk/pstypes.h +++ b/include/ddk/pstypes.h @@ -18,13 +18,13 @@ struct _KPROCESS; struct _ETHREAD; struct _KTHREAD; -typedef NTSTATUS STDCALL (*PKSTART_ROUTINE)(PVOID StartContext); +typedef NTSTATUS STDCALL_FUNC (*PKSTART_ROUTINE)(PVOID StartContext); -typedef VOID STDCALL (*PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE ParentId, +typedef VOID STDCALL_FUNC (*PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create); -typedef VOID STDCALL (*PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE ProcessId, +typedef VOID STDCALL_FUNC (*PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE ProcessId, HANDLE ThreadId, BOOLEAN Create); @@ -49,9 +49,11 @@ extern struct _EPROCESS* EXPORTED PsInitialSystemProcess; extern POBJECT_TYPE EXPORTED PsProcessType; extern POBJECT_TYPE EXPORTED PsThreadType; #else +#ifdef __GNU__ // robd extern struct _EPROCESS* IMPORTED PsInitialSystemProcess; extern POBJECT_TYPE IMPORTED PsProcessType; extern POBJECT_TYPE IMPORTED PsThreadType; #endif +#endif #endif /* __INCLUDE_DDK_PSTYPES_H */ diff --git a/include/ddk/setypes.h b/include/ddk/setypes.h index 7cd7f99..cd4eaa5 100644 --- a/include/ddk/setypes.h +++ b/include/ddk/setypes.h @@ -156,7 +156,7 @@ typedef struct _SE_EXPORTS } SE_EXPORTS, *PSE_EXPORTS; -typedef NTSTATUS STDCALL +typedef NTSTATUS STDCALL_FUNC (*PSE_LOGON_SESSION_TERMINATED_ROUTINE)(IN PLUID LogonId); #endif diff --git a/include/ddk/status.h b/include/ddk/status.h index 81edfb9..b8bd209 100644 --- a/include/ddk/status.h +++ b/include/ddk/status.h @@ -1,6 +1,8 @@ #ifndef __INCLUDE_DDK_STATUS_H #define __INCLUDE_DDK_STATUS_H +#ifndef __ASM__ + #define NTSTAT_SEVERITY_SHIFT 30 #define NTSTAT_SEVERITY_MASK 0x00000003 #define NTSTAT_FACILITY_SHIFT 16 @@ -17,692 +19,698 @@ * FIXME: These may not be the actual values used by NT */ -#define STATUS_SUCCESS (0x00000000) +#define STATUS_SUCCESS ((NTSTATUS)0x00000000) #ifndef STATUS_WAIT_0 -#define STATUS_WAIT_0 (0x00000000) +#define STATUS_WAIT_0 ((NTSTATUS)0x00000000) #endif -#define STATUS_WAIT_63 (0x0000003F) -#define STATUS_ABANDONED (0x00000080) +#define STATUS_WAIT_63 ((NTSTATUS)0x0000003F) +#define STATUS_ABANDONED ((NTSTATUS)0x00000080) #ifndef STATUS_ABANDONED_WAIT_0 -#define STATUS_ABANDONED_WAIT_0 (0x00000080) +#define STATUS_ABANDONED_WAIT_0 ((NTSTATUS)0x00000080) #endif -#define STATUS_ABANDONED_WAIT_63 (0x000000BF) +#define STATUS_ABANDONED_WAIT_63 ((NTSTATUS)0x000000BF) #ifndef STATUS_USER_APC -#define STATUS_USER_APC (0x000000C0) +#define STATUS_USER_APC ((NTSTATUS)0x000000C0) #endif -#define STATUS_KERNEL_APC (0x00000100) -#define STATUS_ALERTED (0x00000101) +#define STATUS_KERNEL_APC ((NTSTATUS)0x00000100) +#define STATUS_ALERTED ((NTSTATUS)0x00000101) #ifndef STATUS_TIMEOUT -#define STATUS_TIMEOUT (0x00000102) +#define STATUS_TIMEOUT ((NTSTATUS)0x00000102) #endif #ifndef STATUS_PENDING -#define STATUS_PENDING (0x00000103) +#define STATUS_PENDING ((NTSTATUS)0x00000103) #endif -#define STATUS_REPARSE (0x00000104) -#define STATUS_MORE_ENTRIES (0x00000105) -#define STATUS_NOT_ALL_ASSIGNED (0x00000106) -#define STATUS_SOME_NOT_MAPPED (0x00000107) -#define STATUS_OPLOCK_BREAK_IN_PROCESS (0x00000108) -#define STATUS_VOLUME_MOUNTED (0x00000109) -#define STATUS_RXACT_COMMITTED (0x0000010A) -#define STATUS_NOTIFY_CLEANUP (0x0000010B) -#define STATUS_NOTIFY_ENUM_DIR (0x0000010C) -#define STATUS_NO_QUOTAS_NO_ACCOUNT (0x0000010D) -#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED (0x0000010E) - -#define STATUS_OBJECT_EXISTS (0x40000000) -#define STATUS_THREAD_WAS_SUSPENDED (0x40000001) -#define STATUS_WORKING_SET_LIMIT_RANGE (0x40000002) -#define STATUS_IMAGE_NOT_AT_BASE (0x40000003) -#define STATUS_RXACT_STATE_CREATED (0x40000004) -#define STATUS_SEGMENT_NOTIFICATION (0x40000005) -#define STATUS_LOCAL_USER_SESSION_KEY (0x40000006) -#define STATUS_BAD_CURRENT_DIRECTORY (0x40000007) -#define STATUS_SERIAL_MORE_WRITES (0x40000008) -#define STATUS_REGISTRY_RECOVERED (0x40000009) -#define STATUS_FT_READ_RECOVERING_FROM_BACKUP (0x4000000A) -#define STATUS_FT_WRITE_RECOVERY (0x4000000B) -#define STATUS_SERIAL_COUNTER_TIMEOUT (0x4000000C) -#define STATUS_NULL_LM_PASSWORD (0x4000000D) -#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH (0x4000000E) -#define STATUS_RECEIVE_PARTIAL (0x4000000F) -#define STATUS_RECEIVE_EXPEDITED (0x40000010) -#define STATUS_RECEIVE_PARTIAL_EXPEDITED (0x40000011) -#define STATUS_EVENT_DONE (0x40000012) -#define STATUS_EVENT_PENDING (0x40000013) -#define STATUS_CHECKING_FILE_SYSTEM (0x40000014) -#define STATUS_FATAL_APP_EXIT (0x40000015) -#define STATUS_PREDEFINED_HANDLE (0x40000016) -#define STATUS_WAS_UNLOCKED (0x40000017) -#define STATUS_SERVICE_NOTIFICATION (0x40000018) -#define STATUS_WAS_LOCKED (0x40000019) -#define STATUS_LOG_HARD_ERROR (0x4000001A) -#define STATUS_ALREADY_WIN32 (0x4000001B) -#define STATUS_WX86_UNSIMULATE (0x4000001C) -#define STATUS_WX86_CONTINUE (0x4000001D) -#define STATUS_WX86_SINGLE_STEP (0x4000001E) -#define STATUS_WX86_BREAKPOINT (0x4000001F) -#define STATUS_WX86_EXCEPTION_CONTINUE (0x40000020) -#define STATUS_WX86_EXCEPTION_LASTCHANCE (0x40000021) -#define STATUS_WX86_EXCEPTION_CHAIN (0x40000022) -#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE (0x40000023) -#define STATUS_NO_YIELD_PERFORMED (0x40000024) -#define STATUS_TIMER_RESUME_IGNORED (0x40000025) -#define STATUS_ARBITRATION_UNHANDLED (0x40000026) -#define STATUS_CARDBUS_NOT_SUPPORTED (0x40000027) -#define STATUS_WX86_CREATEWX86TIB (0x40000028) - -#define STATUS_GUARD_PAGE_VIOLATION (0x80000001) -#define STATUS_DATATYPE_MISALIGNMENT (0x80000002) -#define STATUS_BREAKPOINT (0x80000003) -#define STATUS_SINGLE_STEP (0x80000004) -#define STATUS_BUFFER_OVERFLOW (0x80000005) -#define STATUS_NO_MORE_FILES (0x80000006) -#define STATUS_WAKE_SYSTEM_DEBUGGER (0x80000007) - -#define STATUS_HANDLES_CLOSED (0x8000000A) -#define STATUS_NO_INHERITANCE (0x8000000B) -#define STATUS_GUID_SUBSTITUTION_MADE (0x8000000C) -#define STATUS_PARTIAL_COPY (0x8000000D) -#define STATUS_DEVICE_PAPER_EMPTY (0x8000000E) -#define STATUS_DEVICE_POWERED_OFF (0x8000000F) -#define STATUS_DEVICE_OFF_LINE (0x80000010) -#define STATUS_DEVICE_BUSY (0x80000011) -#define STATUS_NO_MORE_EAS (0x80000012) -#define STATUS_INVALID_EA_NAME (0x80000013) -#define STATUS_EA_LIST_INCONSISTENT (0x80000014) -#define STATUS_INVALID_EA_FLAG (0x80000015) -#define STATUS_VERIFY_REQUIRED (0x80000016) -#define STATUS_EXTRANEOUS_INFORMATION (0x80000017) -#define STATUS_RXACT_COMMIT_NECESSARY (0x80000018) - -#define STATUS_NO_MORE_ENTRIES (0x8000001A) -#define STATUS_FILEMARK_DETECTED (0x8000001B) -#define STATUS_MEDIA_CHANGED (0x8000001C) -#define STATUS_BUS_RESET (0x8000001D) -#define STATUS_END_OF_MEDIA (0x8000001E) -#define STATUS_BEGINNING_OF_MEDIA (0x8000001F) -#define STATUS_MEDIA_CHECK (0x80000020) -#define STATUS_SETMARK_DETECTED (0x80000021) -#define STATUS_NO_DATA_DETECTED (0x80000022) -#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES (0x80000023) -#define STATUS_SERVER_HAS_OPEN_HANDLES (0x80000024) -#define STATUS_ALREADY_DISCONNECTED (0x80000025) -#define STATUS_LONGJUMP (0x80000026) - -#define STATUS_UNSUCCESSFUL (0xc0000001) -#define STATUS_NOT_IMPLEMENTED (0xc0000002) -#define STATUS_INVALID_INFO_CLASS (0xc0000003) -#define STATUS_INFO_LENGTH_MISMATCH (0xc0000004) -#define STATUS_ACCESS_VIOLATION (0xc0000005) -#define STATUS_IN_PAGE_ERROR (0xc0000006) -#define STATUS_PAGEFILE_QUOTA (0xc0000007) -#define STATUS_INVALID_HANDLE (0xc0000008) -#define STATUS_BAD_INITIAL_STACK (0xc0000009) -#define STATUS_BAD_INITIAL_PC (0xc000000a) -#define STATUS_INVALID_CID (0xc000000b) -#define STATUS_TIMER_NOT_CANCELED (0xc000000c) -#define STATUS_INVALID_PARAMETER (0xc000000d) -#define STATUS_NO_SUCH_DEVICE (0xc000000e) -#define STATUS_NO_SUCH_FILE (0xc000000f) -#define STATUS_INVALID_DEVICE_REQUEST (0xc0000010) -#define STATUS_END_OF_FILE (0xc0000011) -#define STATUS_WRONG_VOLUME (0xc0000012) -#define STATUS_NO_MEDIA_IN_DEVICE (0xc0000013) -#define STATUS_UNRECOGNIZED_MEDIA (0xc0000014) -#define STATUS_NONEXISTENT_SECTOR (0xc0000015) -#define STATUS_MORE_PROCESSING_REQUIRED (0xc0000016) -#define STATUS_NO_MEMORY (0xc0000017) -#define STATUS_CONFLICTING_ADDRESSES (0xc0000018) -#define STATUS_NOT_MAPPED_VIEW (0xc0000019) -#define STATUS_UNABLE_TO_FREE_VM (0xc000001a) -#define STATUS_UNABLE_TO_DELETE_SECTION (0xc000001b) -#define STATUS_INVALID_SYSTEM_SERVICE (0xc000001c) -#define STATUS_ILLEGAL_INSTRUCTION (0xc000001d) -#define STATUS_INVALID_LOCK_SEQUENCE (0xc000001e) -#define STATUS_INVALID_VIEW_SIZE (0xc000001f) -#define STATUS_INVALID_FILE_FOR_SECTION (0xc0000020) -#define STATUS_ALREADY_COMMITTED (0xc0000021) -#define STATUS_ACCESS_DENIED (0xc0000022) -#define STATUS_BUFFER_TOO_SMALL (0xc0000023) -#define STATUS_OBJECT_TYPE_MISMATCH (0xc0000024) -#define STATUS_NONCONTINUABLE_EXCEPTION (0xc0000025) -#define STATUS_INVALID_DISPOSITION (0xc0000026) -#define STATUS_UNWIND (0xc0000027) -#define STATUS_BAD_STACK (0xc0000028) -#define STATUS_INVALID_UNWIND_TARGET (0xc0000029) -#define STATUS_NOT_LOCKED (0xc000002a) -#define STATUS_PARITY_ERROR (0xc000002b) -#define STATUS_UNABLE_TO_DECOMMIT_VM (0xc000002c) -#define STATUS_NOT_COMMITTED (0xc000002d) -#define STATUS_INVALID_PORT_ATTRIBUTES (0xc000002e) -#define STATUS_PORT_MESSAGE_TOO_LONG (0xc000002f) -#define STATUS_INVALID_PARAMETER_MIX (0xc0000030) -#define STATUS_INVALID_QUOTA_LOWER (0xc0000031) -#define STATUS_DISK_CORRUPT_ERROR (0xc0000032) -#define STATUS_OBJECT_NAME_INVALID (0xc0000033) -#define STATUS_OBJECT_NAME_NOT_FOUND (0xc0000034) -#define STATUS_OBJECT_NAME_COLLISION (0xc0000035) -#define STATUS_OBJECT_NAME_EXISTS (0x40000000) - - -#define STATUS_PORT_DISCONNECTED (0xc0000037) -#define STATUS_DEVICE_ALREADY_ATTACHED (0xc0000038) -#define STATUS_OBJECT_PATH_INVALID (0xc0000039) -#define STATUS_OBJECT_PATH_NOT_FOUND (0xc000003a) -#define STATUS_PATH_SYNTAX_BAD (0xc000003b) -#define STATUS_DATA_OVERRUN (0xc000003c) -#define STATUS_DATA_LATE_ERROR (0xc000003d) -#define STATUS_DATA_ERROR (0xc000003e) -#define STATUS_CRC_ERROR (0xc000003f) -#define STATUS_SECTION_TOO_BIG (0xc0000040) -#define STATUS_PORT_CONNECTION_REFUSED (0xc0000041) -#define STATUS_INVALID_PORT_HANDLE (0xc0000042) -#define STATUS_SHARING_VIOLATION (0xc0000043) -#define STATUS_QUOTA_EXCEEDED (0xc0000044) -#define STATUS_INVALID_PAGE_PROTECTION (0xc0000045) -#define STATUS_MUTANT_NOT_OWNED (0xc0000046) -#define STATUS_SEMAPHORE_LIMIT_EXCEEDED (0xc0000047) -#define STATUS_PORT_ALREADY_SET (0xc0000048) -#define STATUS_SECTION_NOT_IMAGE (0xc0000049) -#define STATUS_SUSPEND_COUNT_EXCEEDED (0xc000004a) -#define STATUS_THREAD_IS_TERMINATING (0xc000004b) -#define STATUS_BAD_WORKING_SET_LIMIT (0xc000004c) -#define STATUS_INCOMPATIBLE_FILE_MAP (0xc000004d) -#define STATUS_SECTION_PROTECTION (0xc000004e) -#define STATUS_EAS_NOT_SUPPORTED (0xc000004f) -#define STATUS_EA_TOO_LARGE (0xc0000050) -#define STATUS_NONEXISTENT_EA_ENTRY (0xc0000051) -#define STATUS_NO_EAS_ON_FILE (0xc0000052) -#define STATUS_EA_CORRUPT_ERROR (0xc0000053) -#define STATUS_FILE_LOCK_CONFLICT (0xc0000054) -#define STATUS_LOCK_NOT_GRANTED (0xc0000055) -#define STATUS_DELETE_PENDING (0xc0000056) -#define STATUS_CTL_FILE_NOT_SUPPORTED (0xc0000057) -#define STATUS_UNKNOWN_REVISION (0xc0000058) -#define STATUS_REVISION_MISMATCH (0xc0000059) -#define STATUS_INVALID_OWNER (0xc000005a) -#define STATUS_INVALID_PRIMARY_GROUP (0xc000005b) -#define STATUS_NO_IMPERSONATION_TOKEN (0xc000005c) -#define STATUS_CANT_DISABLE_MANDATORY (0xc000005d) -#define STATUS_NO_LOGON_SERVERS (0xc000005e) -#define STATUS_NO_SUCH_LOGON_SESSION (0xc000005f) -#define STATUS_NO_SUCH_PRIVILEGE (0xc0000060) -#define STATUS_PRIVILEGE_NOT_HELD (0xc0000061) -#define STATUS_INVALID_ACCOUNT_NAME (0xc0000062) -#define STATUS_USER_EXISTS (0xc0000063) -#define STATUS_NO_SUCH_USER (0xc0000064) -#define STATUS_GROUP_EXISTS (0xc0000065) -#define STATUS_NO_SUCH_GROUP (0xc0000066) -#define STATUS_MEMBER_IN_GROUP (0xc0000067) -#define STATUS_MEMBER_NOT_IN_GROUP (0xc0000068) -#define STATUS_LAST_ADMIN (0xc0000069) -#define STATUS_WRONG_PASSWORD (0xc000006a) -#define STATUS_ILL_FORMED_PASSWORD (0xc000006b) -#define STATUS_PASSWORD_RESTRICTION (0xc000006c) -#define STATUS_LOGON_FAILURE (0xc000006d) -#define STATUS_ACCOUNT_RESTRICTION (0xc000006e) -#define STATUS_INVALID_LOGON_HOURS (0xc000006f) -#define STATUS_INVALID_WORKSTATION (0xc0000070) -#define STATUS_PASSWORD_EXPIRED (0xc0000071) -#define STATUS_ACCOUNT_DISABLED (0xc0000072) -#define STATUS_NONE_MAPPED (0xc0000073) -#define STATUS_TOO_MANY_LUIDS_REQUESTED (0xc0000074) -#define STATUS_LUIDS_EXHAUSTED (0xc0000075) -#define STATUS_INVALID_SUB_AUTHORITY (0xc0000076) -#define STATUS_INVALID_ACL (0xc0000077) -#define STATUS_INVALID_SID (0xc0000078) -#define STATUS_INVALID_SECURITY_DESCR (0xc0000079) -#define STATUS_PROCEDURE_NOT_FOUND (0xc000007a) -#define STATUS_INVALID_IMAGE_FORMAT (0xc000007b) -#define STATUS_NO_TOKEN (0xc000007c) -#define STATUS_BAD_INHERITANCE_ACL (0xc000007d) -#define STATUS_RANGE_NOT_LOCKED (0xc000007e) -#define STATUS_DISK_FULL (0xc000007f) -#define STATUS_SERVER_DISABLED (0xc0000080) -#define STATUS_SERVER_NOT_DISABLED (0xc0000081) -#define STATUS_TOO_MANY_GUIDS_REQUESTED (0xc0000082) -#define STATUS_GUIDS_EXHAUSTED (0xc0000083) -#define STATUS_INVALID_ID_AUTHORITY (0xc0000084) -#define STATUS_AGENTS_EXHAUSTED (0xc0000085) -#define STATUS_INVALID_VOLUME_LABEL (0xc0000086) -#define STATUS_SECTION_NOT_EXTENDED (0xc0000087) -#define STATUS_NOT_MAPPED_DATA (0xc0000088) -#define STATUS_RESOURCE_DATA_NOT_FOUND (0xc0000089) -#define STATUS_RESOURCE_TYPE_NOT_FOUND (0xc000008a) -#define STATUS_RESOURCE_NAME_NOT_FOUND (0xc000008b) -#define STATUS_ARRAY_BOUNDS_EXCEEDED (0xc000008c) -#define STATUS_FLOAT_DENORMAL_OPERAND (0xc000008d) -#define STATUS_FLOAT_DIVIDE_BY_ZERO (0xc000008e) -#define STATUS_FLOAT_INEXACT_RESULT (0xc000008f) -#define STATUS_FLOAT_INVALID_OPERATION (0xc0000090) -#define STATUS_FLOAT_OVERFLOW (0xc0000091) -#define STATUS_FLOAT_STACK_CHECK (0xc0000092) -#define STATUS_FLOAT_UNDERFLOW (0xc0000093) -#define STATUS_INTEGER_DIVIDE_BY_ZERO (0xc0000094) -#define STATUS_INTEGER_OVERFLOW (0xc0000095) -#define STATUS_PRIVILEGED_INSTRUCTION (0xc0000096) -#define STATUS_TOO_MANY_PAGING_FILES (0xc0000097) -#define STATUS_FILE_INVALID (0xc0000098) -#define STATUS_ALLOTTED_SPACE_EXCEEDED (0xc0000099) -#define STATUS_INSUFFICIENT_RESOURCES (0xc000009a) -#define STATUS_DFS_EXIT_PATH_FOUND (0xc000009b) -#define STATUS_DEVICE_DATA_ERROR (0xc000009c) -#define STATUS_DEVICE_NOT_CONNECTED (0xc000009d) -#define STATUS_DEVICE_POWER_FAILURE (0xc000009e) -#define STATUS_FREE_VM_NOT_AT_BASE (0xc000009f) -#define STATUS_MEMORY_NOT_ALLOCATED (0xc00000a0) -#define STATUS_WORKING_SET_QUOTA (0xc00000a1) -#define STATUS_MEDIA_WRITE_PROTECTED (0xc00000a2) -#define STATUS_DEVICE_NOT_READY (0xc00000a3) -#define STATUS_INVALID_GROUP_ATTRIBUTES (0xc00000a4) -#define STATUS_BAD_IMPERSONATION_LEVEL (0xc00000a5) -#define STATUS_CANT_OPEN_ANONYMOUS (0xc00000a6) -#define STATUS_BAD_VALIDATION_CLASS (0xc00000a7) -#define STATUS_BAD_TOKEN_TYPE (0xc00000a8) -#define STATUS_BAD_MASTER_BOOT_RECORD (0xc00000a9) -#define STATUS_INSTRUCTION_MISALIGNMENT (0xc00000aa) -#define STATUS_INSTANCE_NOT_AVAILABLE (0xc00000ab) -#define STATUS_PIPE_NOT_AVAILABLE (0xc00000ac) -#define STATUS_INVALID_PIPE_STATE (0xc00000ad) -#define STATUS_PIPE_BUSY (0xc00000ae) -#define STATUS_ILLEGAL_FUNCTION (0xc00000af) -#define STATUS_PIPE_DISCONNECTED (0xc00000b0) -#define STATUS_PIPE_CLOSING (0xc00000b1) -#define STATUS_PIPE_CONNECTED (0xc00000b2) -#define STATUS_PIPE_LISTENING (0xc00000b3) -#define STATUS_INVALID_READ_MODE (0xc00000b4) -#define STATUS_IO_TIMEOUT (0xc00000b5) -#define STATUS_FILE_FORCED_CLOSED (0xc00000b6) -#define STATUS_PROFILING_NOT_STARTED (0xc00000b7) -#define STATUS_PROFILING_NOT_STOPPED (0xc00000b8) -#define STATUS_COULD_NOT_INTERPRET (0xc00000b9) -#define STATUS_FILE_IS_A_DIRECTORY (0xc00000ba) -#define STATUS_NOT_SUPPORTED (0xc00000bb) -#define STATUS_REMOTE_NOT_LISTENING (0xc00000bc) -#define STATUS_DUPLICATE_NAME (0xc00000bd) -#define STATUS_BAD_NETWORK_PATH (0xc00000be) -#define STATUS_NETWORK_BUSY (0xc00000bf) -#define STATUS_DEVICE_DOES_NOT_EXIST (0xc00000c0) -#define STATUS_TOO_MANY_COMMANDS (0xc00000c1) -#define STATUS_ADAPTER_HARDWARE_ERROR (0xc00000c2) -#define STATUS_INVALID_NETWORK_RESPONSE (0xc00000c3) -#define STATUS_UNEXPECTED_NETWORK_ERROR (0xc00000c4) -#define STATUS_BAD_REMOTE_ADAPTER (0xc00000c5) -#define STATUS_PRINT_QUEUE_FULL (0xc00000c6) -#define STATUS_NO_SPOOL_SPACE (0xc00000c7) -#define STATUS_PRINT_CANCELLED (0xc00000c8) -#define STATUS_NETWORK_NAME_DELETED (0xc00000c9) -#define STATUS_NETWORK_ACCESS_DENIED (0xc00000ca) -#define STATUS_BAD_DEVICE_TYPE (0xc00000cb) -#define STATUS_BAD_NETWORK_NAME (0xc00000cc) -#define STATUS_TOO_MANY_NAMES (0xc00000cd) -#define STATUS_TOO_MANY_SESSIONS (0xc00000ce) -#define STATUS_SHARING_PAUSED (0xc00000cf) -#define STATUS_REQUEST_NOT_ACCEPTED (0xc00000d0) -#define STATUS_REDIRECTOR_PAUSED (0xc00000d1) -#define STATUS_NET_WRITE_FAULT (0xc00000d2) -#define STATUS_PROFILING_AT_LIMIT (0xc00000d3) -#define STATUS_NOT_SAME_DEVICE (0xc00000d4) -#define STATUS_FILE_RENAMED (0xc00000d5) -#define STATUS_VIRTUAL_CIRCUIT_CLOSED (0xc00000d6) -#define STATUS_NO_SECURITY_ON_OBJECT (0xc00000d7) -#define STATUS_CANT_WAIT (0xc00000d8) -#define STATUS_PIPE_EMPTY (0xc00000d9) -#define STATUS_CANT_ACCESS_DOMAIN_INFO (0xc00000da) -#define STATUS_CANT_TERMINATE_SELF (0xc00000db) -#define STATUS_INVALID_SERVER_STATE (0xc00000dc) -#define STATUS_INVALID_DOMAIN_STATE (0xc00000dd) -#define STATUS_INVALID_DOMAIN_ROLE (0xc00000de) -#define STATUS_NO_SUCH_DOMAIN (0xc00000df) -#define STATUS_DOMAIN_EXISTS (0xc00000e0) -#define STATUS_DOMAIN_LIMIT_EXCEEDED (0xc00000e1) -#define STATUS_OPLOCK_NOT_GRANTED (0xc00000e2) -#define STATUS_INVALID_OPLOCK_PROTOCOL (0xc00000e3) -#define STATUS_INTERNAL_DB_CORRUPTION (0xc00000e4) -#define STATUS_INTERNAL_ERROR (0xc00000e5) -#define STATUS_GENERIC_NOT_MAPPED (0xc00000e6) -#define STATUS_BAD_DESCRIPTOR_FORMAT (0xc00000e7) -#define STATUS_INVALID_USER_BUFFER (0xc00000e8) -#define STATUS_UNEXPECTED_IO_ERROR (0xc00000e9) -#define STATUS_UNEXPECTED_MM_CREATE_ERR (0xc00000ea) -#define STATUS_UNEXPECTED_MM_MAP_ERROR (0xc00000eb) -#define STATUS_UNEXPECTED_MM_EXTEND_ERR (0xc00000ec) -#define STATUS_NOT_LOGON_PROCESS (0xc00000ed) -#define STATUS_LOGON_SESSION_EXISTS (0xc00000ee) -#define STATUS_INVALID_PARAMETER_1 (0xc00000ef) -#define STATUS_INVALID_PARAMETER_2 (0xc00000f0) -#define STATUS_INVALID_PARAMETER_3 (0xc00000f1) -#define STATUS_INVALID_PARAMETER_4 (0xc00000f2) -#define STATUS_INVALID_PARAMETER_5 (0xc00000f3) -#define STATUS_INVALID_PARAMETER_6 (0xc00000f4) -#define STATUS_INVALID_PARAMETER_7 (0xc00000f5) -#define STATUS_INVALID_PARAMETER_8 (0xc00000f6) -#define STATUS_INVALID_PARAMETER_9 (0xc00000f7) -#define STATUS_INVALID_PARAMETER_10 (0xc00000f8) -#define STATUS_INVALID_PARAMETER_11 (0xc00000f9) -#define STATUS_INVALID_PARAMETER_12 (0xc00000fa) -#define STATUS_REDIRECTOR_NOT_STARTED (0xc00000fb) -#define STATUS_REDIRECTOR_STARTED (0xc00000fc) -#define STATUS_STACK_OVERFLOW (0xc00000fd) -#define STATUS_NO_SUCH_PACKAGE (0xc00000fe) -#define STATUS_BAD_FUNCTION_TABLE (0xc00000ff) -#define STATUS_VARIABLE_NOT_FOUND (0xc0000100) -#define STATUS_DIRECTORY_NOT_EMPTY (0xc0000101) -#define STATUS_FILE_CORRUPT_ERROR (0xc0000102) -#define STATUS_NOT_A_DIRECTORY (0xc0000103) -#define STATUS_BAD_LOGON_SESSION_STATE (0xc0000104) -#define STATUS_LOGON_SESSION_COLLISION (0xc0000105) -#define STATUS_NAME_TOO_LONG (0xc0000106) -#define STATUS_FILES_OPEN (0xc0000107) -#define STATUS_CONNECTION_IN_USE (0xc0000108) -#define STATUS_MESSAGE_NOT_FOUND (0xc0000109) -#define STATUS_PROCESS_IS_TERMINATING (0xc000010a) -#define STATUS_INVALID_LOGON_TYPE (0xc000010b) -#define STATUS_NO_GUID_TRANSLATION (0xc000010c) -#define STATUS_CANNOT_IMPERSONATE (0xc000010d) -#define STATUS_IMAGE_ALREADY_LOADED (0xc000010e) -#define STATUS_ABIOS_NOT_PRESENT (0xc000010f) -#define STATUS_ABIOS_LID_NOT_EXIST (0xc0000110) -#define STATUS_ABIOS_LID_ALREADY_OWNED (0xc0000111) -#define STATUS_ABIOS_NOT_LID_OWNER (0xc0000112) -#define STATUS_ABIOS_INVALID_COMMAND (0xc0000113) -#define STATUS_ABIOS_INVALID_LID (0xc0000114) -#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (0xc0000115) -#define STATUS_ABIOS_INVALID_SELECTOR (0xc0000116) -#define STATUS_NO_LDT (0xc0000117) -#define STATUS_INVALID_LDT_SIZE (0xc0000118) -#define STATUS_INVALID_LDT_OFFSET (0xc0000119) -#define STATUS_INVALID_LDT_DESCRIPTOR (0xc000011a) -#define STATUS_INVALID_IMAGE_NE_FORMAT (0xc000011b) -#define STATUS_RXACT_INVALID_STATE (0xc000011c) -#define STATUS_RXACT_COMMIT_FAILURE (0xc000011d) -#define STATUS_MAPPED_FILE_SIZE_ZERO (0xc000011e) -#define STATUS_TOO_MANY_OPENED_FILES (0xc000011f) -#define STATUS_CANCELLED (0xc0000120) -#define STATUS_CANNOT_DELETE (0xc0000121) -#define STATUS_INVALID_COMPUTER_NAME (0xc0000122) -#define STATUS_FILE_DELETED (0xc0000123) -#define STATUS_SPECIAL_ACCOUNT (0xc0000124) -#define STATUS_SPECIAL_GROUP (0xc0000125) -#define STATUS_SPECIAL_USER (0xc0000126) -#define STATUS_MEMBERS_PRIMARY_GROUP (0xc0000127) -#define STATUS_FILE_CLOSED (0xc0000128) -#define STATUS_TOO_MANY_THREADS (0xc0000129) -#define STATUS_THREAD_NOT_IN_PROCESS (0xc000012a) -#define STATUS_TOKEN_ALREADY_IN_USE (0xc000012b) -#define STATUS_PAGEFILE_QUOTA_EXCEEDED (0xc000012c) -#define STATUS_COMMITMENT_LIMIT (0xc000012d) -#define STATUS_INVALID_IMAGE_LE_FORMAT (0xc000012e) -#define STATUS_INVALID_IMAGE_NOT_MZ (0xc000012f) -#define STATUS_INVALID_IMAGE_PROTECT (0xc0000130) -#define STATUS_INVALID_IMAGE_WIN_16 (0xc0000131) -#define STATUS_LOGON_SERVER_CONFLICT (0xc0000132) -#define STATUS_TIME_DIFFERENCE_AT_DC (0xc0000133) -#define STATUS_SYNCHRONIZATION_REQUIRED (0xc0000134) -#define STATUS_DLL_NOT_FOUND (0xc0000135) -#define STATUS_OPEN_FAILED (0xc0000136) -#define STATUS_IO_PRIVILEGE_FAILED (0xc0000137) -#define STATUS_ORDINAL_NOT_FOUND (0xc0000138) -#define STATUS_ENTRYPOINT_NOT_FOUND (0xc0000139) -#define STATUS_CONTROL_C_EXIT (0xc000013a) -#define STATUS_LOCAL_DISCONNECT (0xc000013b) -#define STATUS_REMOTE_DISCONNECT (0xc000013c) -#define STATUS_REMOTE_RESOURCES (0xc000013d) -#define STATUS_LINK_FAILED (0xc000013e) -#define STATUS_LINK_TIMEOUT (0xc000013f) -#define STATUS_INVALID_CONNECTION (0xc0000140) -#define STATUS_INVALID_ADDRESS (0xc0000141) -#define STATUS_DLL_INIT_FAILED (0xc0000142) -#define STATUS_MISSING_SYSTEMFILE (0xc0000143) -#define STATUS_UNHANDLED_EXCEPTION (0xc0000144) -#define STATUS_APP_INIT_FAILURE (0xc0000145) -#define STATUS_PAGEFILE_CREATE_FAILED (0xc0000146) -#define STATUS_NO_PAGEFILE (0xc0000147) -#define STATUS_INVALID_LEVEL (0xc0000148) -#define STATUS_WRONG_PASSWORD_CORE (0xc0000149) -#define STATUS_ILLEGAL_FLOAT_CONTEXT (0xc000014a) -#define STATUS_PIPE_BROKEN (0xc000014b) -#define STATUS_REGISTRY_CORRUPT (0xc000014c) -#define STATUS_REGISTRY_IO_FAILED (0xc000014d) -#define STATUS_NO_EVENT_PAIR (0xc000014e) -#define STATUS_UNRECOGNIZED_VOLUME (0xc000014f) -#define STATUS_SERIAL_NO_DEVICE_INITED (0xc0000150) -#define STATUS_NO_SUCH_ALIAS (0xc0000151) -#define STATUS_MEMBER_NOT_IN_ALIAS (0xc0000152) -#define STATUS_MEMBER_IN_ALIAS (0xc0000153) -#define STATUS_ALIAS_EXISTS (0xc0000154) -#define STATUS_LOGON_NOT_GRANTED (0xc0000155) -#define STATUS_TOO_MANY_SECRETS (0xc0000156) -#define STATUS_SECRET_TOO_LONG (0xc0000157) -#define STATUS_INTERNAL_DB_ERROR (0xc0000158) -#define STATUS_FULLSCREEN_MODE (0xc0000159) -#define STATUS_TOO_MANY_CONTEXT_IDS (0xc000015a) -#define STATUS_LOGON_TYPE_NOT_GRANTED (0xc000015b) -#define STATUS_NOT_REGISTRY_FILE (0xc000015c) -#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED (0xc000015d) -#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR (0xc000015e) -#define STATUS_FT_MISSING_MEMBER (0xc000015f) -#define STATUS_ILL_FORMED_SERVICE_ENTRY (0xc0000160) -#define STATUS_ILLEGAL_CHARACTER (0xc0000161) -#define STATUS_UNMAPPABLE_CHARACTER (0xc0000162) -#define STATUS_UNDEFINED_CHARACTER (0xc0000163) -#define STATUS_FLOPPY_VOLUME (0xc0000164) -#define STATUS_FLOPPY_ID_MARK_NOT_FOUND (0xc0000165) -#define STATUS_FLOPPY_WRONG_CYLINDER (0xc0000166) -#define STATUS_FLOPPY_UNKNOWN_ERROR (0xc0000167) -#define STATUS_FLOPPY_BAD_REGISTERS (0xc0000168) -#define STATUS_DISK_RECALIBRATE_FAILED (0xc0000169) -#define STATUS_DISK_OPERATION_FAILED (0xc000016a) -#define STATUS_DISK_RESET_FAILED (0xc000016b) -#define STATUS_SHARED_IRQ_BUSY (0xc000016c) -#define STATUS_FT_ORPHANING (0xc000016d) -#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT (0xc000016e) - -#define STATUS_PARTITION_FAILURE (0xc0000172) -#define STATUS_INVALID_BLOCK_LENGTH (0xc0000173) -#define STATUS_DEVICE_NOT_PARTITIONED (0xc0000174) -#define STATUS_UNABLE_TO_LOCK_MEDIA (0xc0000175) -#define STATUS_UNABLE_TO_UNLOAD_MEDIA (0xc0000176) -#define STATUS_EOM_OVERFLOW (0xc0000177) -#define STATUS_NO_MEDIA (0xc0000178) - -#define STATUS_NO_SUCH_MEMBER (0xc000017a) -#define STATUS_INVALID_MEMBER (0xc000017b) -#define STATUS_KEY_DELETED (0xc000017c) -#define STATUS_NO_LOG_SPACE (0xc000017d) -#define STATUS_TOO_MANY_SIDS (0xc000017e) -#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED (0xc000017f) -#define STATUS_KEY_HAS_CHILDREN (0xc0000180) -#define STATUS_CHILD_MUST_BE_VOLATILE (0xc0000181) -#define STATUS_DEVICE_CONFIGURATION_ERROR (0xc0000182) -#define STATUS_DRIVER_INTERNAL_ERROR (0xc0000183) -#define STATUS_INVALID_DEVICE_STATE (0xc0000184) -#define STATUS_IO_DEVICE_ERROR (0xc0000185) -#define STATUS_DEVICE_PROTOCOL_ERROR (0xc0000186) -#define STATUS_BACKUP_CONTROLLER (0xc0000187) -#define STATUS_LOG_FILE_FULL (0xc0000188) -#define STATUS_TOO_LATE (0xc0000189) -#define STATUS_NO_TRUST_LSA_SECRET (0xc000018a) -#define STATUS_NO_TRUST_SAM_ACCOUNT (0xc000018b) -#define STATUS_TRUSTED_DOMAIN_FAILURE (0xc000018c) -#define STATUS_TRUSTED_RELATIONSHIP_FAILURE (0xc000018d) -#define STATUS_EVENTLOG_FILE_CORRUPT (0xc000018e) -#define STATUS_EVENTLOG_CANT_START (0xc000018f) -#define STATUS_TRUST_FAILURE (0xc0000190) -#define STATUS_MUTANT_LIMIT_EXCEEDED (0xc0000191) -#define STATUS_NETLOGON_NOT_STARTED (0xc0000192) -#define STATUS_ACCOUNT_EXPIRED (0xc0000193) -#define STATUS_POSSIBLE_DEADLOCK (0xc0000194) -#define STATUS_NETWORK_CREDENTIAL_CONFLICT (0xc0000195) -#define STATUS_REMOTE_SESSION_LIMIT (0xc0000196) -#define STATUS_EVENTLOG_FILE_CHANGED (0xc0000197) -#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (0xc0000198) -#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (0xc0000199) -#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (0xc000019a) -#define STATUS_DOMAIN_TRUST_INCONSISTENT (0xc000019b) -#define STATUS_FS_DRIVER_REQUIRED (0xc000019c) - -#define STATUS_NO_USER_SESSION_KEY (0xc0000202) -#define STATUS_USER_SESSION_DELETED (0xc0000203) -#define STATUS_RESOURCE_LANG_NOT_FOUND (0xc0000204) -#define STATUS_INSUFF_SERVER_RESOURCES (0xc0000205) -#define STATUS_INVALID_BUFFER_SIZE (0xc0000206) -#define STATUS_INVALID_ADDRESS_COMPONENT (0xc0000207) -#define STATUS_INVALID_ADDRESS_WILDCARD (0xc0000208) -#define STATUS_TOO_MANY_ADDRESSES (0xc0000209) -#define STATUS_ADDRESS_ALREADY_EXISTS (0xc000020a) -#define STATUS_ADDRESS_CLOSED (0xc000020b) -#define STATUS_CONNECTION_DISCONNECTED (0xc000020c) -#define STATUS_CONNECTION_RESET (0xc000020d) -#define STATUS_TOO_MANY_NODES (0xc000020e) -#define STATUS_TRANSACTION_ABORTED (0xc000020f) -#define STATUS_TRANSACTION_TIMED_OUT (0xc0000210) -#define STATUS_TRANSACTION_NO_RELEASE (0xc0000211) -#define STATUS_TRANSACTION_NO_MATCH (0xc0000212) -#define STATUS_TRANSACTION_RESPONDED (0xc0000213) -#define STATUS_TRANSACTION_INVALID_ID (0xc0000214) -#define STATUS_TRANSACTION_INVALID_TYPE (0xc0000215) -#define STATUS_NOT_SERVER_SESSION (0xc0000216) -#define STATUS_NOT_CLIENT_SESSION (0xc0000217) -#define STATUS_CANNOT_LOAD_REGISTRY_FILE (0xc0000218) -#define STATUS_DEBUG_ATTACH_FAILED (0xc0000219) -#define STATUS_SYSTEM_PROCESS_TERMINATED (0xc000021a) -#define STATUS_DATA_NOT_ACCEPTED (0xc000021b) -#define STATUS_NO_BROWSER_SERVERS_FOUND (0xc000021c) -#define STATUS_VDM_HARD_ERROR (0xc000021d) -#define STATUS_DRIVER_CANCEL_TIMEOUT (0xc000021e) -#define STATUS_REPLY_MESSAGE_MISMATCH (0xc000021f) -#define STATUS_MAPPED_ALIGNMENT (0xc0000220) -#define STATUS_IMAGE_CHECKSUM_MISMATCH (0xc0000221) -#define STATUS_LOST_WRITEBEHIND_DATA (0xc0000222) -#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID (0xc0000223) -#define STATUS_PASSWORD_MUST_CHANGE (0xc0000224) -#define STATUS_NOT_FOUND (0xc0000225) -#define STATUS_NOT_TINY_STREAM (0xc0000226) -#define STATUS_RECOVERY_FAILURE (0xc0000227) -#define STATUS_STACK_OVERFLOW_READ (0xc0000228) -#define STATUS_FAIL_CHECK (0xc0000229) -#define STATUS_DUPLICATE_OBJECTID (0xc000022a) -#define STATUS_OBJECTID_EXISTS (0xc000022b) -#define STATUS_CONVERT_TO_LARGE (0xc000022c) -#define STATUS_RETRY (0xc000022d) -#define STATUS_FOUND_OUT_OF_SCOPE (0xc000022e) -#define STATUS_ALLOCATE_BUCKET (0xc000022f) -#define STATUS_PROPSET_NOT_FOUND (0xc0000230) -#define STATUS_MARSHALL_OVERFLOW (0xc0000231) -#define STATUS_INVALID_VARIANT (0xc0000232) -#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xc0000233) -#define STATUS_ACCOUNT_LOCKED_OUT (0xc0000234) -#define STATUS_HANDLE_NOT_CLOSABLE (0xc0000235) -#define STATUS_CONNECTION_REFUSED (0xc0000236) -#define STATUS_GRACEFUL_DISCONNECT (0xc0000237) -#define STATUS_ADDRESS_ALREADY_ASSOCIATED (0xc0000238) -#define STATUS_ADDRESS_NOT_ASSOCIATED (0xc0000239) -#define STATUS_CONNECTION_INVALID (0xc000023a) -#define STATUS_CONNECTION_ACTIVE (0xc000023b) -#define STATUS_NETWORK_UNREACHABLE (0xc000023c) -#define STATUS_HOST_UNREACHABLE (0xc000023d) -#define STATUS_PROTOCOL_UNREACHABLE (0xc000023e) -#define STATUS_PORT_UNREACHABLE (0xc000023f) -#define STATUS_REQUEST_ABORTED (0xc0000240) -#define STATUS_CONNECTION_ABORTED (0xc0000241) -#define STATUS_BAD_COMPRESSION_BUFFER (0xc0000242) -#define STATUS_USER_MAPPED_FILE (0xc0000243) -#define STATUS_AUDIT_FAILED (0xc0000244) -#define STATUS_TIMER_RESOLUTION_NOT_SET (0xc0000245) -#define STATUS_CONNECTION_COUNT_LIMIT (0xc0000246) -#define STATUS_LOGIN_TIME_RESTRICTION (0xc0000247) -#define STATUS_LOGIN_WKSTA_RESTRICTION (0xc0000248) -#define STATUS_IMAGE_MP_UP_MISMATCH (0xc0000249) - -#define STATUS_INSUFFICIENT_LOGON_INFO (0xc0000250) -#define STATUS_BAD_DLL_ENTRYPOINT (0xc0000251) -#define STATUS_BAD_SERVICE_ENTRYPOINT (0xc0000252) -#define STATUS_LPC_REPLY_LOST (0xc0000253) -#define STATUS_IP_ADDRESS_CONFLICT1 (0xc0000254) -#define STATUS_IP_ADDRESS_CONFLICT2 (0xc0000255) -#define STATUS_REGISTRY_QUOTA_LIMIT (0xc0000256) -#define STATUS_PATH_NOT_COVERED (0xc0000257) -#define STATUS_NO_CALLBACK_ACTIVE (0xc0000258) -#define STATUS_LICENSE_QUOTA_EXCEEDED (0xc0000259) -#define STATUS_PWD_TOO_SHORT (0xc000025a) -#define STATUS_PWD_TOO_RECENT (0xc000025b) -#define STATUS_PWD_HISTORY_CONFLICT (0xc000025c) -#define STATUS_PLUGPLAY_NO_DEVICE (0xc000025e) -#define STATUS_UNSUPPORTED_COMPRESSION (0xc000025f) -#define STATUS_INVALID_HW_PROFILE (0xc0000260) -#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH (0xc0000261) -#define STATUS_DRIVER_ORDINAL_NOT_FOUND (0xc0000262) -#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (0xc0000263) -#define STATUS_RESOURCE_NOT_OWNED (0xc0000264) -#define STATUS_TOO_MANY_LINKS (0xc0000265) -#define STATUS_QUOTA_LIST_INCONSISTENT (0xc0000266) -#define STATUS_FILE_IS_OFFLINE (0xc0000267) -#define STATUS_EVALUATION_EXPIRATION (0xc0000268) -#define STATUS_ILLEGAL_DLL_RELOCATION (0xc0000269) -#define STATUS_LICENSE_VIOLATION (0xc000026a) -#define STATUS_DLL_INIT_FAILED_LOGOFF (0xc000026b) -#define STATUS_DRIVER_UNABLE_TO_LOAD (0xc000026c) -#define STATUS_DFS_UNAVAILABLE (0xc000026d) -#define STATUS_VOLUME_DISMOUNTED (0xc000026e) -#define STATUS_WX86_INTERNAL_ERROR (0xc000026f) -#define STATUS_WX86_FLOAT_STACK_CHECK (0xc0000270) -#define STATUS_VALIDATE_CONTINUE (0xc0000271) -#define STATUS_NO_MATCH (0xc0000272) -#define STATUS_NO_MORE_MATCHES (0xc0000273) -#define STATUS_INVALID_VLM_OPERATION (0xc0000274) -#define STATUS_NOT_A_REPARSE_POINT (0xc0000275) -#define STATUS_IO_REPARSE_TAG_INVALID (0xc0000276) -#define STATUS_IO_REPARSE_TAG_MISMATCH (0xc0000277) -#define STATUS_IO_REPARSE_DATA_INVALID (0xc0000278) -#define STATUS_IO_REPARSE_TAG_NOT_HANDLED (0xc0000279) - - -#define STATUS_SAM_INIT_FAILURE (0xC00002CB) - - -#define RPC_NT_INVALID_STRING_BINDING (0xC0020001) -#define RPC_NT_WRONG_KIND_OF_BINDING (0xC0020002) -#define RPC_NT_INVALID_BINDING (0xC0020003) -#define RPC_NT_PROTSEQ_NOT_SUPPORTED (0xC0020004) -#define RPC_NT_INVALID_RPC_PROTSEQ (0xC0020005) -#define RPC_NT_INVALID_STRING_UUID (0xC0020006) -#define RPC_NT_INVALID_ENDPOINT_FORMAT (0xC0020007) -#define RPC_NT_INVALID_NET_ADDR (0xC0020008) -#define RPC_NT_NO_ENDPOINT_FOUND (0xC0020009) -#define RPC_NT_INVALID_TIMEOUT (0xC002000A) -#define RPC_NT_OBJECT_NOT_FOUND (0xC002000B) -#define RPC_NT_ALREADY_REGISTERED (0xC002000C) -#define RPC_NT_TYPE_ALREADY_REGISTERED (0xC002000D) -#define RPC_NT_ALREADY_LISTENING (0xC002000E) -#define RPC_NT_NO_PROTSEQS_REGISTERED (0xC002000F) -#define RPC_NT_NOT_LISTENING (0xC0020010) -#define RPC_NT_UNKNOWN_MGR_TYPE (0xC0020011) -#define RPC_NT_UNKNOWN_IF (0xC0020012) -#define RPC_NT_NO_BINDINGS (0xC0020013) -#define RPC_NT_NO_PROTSEQS (0xC0020014) -#define RPC_NT_CANT_CREATE_ENDPOINT (0xC0020015) -#define RPC_NT_OUT_OF_RESOURCES (0xC0020016) -#define RPC_NT_SERVER_UNAVAILABLE (0xC0020017) -#define RPC_NT_SERVER_TOO_BUSY (0xC0020018) -#define RPC_NT_INVALID_NETWORK_OPTIONS (0xC0020019) -#define RPC_NT_NO_CALL_ACTIVE (0xC002001A) -#define RPC_NT_CALL_FAILED (0xC002001B) -#define RPC_NT_CALL_FAILED_DNE (0xC002001C) -#define RPC_NT_PROTOCOL_ERROR (0xC002001D) - - -#define RPC_NT_SS_IN_NULL_CONTEXT (0xC0030004) +#define STATUS_REPARSE ((NTSTATUS)0x00000104) +#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105) +#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS)0x00000106) +#define STATUS_SOME_NOT_MAPPED ((NTSTATUS)0x00000107) +#define STATUS_OPLOCK_BREAK_IN_PROCESS ((NTSTATUS)0x00000108) +#define STATUS_VOLUME_MOUNTED ((NTSTATUS)0x00000109) +#define STATUS_RXACT_COMMITTED ((NTSTATUS)0x0000010A) +#define STATUS_NOTIFY_CLEANUP ((NTSTATUS)0x0000010B) +#define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS)0x0000010C) +#define STATUS_NO_QUOTAS_NO_ACCOUNT ((NTSTATUS)0x0000010D) +#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS)0x0000010E) + +#define STATUS_OBJECT_EXISTS ((NTSTATUS)0x40000000) +#define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS)0x40000001) +#define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS)0x40000002) +#define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003) +#define STATUS_RXACT_STATE_CREATED ((NTSTATUS)0x40000004) +#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005) +#define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS)0x40000006) +#define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS)0x40000007) +#define STATUS_SERIAL_MORE_WRITES ((NTSTATUS)0x40000008) +#define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009) +#define STATUS_FT_READ_RECOVERING_FROM_BACKUP ((NTSTATUS)0x4000000A) +#define STATUS_FT_WRITE_RECOVERY ((NTSTATUS)0x4000000B) +#define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS)0x4000000C) +#define STATUS_NULL_LM_PASSWORD ((NTSTATUS)0x4000000D) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS)0x4000000E) +#define STATUS_RECEIVE_PARTIAL ((NTSTATUS)0x4000000F) +#define STATUS_RECEIVE_EXPEDITED ((NTSTATUS)0x40000010) +#define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS)0x40000011) +#define STATUS_EVENT_DONE ((NTSTATUS)0x40000012) +#define STATUS_EVENT_PENDING ((NTSTATUS)0x40000013) +#define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS)0x40000014) +#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015) +#define STATUS_PREDEFINED_HANDLE ((NTSTATUS)0x40000016) +#define STATUS_WAS_UNLOCKED ((NTSTATUS)0x40000017) +#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018) +#define STATUS_WAS_LOCKED ((NTSTATUS)0x40000019) +#define STATUS_LOG_HARD_ERROR ((NTSTATUS)0x4000001A) +#define STATUS_ALREADY_WIN32 ((NTSTATUS)0x4000001B) +#define STATUS_WX86_UNSIMULATE ((NTSTATUS)0x4000001C) +#define STATUS_WX86_CONTINUE ((NTSTATUS)0x4000001D) +#define STATUS_WX86_SINGLE_STEP ((NTSTATUS)0x4000001E) +#define STATUS_WX86_BREAKPOINT ((NTSTATUS)0x4000001F) +#define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS)0x40000020) +#define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS)0x40000021) +#define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS)0x40000022) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS)0x40000023) +#define STATUS_NO_YIELD_PERFORMED ((NTSTATUS)0x40000024) +#define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS)0x40000025) +#define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS)0x40000026) +#define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS)0x40000027) +#define STATUS_WX86_CREATEWX86TIB ((NTSTATUS)0x40000028) + +#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001) +#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002) +#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003) +#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005) +#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006) +#define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS)0x80000007) + +#define STATUS_HANDLES_CLOSED ((NTSTATUS)0x8000000A) +#define STATUS_NO_INHERITANCE ((NTSTATUS)0x8000000B) +#define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS)0x8000000C) +#define STATUS_PARTIAL_COPY ((NTSTATUS)0x8000000D) +#define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS)0x8000000E) +#define STATUS_DEVICE_POWERED_OFF ((NTSTATUS)0x8000000F) +#define STATUS_DEVICE_OFF_LINE ((NTSTATUS)0x80000010) +#define STATUS_DEVICE_BUSY ((NTSTATUS)0x80000011) +#define STATUS_NO_MORE_EAS ((NTSTATUS)0x80000012) +#define STATUS_INVALID_EA_NAME ((NTSTATUS)0x80000013) +#define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS)0x80000014) +#define STATUS_INVALID_EA_FLAG ((NTSTATUS)0x80000015) +#define STATUS_VERIFY_REQUIRED ((NTSTATUS)0x80000016) +#define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS)0x80000017) +#define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS)0x80000018) + +#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001A) +#define STATUS_FILEMARK_DETECTED ((NTSTATUS)0x8000001B) +#define STATUS_MEDIA_CHANGED ((NTSTATUS)0x8000001C) +#define STATUS_BUS_RESET ((NTSTATUS)0x8000001D) +#define STATUS_END_OF_MEDIA ((NTSTATUS)0x8000001E) +#define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS)0x8000001F) +#define STATUS_MEDIA_CHECK ((NTSTATUS)0x80000020) +#define STATUS_SETMARK_DETECTED ((NTSTATUS)0x80000021) +#define STATUS_NO_DATA_DETECTED ((NTSTATUS)0x80000022) +#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS)0x80000023) +#define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS)0x80000024) +#define STATUS_ALREADY_DISCONNECTED ((NTSTATUS)0x80000025) +#define STATUS_LONGJUMP ((NTSTATUS)0x80000026) + +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xc0000001) +#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xc0000002) +#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xc0000003) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004) +#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xc0000005) +#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xc0000006) +#define STATUS_PAGEFILE_QUOTA ((NTSTATUS)0xc0000007) +#define STATUS_INVALID_HANDLE ((NTSTATUS)0xc0000008) +#define STATUS_BAD_INITIAL_STACK ((NTSTATUS)0xc0000009) +#define STATUS_BAD_INITIAL_PC ((NTSTATUS)0xc000000a) +#define STATUS_INVALID_CID ((NTSTATUS)0xc000000b) +#define STATUS_TIMER_NOT_CANCELED ((NTSTATUS)0xc000000c) +#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xc000000d) +#define STATUS_NO_SUCH_DEVICE ((NTSTATUS)0xc000000e) +#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xc000000f) +#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xc0000010) +#define STATUS_END_OF_FILE ((NTSTATUS)0xc0000011) +#define STATUS_WRONG_VOLUME ((NTSTATUS)0xc0000012) +#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS)0xc0000013) +#define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS)0xc0000014) +#define STATUS_NONEXISTENT_SECTOR ((NTSTATUS)0xc0000015) +#define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS)0xc0000016) +#define STATUS_NO_MEMORY ((NTSTATUS)0xc0000017) +#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xc0000018) +#define STATUS_NOT_MAPPED_VIEW ((NTSTATUS)0xc0000019) +#define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS)0xc000001a) +#define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS)0xc000001b) +#define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS)0xc000001c) +#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xc000001d) +#define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS)0xc000001e) +#define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xc000001f) +#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xc0000020) +#define STATUS_ALREADY_COMMITTED ((NTSTATUS)0xc0000021) +#define STATUS_ACCESS_DENIED ((NTSTATUS)0xc0000022) +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xc0000023) +#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xc0000024) +#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xc0000025) +#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xc0000026) +#define STATUS_UNWIND ((NTSTATUS)0xc0000027) +#define STATUS_BAD_STACK ((NTSTATUS)0xc0000028) +#define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS)0xc0000029) +#define STATUS_NOT_LOCKED ((NTSTATUS)0xc000002a) +#define STATUS_PARITY_ERROR ((NTSTATUS)0xc000002b) +#define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS)0xc000002c) +#define STATUS_NOT_COMMITTED ((NTSTATUS)0xc000002d) +#define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS)0xc000002e) +#define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS)0xc000002f) +#define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS)0xc0000030) +#define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS)0xc0000031) +#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS)0xc0000032) +#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xc0000033) +#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xc0000034) +#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xc0000035) +#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000) + + +#define STATUS_PORT_DISCONNECTED ((NTSTATUS)0xc0000037) +#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS)0xc0000038) +#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xc0000039) +#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xc000003a) +#define STATUS_PATH_SYNTAX_BAD ((NTSTATUS)0xc000003b) +#define STATUS_DATA_OVERRUN ((NTSTATUS)0xc000003c) +#define STATUS_DATA_LATE_ERROR ((NTSTATUS)0xc000003d) +#define STATUS_DATA_ERROR ((NTSTATUS)0xc000003e) +#define STATUS_CRC_ERROR ((NTSTATUS)0xc000003f) +#define STATUS_SECTION_TOO_BIG ((NTSTATUS)0xc0000040) +#define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS)0xc0000041) +#define STATUS_INVALID_PORT_HANDLE ((NTSTATUS)0xc0000042) +#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xc0000043) +#define STATUS_QUOTA_EXCEEDED ((NTSTATUS)0xc0000044) +#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xc0000045) +#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xc0000046) +#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xc0000047) +#define STATUS_PORT_ALREADY_SET ((NTSTATUS)0xc0000048) +#define STATUS_SECTION_NOT_IMAGE ((NTSTATUS)0xc0000049) +#define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS)0xc000004a) +#define STATUS_THREAD_IS_TERMINATING ((NTSTATUS)0xc000004b) +#define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS)0xc000004c) +#define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS)0xc000004d) +#define STATUS_SECTION_PROTECTION ((NTSTATUS)0xc000004e) +#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS)0xc000004f) +#define STATUS_EA_TOO_LARGE ((NTSTATUS)0xc0000050) +#define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS)0xc0000051) +#define STATUS_NO_EAS_ON_FILE ((NTSTATUS)0xc0000052) +#define STATUS_EA_CORRUPT_ERROR ((NTSTATUS)0xc0000053) +#define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS)0xc0000054) +#define STATUS_LOCK_NOT_GRANTED ((NTSTATUS)0xc0000055) +#define STATUS_DELETE_PENDING ((NTSTATUS)0xc0000056) +#define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS)0xc0000057) +#define STATUS_UNKNOWN_REVISION ((NTSTATUS)0xc0000058) +#define STATUS_REVISION_MISMATCH ((NTSTATUS)0xc0000059) +#define STATUS_INVALID_OWNER ((NTSTATUS)0xc000005a) +#define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS)0xc000005b) +#define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS)0xc000005c) +#define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS)0xc000005d) +#define STATUS_NO_LOGON_SERVERS ((NTSTATUS)0xc000005e) +#define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS)0xc000005f) +#define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS)0xc0000060) +#define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xc0000061) +#define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS)0xc0000062) +#define STATUS_USER_EXISTS ((NTSTATUS)0xc0000063) +#define STATUS_NO_SUCH_USER ((NTSTATUS)0xc0000064) +#define STATUS_GROUP_EXISTS ((NTSTATUS)0xc0000065) +#define STATUS_NO_SUCH_GROUP ((NTSTATUS)0xc0000066) +#define STATUS_MEMBER_IN_GROUP ((NTSTATUS)0xc0000067) +#define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS)0xc0000068) +#define STATUS_LAST_ADMIN ((NTSTATUS)0xc0000069) +#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xc000006a) +#define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS)0xc000006b) +#define STATUS_PASSWORD_RESTRICTION ((NTSTATUS)0xc000006c) +#define STATUS_LOGON_FAILURE ((NTSTATUS)0xc000006d) +#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xc000006e) +#define STATUS_INVALID_LOGON_HOURS ((NTSTATUS)0xc000006f) +#define STATUS_INVALID_WORKSTATION ((NTSTATUS)0xc0000070) +#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xc0000071) +#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xc0000072) +#define STATUS_NONE_MAPPED ((NTSTATUS)0xc0000073) +#define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS)0xc0000074) +#define STATUS_LUIDS_EXHAUSTED ((NTSTATUS)0xc0000075) +#define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS)0xc0000076) +#define STATUS_INVALID_ACL ((NTSTATUS)0xc0000077) +#define STATUS_INVALID_SID ((NTSTATUS)0xc0000078) +#define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS)0xc0000079) +#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xc000007a) +#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xc000007b) +#define STATUS_NO_TOKEN ((NTSTATUS)0xc000007c) +#define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS)0xc000007d) +#define STATUS_RANGE_NOT_LOCKED ((NTSTATUS)0xc000007e) +#define STATUS_DISK_FULL ((NTSTATUS)0xc000007f) +#define STATUS_SERVER_DISABLED ((NTSTATUS)0xc0000080) +#define STATUS_SERVER_NOT_DISABLED ((NTSTATUS)0xc0000081) +#define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS)0xc0000082) +#define STATUS_GUIDS_EXHAUSTED ((NTSTATUS)0xc0000083) +#define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS)0xc0000084) +#define STATUS_AGENTS_EXHAUSTED ((NTSTATUS)0xc0000085) +#define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS)0xc0000086) +#define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS)0xc0000087) +#define STATUS_NOT_MAPPED_DATA ((NTSTATUS)0xc0000088) +#define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS)0xc0000089) +#define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS)0xc000008a) +#define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS)0xc000008b) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xc000008c) +#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xc000008d) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xc000008e) +#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xc000008f) +#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xc0000090) +#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xc0000091) +#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xc0000092) +#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xc0000093) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xc0000094) +#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xc0000095) +#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xc0000096) +#define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS)0xc0000097) +#define STATUS_FILE_INVALID ((NTSTATUS)0xc0000098) +#define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS)0xc0000099) +#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xc000009a) +#define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS)0xc000009b) +#define STATUS_DEVICE_DATA_ERROR ((NTSTATUS)0xc000009c) +#define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS)0xc000009d) +#define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS)0xc000009e) +#define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS)0xc000009f) +#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xc00000a0) +#define STATUS_WORKING_SET_QUOTA ((NTSTATUS)0xc00000a1) +#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS)0xc00000a2) +#define STATUS_DEVICE_NOT_READY ((NTSTATUS)0xc00000a3) +#define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS)0xc00000a4) +#define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS)0xc00000a5) +#define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS)0xc00000a6) +#define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS)0xc00000a7) +#define STATUS_BAD_TOKEN_TYPE ((NTSTATUS)0xc00000a8) +#define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS)0xc00000a9) +#define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS)0xc00000aa) +#define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS)0xc00000ab) +#define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS)0xc00000ac) +#define STATUS_INVALID_PIPE_STATE ((NTSTATUS)0xc00000ad) +#define STATUS_PIPE_BUSY ((NTSTATUS)0xc00000ae) +#define STATUS_ILLEGAL_FUNCTION ((NTSTATUS)0xc00000af) +#define STATUS_PIPE_DISCONNECTED ((NTSTATUS)0xc00000b0) +#define STATUS_PIPE_CLOSING ((NTSTATUS)0xc00000b1) +#define STATUS_PIPE_CONNECTED ((NTSTATUS)0xc00000b2) +#define STATUS_PIPE_LISTENING ((NTSTATUS)0xc00000b3) +#define STATUS_INVALID_READ_MODE ((NTSTATUS)0xc00000b4) +#define STATUS_IO_TIMEOUT ((NTSTATUS)0xc00000b5) +#define STATUS_FILE_FORCED_CLOSED ((NTSTATUS)0xc00000b6) +#define STATUS_PROFILING_NOT_STARTED ((NTSTATUS)0xc00000b7) +#define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS)0xc00000b8) +#define STATUS_COULD_NOT_INTERPRET ((NTSTATUS)0xc00000b9) +#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xc00000ba) +#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xc00000bb) +#define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS)0xc00000bc) +#define STATUS_DUPLICATE_NAME ((NTSTATUS)0xc00000bd) +#define STATUS_BAD_NETWORK_PATH ((NTSTATUS)0xc00000be) +#define STATUS_NETWORK_BUSY ((NTSTATUS)0xc00000bf) +#define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS)0xc00000c0) +#define STATUS_TOO_MANY_COMMANDS ((NTSTATUS)0xc00000c1) +#define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS)0xc00000c2) +#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS)0xc00000c3) +#define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS)0xc00000c4) +#define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS)0xc00000c5) +#define STATUS_PRINT_QUEUE_FULL ((NTSTATUS)0xc00000c6) +#define STATUS_NO_SPOOL_SPACE ((NTSTATUS)0xc00000c7) +#define STATUS_PRINT_CANCELLED ((NTSTATUS)0xc00000c8) +#define STATUS_NETWORK_NAME_DELETED ((NTSTATUS)0xc00000c9) +#define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS)0xc00000ca) +#define STATUS_BAD_DEVICE_TYPE ((NTSTATUS)0xc00000cb) +#define STATUS_BAD_NETWORK_NAME ((NTSTATUS)0xc00000cc) +#define STATUS_TOO_MANY_NAMES ((NTSTATUS)0xc00000cd) +#define STATUS_TOO_MANY_SESSIONS ((NTSTATUS)0xc00000ce) +#define STATUS_SHARING_PAUSED ((NTSTATUS)0xc00000cf) +#define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS)0xc00000d0) +#define STATUS_REDIRECTOR_PAUSED ((NTSTATUS)0xc00000d1) +#define STATUS_NET_WRITE_FAULT ((NTSTATUS)0xc00000d2) +#define STATUS_PROFILING_AT_LIMIT ((NTSTATUS)0xc00000d3) +#define STATUS_NOT_SAME_DEVICE ((NTSTATUS)0xc00000d4) +#define STATUS_FILE_RENAMED ((NTSTATUS)0xc00000d5) +#define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS)0xc00000d6) +#define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS)0xc00000d7) +#define STATUS_CANT_WAIT ((NTSTATUS)0xc00000d8) +#define STATUS_PIPE_EMPTY ((NTSTATUS)0xc00000d9) +#define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS)0xc00000da) +#define STATUS_CANT_TERMINATE_SELF ((NTSTATUS)0xc00000db) +#define STATUS_INVALID_SERVER_STATE ((NTSTATUS)0xc00000dc) +#define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS)0xc00000dd) +#define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS)0xc00000de) +#define STATUS_NO_SUCH_DOMAIN ((NTSTATUS)0xc00000df) +#define STATUS_DOMAIN_EXISTS ((NTSTATUS)0xc00000e0) +#define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS)0xc00000e1) +#define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS)0xc00000e2) +#define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS)0xc00000e3) +#define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS)0xc00000e4) +#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xc00000e5) +#define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS)0xc00000e6) +#define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS)0xc00000e7) +#define STATUS_INVALID_USER_BUFFER ((NTSTATUS)0xc00000e8) +#define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS)0xc00000e9) +#define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS)0xc00000ea) +#define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS)0xc00000eb) +#define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS)0xc00000ec) +#define STATUS_NOT_LOGON_PROCESS ((NTSTATUS)0xc00000ed) +#define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS)0xc00000ee) +#define STATUS_INVALID_PARAMETER_1 ((NTSTATUS)0xc00000ef) +#define STATUS_INVALID_PARAMETER_2 ((NTSTATUS)0xc00000f0) +#define STATUS_INVALID_PARAMETER_3 ((NTSTATUS)0xc00000f1) +#define STATUS_INVALID_PARAMETER_4 ((NTSTATUS)0xc00000f2) +#define STATUS_INVALID_PARAMETER_5 ((NTSTATUS)0xc00000f3) +#define STATUS_INVALID_PARAMETER_6 ((NTSTATUS)0xc00000f4) +#define STATUS_INVALID_PARAMETER_7 ((NTSTATUS)0xc00000f5) +#define STATUS_INVALID_PARAMETER_8 ((NTSTATUS)0xc00000f6) +#define STATUS_INVALID_PARAMETER_9 ((NTSTATUS)0xc00000f7) +#define STATUS_INVALID_PARAMETER_10 ((NTSTATUS)0xc00000f8) +#define STATUS_INVALID_PARAMETER_11 ((NTSTATUS)0xc00000f9) +#define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xc00000fa) +#define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS)0xc00000fb) +#define STATUS_REDIRECTOR_STARTED ((NTSTATUS)0xc00000fc) +#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xc00000fd) +#define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xc00000fe) +#define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS)0xc00000ff) +#define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS)0xc0000100) +#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS)0xc0000101) +#define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS)0xc0000102) +#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xc0000103) +#define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS)0xc0000104) +#define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS)0xc0000105) +#define STATUS_NAME_TOO_LONG ((NTSTATUS)0xc0000106) +#define STATUS_FILES_OPEN ((NTSTATUS)0xc0000107) +#define STATUS_CONNECTION_IN_USE ((NTSTATUS)0xc0000108) +#define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS)0xc0000109) +#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xc000010a) +#define STATUS_INVALID_LOGON_TYPE ((NTSTATUS)0xc000010b) +#define STATUS_NO_GUID_TRANSLATION ((NTSTATUS)0xc000010c) +#define STATUS_CANNOT_IMPERSONATE ((NTSTATUS)0xc000010d) +#define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xc000010e) +#define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS)0xc000010f) +#define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS)0xc0000110) +#define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS)0xc0000111) +#define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS)0xc0000112) +#define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS)0xc0000113) +#define STATUS_ABIOS_INVALID_LID ((NTSTATUS)0xc0000114) +#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS)0xc0000115) +#define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS)0xc0000116) +#define STATUS_NO_LDT ((NTSTATUS)0xc0000117) +#define STATUS_INVALID_LDT_SIZE ((NTSTATUS)0xc0000118) +#define STATUS_INVALID_LDT_OFFSET ((NTSTATUS)0xc0000119) +#define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS)0xc000011a) +#define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS)0xc000011b) +#define STATUS_RXACT_INVALID_STATE ((NTSTATUS)0xc000011c) +#define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS)0xc000011d) +#define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS)0xc000011e) +#define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS)0xc000011f) +#define STATUS_CANCELLED ((NTSTATUS)0xc0000120) +#define STATUS_CANNOT_DELETE ((NTSTATUS)0xc0000121) +#define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS)0xc0000122) +#define STATUS_FILE_DELETED ((NTSTATUS)0xc0000123) +#define STATUS_SPECIAL_ACCOUNT ((NTSTATUS)0xc0000124) +#define STATUS_SPECIAL_GROUP ((NTSTATUS)0xc0000125) +#define STATUS_SPECIAL_USER ((NTSTATUS)0xc0000126) +#define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS)0xc0000127) +#define STATUS_FILE_CLOSED ((NTSTATUS)0xc0000128) +#define STATUS_TOO_MANY_THREADS ((NTSTATUS)0xc0000129) +#define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS)0xc000012a) +#define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS)0xc000012b) +#define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS)0xc000012c) +#define STATUS_COMMITMENT_LIMIT ((NTSTATUS)0xc000012d) +#define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS)0xc000012e) +#define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS)0xc000012f) +#define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS)0xc0000130) +#define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS)0xc0000131) +#define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS)0xc0000132) +#define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS)0xc0000133) +#define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS)0xc0000134) +#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xc0000135) +#define STATUS_OPEN_FAILED ((NTSTATUS)0xc0000136) +#define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS)0xc0000137) +#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xc0000138) +#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xc0000139) +#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xc000013a) +#define STATUS_LOCAL_DISCONNECT ((NTSTATUS)0xc000013b) +#define STATUS_REMOTE_DISCONNECT ((NTSTATUS)0xc000013c) +#define STATUS_REMOTE_RESOURCES ((NTSTATUS)0xc000013d) +#define STATUS_LINK_FAILED ((NTSTATUS)0xc000013e) +#define STATUS_LINK_TIMEOUT ((NTSTATUS)0xc000013f) +#define STATUS_INVALID_CONNECTION ((NTSTATUS)0xc0000140) +#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xc0000141) +#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xc0000142) +#define STATUS_MISSING_SYSTEMFILE ((NTSTATUS)0xc0000143) +#define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS)0xc0000144) +#define STATUS_APP_INIT_FAILURE ((NTSTATUS)0xc0000145) +#define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS)0xc0000146) +#define STATUS_NO_PAGEFILE ((NTSTATUS)0xc0000147) +#define STATUS_INVALID_LEVEL ((NTSTATUS)0xc0000148) +#define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS)0xc0000149) +#define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS)0xc000014a) +#define STATUS_PIPE_BROKEN ((NTSTATUS)0xc000014b) +#define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xc000014c) +#define STATUS_REGISTRY_IO_FAILED ((NTSTATUS)0xc000014d) +#define STATUS_NO_EVENT_PAIR ((NTSTATUS)0xc000014e) +#define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS)0xc000014f) +#define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS)0xc0000150) +#define STATUS_NO_SUCH_ALIAS ((NTSTATUS)0xc0000151) +#define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS)0xc0000152) +#define STATUS_MEMBER_IN_ALIAS ((NTSTATUS)0xc0000153) +#define STATUS_ALIAS_EXISTS ((NTSTATUS)0xc0000154) +#define STATUS_LOGON_NOT_GRANTED ((NTSTATUS)0xc0000155) +#define STATUS_TOO_MANY_SECRETS ((NTSTATUS)0xc0000156) +#define STATUS_SECRET_TOO_LONG ((NTSTATUS)0xc0000157) +#define STATUS_INTERNAL_DB_ERROR ((NTSTATUS)0xc0000158) +#define STATUS_FULLSCREEN_MODE ((NTSTATUS)0xc0000159) +#define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS)0xc000015a) +#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xc000015b) +#define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xc000015c) +#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xc000015d) +#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS)0xc000015e) +#define STATUS_FT_MISSING_MEMBER ((NTSTATUS)0xc000015f) +#define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS)0xc0000160) +#define STATUS_ILLEGAL_CHARACTER ((NTSTATUS)0xc0000161) +#define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS)0xc0000162) +#define STATUS_UNDEFINED_CHARACTER ((NTSTATUS)0xc0000163) +#define STATUS_FLOPPY_VOLUME ((NTSTATUS)0xc0000164) +#define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS)0xc0000165) +#define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS)0xc0000166) +#define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS)0xc0000167) +#define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS)0xc0000168) +#define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS)0xc0000169) +#define STATUS_DISK_OPERATION_FAILED ((NTSTATUS)0xc000016a) +#define STATUS_DISK_RESET_FAILED ((NTSTATUS)0xc000016b) +#define STATUS_SHARED_IRQ_BUSY ((NTSTATUS)0xc000016c) +#define STATUS_FT_ORPHANING ((NTSTATUS)0xc000016d) +#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS)0xc000016e) + +#define STATUS_PARTITION_FAILURE ((NTSTATUS)0xc0000172) +#define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS)0xc0000173) +#define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS)0xc0000174) +#define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS)0xc0000175) +#define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS)0xc0000176) +#define STATUS_EOM_OVERFLOW ((NTSTATUS)0xc0000177) +#define STATUS_NO_MEDIA ((NTSTATUS)0xc0000178) + +#define STATUS_NO_SUCH_MEMBER ((NTSTATUS)0xc000017a) +#define STATUS_INVALID_MEMBER ((NTSTATUS)0xc000017b) +#define STATUS_KEY_DELETED ((NTSTATUS)0xc000017c) +#define STATUS_NO_LOG_SPACE ((NTSTATUS)0xc000017d) +#define STATUS_TOO_MANY_SIDS ((NTSTATUS)0xc000017e) +#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xc000017f) +#define STATUS_KEY_HAS_CHILDREN ((NTSTATUS)0xc0000180) +#define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS)0xc0000181) +#define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS)0xc0000182) +#define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS)0xc0000183) +#define STATUS_INVALID_DEVICE_STATE ((NTSTATUS)0xc0000184) +#define STATUS_IO_DEVICE_ERROR ((NTSTATUS)0xc0000185) +#define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS)0xc0000186) +#define STATUS_BACKUP_CONTROLLER ((NTSTATUS)0xc0000187) +#define STATUS_LOG_FILE_FULL ((NTSTATUS)0xc0000188) +#define STATUS_TOO_LATE ((NTSTATUS)0xc0000189) +#define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS)0xc000018a) +#define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS)0xc000018b) +#define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS)0xc000018c) +#define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS)0xc000018d) +#define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS)0xc000018e) +#define STATUS_EVENTLOG_CANT_START ((NTSTATUS)0xc000018f) +#define STATUS_TRUST_FAILURE ((NTSTATUS)0xc0000190) +#define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS)0xc0000191) +#define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS)0xc0000192) +#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xc0000193) +#define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS)0xc0000194) +#define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS)0xc0000195) +#define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS)0xc0000196) +#define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS)0xc0000197) +#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS)0xc0000198) +#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS)0xc0000199) +#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS)0xc000019a) +#define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS)0xc000019b) +#define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS)0xc000019c) + +#define STATUS_NO_USER_SESSION_KEY ((NTSTATUS)0xc0000202) +#define STATUS_USER_SESSION_DELETED ((NTSTATUS)0xc0000203) +#define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS)0xc0000204) +#define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS)0xc0000205) +#define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS)0xc0000206) +#define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS)0xc0000207) +#define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS)0xc0000208) +#define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS)0xc0000209) +#define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS)0xc000020a) +#define STATUS_ADDRESS_CLOSED ((NTSTATUS)0xc000020b) +#define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS)0xc000020c) +#define STATUS_CONNECTION_RESET ((NTSTATUS)0xc000020d) +#define STATUS_TOO_MANY_NODES ((NTSTATUS)0xc000020e) +#define STATUS_TRANSACTION_ABORTED ((NTSTATUS)0xc000020f) +#define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS)0xc0000210) +#define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS)0xc0000211) +#define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS)0xc0000212) +#define STATUS_TRANSACTION_RESPONDED ((NTSTATUS)0xc0000213) +#define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS)0xc0000214) +#define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS)0xc0000215) +#define STATUS_NOT_SERVER_SESSION ((NTSTATUS)0xc0000216) +#define STATUS_NOT_CLIENT_SESSION ((NTSTATUS)0xc0000217) +#define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS)0xc0000218) +#define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS)0xc0000219) +#define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS)0xc000021a) +#define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS)0xc000021b) +#define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS)0xc000021c) +#define STATUS_VDM_HARD_ERROR ((NTSTATUS)0xc000021d) +#define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS)0xc000021e) +#define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS)0xc000021f) +#define STATUS_MAPPED_ALIGNMENT ((NTSTATUS)0xc0000220) +#define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS)0xc0000221) +#define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS)0xc0000222) +#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS)0xc0000223) +#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xc0000224) +#define STATUS_NOT_FOUND ((NTSTATUS)0xc0000225) +#define STATUS_NOT_TINY_STREAM ((NTSTATUS)0xc0000226) +#define STATUS_RECOVERY_FAILURE ((NTSTATUS)0xc0000227) +#define STATUS_STACK_OVERFLOW_READ ((NTSTATUS)0xc0000228) +#define STATUS_FAIL_CHECK ((NTSTATUS)0xc0000229) +#define STATUS_DUPLICATE_OBJECTID ((NTSTATUS)0xc000022a) +#define STATUS_OBJECTID_EXISTS ((NTSTATUS)0xc000022b) +#define STATUS_CONVERT_TO_LARGE ((NTSTATUS)0xc000022c) +#define STATUS_RETRY ((NTSTATUS)0xc000022d) +#define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS)0xc000022e) +#define STATUS_ALLOCATE_BUCKET ((NTSTATUS)0xc000022f) +#define STATUS_PROPSET_NOT_FOUND ((NTSTATUS)0xc0000230) +#define STATUS_MARSHALL_OVERFLOW ((NTSTATUS)0xc0000231) +#define STATUS_INVALID_VARIANT ((NTSTATUS)0xc0000232) +#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS)0xc0000233) +#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xc0000234) +#define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xc0000235) +#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xc0000236) +#define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS)0xc0000237) +#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xc0000238) +#define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS)0xc0000239) +#define STATUS_CONNECTION_INVALID ((NTSTATUS)0xc000023a) +#define STATUS_CONNECTION_ACTIVE ((NTSTATUS)0xc000023b) +#define STATUS_NETWORK_UNREACHABLE ((NTSTATUS)0xc000023c) +#define STATUS_HOST_UNREACHABLE ((NTSTATUS)0xc000023d) +#define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS)0xc000023e) +#define STATUS_PORT_UNREACHABLE ((NTSTATUS)0xc000023f) +#define STATUS_REQUEST_ABORTED ((NTSTATUS)0xc0000240) +#define STATUS_CONNECTION_ABORTED ((NTSTATUS)0xc0000241) +#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xc0000242) +#define STATUS_USER_MAPPED_FILE ((NTSTATUS)0xc0000243) +#define STATUS_AUDIT_FAILED ((NTSTATUS)0xc0000244) +#define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS)0xc0000245) +#define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS)0xc0000246) +#define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS)0xc0000247) +#define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS)0xc0000248) +#define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS)0xc0000249) + +#define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS)0xc0000250) +#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS)0xc0000251) +#define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS)0xc0000252) +#define STATUS_LPC_REPLY_LOST ((NTSTATUS)0xc0000253) +#define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS)0xc0000254) +#define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS)0xc0000255) +#define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS)0xc0000256) +#define STATUS_PATH_NOT_COVERED ((NTSTATUS)0xc0000257) +#define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS)0xc0000258) +#define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS)0xc0000259) +#define STATUS_PWD_TOO_SHORT ((NTSTATUS)0xc000025a) +#define STATUS_PWD_TOO_RECENT ((NTSTATUS)0xc000025b) +#define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS)0xc000025c) +#define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS)0xc000025e) +#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xc000025f) +#define STATUS_INVALID_HW_PROFILE ((NTSTATUS)0xc0000260) +#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS)0xc0000261) +#define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS)0xc0000262) +#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xc0000263) +#define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS)0xc0000264) +#define STATUS_TOO_MANY_LINKS ((NTSTATUS)0xc0000265) +#define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS)0xc0000266) +#define STATUS_FILE_IS_OFFLINE ((NTSTATUS)0xc0000267) +#define STATUS_EVALUATION_EXPIRATION ((NTSTATUS)0xc0000268) +#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS)0xc0000269) +#define STATUS_LICENSE_VIOLATION ((NTSTATUS)0xc000026a) +#define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS)0xc000026b) +#define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS)0xc000026c) +#define STATUS_DFS_UNAVAILABLE ((NTSTATUS)0xc000026d) +#define STATUS_VOLUME_DISMOUNTED ((NTSTATUS)0xc000026e) +#define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS)0xc000026f) +#define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS)0xc0000270) +#define STATUS_VALIDATE_CONTINUE ((NTSTATUS)0xc0000271) +#define STATUS_NO_MATCH ((NTSTATUS)0xc0000272) +#define STATUS_NO_MORE_MATCHES ((NTSTATUS)0xc0000273) +#define STATUS_INVALID_VLM_OPERATION ((NTSTATUS)0xc0000274) +#define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS)0xc0000275) +#define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS)0xc0000276) +#define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS)0xc0000277) +#define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS)0xc0000278) +#define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS)0xc0000279) + + +#define STATUS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002CB) + + +#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001) +#define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002) +#define RPC_NT_INVALID_BINDING ((NTSTATUS)0xC0020003) +#define RPC_NT_PROTSEQ_NOT_SUPPORTED ((NTSTATUS)0xC0020004) +#define RPC_NT_INVALID_RPC_PROTSEQ ((NTSTATUS)0xC0020005) +#define RPC_NT_INVALID_STRING_UUID ((NTSTATUS)0xC0020006) +#define RPC_NT_INVALID_ENDPOINT_FORMAT ((NTSTATUS)0xC0020007) +#define RPC_NT_INVALID_NET_ADDR ((NTSTATUS)0xC0020008) +#define RPC_NT_NO_ENDPOINT_FOUND ((NTSTATUS)0xC0020009) +#define RPC_NT_INVALID_TIMEOUT ((NTSTATUS)0xC002000A) +#define RPC_NT_OBJECT_NOT_FOUND ((NTSTATUS)0xC002000B) +#define RPC_NT_ALREADY_REGISTERED ((NTSTATUS)0xC002000C) +#define RPC_NT_TYPE_ALREADY_REGISTERED ((NTSTATUS)0xC002000D) +#define RPC_NT_ALREADY_LISTENING ((NTSTATUS)0xC002000E) +#define RPC_NT_NO_PROTSEQS_REGISTERED ((NTSTATUS)0xC002000F) +#define RPC_NT_NOT_LISTENING ((NTSTATUS)0xC0020010) +#define RPC_NT_UNKNOWN_MGR_TYPE ((NTSTATUS)0xC0020011) +#define RPC_NT_UNKNOWN_IF ((NTSTATUS)0xC0020012) +#define RPC_NT_NO_BINDINGS ((NTSTATUS)0xC0020013) +#define RPC_NT_NO_PROTSEQS ((NTSTATUS)0xC0020014) +#define RPC_NT_CANT_CREATE_ENDPOINT ((NTSTATUS)0xC0020015) +#define RPC_NT_OUT_OF_RESOURCES ((NTSTATUS)0xC0020016) +#define RPC_NT_SERVER_UNAVAILABLE ((NTSTATUS)0xC0020017) +#define RPC_NT_SERVER_TOO_BUSY ((NTSTATUS)0xC0020018) +#define RPC_NT_INVALID_NETWORK_OPTIONS ((NTSTATUS)0xC0020019) +#define RPC_NT_NO_CALL_ACTIVE ((NTSTATUS)0xC002001A) +#define RPC_NT_CALL_FAILED ((NTSTATUS)0xC002001B) +#define RPC_NT_CALL_FAILED_DNE ((NTSTATUS)0xC002001C) +#define RPC_NT_PROTOCOL_ERROR ((NTSTATUS)0xC002001D) + + +#define RPC_NT_SS_IN_NULL_CONTEXT ((NTSTATUS)0xC0030004) /* FIXME: Are these official values ?? */ -#define STATUS_FS_QUERY_REQUIRED (0xC1000001) -#define STATUS_HANDLE_NOT_WAITABLE (0xC1000002) -#define STATUS_OBJECT_FILE_MISMATCH (0xC1000003) -#define STATUS_INVALID_PARAMETER_MAX (0xC1000004) -#define STATUS_CONFLICTING_ADDRESS (0xC1000005) -#define STATUS_NO_MEDIA_IN_DRIVE (0xC1000006) +#define STATUS_FS_QUERY_REQUIRED ((NTSTATUS)0xC1000001) +#define STATUS_HANDLE_NOT_WAITABLE ((NTSTATUS)0xC1000002) +#define STATUS_OBJECT_FILE_MISMATCH ((NTSTATUS)0xC1000003) +#define STATUS_INVALID_PARAMETER_MAX ((NTSTATUS)0xC1000004) +#define STATUS_CONFLICTING_ADDRESS ((NTSTATUS)0xC1000005) +#define STATUS_NO_MEDIA_IN_DRIVE ((NTSTATUS)0xC1000006) + +#else /* !__ASM__ */ + +#define STATUS_INVALID_SYSTEM_SERVICE 0xc000001c + +#endif /* !__ASM__ */ #endif /* __INCLUDE_DDK_STATUS_H */ diff --git a/include/ddk/winddi.h b/include/ddk/winddi.h index c4de4c7..7c69738 100644 --- a/include/ddk/winddi.h +++ b/include/ddk/winddi.h @@ -388,9 +388,9 @@ enum _SPS_RC enum _SURF_TYPES { - STYPE_BITMAP = 1, - STYPE_DEVICE, - STYPE_DEVBITMAP + STYPE_BITMAP = 0, + STYPE_DEVICE = 1, + STYPE_DEVBITMAP = 3 }; #define WO_RGN_CLIENT_DELTA 0x00000001 diff --git a/include/debug.h b/include/debug.h index 75d8798..38c9223 100644 --- a/include/debug.h +++ b/include/debug.h @@ -23,11 +23,13 @@ #define CHECKED #endif +#ifndef assert #ifndef NASSERT #define assert(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); } #else #define assert(x) #endif +#endif #define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0); diff --git a/include/defines.h b/include/defines.h index 3923d6a..30cca02 100644 --- a/include/defines.h +++ b/include/defines.h @@ -570,7 +570,7 @@ extern "C" { #define TAPE_SHORT_FILEMARKS (0x2L) /* CreateWindow */ -#define CW_USEDEFAULT (0x80000000) +#define CW_USEDEFAULT (0x80000000L) #define WS_BORDER (0x800000L) #define WS_CAPTION (0xc00000L) #define WS_CHILD (0x40000000L) @@ -848,6 +848,10 @@ extern "C" { #define DC_SMALLCAP (2) /* DrawEdge */ +#define BDR_OUTER (3) +#define BDR_INNER (12) +#define BDR_RAISED (5) +#define BDR_SUNKEN (10) #define BDR_RAISEDINNER (4) #define BDR_SUNKENINNER (8) #define BDR_RAISEDOUTER (1) @@ -3568,6 +3572,7 @@ extern "C" { #define LVS_SMALLICON (2) #define LVS_SORTASCENDING (16) #define LVS_SORTDESCENDING (32) +#define LVS_OWNERDATA 0x1000 #define LVS_TYPESTYLEMASK (64512) #define LVSIL_NORMAL (0) #define LVSIL_SMALL (1) @@ -4187,23 +4192,24 @@ extern "C" { #define HTBOTTOMRIGHT (17) #define HTCAPTION (2) #define HTCLIENT (1) -#define HTERROR (-2) +#define HTERROR (-2) #define HTGROWBOX (4) #define HTHSCROLL (6) -#define HTLEFT (10) -#define HTMENU (5) +#define HTLEFT (10) +#define HTMENU (5) #define HTNOWHERE (0) #define HTREDUCE (8) -#define HTRIGHT (11) -#define HTSIZE (4) +#define HTRIGHT (11) +#define HTSIZE (4) #define HTSYSMENU (3) -#define HTTOP (12) +#define HTTOP (12) #define HTTOPLEFT (13) #define HTTOPRIGHT (14) #define HTTRANSPARENT (-1) #define HTVSCROLL (7) -#define HTZOOM (9) -#define HTBORDER (18) +#define HTZOOM (9) +#define HTBORDER (18) +#define HTCLOSE (20) #define HTMAXBUTTON HTZOOM #define HTMINBUTTON HTREDUCE @@ -4479,6 +4485,24 @@ extern "C" { #define TMPF_TRUETYPE (0x4) #define TMPF_DEVICE (0x8) +/* CopyFileEx options */ +#define COPY_FILE_FAIL_IF_EXISTS (1) + +/* CopyProgressRoutine callback */ +#define CALLBACK_CHUNK_FINISHED (0) +#define CALLBACK_STREAM_SWITCH (1) + +#define PROGRESS_CONTINUE (0) +#define PROGRESS_CANCEL (1) +#define PROGRESS_STOP (2) +#define PROGRESS_QUIET (3) + +/* GetFileAttributes */ +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + +/* GetFileCompressedSize */ +#define INVALID_FILE_SIZE ((DWORD)-1) + /* --------------------- old stuff, need to organize! --------------- */ /* BEGINNING of windowsx.h stuff from old headers: */ @@ -4718,6 +4742,52 @@ DECLARE_HANDLE(HANDLE); #endif +#ifndef __USE_W32API + + +typedef enum _SC_STATUS_TYPE { + SC_STATUS_PROCESS_INFO = 0 +} SC_STATUS_TYPE; + +typedef enum _SC_ENUM_TYPE { + SC_ENUM_PROCESS_INFO = 0 +} SC_ENUM_TYPE; + +#endif /* !__USE_W32API */ + +typedef enum _SystemState { + STATE_SYSTEM_UNAVAILABLE = 0x00000001, // Disabled + STATE_SYSTEM_SELECTED = 0x00000002, + STATE_SYSTEM_FOCUSED = 0x00000004, + STATE_SYSTEM_PRESSED = 0x00000008, + STATE_SYSTEM_CHECKED = 0x00000010, + STATE_SYSTEM_MIXED = 0x00000020, // 3-state checkbox or toolbar button + STATE_SYSTEM_READONLY = 0x00000040, + STATE_SYSTEM_HOTTRACKED = 0x00000080, + STATE_SYSTEM_DEFAULT = 0x00000100, + STATE_SYSTEM_EXPANDED = 0x00000200, + STATE_SYSTEM_COLLAPSED = 0x00000400, + STATE_SYSTEM_BUSY = 0x00000800, + STATE_SYSTEM_FLOATING = 0x00001000, // Children "owned" not "contained" by parent + STATE_SYSTEM_MARQUEED = 0x00002000, + STATE_SYSTEM_ANIMATED = 0x00004000, + STATE_SYSTEM_INVISIBLE = 0x00008000, + STATE_SYSTEM_OFFSCREEN = 0x00010000, + STATE_SYSTEM_SIZEABLE = 0x00020000, + STATE_SYSTEM_MOVEABLE = 0x00040000, + STATE_SYSTEM_SELFVOICING = 0x00080000, + STATE_SYSTEM_FOCUSABLE = 0x00100000, + STATE_SYSTEM_SELECTABLE = 0x00200000, + STATE_SYSTEM_LINKED = 0x00400000, + STATE_SYSTEM_TRAVERSED = 0x00800000, + STATE_SYSTEM_MULTISELECTABLE = 0x01000000, // Supports multiple selection + STATE_SYSTEM_EXTSELECTABLE = 0x02000000, // Supports extended selection + STATE_SYSTEM_ALERT_LOW = 0x04000000, // This information is of low priority + STATE_SYSTEM_ALERT_MEDIUM = 0x08000000, // This information is of medium priority + STATE_SYSTEM_ALERT_HIGH = 0x10000000, // This information is of high priority + STATE_SYSTEM_VALID = 0x1FFFFFFF +} SystemState; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/errors.h b/include/errors.h index fbb4023..30a219b 100644 --- a/include/errors.h +++ b/include/errors.h @@ -58,6 +58,10 @@ extern "C" { #define LZERROR_BADOUTHANDLE (-2) #define LZERROR_BADINHANDLE (-1) #define NO_ERROR 0L + +#if 0 +#include "../reactos/errcodes.h" +#else #define ERROR_SUCCESS 0L #define ERROR_INVALID_FUNCTION 1L #define ERROR_FILE_NOT_FOUND 2L @@ -724,6 +728,7 @@ extern "C" { #define ERROR_REC_NON_EXISTENT 4005L #define ERROR_RPL_NOT_ALLOWED 4006L #define ERROR_NO_BROWSER_SERVERS_FOUND 6118L +#endif /* HRESULT values for OLE, SHELL and other Interface stuff */ diff --git a/include/excpt.h b/include/excpt.h index a10c909..865e66d 100644 --- a/include/excpt.h +++ b/include/excpt.h @@ -19,7 +19,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -96,7 +96,7 @@ typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; /* - * A macro which (dispite its name) *removes* an installed + * A macro which (despite its name) *removes* an installed * exception handler. Should be used only in conjunction with the above * install routine __try1. * Move the pointer to the old reg. struct (at the current stack diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h index 8b1e4dd..530c067 100644 --- a/include/freetype/internal/ftdebug.h +++ b/include/freetype/internal/ftdebug.h @@ -130,12 +130,16 @@ /*************************************************************************/ +#if __GNUC__ >= 3 +#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ +#else #define FT_TRACE( level, varformat ) \ do \ { \ if ( ft_trace_levels[FT_COMPONENT] >= level ) \ FT_XCAT( FT_Message, varformat ); \ } while ( 0 ) +#endif FT_EXPORT_DEF( void ) FT_SetTraceLevel( FT_Trace component, @@ -190,8 +194,11 @@ /* print a message and exit */ FT_EXPORT_DEF( void ) FT_Panic( const char* fmt, ... ); +#if __GNUC__ >= 3 +#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ +#else #define FT_ERROR( varformat ) FT_XCAT( FT_Message, varformat ) - +#endif #endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */ diff --git a/include/funcs.h b/include/funcs.h index 1d0902f..3c1798b 100644 --- a/include/funcs.h +++ b/include/funcs.h @@ -37,6 +37,19 @@ extern "C" { #endif /* __cplusplus */ +typedef +DWORD (CALLBACK *PPROGRESS_ROUTINE)( + LARGE_INTEGER TotalFileSize, + LARGE_INTEGER TotalBytesTransferred, + LARGE_INTEGER StreamSize, + LARGE_INTEGER StreamBytesTransferred, + DWORD StreamNumber, + DWORD CallbackReason, + HANDLE SourceFile, + HANDLE DestinationFile, + LPVOID UserData); +typedef PPROGRESS_ROUTINE LPPROGRESS_ROUTINE; + /* These functions were a real pain, having to figure out which had Unicode/Ascii versions and which did not */ @@ -341,8 +354,10 @@ extern "C" { #define FindNextFile FindNextFileW #define SearchPath SearchPathW #define CopyFile CopyFileW +#define CopyFileEx CopyFileExW #define MoveFile MoveFileW #define MoveFileEx MoveFileExW +#define MoveFileWithProgress MoveFileWithProgressW #define CreateNamedPipe CreateNamedPipeW #define GetNamedPipeHandleState GetNamedPipeHandleStateW #define CallNamedPipe CallNamedPipeW @@ -745,8 +760,10 @@ extern "C" { #define FindNextFile FindNextFileA #define SearchPath SearchPathA #define CopyFile CopyFileA +#define CopyFileEx CopyFileExA #define MoveFile MoveFileA #define MoveFileEx MoveFileExA +#define MoveFileWithProgress MoveFileWithProgressA #define CreateNamedPipe CreateNamedPipeA #define GetNamedPipeHandleState GetNamedPipeHandleStateA #define CallNamedPipe CallNamedPipeA @@ -865,7 +882,6 @@ int STDCALL AbortDoc(HDC); WINBOOL STDCALL AbortPath(HDC); WINBOOL STDCALL AbortPrinter(HANDLE); WINBOOL CALLBACK AbortProc(HDC, int); -WINBOOL STDCALL AbortSystemShutdown(LPTSTR); WINBOOL STDCALL AccessCheck( PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, @@ -933,7 +949,11 @@ LockResource( ); int +#ifdef __GNUC__ STDCALL +#else +__stdcall +#endif WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -5503,7 +5523,8 @@ WINBOOL STDCALL DrawEdge(HDC hdc, LPRECT qrc, UINT edge, UINT grfFlags); -WINBOOL STDCALL +WINBOOL +STDCALL DrawFrameControl(HDC, LPRECT, UINT, UINT); WINBOOL diff --git a/include/kernel32/winnls.h b/include/kernel32/winnls.h index b293529..d07a3ba 100644 --- a/include/kernel32/winnls.h +++ b/include/kernel32/winnls.h @@ -151,12 +151,12 @@ #define SUBLANGID(l) ((WORD)(l) >> 10) #endif -#if 0 +#ifdef _KERNEL32_INCLUDE_LANG_ #define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)) #define LANG_USER_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)) -#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)) -#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT)) -#define LOCALE_NEUTRAL (MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)) +//#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)) +//#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT)) +//#define LOCALE_NEUTRAL (MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)) #endif /* Language IDs (were in winnt.h, for some reason) */ diff --git a/include/libc/atexit.h b/include/libc/atexit.h index b3a9f01..5dbdffe 100644 --- a/include/libc/atexit.h +++ b/include/libc/atexit.h @@ -1,6 +1,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #ifndef __dj_include_libc_atexit_h__ -#define __dj_include_libc_dosexec_h__ +#define __dj_include_libc_atexit_h__ #ifdef __cplusplus extern "C" { @@ -30,4 +30,4 @@ extern struct __atexit *__atexit_ptr; } #endif -#endif /* __dj_include_libc_dosexec_h__ */ +#endif /* __dj_include_libc_atexit_h__ */ diff --git a/include/msvcrt/alloc.h b/include/msvcrt/alloc.h index 3a97961..c18bb7b 100644 --- a/include/msvcrt/alloc.h +++ b/include/msvcrt/alloc.h @@ -22,7 +22,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -33,14 +33,14 @@ #ifndef __STRICT_ANSI__ -#ifndef _ALLOC_H_ -#define _ALLOC_H_ +#ifndef _ALLOC_H_ +#define _ALLOC_H_ #include #ifndef RC_INVOKED -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -48,38 +48,39 @@ extern "C" { * The structure used to walk through the heap with _heapwalk. * TODO: This is a guess at the internals of this structure. */ -typedef struct _heapinfo +typedef struct _heapinfo { - void* ptr; - unsigned int size; - int in_use; + void* ptr; + unsigned int size; + int in_use; } _HEAPINFO; -int _heapwalk (_HEAPINFO* pHeapinfo); +int _heapwalk(_HEAPINFO* pHeapinfo); #ifdef __GNUC__ #ifdef USE_C_ALLOCA -void * C_alloca(size_t size); -#define _alloca(x) C_alloca(x) -#else /* USE_C_ALLOCA */ -#define _alloca(x) __builtin_alloca(x) -#endif /* USE_C_ALLOCA */ -#else /* __GNUC__ */ -void * _alloca(size_t size); -#endif /* __GNUC__ */ +void* C_alloca(size_t size); +#define _alloca(x) C_alloca(x) +#else /* USE_C_ALLOCA */ +#define _alloca(x) __builtin_alloca(x) +#endif /* USE_C_ALLOCA */ +#else /* __GNUC__ */ +void* _alloca(size_t size); +#endif /* __GNUC__ */ -#ifndef _NO_OLDNAMES -#define heapwalk(x) _heapwalk(x) -#define alloca(s) _alloca(s) -#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifndef _NO_OLDNAMES +#define heapwalk(x) _heapwalk(x) +#define alloca(s) _alloca(s) +#endif /* Not _NO_OLDNAMES */ + +#ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ +#endif /* Not RC_INVOKED */ -#endif /* Not _ALLOC_H_ */ +#endif /* Not _ALLOC_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/assert.h b/include/msvcrt/assert.h index 8d85fcf..bad7931 100644 --- a/include/msvcrt/assert.h +++ b/include/msvcrt/assert.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -25,9 +25,10 @@ */ #ifndef _ASSERT_H_ -#define _ASSERT_H_ +#define _ASSERT_H_ -#ifdef __cplusplus + +#ifdef __cplusplus extern "C" { #endif @@ -36,7 +37,7 @@ extern "C" { /* * If not debugging, assert does nothing. */ -#define assert(x) ((void)0); +#define assert(x) ((void)0) #else /* debugging enabled */ @@ -44,26 +45,25 @@ extern "C" { * CRTDLL nicely supplies a function which does the actual output and * call to abort. */ -#ifndef __ATTRIB_NORETURN -#ifdef __GNUC__ -#define _ATTRIB_NORETURN __attribute__ ((noreturn)) -#else /* Not __GNUC__ */ -#define _ATTRIB_NORETURN -#endif /* __GNUC__ */ +#ifndef __ATTRIB_NORETURN +#ifdef __GNUC__ +#define _ATTRIB_NORETURN __attribute__ ((noreturn)) +#else /* Not __GNUC__ */ +#define _ATTRIB_NORETURN +#endif /* __GNUC__ */ #endif -void _assert (const char* szExpression, const char* szFileName, int nLine) -_ATTRIB_NORETURN -; +void _assert(const char* szExpression, const char* szFileName, int nLine) _ATTRIB_NORETURN; /* * Definition of the assert macro. */ -#define assert(x) if(!(x)) _assert( #x , __FILE__, __LINE__); -#endif /* NDEBUG */ +#define assert(x) if(!(x)) _assert( #x , __FILE__, __LINE__); +#endif /* NDEBUG */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif +#endif /* Not _ASSERT_H_ */ + diff --git a/include/msvcrt/conio.h b/include/msvcrt/conio.h index db012be..4403d06 100644 --- a/include/msvcrt/conio.h +++ b/include/msvcrt/conio.h @@ -16,7 +16,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -25,43 +25,39 @@ * */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ -#ifndef _CONIO_H_ -#define _CONIO_H_ +#ifndef _CONIO_H_ +#define _CONIO_H_ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -char* _cgets (char* szBuffer); -int _cprintf (const char* szFormat, ...); -int _cputs (const char* szString); -int _cscanf (char* szFormat, ...); +char* _cgets(char*); +int _cprintf(const char*, ...); +int _cputs(const char*); +int _cscanf(char*, ...); +int _getch(void); +int _getche(void); +int _kbhit(void); +int _putch(int); +int _ungetch(int); -int _getch (void); -int _getche (void); -int _kbhit (void); -int _putch (int cPut); -int _ungetch (int cUnget); +#ifndef _NO_OLDNAMES +#define getch _getch +#define getche _getche +#define kbhit _kbhit +#define putch(cPut) _putch(cPut) +#define ungetch(cUnget) _ungetch(cUnget) +#endif /* Not _NO_OLDNAMES */ -#ifndef _NO_OLDNAMES - -#define getch _getch -#define getche _getche -#define kbhit _kbhit -#define putch(cPut) _putch(cPut) -#define ungetch(cUnget) _ungetch(cUnget) - -#endif /* Not _NO_OLDNAMES */ - - -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not _CONIO_H_ */ +#endif /* Not _CONIO_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/crttypes.h b/include/msvcrt/crttypes.h new file mode 100644 index 0000000..fe15209 --- /dev/null +++ b/include/msvcrt/crttypes.h @@ -0,0 +1,63 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: include/msvcrt/crttypes.h + * PURPOSE: + * PROGRAMMER: + * UPDATE HISTORY: + * + */ + +#ifndef __CRT_TYPES__ +#define __CRT_TYPES__ + + +#ifdef __GNUC__ + +//typedef long long LONGLONG; +//typedef unsigned long long ULONGLONG; +//typedef long long *PLONGLONG; +//typedef unsigned long long *PULONGLONG; +#define HAVE_LONGLONG +#define LONGLONG_DEFINED +#define LONGLONG long long +#define ULONGLONG unsigned long long +#define PLONGLONG long long * +#define PULONGLONG unsigned long long * + +#else /*__GNUC__*/ + +#define LONGLONG_DEFINED +#define LONGLONG __int64 +#define ULONGLONG unsigned __int64 +#define PLONGLONG __int64* +#define PULONGLONG unsigned __int64* +#define __attribute__(a) +#define __volatile + +#define inline __inline +#define __asm__ +#define __volatile__(a) +#define __attribute__(a) +struct _KTHREAD { int foobar; }; +struct _ETHREAD { int foobar; }; +struct _EPROCESS { int foobar; }; + +#ifndef _DEBUG +#pragma function(_disable,_enable) +#pragma function(_inp,_inpw,_outp,_outpw) +#pragma function(_lrotl,_lrotr,_rotl,_rotr) +#pragma function(abs,fabs,labs) +#pragma function(memcpy,memcmp,memset) +#pragma function(strcat,strcmp,strcpy,strlen,_strset) +#pragma function(fmod,sqrt) +#pragma function(log,log10,pow,exp) +#pragma function(tan,atan,atan2,tanh) +#pragma function(cos,acos,cosh) +#pragma function(sin,asin,sinh) +#endif + +#endif /*__GNUC__*/ + + +#endif /* __CRT_TYPES__ */ diff --git a/include/msvcrt/ctype.h b/include/msvcrt/ctype.h index c610ba9..877b993 100644 --- a/include/msvcrt/ctype.h +++ b/include/msvcrt/ctype.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -27,8 +27,8 @@ #ifndef _CTYPE_H_ #define _CTYPE_H_ -#define __need_wchar_t -#define __need_wint_t +#define __need_wchar_t +#define __need_wint_t #include @@ -36,53 +36,55 @@ * The following flags are used to tell iswctype and _isctype what character * types you are looking for. */ -#define _UPPER 0x0001 -#define _LOWER 0x0002 -#define _DIGIT 0x0004 -#define _SPACE 0x0008 -#define _PUNCT 0x0010 -#define _CONTROL 0x0020 -#define _BLANK 0x0040 -#define _HEX 0x0080 +#define _UPPER 0x0001 +#define _LOWER 0x0002 +#define _DIGIT 0x0004 +#define _SPACE 0x0008 /* HT LF VT FF CR SP */ +#define _PUNCT 0x0010 +#define _CONTROL 0x0020 +#define _BLANK 0x0040 /* this is SP only, not SP and HT as in C99 */ +#define _HEX 0x0080 +#define _LEADBYTE 0x8000 -#define _ALPHA 0x0103 -#define _LEADBYTE 0x8000 +#define _ALPHA 0x0103 #ifdef __cplusplus extern "C" { #endif -int isalnum(int c); -int isalpha(int c); -int iscntrl(int c); -int isdigit(int c); -int isgraph(int c); -int islower(int c); -int isprint(int c); -int ispunct(int c); -int isspace(int c); -int isupper(int c); -int isxdigit(int c); - -#ifndef __STRICT_ANSI__ -int _isctype (unsigned int c, int ctypeFlags); +int isalnum(int); +int isalpha(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); + +#ifndef __STRICT_ANSI__ +int _isctype (unsigned int, int); #endif -int tolower(int c); -int toupper(int c); +/* These are the ANSI versions, with correct checking of argument */ +int tolower(int); +int toupper(int); /* * NOTE: The above are not old name type wrappers, but functions exported - * explicitly by MSVCRT. However, underscored versions are also exported. + * explicitly by MSVCRT/CRTDLL. However, underscored versions are also + * exported. */ -#ifndef __STRICT_ANSI__ -int _tolower(int c); -int _toupper(int c); -#endif - -#ifndef WEOF -#define WEOF (wchar_t)(0xFFFF) +#ifndef __STRICT_ANSI__ +/* + * These are the cheap non-std versions: The return values are undefined + * if the argument is not ASCII char or is not of appropriate case + */ +int _tolower(int); +int _toupper(int); #endif /* @@ -94,46 +96,53 @@ int _toupper(int c); * problems under the current Cygwin compiler distribution. */ -typedef int wctype_t; +typedef int wctype_t; + /* Wide character equivalents */ -int iswalnum(wint_t wc); -int iswalpha(wint_t wc); -int iswascii(wint_t wc); -int iswcntrl(wint_t wc); -int iswctype(wint_t wc, wctype_t wctypeFlags); -int is_wctype(wint_t wc, wctype_t wctypeFlags); /* Obsolete! */ -int iswdigit(wint_t wc); -int iswgraph(wint_t wc); -int iswlower(wint_t wc); -int iswprint(wint_t wc); -int iswpunct(wint_t wc); -int iswspace(wint_t wc); -int iswupper(wint_t wc); -int iswxdigit(wint_t wc); - -wchar_t towlower(wchar_t c); -wchar_t towupper(wchar_t c); - -int isleadbyte (int c); - -#ifndef __STRICT_ANSI__ -int __isascii (int c); -int __toascii (int c); -int __iscsymf (int c); /* Valid first character in C symbol */ -int __iscsym (int c); /* Valid character in C symbol (after first) */ - -#ifndef _NO_OLDNAMES -#define isascii(c) __isascii(c) -#define toascii(c) _toascii(c) -#define iscsymf(c) __iscsymf(c) -#define iscsym(c) __iscsym(c) -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +int iswalnum(wint_t); +int iswalpha(wint_t); +int iswascii(wint_t); +int iswcntrl(wint_t); +int iswctype(wint_t, wctype_t); +int is_wctype(wint_t, wctype_t); /* Obsolete! */ +int iswdigit(wint_t); +int iswgraph(wint_t); +int iswlower(wint_t); +int iswprint(wint_t); +int iswpunct(wint_t); +int iswspace(wint_t); +int iswupper(wint_t); +int iswxdigit(wint_t); + +//wchar_t towlower(wchar_t); +wchar_t towupper(wchar_t); +int towlower(wint_t); +//int towupper(wint_t); + +int isleadbyte(int); + +#ifndef __STRICT_ANSI__ +int __isascii(int); +int __toascii(int); +int __iscsymf(int); /* Valid first character in C symbol */ +int __iscsym(int); /* Valid character in C symbol (after first) */ + +#ifndef _NO_OLDNAMES +#define isascii(c) __isascii(c) +#define toascii(c) _toascii(c) +#define iscsymf(c) __iscsymf(c) +#define iscsym(c) __iscsym(c) +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not __STRICT_ANSI__ */ #ifdef __cplusplus } #endif -#endif /* Not _CTYPE_H_ */ +#endif /* Not _CTYPE_H_ */ diff --git a/include/msvcrt/dir.h b/include/msvcrt/dir.h index 97e52d2..a273e80 100644 --- a/include/msvcrt/dir.h +++ b/include/msvcrt/dir.h @@ -2,6 +2,8 @@ * dir.h * * Functions for working with directories and path names. + * This file OBSOLESCENT and only provided for backward compatibility. + * Please use io.h instead. * * This file is part of the Mingw32 package. * @@ -15,7 +17,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -27,28 +29,28 @@ #ifndef __STRICT_ANSI__ #ifndef _DIR_H_ -#define _DIR_H_ +#define _DIR_H_ -#include /* To get FILENAME_MAX... ugly. */ -#include /* To get time_t. */ +#include /* To get FILENAME_MAX... ugly. */ +#include /* To get time_t. */ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif /* * Attributes of files as returned by _findfirst et al. */ -#define _A_NORMAL 0x00000000 -#define _A_RDONLY 0x00000001 -#define _A_HIDDEN 0x00000002 -#define _A_SYSTEM 0x00000004 -#define _A_VOLID 0x00000008 -#define _A_SUBDIR 0x00000010 -#define _A_ARCH 0x00000020 - -#ifndef _FSIZE_T_DEFINED -typedef unsigned long _fsize_t; +#define _A_NORMAL 0x00000000 +#define _A_RDONLY 0x00000001 +#define _A_HIDDEN 0x00000002 +#define _A_SYSTEM 0x00000004 +#define _A_VOLID 0x00000008 +#define _A_SUBDIR 0x00000010 +#define _A_ARCH 0x00000020 + +#ifndef _FSIZE_T_DEFINED +typedef unsigned long _fsize_t; #define _FSIZE_T_DEFINED #endif @@ -58,42 +60,42 @@ typedef unsigned long _fsize_t; */ struct _finddata_t { - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - _fsize_t size; - char name[FILENAME_MAX]; /* may include spaces. */ + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + _fsize_t size; + char name[FILENAME_MAX]; /* may include spaces. */ }; struct _finddatai64_t { - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - __int64 size; - char name[FILENAME_MAX]; /* may include spaces. */ + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + __int64 size; + char name[FILENAME_MAX]; /* may include spaces. */ }; struct _wfinddata_t { - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - _fsize_t size; - wchar_t name[FILENAME_MAX]; /* may include spaces. */ + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + _fsize_t size; + wchar_t name[FILENAME_MAX]; /* may include spaces. */ }; struct _wfinddatai64_t { - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - __int64 size; - wchar_t name[FILENAME_MAX]; /* may include spaces. */ + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + __int64 size; + wchar_t name[FILENAME_MAX]; /* may include spaces. */ }; /* @@ -102,47 +104,46 @@ struct _wfinddatai64_t * _findclose calls. _findnext also returns -1 if no match could be found, * and 0 if a match was found. Call _findclose when you are finished. */ -int _findclose (int nHandle); -int _findfirst (const char* szFilespec, struct _finddata_t* find); -int _findfirsti64 (const char* szFilespec, struct _finddatai64_t* find); -int _findnext (int nHandle, struct _finddata_t* find); -int _findnexti64 (int nHandle, struct _finddatai64_t* find); - -int _chdir (const char* szPath); -char* _getcwd (char* caBuffer, int nBufferSize); -int _mkdir (const char* szPath); -char* _mktemp (char* szTemplate); -int _rmdir (const char* szPath); +int _findclose(int nHandle); +int _findfirst(const char* szFilespec, struct _finddata_t* find); +int _findnext(int nHandle, struct _finddata_t* find); +int _findfirsti64(const char* szFilespec, struct _finddatai64_t* find); +int _findnexti64(int nHandle, struct _finddatai64_t* find); +/* Wide character versions */ +int _wfindfirst(const wchar_t *_name, struct _wfinddata_t *result); +int _wfindfirsti64(const wchar_t *_name, struct _wfinddatai64_t *result); +int _wfindnext(int handle, struct _wfinddata_t *result); +int _wfindnexti64(int handle, struct _wfinddatai64_t *result); +int _chdir(const char* szPath); +char* _getcwd(char* caBuffer, int nBufferSize); +int _mkdir(const char* szPath); +char* _mktemp(char* szTemplate); +int _rmdir(const char* szPath); /* Wide character versions */ -int _wfindfirst(const wchar_t *_name, struct _wfinddata_t *result); -int _wfindfirsti64(const wchar_t *_name, struct _wfinddatai64_t *result); -int _wfindnext(int handle, struct _wfinddata_t *result); -int _wfindnexti64(int handle, struct _wfinddatai64_t *result); - -int _wchdir(const wchar_t *szPath); +int _wchdir(const wchar_t *szPath); wchar_t* _wgetcwd(wchar_t *buffer, int maxlen); -int _wmkdir(const wchar_t *_path); -wchar_t* _wmktemp (wchar_t *_template); -int _wrmdir(const wchar_t *_path); +int _wmkdir(const wchar_t *_path); +wchar_t* _wmktemp(wchar_t *_template); +int _wrmdir(const wchar_t *_path); #ifndef _NO_OLDNAMES -int chdir (const char* szPath); -char* getcwd (char* caBuffer, int nBufferSize); -int mkdir (const char* szPath); -char* mktemp (char* szTemplate); -int rmdir (const char* szPath); +int chdir(const char* szPath); +char* getcwd(char* caBuffer, int nBufferSize); +int mkdir(const char* szPath); +char* mktemp(char* szTemplate); +int rmdir(const char* szPath); #endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not _DIR_H_ */ +#endif /* Not _DIR_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/direct.h b/include/msvcrt/direct.h index e1849ec..390c193 100644 --- a/include/msvcrt/direct.h +++ b/include/msvcrt/direct.h @@ -1,3 +1,30 @@ +/* + * direct.h + * + * Functions for manipulating paths and directories (included from io.h) + * plus functions for setting the current drive. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Colin Peters + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * $Revision$ + * $Author$ + * $Date$ + * + */ + #ifndef _DIRECT_H_ #define _DIRECT_H_ @@ -11,36 +38,44 @@ typedef unsigned int size_t; #define _SIZE_T_ #endif +#ifdef __cplusplus +extern "C" { +#endif + struct _diskfree_t { - unsigned short total_clusters; - unsigned short avail_clusters; - unsigned short sectors_per_cluster; - unsigned short bytes_per_sector; + unsigned short total_clusters; + unsigned short avail_clusters; + unsigned short sectors_per_cluster; + unsigned short bytes_per_sector; }; -unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace); +int _getdrive(void); +int _chdrive(int); +char* _getcwd(char*, int); -int _chdrive( int drive ); -int _getdrive( void ); +unsigned int _getdiskfree(unsigned int, struct _diskfree_t*); -char *_getcwd( char *buffer, int maxlen ); -char *_getdcwd (int nDrive, char* caBuffer, int nBufLen); +int _chdir(const char*); +int _mkdir(const char*); +int _rmdir(const char*); -int _chdir(const char *_path); -int _mkdir(const char *_path); -int _rmdir(const char *_path); - -#define chdir _chdir +#define chdir _chdir #define getcwd _getcwd -#define mkdir _mkdir -#define rmdir _rmdir +#define mkdir _mkdir +#define rmdir _rmdir +char* _getdcwd(int nDrive, char* caBuffer, int nBufLen); -wchar_t *_wgetcwd( wchar_t *buffer, int maxlen ); -wchar_t *_wgetdcwd (int nDrive, wchar_t* caBuffer, int nBufLen); +wchar_t* _wgetcwd(wchar_t *buffer, int maxlen); +wchar_t* _wgetdcwd(int nDrive, wchar_t* caBuffer, int nBufLen); -int _wchdir(const wchar_t *_path); -int _wmkdir(const wchar_t *_path); -int _wrmdir(const wchar_t *_path); +int _wchdir(const wchar_t* _path); +int _wmkdir(const wchar_t* _path); +int _wrmdir(const wchar_t* _path); +#ifdef __cplusplus +} #endif + +#endif /* Not _DIRECT_H_ */ + diff --git a/include/msvcrt/errno.h b/include/msvcrt/errno.h index 9fae110..3bd941f 100644 --- a/include/msvcrt/errno.h +++ b/include/msvcrt/errno.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -25,11 +25,7 @@ */ #ifndef _ERRNO_H_ -#define _ERRNO_H_ - -#ifdef __cplusplus -extern "C" { -#endif +#define _ERRNO_H_ /* * Error numbers. @@ -39,50 +35,50 @@ extern "C" { * of the descriptions returned by strerror do not obviously match * their error naming. */ -#define EPERM 1 /* Operation not permitted */ -#define ENOFILE 2 /* No such file or directory */ -#define ENOENT 2 -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted function call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Resource temporarily unavailable */ -#define ENOMEM 12 /* Not enough space */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ +#define EPERM 1 /* Operation not permitted */ +#define ENOFILE 2 /* No such file or directory */ +#define ENOENT 2 +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted function call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Resource temporarily unavailable */ +#define ENOMEM 12 /* Not enough space */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ /* 15 - Unknown Error */ -#define EBUSY 16 /* strerror reports "Resource device" */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Improper link (cross-device link?) */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate I/O control operation */ +#define EBUSY 16 /* strerror reports "Resource device" */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Improper link (cross-device link?) */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate I/O control operation */ /* 26 - Unknown Error */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Domain error (math functions) */ -#define ERANGE 34 /* Result too large (possibly too small) */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Domain error (math functions) */ +#define ERANGE 34 /* Result too large (possibly too small) */ /* 35 - Unknown Error */ -#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */ -#define EDEADLK 36 +#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */ +#define EDEADLK 36 /* 37 - Unknown Error */ -#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */ -#define ENOLCK 39 /* No locks available (46 in Cyg?) */ -#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */ -#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ -#define EILSEQ 42 /* Illegal byte sequence */ +#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */ +#define ENOLCK 39 /* No locks available (46 in Cyg?) */ +#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */ +#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ +#define EILSEQ 42 /* Illegal byte sequence */ /* * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the @@ -91,30 +87,34 @@ extern "C" { * of errors (look at the comment above them). */ +#ifdef __cplusplus +extern "C" { +#endif + /* * Definitions of macros for the 'variables' errno, _doserrno, sys_nerr and * sys_errlist. */ -int* _errno(void); -#define errno (*_errno()) +int* _errno(void); +#define errno (*_errno()) -int* __doserrno(void); -#define _doserrno (*__doserrno()) +int* __doserrno(void); +#define _doserrno (*__doserrno()) /* One of the MSVCRTxx libraries */ -extern int* __imp__sys_nerr; +extern int* __imp__sys_nerr; #ifndef sys_nerr -#define sys_nerr (*__imp__sys_nerr) +#define sys_nerr (*__imp__sys_nerr) #endif -extern char** __imp__sys_errlist; +extern char** __imp__sys_errlist; #ifndef sys_errlist -#define sys_errlist (__imp__sys_errlist) +#define sys_errlist (__imp__sys_errlist) #endif -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif +#endif /* Not _ERRNO_H_ */ diff --git a/include/msvcrt/fcntl.h b/include/msvcrt/fcntl.h index 8e7491c..5a135b1 100644 --- a/include/msvcrt/fcntl.h +++ b/include/msvcrt/fcntl.h @@ -16,7 +16,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -25,7 +25,7 @@ * */ /* Appropriated for Reactos Crtdll by Ariadne */ -/* added _O_RANDOM_O_SEQUENTIAL _O_SHORT_LIVED*/ +/* added _O_RANDOM_O_SEQUENTIAL _O_SHORT_LIVED*/ /* changed fmode_dll */ #ifndef _FCNTL_H_ @@ -41,13 +41,13 @@ * TODO: Which flags work? */ #if 0 -#if __MSVCRT__ +#ifdef __MSVCRT__ // || _MSVCRT_LIB_ extern unsigned int* __imp__fmode; -#define _fmode (*__imp__fmode) +#define _fmode (*__imp__fmode) #else /* CRTDLL */ extern unsigned int* _fmode_dll; -#define _fmode (*_fmode_dll) +#define _fmode (*_fmode_dll) #endif #endif /* 0 */ @@ -60,68 +60,70 @@ extern unsigned int _fmode; /* Specifiy one of these flags to define the access mode. */ -#define _O_RDONLY 0 -#define _O_WRONLY 1 -#define _O_RDWR 2 +#define _O_RDONLY 0 +#define _O_WRONLY 1 +#define _O_RDWR 2 /* Mask for access mode bits in the _open flags. */ -#define _O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#define _O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) -#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */ -#define _O_CREAT 0x0100 /* Create the file if it does not exist. */ -#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */ -#define _O_EXCL 0x0400 /* Open only if the file does not exist. */ +#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */ +#define _O_RANDOM 0x0010 +#define _O_SEQUENTIAL _O_RANDOM +#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing. + * WARNING: Even if not created by _open! */ +#define _O_NOINHERIT 0x0080 -/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */ -#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */ -#define _O_BINARY 0x8000 /* Input and output is not translated. */ -#define _O_RAW _O_BINARY +#define _O_CREAT 0x0100 /* Create the file if it does not exist. */ +#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */ +#define _O_EXCL 0x0400 /* Open only if the file does not exist. */ -#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing. - * WARNING: Even if not created by _open! */ -#define _O_NOINHERIT 0x0080 +#define _O_SHORT_LIVED 0x1000 +/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */ +#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */ +#define _O_BINARY 0x8000 /* Input and output is not translated. */ +#define _O_RAW _O_BINARY -#define _O_RANDOM 0x0010 -#define _O_SEQUENTIAL _O_RANDOM -#define _O_SHORT_LIVED 0x1000 #ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES +#ifndef _NO_OLDNAMES /* POSIX/Non-ANSI names for increased portability */ -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_RDWR _O_RDWR -#define O_ACCMODE _O_ACCMODE -#define O_APPEND _O_APPEND -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC -#define O_EXCL _O_EXCL -#define O_TEXT _O_TEXT -#define O_BINARY _O_BINARY -#define O_TEMPORARY _O_TEMPORARY -#define O_NOINHERIT _O_NOINHERIT - -#define O_RANDOM _O_RANDOM -#define O_SEQUENTIAL _O_RANDOM +#define O_RDONLY _O_RDONLY +#define O_WRONLY _O_WRONLY +#define O_RDWR _O_RDWR +#define O_ACCMODE _O_ACCMODE +#define O_APPEND _O_APPEND +#define O_CREAT _O_CREAT +#define O_TRUNC _O_TRUNC +#define O_EXCL _O_EXCL +#define O_TEXT _O_TEXT +#define O_BINARY _O_BINARY +#define O_TEMPORARY _O_TEMPORARY +#define O_NOINHERIT _O_NOINHERIT + +#define O_RANDOM _O_RANDOM +#define O_SEQUENTIAL _O_RANDOM #define O_SHORT_LIVED _O_SHORT_LIVED -#endif /* Not _NO_OLDNAMES */ +#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -int _setmode (int nHandle, int nAccessMode); +int _setmode (int, int); -#ifndef _NO_OLDNAMES -int setmode (int nHandle, int nAccessMode); -#endif /* Not _NO_OLDNAMES */ +#ifndef _NO_OLDNAMES +int setmode (int, int); +#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not __STRICT_ANSI__ */ -#endif /* Not _FCNTL_H_ */ +#endif /* Not __STRICT_ANSI__ */ + +#endif /* Not _FCNTL_H_ */ + diff --git a/include/msvcrt/float.h b/include/msvcrt/float.h index 4c4304a..1f436a7 100644 --- a/include/msvcrt/float.h +++ b/include/msvcrt/float.h @@ -24,7 +24,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -36,164 +36,179 @@ #ifndef _FLOAT_H_ #define _FLOAT_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define FLT_ROUNDS 1 -#define FLT_GUARD 1 -#define FLT_NORMALIZE 1 +#define FLT_ROUNDS 1 +#define FLT_GUARD 1 +#define FLT_NORMALIZE 1 /* * The characteristics of float. */ /* The radix for floating point representation. */ -#define FLT_RADIX 2 +#define FLT_RADIX 2 /* Decimal digits of precision. */ -#define FLT_DIG 6 +#define FLT_DIG 6 /* Smallest number such that 1+x != 1 */ -#define FLT_EPSILON 1.19209290e-07F +#define FLT_EPSILON 1.19209290e-07F /* The number of base FLT_RADIX digits in the mantissa. */ -#define FLT_MANT_DIG 24 +#define FLT_MANT_DIG 24 /* The maximum floating point number. */ -#define FLT_MAX 3.40282347e+38F +#define FLT_MAX 3.40282347e+38F /* Maximum n such that FLT_RADIX^n - 1 is representable. */ -#define FLT_MAX_EXP 128 +#define FLT_MAX_EXP 128 /* Maximum n such that 10^n is representable. */ -#define FLT_MAX_10_EXP 38 +#define FLT_MAX_10_EXP 38 /* Minimum normalized floating-point number. */ -#define FLT_MIN 1.17549435e-38F +#define FLT_MIN 1.17549435e-38F /* Minimum n such that FLT_RADIX^n is a normalized number. */ -#define FLT_MIN_EXP (-125) +#define FLT_MIN_EXP (-125) /* Minimum n such that 10^n is a normalized number. */ -#define FLT_MIN_10_EXP (-37) +#define FLT_MIN_10_EXP (-37) /* * The characteristics of double. */ -#define DBL_DIG 15 -#define DBL_EPSILON 1.1102230246251568e-16 -#define DBL_MANT_DIG 53 -#define DBL_MAX 1.7976931348623157e+308 -#define DBL_MAX_EXP 1024 -#define DBL_MAX_10_EXP 308 -#define DBL_MIN 2.2250738585072014e-308 -#define DBL_MIN_EXP (-1021) -#define DBL_MIN_10_EXP (-307) +#define DBL_DIG 15 +#define DBL_EPSILON 1.1102230246251568e-16 +#define DBL_MANT_DIG 53 +#define DBL_MAX 1.7976931348623157e+308 +#define DBL_MAX_EXP 1024 +#define DBL_MAX_10_EXP 308 +#define DBL_MIN 2.2250738585072014e-308 +#define DBL_MIN_EXP (-1021) +#define DBL_MIN_10_EXP (-307) /* * The characteristics of long double. * NOTE: long double is the same as double. */ -#define LDBL_DIG 15 -#define LDBL_EPSILON 1.1102230246251568e-16L -#define LDBL_MANT_DIG 53 -#define LDBL_MAX 1.7976931348623157e+308L -#define LDBL_MAX_EXP 1024 -#define LDBL_MAX_10_EXP 308 -#define LDBL_MIN 2.2250738585072014e-308L -#define LDBL_MIN_EXP (-1021) -#define LDBL_MIN_10_EXP (-307) +#define LDBL_DIG 15 +#define LDBL_EPSILON 1.1102230246251568e-16L +#define LDBL_MANT_DIG 53 +#define LDBL_MAX 1.7976931348623157e+308L +#define LDBL_MAX_EXP 1024 +#define LDBL_MAX_10_EXP 308 +#define LDBL_MIN 2.2250738585072014e-308L +#define LDBL_MIN_EXP (-1021) +#define LDBL_MIN_10_EXP (-307) /* * Functions and definitions for controlling the FPU. */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ /* TODO: These constants are only valid for x86 machines */ /* Control word masks for unMask */ -#define _MCW_EM 0x0008001F /* Error masks */ -#define _MCW_IC 0x00040000 /* Infinity */ -#define _MCW_RC 0x00000300 /* Rounding */ -#define _MCW_PC 0x00030000 /* Precision */ +#define _MCW_EM 0x0008001F /* Error masks */ +#define _MCW_IC 0x00040000 /* Infinity */ +#define _MCW_RC 0x00000300 /* Rounding */ +#define _MCW_PC 0x00030000 /* Precision */ /* Control word values for unNew (use with related unMask above) */ -#define _EM_INVALID 0x00000010 -#define _EM_DENORMAL 0x00080000 -#define _EM_ZERODIVIDE 0x00000008 -#define _EM_OVERFLOW 0x00000004 -#define _EM_UNDERFLOW 0x00000002 -#define _EM_INEXACT 0x00000001 -#define _IC_AFFINE 0x00040000 -#define _IC_PROJECTIVE 0x00000000 -#define _RC_CHOP 0x00000300 -#define _RC_UP 0x00000200 -#define _RC_DOWN 0x00000100 -#define _RC_NEAR 0x00000000 -#define _PC_24 0x00020000 -#define _PC_53 0x00010000 -#define _PC_64 0x00000000 +#define _EM_INVALID 0x00000010 +#define _EM_DENORMAL 0x00080000 +#define _EM_ZERODIVIDE 0x00000008 +#define _EM_OVERFLOW 0x00000004 +#define _EM_UNDERFLOW 0x00000002 +#define _EM_INEXACT 0x00000001 +#define _IC_AFFINE 0x00040000 +#define _IC_PROJECTIVE 0x00000000 +#define _RC_CHOP 0x00000300 +#define _RC_UP 0x00000200 +#define _RC_DOWN 0x00000100 +#define _RC_NEAR 0x00000000 +#define _PC_24 0x00020000 +#define _PC_53 0x00010000 +#define _PC_64 0x00000000 + +/* Return values for fpclass. */ +#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ +#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ +#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ +#define _FPCLASS_NN 0x0008 /* Negative Normal */ +#define _FPCLASS_ND 0x0010 /* Negative Denormal */ +#define _FPCLASS_NZ 0x0020 /* Negative Zero */ +#define _FPCLASS_PZ 0x0040 /* Positive Zero */ +#define _FPCLASS_PD 0x0080 /* Positive Denormal */ +#define _FPCLASS_PN 0x0100 /* Positive Normal */ +#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ + + +#ifdef __cplusplus +extern "C" { +#endif /* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), * i.e. change the bits in unMask to have the values they have in unNew, * leaving other bits unchanged. */ -unsigned int _controlfp (unsigned int unNew, unsigned int unMask); -unsigned int _control87 (unsigned int unNew, unsigned int unMask); +unsigned int _controlfp(unsigned int unNew, unsigned int unMask); +unsigned int _control87(unsigned int unNew, unsigned int unMask); -unsigned int _clearfp (void); /* Clear the FPU status word */ -unsigned int _statusfp (void); /* Report the FPU status word */ -#define _clear87 _clearfp -#define _status87 _statusfp +unsigned int _clearfp(void); /* Clear the FPU status word */ +unsigned int _statusfp(void); /* Report the FPU status word */ +#define _clear87 _clearfp +#define _status87 _statusfp -void _fpreset (void); /* Reset the FPU */ + +/* + MSVCRT.dll _fpreset initializes the control register to 0x27f, + the status register to zero and the tag word to 0FFFFh. + This differs from asm instruction finit/fninit which set control + word to 0x37f (64 bit mantissa precison rather than 53 bit). + By default, the mingw version of _fpreset sets fp control as + per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when + building your application. +*/ +void _fpreset(void); /* Reset the FPU */ /* Global 'variable' for the current floating point error code. */ -extern int * __fpecode(void); -#define _fpecode (*(__fpecode())) +int* __fpecode(void); +#define _fpecode (*(__fpecode())) /* - * IEEE recommended functions + * IEEE recommended functions. MS puts them in float.h + * but they really belong in math.h. */ -double _chgsign (double x); -double _copysign (double dTo, double dFrom); -double _logb (double x); -double _nextafter (double x, double y); -double _scalb (double x, long n); +double _chgsign (double); +double _copysign (double, double); +double _logb (double); +double _nextafter (double, double); +double _scalb (double, long); -/* Return values for fpclass. */ -#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ -#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ -#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ -#define _FPCLASS_NN 0x0008 /* Negative Normal */ -#define _FPCLASS_ND 0x0010 /* Negative Denormal */ -#define _FPCLASS_NZ 0x0020 /* Negative Zero */ -#define _FPCLASS_PZ 0x0040 /* Positive Zero */ -#define _FPCLASS_PD 0x0080 /* Positive Denormal */ -#define _FPCLASS_PN 0x0100 /* Positive Normal */ -#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ - -int _finite (double x); -int _fpclass (double x); -int _isnan (double x); -int _isinf (double x); // not exported - -int _isnanl (long double x); // not exported -int _isinfl (long double x); // not exported - -#define isnan(x) _isnan(x) -#define isinf(x) _isinf(x) - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __cplusplus +int _finite (double); +int _fpclass (double); +int _isnan (double); + +int _isinf (double); // not exported +int _isnanl (long double); // not exported +int _isinfl (long double); // not exported + +#define isnan(x) _isnan(x) +#define isinf(x) _isinf(x) + + +#ifdef __cplusplus } #endif +#endif /* Not __STRICT_ANSI__ */ + #endif /* _FLOAT_H_ */ + diff --git a/include/msvcrt/internal/atexit.h b/include/msvcrt/internal/atexit.h index b3a9f01..f2a1fcc 100644 --- a/include/msvcrt/internal/atexit.h +++ b/include/msvcrt/internal/atexit.h @@ -13,11 +13,11 @@ extern "C" { #ifndef _POSIX_SOURCE struct __atexit { - struct __atexit *__next; - void (*__function)(void); + struct __atexit* __next; + void (*__function)(void); }; -extern struct __atexit *__atexit_ptr; +extern struct __atexit* __atexit_ptr; #endif /* !_POSIX_SOURCE */ #endif /* !__STRICT_ANSI__ */ diff --git a/include/msvcrt/internal/file.h b/include/msvcrt/internal/file.h index cb17b08..4507cf1 100644 --- a/include/msvcrt/internal/file.h +++ b/include/msvcrt/internal/file.h @@ -12,9 +12,7 @@ extern "C" { #endif #ifndef __dj_ENFORCE_ANSI_FREESTANDING - #ifndef __STRICT_ANSI__ - #ifndef _POSIX_SOURCE #ifndef _IORMONCL @@ -26,45 +24,32 @@ extern "C" { #define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */ #endif - // might need check for IO_APPEND aswell -#define OPEN4WRITING(f) ((((f)->_flag & _IOWRT) == _IOWRT ) ) - -#define OPEN4READING(f) ((((f)->_flag & _IOREAD) == _IOREAD ) ) +#define OPEN4WRITING(f) ((((f)->_flag & _IOWRT) == _IOWRT)) +#define OPEN4READING(f) ((((f)->_flag & _IOREAD) == _IOREAD)) // might need check for IO_APPEND aswell -#define WRITE_STREAM(f) ((((f)->_flag & _IOWRT) == _IOWRT ) ) - -#define READ_STREAM(f) ((((f)->_flag & _IOREAD) == _IOREAD ) ) - - -char __validfp (FILE *f); +#define WRITE_STREAM(f) ((((f)->_flag & _IOWRT) == _IOWRT)) +#define READ_STREAM(f) ((((f)->_flag & _IOREAD) == _IOREAD)) +char __validfp(FILE*); int __set_errno(int err); -int __set_doserrno (int error); - -void *filehnd(int fn); - -char __is_text_file(FILE *p); - -int __fileno_alloc(void *hFile, int mode); - -int _doprnt(const char *fmt, va_list args, FILE *f); -int _doscan(FILE *iop, const char *fmt, va_list argp); - - -int __fileno_dup2( int handle1, int handle2 ); +int __set_doserrno(int error); +void* filehnd(int fn); +char __is_text_file(FILE*); +int __fileno_alloc(void* hFile, int mode); +int _doprnt(const char* fmt, va_list args, FILE *); +int _doscan(FILE* iop, const char* fmt, va_list argp); +int __fileno_dup2(int handle1, int handle2); int __fileno_getmode(int _fd); int __fileno_setmode(int _fd, int _newmode); int __fileno_close(int _fd); - void sigabort_handler(int sig); #include -void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder ); -time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ); - +void UnixTimeToFileTime(time_t unix_time, FILETIME* filetime, DWORD remainder); +time_t FileTimeToUnixTime(const FILETIME* filetime, DWORD *remainder); #endif /* !_POSIX_SOURCE */ #endif /* !__STRICT_ANSI__ */ @@ -73,24 +58,19 @@ time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ); #ifndef __dj_ENFORCE_FUNCTION_CALLS #endif /* !__dj_ENFORCE_FUNCTION_CALLS */ - #define __FILE_REC_MAX 20 typedef struct __file_rec { - struct __file_rec *next; - int count; - FILE *files[__FILE_REC_MAX]; + struct __file_rec* next; + int count; + FILE* files[__FILE_REC_MAX]; } __file_rec; -extern __file_rec *__file_rec_list; +extern __file_rec* __file_rec_list; #ifdef __cplusplus } #endif - #endif /* __dj_include_libc_file_h__ */ - - - diff --git a/include/msvcrt/internal/ieee.h b/include/msvcrt/internal/ieee.h index 788908b..e6188c2 100644 --- a/include/msvcrt/internal/ieee.h +++ b/include/msvcrt/internal/ieee.h @@ -2,24 +2,24 @@ #define _IEEE_H typedef struct { - unsigned int mantissa:23; - unsigned int exponent:8; - unsigned int sign:1; + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int sign:1; } float_t; typedef struct { - unsigned int mantissal:32; - unsigned int mantissah:20; - unsigned int exponent:11; - unsigned int sign:1; + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; } double_t; typedef struct { - unsigned int mantissal:32; - unsigned int mantissah:32; - unsigned int exponent:15; - unsigned int sign:1; - unsigned int empty:16; + unsigned int mantissal:32; + unsigned int mantissah:32; + unsigned int exponent:15; + unsigned int sign:1; + unsigned int empty:16; } long_double_t; #endif diff --git a/include/msvcrt/internal/rterror.h b/include/msvcrt/internal/rterror.h index 6979abe..b32bc7f 100644 --- a/include/msvcrt/internal/rterror.h +++ b/include/msvcrt/internal/rterror.h @@ -3,27 +3,29 @@ #ifndef __MSVCRT_INTERNAL_RTERROR_H #define __MSVCRT_INTERNAL_RTERROR_H -#define _RT_STACK 0 /* stack overflow */ -#define _RT_NULLPTR 1 /* null pointer assignment */ -#define _RT_FLOAT 2 /* floating point not loaded */ -#define _RT_INTDIV 3 /* integer divide by 0 */ -#define _RT_SPACEARG 4 /* not enough space for arguments */ -#define _RT_SPACEENV 5 /* not enough space for environment */ -#define _RT_ABORT 6 /* abnormal program termination */ -#define _RT_THREAD 7 /* not enough space for thread data */ -#define _RT_LOCK 8 /* unexpected multi-thread lock error */ -#define _RT_HEAP 9 /* unexpected heap error */ -#define _RT_OPENCON 10 /* unable to open console device */ -#define _RT_NONCONT 11 /* non-continuable exception */ -#define _RT_INVALDISP 12 /* invalid disposition of exception */ -#define _RT_ONEXIT 13 /* insufficient heap to allocate - * initial table of function pointers - * used by _onexit()/atexit(). */ -#define _RT_PUREVIRT 14 /* pure virtual function call attempted - * (C++ error) */ -#define _RT_STDIOINIT 15 /* not enough space for stdio initialization */ -#define _RT_LOWIOINIT 16 /* not enough space for lowio initialization */ + +#define _RT_STACK 0 /* stack overflow */ +#define _RT_NULLPTR 1 /* null pointer assignment */ +#define _RT_FLOAT 2 /* floating point not loaded */ +#define _RT_INTDIV 3 /* integer divide by 0 */ +#define _RT_SPACEARG 4 /* not enough space for arguments */ +#define _RT_SPACEENV 5 /* not enough space for environment */ +#define _RT_ABORT 6 /* abnormal program termination */ +#define _RT_THREAD 7 /* not enough space for thread data */ +#define _RT_LOCK 8 /* unexpected multi-thread lock error */ +#define _RT_HEAP 9 /* unexpected heap error */ +#define _RT_OPENCON 10 /* unable to open console device */ +#define _RT_NONCONT 11 /* non-continuable exception */ +#define _RT_INVALDISP 12 /* invalid disposition of exception */ +#define _RT_ONEXIT 13 /* insufficient heap to allocate + * initial table of function pointers + * used by _onexit()/atexit(). */ +#define _RT_PUREVIRT 14 /* pure virtual function call attempted + * (C++ error) */ +#define _RT_STDIOINIT 15 /* not enough space for stdio initialization */ +#define _RT_LOWIOINIT 16 /* not enough space for lowio initialization */ void _amsg_exit (int errnum); + #endif /* __MSVCRT_INTERNAL_RTERROR_H */ diff --git a/include/msvcrt/internal/stdio.h b/include/msvcrt/internal/stdio.h index b272136..8b84ced 100644 --- a/include/msvcrt/internal/stdio.h +++ b/include/msvcrt/internal/stdio.h @@ -3,9 +3,9 @@ #ifndef __MSVCRT_INTERNAL_STDIO_H #define __MSVCRT_INTERNAL_STDIO_H -int __vfscanf (FILE *s, const char *format, va_list argptr); -int __vscanf (const char *format, va_list arg); -int __vsscanf (const char *s,const char *format,va_list arg); +int __vfscanf(FILE* s, const char* format, va_list argptr); +int __vscanf(const char* format, va_list arg); +int __vsscanf(const char* s,const char* format, va_list arg); #endif /* __MSVCRT_INTERNAL_STDIO_H */ diff --git a/include/msvcrt/internal/tls.h b/include/msvcrt/internal/tls.h index bbc21e9..b1ec17d 100644 --- a/include/msvcrt/internal/tls.h +++ b/include/msvcrt/internal/tls.h @@ -3,25 +3,26 @@ #ifndef __MSVCRT_INTERNAL_TLS_H #define __MSVCRT_INTERNAL_TLS_H +#include #include typedef struct _ThreadData { - int terrno; /* *nix error code */ - unsigned long tdoserrno; /* Win32 error code (for I/O only) */ - unsigned long long tnext; /* used by rand/srand */ + int terrno; /* *nix error code */ + unsigned long tdoserrno; /* Win32 error code (for I/O only) */ + unsigned LONGLONG tnext; /* used by rand/srand */ - char *lasttoken; /* used by strtok */ - wchar_t *wlasttoken; /* used by wcstok */ + char *lasttoken; /* used by strtok */ + wchar_t *wlasttoken; /* used by wcstok */ - int fpecode; /* fp exception code */ + int fpecode; /* fp exception code */ /* qsort variables */ - int (*qcmp)(const void *, const void *); /* the comparison routine */ - int qsz; /* size of each record */ - int thresh; /* THRESHold in chars */ - int mthresh; /* MTHRESHold in chars */ + int (*qcmp)(const void *, const void *); /* the comparison routine */ + int qsz; /* size of each record */ + int thresh; /* THRESHold in chars */ + int mthresh; /* MTHRESHold in chars */ } THREADDATA, *PTHREADDATA; diff --git a/include/msvcrt/io.h b/include/msvcrt/io.h index d91817e..2032cae 100644 --- a/include/msvcrt/io.h +++ b/include/msvcrt/io.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -27,10 +27,11 @@ /* added D_OK */ /* changed get_osfhandle and open_osfhandle */ /* added fileno as macro */ -#ifndef _IO_H_ -#define _IO_H_ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ + +#ifndef _IO_H_ +#define _IO_H_ #include @@ -47,109 +48,121 @@ /* TODO: Maximum number of open handles has not been tested, I just set * it the same as FOPEN_MAX. */ -#define HANDLE_MAX FOPEN_MAX +#define HANDLE_MAX FOPEN_MAX /* Some defines for _access nAccessMode (MS doesn't define them, but * it doesn't seem to hurt to add them). */ -#define F_OK 0 /* Check for file existence */ -#define W_OK 2 /* Check for write permission */ -#define R_OK 4 /* Check for read permission */ +#define F_OK 0 /* Check for file existence */ +#define W_OK 2 /* Check for write permission */ +#define R_OK 4 /* Check for read permission */ /* TODO: Is this safe? X_OK not supported directly... */ -#define X_OK R_OK /* Check for execute permission */ -#define D_OK 0x10 +#define X_OK R_OK /* Check for execute permission */ +#define D_OK 0x10 -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -int _access (const char* szFileName, int nAccessMode); -int _chmod (const char* szPath, int nMode); -int _chsize (int nHandle, long lnNewSize); -int _close (int nHandle); -int _commit(int _fd); -int _creat (const char* szFileName, int nAccessMode); -int _dup (int nHandle); -int _dup2 (int nOldHandle, int nNewHandle); -long _filelength (int nHandle); -__int64 _filelengthi64(int nHandle); -int _fileno (FILE* fileGetHandle); -void* _get_osfhandle (int nHandle); -int _isatty (int nHandle); +int _access (const char*, int); +int _chsize (int, long); +int _close (int); +int _commit(int); + +/* NOTE: The only significant bit in unPermissions appears to be bit 7 (0x80), + * the "owner write permission" bit (on FAT). */ +int _creat (const char*, int); +int _dup (int); +int _dup2 (int, int); +long _filelength (int); +int _fileno (FILE*); +void* _get_osfhandle (int); +int _isatty (int); + +int _chmod (const char* szPath, int nMode); +__int64 _filelengthi64(int nHandle); /* In a very odd turn of events this function is excluded from those * files which define _STREAM_COMPAT. This is required in order to * build GNU libio because of a conflict with _eof in streambuf.h * line 107. Actually I might just be able to change the name of * the enum member in streambuf.h... we'll see. TODO */ -#ifndef _STREAM_COMPAT -int _eof (int nHandle); +#ifndef _STREAM_COMPAT +int _eof (int); #endif /* LK_... locking commands defined in sys/locking.h. */ -int _locking (int nHandle, int nCmd, long lnLockRegionLength); +int _locking (int, int, long); -off_t _lseek(int _fd, off_t _offset, int _whence); -__int64 _lseeki64(int _fildes, __int64 _offset, int _whence); -int _open (const char* szFileName, int nFlags, ...); -int _open_osfhandle (void *lnOSHandle, int nFlags); -int _pipe (int *naHandles, unsigned int unSize, int nMode); -size_t _read(int _fd, void *_buf, size_t _nbyte); +off_t _lseek(int, off_t, int); -/* SH_... flags for nFlag defined in share.h */ -int _sopen (char* szFileName, int nAccess, int nFlag, int nMode); +/* Optional third argument is unsigned unPermissions. */ +int _open (const char*, int, ...); -long _tell(int nHandle); -__int64 _telli64(int nHandle); -unsigned _umask(unsigned unMode); -int _unlink(const char* szFileName); -size_t _write(int _fd, const void *_buf, size_t _nbyte); +int _open_osfhandle (void*, int); +int _pipe (int*, unsigned int, int); +size_t _read(int, void*, size_t); +/* SH_... flags for nShFlags defined in share.h + * Optional fourth argument is unsigned unPermissions */ +int _sopen (char*, int, int, int); -/* wide character functions */ -int _waccess(const wchar_t *_path, int _amode); -int _wchmod(const wchar_t *filename, int mode); -int _wcreat(const wchar_t *filename, int mode); +long _tell(int); +/* Should umask be in sys/stat.h and/or sys/types.h instead? */ +unsigned _umask(unsigned); +int _unlink(const char*); +size_t _write(int, const void*, size_t); -int _wopen(const wchar_t *_path, int _oflag,...); -int _wsopen(wchar_t *path, int access, int shflag, int mode); -int _wunlink(const wchar_t *filename); +__int64 _lseeki64(int _fildes, __int64 _offset, int _whence); +__int64 _telli64(int nHandle); +/* Wide character versions. Also declared in wchar.h. */ +/* Not in crtdll.dll */ +int _waccess(const wchar_t*, int); +int _wchmod(const wchar_t*, int); +int _wcreat(const wchar_t*, int); -#ifndef _NO_OLDNAMES +int _wunlink(const wchar_t*); +int _wopen(const wchar_t*, int, ...); +int _wsopen(wchar_t*, int, int, int); + + +#ifndef _NO_OLDNAMES /* * Non-underscored versions of non-ANSI functions to improve portability. * These functions live in libmoldname.a. */ -#define access _access -#define chmod _chmod -#define chsize _chsize -#define close _close -#define creat _creat -#define dup _dup -#define dup2 _dup2 -#define eof _eof -#define filelength _filelength -#define fileno(f) ((f)->_file) -#define isatty _isatty -#define lseek _lseek -#define open _open -#define read _read -#define sopen(path,access,shflag,mode) _open((path), (access)|(shflag), (mode)) -#define tell(file) _lseek(_file, 0, SEEK_CUR) -#define umask _umask -#define unlink _unlink -#define write _write - -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus +#define access _access +#define chmod _chmod +#define chsize _chsize +#define close _close +#define creat _creat +#define dup _dup +#define dup2 _dup2 +#define eof _eof +#define filelength _filelength +#define fileno(f) ((f)->_file) +#define isatty _isatty +#define lseek _lseek +#define open _open +#define read _read +#define sopen(path,access,shflag,mode) _open((path), (access)|(shflag), (mode)) +#define tell(file) _lseek(_file, 0, SEEK_CUR) +#define umask _umask +#define unlink _unlink +#define write _write + + +#endif /* Not _NO_OLDNAMES */ + +#ifdef __cplusplus } #endif -#endif /* Not strict ANSI */ +#endif /* _IO_H_ not defined */ + +#endif /* Not strict ANSI */ -#endif /* _IO_H_ not defined */ diff --git a/include/msvcrt/locale.h b/include/msvcrt/locale.h index 8a6e7d4..4695e24 100644 --- a/include/msvcrt/locale.h +++ b/include/msvcrt/locale.h @@ -16,7 +16,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -25,12 +25,9 @@ * */ -#ifndef _LOCALE_H_ -#define _LOCALE_H_ +#ifndef _LOCALE_H_ +#define _LOCALE_H_ -#ifdef __cplusplus -extern "C" { -#endif /* * NOTE: I have tried to test this, but I am limited by my knowledge of @@ -41,44 +38,50 @@ extern "C" { * of the system). */ -#define LC_ALL 0 -#define LC_COLLATE 1 -#define LC_CTYPE 2 -#define LC_MONETARY 3 -#define LC_NUMERIC 4 -#define LC_TIME 5 +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 +#define LC_MIN LC_ALL +#define LC_MAX LC_TIME /* * The structure returned by 'localeconv'. */ struct lconv { - char* decimal_point; - char* thousands_sep; - char* grouping; - char* int_curr_symbol; - char* currency_symbol; - char* mon_decimal_point; - char* mon_thousands_sep; - char* mon_grouping; - char* positive_sign; - char* negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; }; -char* setlocale (int nCategory, const char* locale); -struct lconv* localeconv (void); +#ifdef __cplusplus +extern "C" { +#endif + +char* setlocale(int, const char*); +struct lconv* localeconv(void); -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif +#endif /* Not _LOCALE_H_ */ diff --git a/include/msvcrt/malloc.h b/include/msvcrt/malloc.h index b907c22..212faa6 100644 --- a/include/msvcrt/malloc.h +++ b/include/msvcrt/malloc.h @@ -18,7 +18,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -27,22 +27,22 @@ * */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ #ifndef _MALLOC_H_ #define _MALLOC_H_ #include -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -void * _expand( void *memblock, size_t size ); -int _heapchk (void); /* Verify heap integrety. */ -int _heapmin (void); /* Return unused heap to the OS. */ -int _heapset (unsigned int unFill); -size_t _msize (void* pBlock); +int _heapchk(void); /* Verify heap integrety. */ +int _heapmin(void); /* Return unused heap to the OS. */ +int _heapset(unsigned int); +size_t _msize(void*); +void* _expand(void*, size_t); #ifdef __cplusplus } diff --git a/include/msvcrt/math.h b/include/msvcrt/math.h index 9afe1df..958ff27 100644 --- a/include/msvcrt/math.h +++ b/include/msvcrt/math.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -28,6 +28,8 @@ #ifndef _MATH_H_ #define _MATH_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -42,99 +44,99 @@ extern "C" { * * NOTE: The CRTDLL version uses _HUGE_dll instead. */ -#if __MSVCRT__ -extern double* __imp__HUGE; -#define HUGE_VAL (*__imp__HUGE) +#ifdef _MSVCRT_LIB_ +extern double* __imp__HUGE; +#define HUGE_VAL (*__imp__HUGE) #else /* CRTDLL */ -extern double* _HUGE_dll; -#define HUGE_VAL (*_HUGE_dll) +extern double* _HUGE_dll; +#define HUGE_VAL (*_HUGE_dll) #endif struct _exception { - int type; - char *name; - double arg1; - double arg2; - double retval; + int type; + char *name; + double arg1; + double arg2; + double retval; }; /* * Types for the above _exception structure. */ -#define _DOMAIN 1 /* domain error in argument */ -#define _SING 2 /* singularity */ -#define _OVERFLOW 3 /* range overflow */ -#define _UNDERFLOW 4 /* range underflow */ -#define _TLOSS 5 /* total loss of precision */ -#define _PLOSS 6 /* partial loss of precision */ +#define _DOMAIN 1 /* domain error in argument */ +#define _SING 2 /* singularity */ +#define _OVERFLOW 3 /* range overflow */ +#define _UNDERFLOW 4 /* range underflow */ +#define _TLOSS 5 /* total loss of precision */ +#define _PLOSS 6 /* partial loss of precision */ /* * Exception types with non-ANSI names for compatibility. */ -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES - -#define DOMAIN _DOMAIN -#define SING _SING -#define OVERFLOW _OVERFLOW -#define UNDERFLOW _UNDERFLOW -#define TLOSS _TLOSS -#define PLOSS _PLOSS - -#endif /* Not _NO_OLDNAMES */ -#endif /* Not __STRICT_ANSI__ */ - - -double sin (double x); -double cos (double x); -double tan (double x); -double sinh (double x); -double cosh (double x); -double tanh (double x); -double asin (double x); -double acos (double x); -double atan (double x); -double atan2 (double y, double x); -double exp (double x); -double log (double x); -double log10 (double x); -double pow (double x, double y); -long double powl (long double x,long double y); -double sqrt (double x); -double ceil (double x); -double floor (double x); -double fabs (double x); -double ldexp (double x, int n); -double frexp (double x, int* exp); -double modf (double x, double* ip); +#ifndef __STRICT_ANSI__ +#ifndef _NO_OLDNAMES + +#define DOMAIN _DOMAIN +#define SING _SING +#define OVERFLOW _OVERFLOW +#define UNDERFLOW _UNDERFLOW +#define TLOSS _TLOSS +#define PLOSS _PLOSS + +#endif /* Not _NO_OLDNAMES */ +#endif /* Not __STRICT_ANSI__ */ + + +double sin (double x); +double cos (double x); +double tan (double x); +double sinh (double x); +double cosh (double x); +double tanh (double x); +double asin (double x); +double acos (double x); +double atan (double x); +double atan2 (double y, double x); +double exp (double x); +double log (double x); +double log10 (double x); +double pow (double x, double y); +long double powl (long double x,long double y); +double sqrt (double x); +double ceil (double x); +double floor (double x); +double fabs (double x); +double ldexp (double x, int n); +double frexp (double x, int* exp); +double modf (double x, double* ip); long double modfl (long double x,long double* ip); -double fmod (double x, double y); +double fmod (double x, double y); -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ /* Complex number (for cabs) */ struct _complex { - double x; /* Real part */ - double y; /* Imaginary part */ + double x; /* Real part */ + double y; /* Imaginary part */ }; -double _cabs (struct _complex x); -double _hypot (double x, double y); -double _j0 (double x); -double _j1 (double x); -double _jn (int n, double x); -double _y0 (double x); -double _y1 (double x); -double _yn (int n, double x); +double _cabs (struct _complex x); +double _hypot (double x, double y); +double _j0 (double x); +double _j1 (double x); +double _jn (int n, double x); +double _y0 (double x); +double _y1 (double x); +double _yn (int n, double x); -#ifndef _NO_OLDNAMES +#ifndef _NO_OLDNAMES /* * Non-underscored versions of non-ANSI functions. These reside in @@ -149,13 +151,48 @@ double y0 (double x); double y1 (double x); double yn (int n, double x); -#endif /* Not _NO_OLDNAMES */ +#endif /* Not _NO_OLDNAMES */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ #ifdef __cplusplus } #endif + +#ifdef __MSVCRT__ +double linkme_sin(double x); +double linkme_cos(double x); +double linkme_tan(double x); +double linkme_sinh(double x); +double linkme_cosh(double x); +double linkme_tanh(double x); +double linkme_asin(double x); +double linkme_acos(double x); +double linkme_atan(double x); +double linkme_atan2(double y, double x); +double linkme_exp(double x); +double linkme_log(double x); +double linkme_log10(double x); +double linkme_pow(double x, double y); +long double linkme_powl(long double x,long double y); +double linkme_sqrt(double x); +double linkme_ceil(double x); +double linkme_floor(double x); +double linkme_fabs(double x); +double linkme_ldexp(double x, int n); +double linkme_frexp(double x, int* exp); +double linkme_modf(double x, double* ip); +long double linkme_modfl(long double x,long double* ip); +double linkme_fmod(double x, double y); + +//linkme_log2 +//linkme_floor +//linkme_ldexp +//linkme_pow + +#endif + + #endif /* Not _MATH_H_ */ diff --git a/include/msvcrt/mbctype.h b/include/msvcrt/mbctype.h index 686b363..dc672d8 100644 --- a/include/msvcrt/mbctype.h +++ b/include/msvcrt/mbctype.h @@ -1,24 +1,48 @@ -#ifndef _MBCTYPE_H -#define _MBCTYPE_H +/* + * mbctype.h + * + * Functions for testing multibyte character types and converting characters. + * + * This file is part of the Mingw32 package. + * + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ -#ifdef __cplusplus -extern "C" { -#endif +#ifndef _MBCTYPE_H_ +#define _MBCTYPE_H_ -//#define _MS 0x01 -//#define _MP 0x02 -//#define _M1 0x04 -//#define _M2 0x08 -#define _MBC_SINGLE 0 -#define _MBC_LEAD 1 -#define _MBC_TRAIL 2 -#define _MBC_ILLEGAL -1 +/* return values for _mbsbtype and _mbbtype in mbstring.h */ +#define _MBC_SINGLE 0 +#define _MBC_LEAD 1 +#define _MBC_TRAIL 2 +#define _MBC_ILLEGAL (-1) +/* args for setmbcp (in lieu of actual codepage) */ #define _MB_CP_SBCS 0 -#define _MB_CP_OEM -2 -#define _MB_CP_ANSI -3 -#define _MB_CP_LOCALE -4 +#define _MB_CP_OEM (-2) +#define _MB_CP_ANSI (-3) +#define _MB_CP_LOCALE (-4) + +/* TODO: bit masks */ +/* +//#define _MS 0x01 +//#define _MP 0x02 +//#define _M1 0x04 +//#define _M2 0x08 +#define _SBUP +#define _SBLOW +*/ #define _KNJ_M ((char)0x01) /* Non-punctuation of Kana-set */ #define _KNJ_P ((char)0x02) /* Punctuation of Kana-set */ @@ -35,15 +59,20 @@ extern "C" { #define _M2 (_M_|__2) #define _P2 (_P_|__2) +#ifdef __cplusplus +extern "C" { +#endif + extern char _jctype[257]; -int _ismbbkalnum( unsigned int c ); -int _ismbbkana( unsigned char c ); +int _ismbbkana(unsigned char); +int _ismbbkalnum(unsigned int); #ifdef __cplusplus } #endif -#endif +#endif /* Not _MCTYPE_H_ */ + diff --git a/include/msvcrt/mbstring.h b/include/msvcrt/mbstring.h index a7bc5ba..e331606 100644 --- a/include/msvcrt/mbstring.h +++ b/include/msvcrt/mbstring.h @@ -1,108 +1,114 @@ +/* + * mbstring.h + * + * Protototypes for string functions supporting multibyte characters. + * + * This file is part of the Mingw32 package. + * + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + #ifndef _MBSTRING_H_ #define _MBSTRING_H_ -#ifdef __cplusplus -extern "C" { -#endif - #include -size_t _mbstrlen(const char *str); - - - - -int _mbbtype(unsigned char c, int type); -int _mbsbtype( const unsigned char *str, size_t n ); - -unsigned int _mbbtombc(unsigned int c); -unsigned int _mbctombb(unsigned int c); - -unsigned char * _mbscat(unsigned char *dst, const unsigned char *src); -unsigned char * _mbschr(unsigned char *str, unsigned char* c); -int _mbscmp(const unsigned char *, const unsigned char *); -int _mbscoll(const unsigned char *, const unsigned char *); -unsigned char * _mbscpy(unsigned char *, const unsigned char *); -size_t _mbscspn(const unsigned char *, const unsigned char *); -unsigned char * _mbsdup(const unsigned char *str); -int _mbsicmp(const unsigned char *, const unsigned char *); -int _mbsicoll(const unsigned char *, const unsigned char *); -size_t _mbslen(const unsigned char *str); - -unsigned char * _mbsncat(unsigned char *, const unsigned char *, size_t); -unsigned char * _mbsnbcat(unsigned char *, const unsigned char *, size_t); - - -int _mbsncmp(const unsigned char *, const unsigned char *, size_t); -int _mbsnbcmp(const unsigned char *, const unsigned char *, size_t); - -int _mbsncoll(const unsigned char *, const unsigned char *, size_t); -int _mbsnbcoll(const unsigned char *, const unsigned char *, size_t); - -unsigned char * _mbsncpy(unsigned char *, const unsigned char *, size_t); -unsigned char * _mbsnbcpy(unsigned char *, const unsigned char *, size_t); - -int _mbsnicmp(const unsigned char *, const unsigned char *, size_t); -int _mbsnbicmp(const unsigned char *, const unsigned char *, size_t); - -int _mbsnicoll(const unsigned char *, const unsigned char *, size_t); -int _mbsnbicoll(const unsigned char *, const unsigned char *, size_t); - -unsigned char * _mbsnset(unsigned char *, unsigned int, size_t); -unsigned char * _mbsnbset(unsigned char *, unsigned int, size_t); - -size_t _mbsnccnt(const unsigned char *, size_t); - - -unsigned char * _mbspbrk(const unsigned char *, const unsigned char *); -unsigned char * _mbsrchr(const unsigned char *, unsigned int); -unsigned char * _mbsrev(unsigned char *); -unsigned char * _mbsset(unsigned char *, unsigned int); -size_t _mbsspn(const unsigned char *, const unsigned char *); - -unsigned char * _mbsstr(const unsigned char *, const unsigned char *); -unsigned char * _mbstok(unsigned char *, unsigned char *); - -unsigned char * _mbslwr(unsigned char *str); -unsigned char * _mbsupr(unsigned char *str); - -size_t _mbclen(const unsigned char *); -void _mbccpy(unsigned char *, const unsigned char *); - -/* tchar routines */ +#ifdef __cplusplus +extern "C" { +#endif -unsigned char * _mbsdec(const unsigned char *, const unsigned char *); -unsigned char * _mbsinc(const unsigned char *); -size_t _mbsnbcnt(const unsigned char *, size_t); -unsigned int _mbsnextc (const unsigned char *); -unsigned char * _mbsninc(const unsigned char *, size_t); -unsigned char * _mbsspnp(const unsigned char *, const unsigned char *); /* character routines */ - -int _ismbcalnum(unsigned int c); -int _ismbcalpha(unsigned int c); -int _ismbcdigit(unsigned int c); -int _ismbcgraph(unsigned int c); -int _ismbclegal(unsigned int c); -int _ismbclower(unsigned int c); -int _ismbcprint(unsigned int c); -int _ismbcpunct(unsigned int c); -int _ismbcspace(unsigned int c); -int _ismbcupper(unsigned int c); +int _ismbcalnum(unsigned int); +int _ismbcalpha(unsigned int); +int _ismbcdigit(unsigned int); +int _ismbcgraph(unsigned int); +int _ismbcprint(unsigned int); +int _ismbcpunct(unsigned int); +int _ismbcspace(unsigned int); +int _ismbclower(unsigned int); +int _ismbcupper(unsigned int); +int _ismbclegal(unsigned int); + +int _ismbblead(unsigned int); +int _ismbbtrail(unsigned int); +int _ismbslead(const unsigned char*, const unsigned char*); +int _ismbstrail(const unsigned char*, const unsigned char*); unsigned int _mbctolower(unsigned int); unsigned int _mbctoupper(unsigned int); +void _mbccpy(unsigned char*, const unsigned char*); +size_t _mbclen(const unsigned char*); + +unsigned int _mbbtombc(unsigned int); +unsigned int _mbctombb(unsigned int); + +/* Return value constants for these are defined in mbctype.h. */ +int _mbbtype(unsigned char, int); +int _mbsbtype(const unsigned char*, size_t); + +unsigned char* _mbscpy(unsigned char*, const unsigned char*); +unsigned char* _mbsncpy(unsigned char*, const unsigned char*, size_t); +unsigned char* _mbsnbcpy(unsigned char*, const unsigned char*, size_t); +unsigned char* _mbsset(unsigned char*, unsigned int); +unsigned char* _mbsnset(unsigned char*, unsigned int, size_t); +unsigned char* _mbsnbset(unsigned char*, unsigned int, size_t); + +unsigned char* _mbsdup(const unsigned char*); +unsigned char* _mbsrev(unsigned char*); +unsigned char* _mbscat(unsigned char*, const unsigned char*); +unsigned char* _mbsncat(unsigned char*, const unsigned char*, size_t); +unsigned char* _mbsnbcat(unsigned char*, const unsigned char*, size_t); +size_t _mbslen(const unsigned char*); +size_t _mbsnbcnt(const unsigned char*, size_t); +size_t _mbsnccnt(const unsigned char*, size_t); +unsigned char* _mbschr(unsigned char*, unsigned char*); +unsigned char* _mbsrchr(const unsigned char*, unsigned int); +size_t _mbsspn(const unsigned char*, const unsigned char*); +size_t _mbscspn(const unsigned char*, const unsigned char*); +unsigned char* _mbsspnp(const unsigned char*, const unsigned char*); +unsigned char* _mbspbrk(const unsigned char*, const unsigned char*); +int _mbscmp(const unsigned char*, const unsigned char*); +int _mbsicmp(const unsigned char*, const unsigned char*); +int _mbsncmp(const unsigned char*, const unsigned char*, size_t); +int _mbsnicmp(const unsigned char*, const unsigned char*, size_t); +int _mbsnbcmp(const unsigned char*, const unsigned char*, size_t); +int _mbsnbicmp(const unsigned char*, const unsigned char*, size_t); +int _mbscoll(const unsigned char*, const unsigned char*); +int _mbsicoll(const unsigned char*, const unsigned char*); +int _mbsncoll(const unsigned char*, const unsigned char*, size_t); +int _mbsnicoll(const unsigned char*, const unsigned char*, size_t); +int _mbsnbcoll(const unsigned char*, const unsigned char*, size_t); + +int _mbsnbicoll(const unsigned char*, const unsigned char*, size_t); + +unsigned char* _mbsinc(const unsigned char*); +unsigned char* _mbsninc(const unsigned char*, size_t); +unsigned char* _mbsdec(const unsigned char*, const unsigned char*); +unsigned int _mbsnextc (const unsigned char*); +unsigned char* _mbslwr(unsigned char*); +unsigned char* _mbsupr(unsigned char*); +unsigned char* _mbstok(unsigned char*, unsigned char*); + +unsigned char* _mbsstr(const unsigned char*, const unsigned char*); +size_t _mbstrlen(const char*str); -int _ismbblead( unsigned int c); -int _ismbbtrail( unsigned int c); -int _ismbslead( const unsigned char *s, const unsigned char *c); -int _ismbstrail( const unsigned char *s, const unsigned char *c); #ifdef __cplusplus } #endif -#endif +#endif /* Not _MBSTRING_H_ */ + diff --git a/include/msvcrt/msvcrtdbg.h b/include/msvcrt/msvcrtdbg.h index 3916f9a..bbc042e 100644 --- a/include/msvcrt/msvcrtdbg.h +++ b/include/msvcrt/msvcrtdbg.h @@ -17,6 +17,7 @@ #define __MSVCRT_DEBUG #include +#include #if 0 #ifdef NDEBUG @@ -28,7 +29,11 @@ #define DPRINT1(args...) do { DbgPrint("(MSVCRT:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT1 do { DbgPrint("MSVCRT:%s:%d\n",__FILE__,__LINE__); } while(0); #else +#ifdef __GNUC__ #define DPRINT1(args...) +#else +#define DPRINT DbgPrint +#endif #define CHECKPOINT1 #endif @@ -36,8 +41,24 @@ #define DPRINT(args...) do { DbgPrint("(MSVCRT:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT do { DbgPrint("MSVCRT:%s:%d\n",__FILE__,__LINE__); } while(0); #else +#ifdef __GNUC__ #define DPRINT(args...) +#else +#define DPRINT DbgPrint +#endif #define CHECKPOINT #endif /* NDEBUG */ +//ULONG CDECL DbgPrint(PCH Format, ...); +//ULONG DbgPrint(PCH Format,...); +//unsigned long DbgPrint(const char* Format, ...); + + + +//#define TRACE 0 ? (void)0 : Trace + +//void Trace(TCHAR* lpszFormat, ...); + + + #endif /* __MSVCRT_DEBUG */ diff --git a/include/msvcrt/process.h b/include/msvcrt/process.h index 15f4851..25ee6f6 100644 --- a/include/msvcrt/process.h +++ b/include/msvcrt/process.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -26,71 +26,71 @@ /* Appropriated for Reactos Crtdll by Ariadne */ /* changed second argument of cwait from nPID to hProc */ -#ifndef _PROCESS_H_ -#define _PROCESS_H_ +#ifndef __STRICT_ANSI__ -#ifndef __STRICT_ANSI__ - -#ifdef __cplusplus -extern "C" { -#endif - -void _cexit(void); -void _c_exit(void); +#ifndef _PROCESS_H_ +#define _PROCESS_H_ /* * Constants for cwait actions. * Obsolete for Win32. */ -#define _WAIT_CHILD 0 -#define _WAIT_GRANDCHILD 1 - -#ifndef _NO_OLDNAMES -#define WAIT_CHILD _WAIT_CHILD -#define WAIT_GRANDCHILD _WAIT_GRANDCHILD -#endif /* Not _NO_OLDNAMES */ - -int _cwait (int* pnStatus, int hProc, int nAction); - -int _getpid(void); - -int _execl (const char* szPath, const char* szArgv0, ...); -int _execle (const char* szPath, const char* szArgv0, ...); -int _execlp (const char* szPath, const char* szArgv0, ...); -int _execlpe (const char* szPath, const char* szArgv0, ...); -int _execv (const char* szPath, char* const* szaArgv); -int _execve (const char* szPath, char* const* szaArgv, char* const* szaEnv); -int _execvp (const char* szPath, char* const* szaArgv); -int _execvpe (const char* szPath, char* const* szaArgv, char* const* szaEnv); +#define _WAIT_CHILD 0 +#define _WAIT_GRANDCHILD 1 +#ifndef _NO_OLDNAMES +#define WAIT_CHILD _WAIT_CHILD +#define WAIT_GRANDCHILD _WAIT_GRANDCHILD +#endif /* Not _NO_OLDNAMES */ /* * Mode constants for spawn functions. */ -#define _P_WAIT 0 -#define _P_NOWAIT 1 -#define _P_OVERLAY 2 -#define _OLD_P_OVERLAY _P_OVERLAY -#define _P_NOWAITO 3 -#define _P_DETACH 4 - -#ifndef _NO_OLDNAMES -#define P_WAIT _P_WAIT -#define P_NOWAIT _P_NOWAIT -#define P_OVERLAY _P_OVERLAY -#define OLD_P_OVERLAY _OLD_P_OVERLAY -#define P_NOWAITO _P_NOWAITO -#define P_DETACH _P_DETACH -#endif /* Not _NO_OLDNAMES */ - -int _spawnl (int nMode, const char* szPath, const char* szArgv0, ...); -int _spawnle (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnlp (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnlpe (int nMode, const char* szPath, const char* szArgv0,...); -int _spawnv (int nMode, const char* szPath, char* const* szaArgv); -int _spawnve (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); -int _spawnvp (int nMode, const char* szPath, char* const* szaArgv); -int _spawnvpe (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _P_OVERLAY 2 +#define _OLD_P_OVERLAY _P_OVERLAY +#define _P_NOWAITO 3 +#define _P_DETACH 4 + +#ifndef _NO_OLDNAMES +#define P_WAIT _P_WAIT +#define P_NOWAIT _P_NOWAIT +#define P_OVERLAY _P_OVERLAY +#define OLD_P_OVERLAY _OLD_P_OVERLAY +#define P_NOWAITO _P_NOWAITO +#define P_DETACH _P_DETACH +#endif /* Not _NO_OLDNAMES */ + + +#ifdef __cplusplus +extern "C" { +#endif + +void _cexit(void); +void _c_exit(void); + +int _cwait (int* pnStatus, int hProc, int nAction); + +int _getpid(void); + +int _execl (const char* szPath, const char* szArgv0, ...); +int _execle (const char* szPath, const char* szArgv0, ...); +int _execlp (const char* szPath, const char* szArgv0, ...); +int _execlpe (const char* szPath, const char* szArgv0, ...); +int _execv (const char* szPath, char* const* szaArgv); +int _execve (const char* szPath, char* const* szaArgv, char* const* szaEnv); +int _execvp (const char* szPath, char* const* szaArgv); +int _execvpe (const char* szPath, char* const* szaArgv, char* const* szaEnv); + +int _spawnl (int nMode, const char* szPath, const char* szArgv0, ...); +int _spawnle (int nMode, const char* szPath, const char* szArgv0,...); +int _spawnlp (int nMode, const char* szPath, const char* szArgv0,...); +int _spawnlpe (int nMode, const char* szPath, const char* szArgv0,...); +int _spawnv (int nMode, const char* szPath, char* const* szaArgv); +int _spawnve (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); +int _spawnvp (int nMode, const char* szPath, char* const* szaArgv); +int _spawnvpe (int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv); /* * The functions _beginthreadex and _endthreadex are not provided by CRTDLL. * They are provided by MSVCRT. @@ -103,58 +103,58 @@ int _spawnvpe (int nMode, const char* szPath, char* const* szaArgv, char* const* * NOTE: No old names for these functions. Use the underscore. */ unsigned long - _beginthread (void (__cdecl *pfuncStart)(void *), - unsigned unStackSize, void* pArgList); -void _endthread (void); + _beginthread(void (__cdecl *pfuncStart)(void*), + unsigned unStackSize, void* pArgList); +void _endthread (void); -#if __MSVCRT__ +#ifdef __MSVCRT__ unsigned long - _beginthreadex (void *pSecurity, unsigned unStackSize, - unsigned (__stdcall *pfuncStart)(void*), void* pArgList, - unsigned unInitFlags, unsigned* pThreadAddr); -void _endthreadex (unsigned unExitCode); + _beginthreadex(void* pSecurity, unsigned unStackSize, + unsigned (__stdcall *pfuncStart)(void*), void* pArgList, + unsigned unInitFlags, unsigned* pThreadAddr); +void _endthreadex(unsigned unExitCode); #endif -void *_loaddll (char *name); -int _unloaddll(void *handle); +void* _loaddll(char* name); +int _unloaddll(void* handle); unsigned long __threadid(void); -#define _threadid __threadid() -void * __threadhandle(void); +#define _threadid __threadid() +void* __threadhandle(void); -#ifndef _NO_OLDNAMES +#ifndef _NO_OLDNAMES -#define cwait _cwait -#define getpid _getpid -#define execl _execl -#define execle _execle -#define execlp _execlp -#define execlpe _execlpe +#define cwait _cwait +#define getpid _getpid +#define execl _execl +#define execle _execle +#define execlp _execlp +#define execlpe _execlpe -#define execv _execv -#define execve _execve -#define execvp _execvp -#define execvpe _execvpe +#define execv _execv +#define execve _execve +#define execvp _execvp +#define execvpe _execvpe -#define spawnl _spawnl -#define spawnle _spawnle -#define spawnlp _spawnlp -#define spawnlpe _spawnlpe +#define spawnl _spawnl +#define spawnle _spawnle +#define spawnlp _spawnlp +#define spawnlpe _spawnlpe #define spawnv _spawnv #define spawnve _spawnve #define spawnvp _spawnvp #define spawnvpe _spawnvpe +#endif /* Not _NO_OLDNAMES */ -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not __STRICT_ANSI__ */ +#endif /* _PROCESS_H_ not defined */ + +#endif /* Not __STRICT_ANSI__ */ -#endif /* _PROCESS_H_ not defined */ diff --git a/include/msvcrt/share.h b/include/msvcrt/share.h index 8e3af3f..4caf128 100644 --- a/include/msvcrt/share.h +++ b/include/msvcrt/share.h @@ -1,17 +1,44 @@ -#ifndef _include_share_h_ -#define _include_share_h_ +/* + * share.h + * + * Constants for file sharing functions. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Colin Peters + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * $Revision$ + * $Author$ + * $Date$ + * + */ +#ifndef _SHARE_H_ +#define _SHARE_H_ -#define SH_COMPAT 0x0000 -#define SH_DENYRW 0x0010 -#define SH_DENYWR 0x0020 -#define SH_DENYRD 0x0030 -#define SH_DENYNO 0x0040 -#define _SH_COMPAT SH_COMPAT -#define _SH_DENYRW SH_DENYRW -#define _SH_DENYWR SH_DENYWR -#define _SH_DENYRD SH_DENYRD -#define _SH_DENYNO SH_DENYNO +#define SH_COMPAT 0x0000 +#define SH_DENYRW 0x0010 +#define SH_DENYWR 0x0020 +#define SH_DENYRD 0x0030 +#define SH_DENYNO 0x0040 -#endif +#define _SH_COMPAT SH_COMPAT +#define _SH_DENYRW SH_DENYRW +#define _SH_DENYWR SH_DENYWR +#define _SH_DENYRD SH_DENYRD +#define _SH_DENYNO SH_DENYNO + + +#endif /* Not _SHARE_H_ */ diff --git a/include/msvcrt/signal.h b/include/msvcrt/signal.h index 05b2aac..344d4b2 100644 --- a/include/msvcrt/signal.h +++ b/include/msvcrt/signal.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,33 +24,9 @@ * */ /* added some extra signal constants */ -#ifndef _SIGNAL_H_ -#define _SIGNAL_H_ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The prototypes (below) are the easy part. The hard part is figuring - * out what signals are available and what numbers they are assigned - * along with appropriate values of SIG_DFL and SIG_IGN. - */ - -/* - * A pointer to a signal handler function. A signal handler takes a - * single int, which is the signal it handles. - */ -typedef void (*_p_sig_fn_t)(int nSig); - -/* - * These are special values of signal handler pointers which are - * used to send a signal to the default handler (SIG_DFL), ignore - * the signal (SIG_IGN), or indicate an error return (SIG_ERR). - */ -#define SIG_DFL ((_p_sig_fn_t) 0) -#define SIG_IGN ((_p_sig_fn_t) 1) -#define SIG_ERR ((_p_sig_fn_t) -1) /* * The actual signal values. Using other values with signal @@ -68,44 +44,70 @@ typedef void (*_p_sig_fn_t)(int nSig); * structured exception handling frame. Results may be better if I ever * manage to get the SEH stuff down. */ -#define SIGINT 2 /* Interactive attention */ -#define SIGILL 4 /* Illegal instruction */ -#define SIGFPE 8 /* Floating point error */ -#define SIGSEGV 11 /* Segmentation violation */ -#define SIGTERM 15 /* Termination request */ -#define SIGBREAK 21 /* Control-break */ -#define SIGABRT 22 /* Abnormal termination (abort) */ +#define SIGINT 2 /* Interactive attention */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGFPE 8 /* Floating point error */ +#define SIGSEGV 11 /* Segmentation violation */ +#define SIGTERM 15 /* Termination request */ +#define SIGBREAK 21 /* Control-break */ +#define SIGABRT 22 /* Abnormal termination (abort) */ -#define SIGALRM 293 -#define SIGHUP 294 +#define SIGALRM 293 +#define SIGHUP 294 /* SIGINT is ansi */ -#define SIGKILL 296 -#define SIGPIPE 297 -#define SIGQUIT 298 -#define SIGUSR1 299 -#define SIGUSR2 300 +#define SIGKILL 296 +#define SIGPIPE 297 +#define SIGQUIT 298 +#define SIGUSR1 299 +#define SIGUSR2 300 #define SIGNOFP 301 #define SIGTRAP 302 -#define SIGTIMR 303 /* Internal for setitimer (SIGALRM, SIGPROF) */ +#define SIGTIMR 303 /* Internal for setitimer (SIGALRM, SIGPROF) */ #define SIGPROF 304 #define SIGMAX 320 /* + * The prototypes (below) are the easy part. The hard part is figuring + * out what signals are available and what numbers they are assigned + * along with appropriate values of SIG_DFL and SIG_IGN. + */ + +/* + * A pointer to a signal handler function. A signal handler takes a + * single int, which is the signal it handles. + */ +typedef void (*_p_sig_fn_t)(int); + +/* + * These are special values of signal handler pointers which are + * used to send a signal to the default handler (SIG_DFL), ignore + * the signal (SIG_IGN), or indicate an error return (SIG_ERR). + */ +#define SIG_DFL ((_p_sig_fn_t) 0) +#define SIG_IGN ((_p_sig_fn_t) 1) +#define SIG_ERR ((_p_sig_fn_t) -1) + +#ifdef __cplusplus +extern "C" { +#endif + + +/* * Call signal to set the signal handler for signal sig to the * function pointed to by handler. Returns a pointer to the * previous handler, or SIG_ERR if an error occurs. Initially * unhandled signals defined above will return SIG_DFL. */ -_p_sig_fn_t signal(int sig, _p_sig_fn_t func); +_p_sig_fn_t signal(int sig, _p_sig_fn_t func); /* * Raise the signal indicated by sig. Returns non-zero on success. */ -int raise (int sig); +int raise(int); -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif +#endif /* Not _SIGNAL_H_ */ diff --git a/include/msvcrt/stdarg.h b/include/msvcrt/stdarg.h index 77694ae..265ad6f 100644 --- a/include/msvcrt/stdarg.h +++ b/include/msvcrt/stdarg.h @@ -23,7 +23,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -48,7 +48,7 @@ #define _VA_LIST_DEFINED #endif -#ifndef _VA_LIST +#ifndef _VA_LIST #define _VA_LIST typedef char* va_list; #endif @@ -58,31 +58,33 @@ typedef char* va_list; * Amount of space required in an argument list (ie. the stack) for an * argument of type t. */ -#define __va_argsiz(t) \ - (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) +#define __va_argsiz(t) \ + (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) /* * Start variable argument list processing by setting AP to point to the * argument after pN. */ -#ifdef __GNUC__ +#ifdef __GNUC__ /* * In GNU the stack is not necessarily arranged very neatly in order to * pack shorts and such into a smaller argument list. Fortunately a * neatly arranged version is available through the use of __builtin_next_arg. */ #ifndef va_start -#define va_start(ap, pN) \ - ((ap) = ((va_list) __builtin_next_arg(pN))) +#define va_start(ap, pN) \ + ((ap) = ((va_list) __builtin_next_arg(pN))) #endif #else /* * For a simple minded compiler this should work (it works in GNU too for * vararg lists that don't follow shorts and such). */ -#define va_start(ap, pN) \ - ((ap) = ((va_list) (&pN) + __va_argsiz(pN))) +#ifndef va_start +#define va_start(ap, pN) \ + ((ap) = ((va_list) (&pN) + __va_argsiz(pN))) +#endif #endif @@ -90,9 +92,9 @@ typedef char* va_list; * End processing of variable argument list. In this case we do nothing. */ #ifndef va_end -#define va_end(ap) ((void)0) +#define va_end(ap) ((void)0) #endif - + /* * Increment ap to the next argument in the list while returing a @@ -103,12 +105,11 @@ typedef char* va_list; */ #ifndef va_arg -#define va_arg(ap, t) \ - (((ap) = (ap) + __va_argsiz(t)), \ - *((t*) (void*) ((ap) - __va_argsiz(t)))) +#define va_arg(ap, t) \ + (((ap) = (ap) + __va_argsiz(t)), \ + *((t*) (void*) ((ap) - __va_argsiz(t)))) #endif - + #endif /* Not RC_INVOKED */ #endif /* not _STDARG_H_ */ - diff --git a/include/msvcrt/stddef.h b/include/msvcrt/stddef.h index c735d28..b8c2044 100644 --- a/include/msvcrt/stddef.h +++ b/include/msvcrt/stddef.h @@ -25,7 +25,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -42,8 +42,8 @@ * wants us just to define one data type. So don't define * the symbols that indicate this file's entire job has been done. */ -#if (!defined(__need_wchar_t) && !defined(__need_wint_t) \ - && !defined(__need_size_t) && !defined(__need_ptrdiff_t) \ +#if (!defined(__need_wchar_t) && !defined(__need_wint_t) \ + && !defined(__need_size_t) && !defined(__need_ptrdiff_t) \ && !defined(__need_NULL)) #define __MSVCRT_STDDEF_H_ #endif @@ -69,13 +69,13 @@ #ifndef _PTRDIFF_T_ #define _PTRDIFF_T_ #ifndef __PTRDIFF_TYPE__ -#define __PTRDIFF_TYPE__ int +#define __PTRDIFF_TYPE__ int #endif -typedef __PTRDIFF_TYPE__ ptrdiff_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; #endif /* If this symbol has done its job, get rid of it. */ -#undef __need_ptrdiff_t +#undef __need_ptrdiff_t #endif /* __MSVCRT_STDDEF_H_ or __need_ptrdiff_t. */ @@ -93,12 +93,12 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; #define SIZE_T_DEFINED #define _SIZE_T #ifndef __SIZE_TYPE__ -#define __SIZE_TYPE__ unsigned int +#define __SIZE_TYPE__ unsigned int #endif -typedef __SIZE_TYPE__ size_t; +typedef __SIZE_TYPE__ size_t; #endif -#undef __need_size_t +#undef __need_size_t #endif /* __MSVCRT_STDDEF_H_ or __need_size_t. */ @@ -116,16 +116,16 @@ typedef __SIZE_TYPE__ size_t; #define _WCHAR_T #define _WCHAR_T_DEFINED #ifndef __WCHAR_TYPE__ -#define __WCHAR_TYPE__ short unsigned int +#define __WCHAR_TYPE__ short unsigned int #endif #ifndef __cplusplus -typedef __WCHAR_TYPE__ wchar_t; -#endif /* C++ */ -#endif /* wchar_t not already defined */ +typedef __WCHAR_TYPE__ wchar_t; +#endif /* C++ */ +#endif /* wchar_t not already defined */ -#undef __need_wchar_t +#undef __need_wchar_t -#endif /* __MSVCRT_STDDEF_H_ or __need_wchar_t. */ +#endif /* __MSVCRT_STDDEF_H_ or __need_wchar_t. */ /* * wint_t, the equivalent of int in wchar ctype functions. @@ -134,17 +134,17 @@ typedef __WCHAR_TYPE__ wchar_t; #ifndef _WINT_T_ #define _WINT_T_ -#define _WINT_T /* To satisfy libstdc++ */ +#define _WINT_T /* To satisfy libstdc++ */ #ifndef __WINT_TYPE__ -#define __WINT_TYPE__ short int -#endif /* Not defined __WINT_TYPE__ */ +#define __WINT_TYPE__ short int +#endif /* Not defined __WINT_TYPE__ */ -typedef __WINT_TYPE__ wint_t; -#endif /* Not defined _WINT_T_ */ +typedef __WINT_TYPE__ wint_t; +#endif /* Not defined _WINT_T_ */ -#undef __need_wint_t +#undef __need_wint_t -#endif /* __MSVCRT_STDDEF_H_ or __need_wint_t. */ +#endif /* __MSVCRT_STDDEF_H_ or __need_wint_t. */ /* @@ -157,7 +157,7 @@ typedef __WINT_TYPE__ wint_t; #define NULL (0) #endif /* __MSVCRT_STDDEF_H_ or __need_NULL */ -#undef __need_NULL +#undef __need_NULL /* @@ -167,8 +167,8 @@ typedef __WINT_TYPE__ wint_t; */ #if defined (__MSVCRT_STDDEF_H_) -#define offsetof(TYPE, MEMBER) ((size_t) &( ((TYPE *) 0)->MEMBER )) -#endif /* __MSVCRT_STDDEF_H_ */ +#define offsetof(TYPE, MEMBER) ((size_t) &( ((TYPE *) 0)->MEMBER )) +#endif /* __MSVCRT_STDDEF_H_ */ #endif /* not __MSVCRT_STDDEF_H_ */ diff --git a/include/msvcrt/stdio.h b/include/msvcrt/stdio.h index ce8956a..e2fdff2 100644 --- a/include/msvcrt/stdio.h +++ b/include/msvcrt/stdio.h @@ -19,7 +19,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -33,7 +33,7 @@ /* added filbuf and flsbuf and fwalk */ #ifndef _STDIO_H_ -#define _STDIO_H_ +#define _STDIO_H_ #ifdef __cplusplus extern "C" { @@ -54,6 +54,9 @@ extern "C" { #define _IOERR 0x000200 #define _IOSTRG 0x000400 +#define _IOBINARY 0x000800 +#define _IOTEXT 0x000000 + #define _IOAPPEND 0x002000 #define _IORMONCL 0x004000 /* remove on close, for temp files */ /* if _flag & _IORMONCL, ._name_to_remove needs freeing */ @@ -72,7 +75,7 @@ extern "C" { */ //#ifndef _VA_LIST //#define _VA_LIST -//typedef char* va_list; +//typedef char* va_list; //#endif #include @@ -82,14 +85,14 @@ extern "C" { */ #ifndef _FILE_DEFINED typedef struct { - char *_ptr; - int _cnt; - char *_base; - int _flag; - int _file; - int _ungotchar; - int _bufsiz; - char *_name_to_remove; + char* _ptr; + int _cnt; + char* _base; + int _flag; + int _file; + int _ungotchar; + int _bufsiz; + char* _name_to_remove; } FILE; #define _FILE_DEFINED #endif @@ -100,16 +103,15 @@ typedef struct { * The three standard file pointers provided by the run time library. * NOTE: These will go to the bit-bucket silently in GUI applications! */ -extern FILE _iob[]; /* an array of FILE */ -#define stdin (&_iob[0]) -#define stdout (&_iob[1]) -#define stderr (&_iob[2]) -#define stdaux (&_iob[3]) -#define stdprn (&_iob[4]) +extern FILE _iob[]; /* an array of FILE */ +#define stdin (&_iob[0]) +#define stdout (&_iob[1]) +#define stderr (&_iob[2]) +#define stdaux (&_iob[3]) +#define stdprn (&_iob[4]) /* Returned by various functions on end of file condition or error. */ -#define EOF (-1) - +#define EOF (-1) /* * The maximum length of a file name. You should use GetVolumeInformation @@ -118,45 +120,39 @@ extern FILE _iob[]; /* an array of FILE */ * NOTE: This is used in the structure _finddata_t (see dir.h) so changing it * is probably not a good idea. */ -#define FILENAME_MAX (260) +#define FILENAME_MAX (260) /* * The maximum number of files that may be open at once. I have set this to * a conservative number. The actual value may be higher. */ -#define FOPEN_MAX (20) - +#define FOPEN_MAX (20) /* * File Operations */ -FILE* _fdopen(int handle, char *mode); -FILE* _wfdopen(int handle, wchar_t *mode); - -FILE* fopen (const char* szFileName, const char* szMode); -FILE* _wfopen(const wchar_t *file, const wchar_t *mode); - -FILE* freopen(const char* szNewFileName, const char* szNewMode, - FILE* fileChangeAssociation); -FILE* _wfreopen(const wchar_t *file, const wchar_t *mode, FILE *f); - -FILE* _fsopen(const char *file, const char *mode, int shflag); -FILE* _wfsopen(const wchar_t *file, const wchar_t *mode, int shflag); - -int fflush(FILE* fileFlush); -int fclose(FILE* fileClose); -#define fcloseall _fcloseall -int remove(const char* szFileName); -int _wremove(const wchar_t* szFileName); -int rename(const char* szOldFileName, const char* szNewFileName); -int _wrename(const wchar_t *oldName, const wchar_t *newName); -FILE* tmpfile(void); - -int _filbuf(FILE *f); -int _flsbuf(int c, FILE *f); -void _fwalk(void (*func)(FILE *)); // not exported -int _fcloseall(void); - +FILE* fopen(const char* szFileName, const char* szMode); +FILE* freopen(const char* szNewFileName, const char* szNewMode, FILE* fileChangeAssociation); +int fflush(FILE* fileFlush); +int fclose(FILE* fileClose); +#define fcloseall _fcloseall +int remove(const char* szFileName); +int rename(const char* szOldFileName, const char* szNewFileName); +FILE* tmpfile(void); + +FILE* _fdopen(int handle, char *mode); +FILE* _wfdopen(int handle, wchar_t *mode); +FILE* _wfopen(const wchar_t *file, const wchar_t *mode); +FILE* _wfreopen(const wchar_t *file, const wchar_t *mode, FILE *f); +FILE* _fsopen(const char *file, const char *mode, int shflag); +FILE* _wfsopen(const wchar_t *file, const wchar_t *mode, int shflag); +int _wremove(const wchar_t* szFileName); +int _wrename(const wchar_t *oldName, const wchar_t *newName); + +int _filbuf(FILE* f); +int _flsbuf(int c, FILE* f); +void _fwalk(void (*func)(FILE*)); // not exported +int _fcloseall(void); /* * The maximum size of name (including NUL) that will be put in the user @@ -165,16 +161,16 @@ int _fcloseall(void); * maximum file name length above it is probably reasonable. I could be * wrong... */ -#define L_tmpnam (260) +#define L_tmpnam (260) -char* tmpnam (char caName[]); -wchar_t* _wtmpnam(wchar_t *s); +char* tmpnam(char caName[]); +char* _tempnam(const char *szDir, const char *szPfx); -char* _tempnam (const char *szDir, const char *szPfx); +wchar_t* _wtmpnam(wchar_t *s); wchar_t *_wtempnam(const wchar_t *dir,const wchar_t *prefix); #ifndef _NO_OLDNAMES -#define tempnam _tempnam +#define tempnam _tempnam #endif /* Not _NO_OLDNAMES */ /* @@ -182,120 +178,121 @@ wchar_t *_wtempnam(const wchar_t *dir,const wchar_t *prefix); * NOTE: _IOFBF works, but _IOLBF seems to work like unbuffered... * maybe I'm testing it wrong? */ -#define _IOFBF 0 /* fully buffered */ -#define _IOLBF 1 /* line buffered */ -#define _IONBF 2 /* unbuffered */ - -int setvbuf (FILE* fileSetBuffer, char* caBuffer, int nMode, - size_t sizeBuffer); +#define _IOFBF 0 /* fully buffered */ +#define _IOLBF 1 /* line buffered */ +#define _IONBF 2 /* unbuffered */ +int setvbuf(FILE* fileSetBuffer, char* caBuffer, int nMode, size_t sizeBuffer); /* * The buffer size as used by setbuf such that it is equivalent to * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ). */ -#define BUFSIZ 512 +#define BUFSIZ 512 -void setbuf (FILE* fileSetBuffer, char* caBuffer); +void setbuf(FILE* fileSetBuffer, char* caBuffer); /* * Pipe Operations */ -int _pclose (FILE* pipeClose); -FILE* _popen (const char* szPipeName, const char* szMode); -FILE* _wpopen (const wchar_t *cm, const wchar_t *md); +int _pclose(FILE* pipeClose); +FILE* _popen(const char* szPipeName, const char* szMode); +FILE* _wpopen(const wchar_t *cm, const wchar_t *md); -#define popen _popen -#define pclose _pclose +#define popen _popen +#define pclose _pclose /* Wide character version */ -FILE* _wpopen (const wchar_t* szPipeName, const wchar_t* szMode); +FILE* _wpopen(const wchar_t* szPipeName, const wchar_t* szMode); /* * Formatted Output */ -int fprintf (FILE* filePrintTo, const char* szFormat, ...); -int printf (const char* szFormat, ...); -int sprintf (char* caBuffer, const char* szFormat, ...); -int vfprintf (FILE* filePrintTo, const char* szFormat, va_list varg); -int vprintf (const char* szFormat, va_list varg); -int vsprintf (char* caBuffer, const char* szFormat, va_list varg); +int fprintf(FILE* filePrintTo, const char* szFormat, ...); +int printf(const char* szFormat, ...); +int sprintf(char* caBuffer, const char* szFormat, ...); +int _snprintf(char*, size_t, const char*, ...); +int vfprintf(FILE* filePrintTo, const char* szFormat, va_list varg); +int vprintf(const char* szFormat, va_list varg); +int vsprintf(char* caBuffer, const char* szFormat, va_list varg); +int _vsnprintf(char* caBuffer, size_t cnt, const char* szFormat, va_list varg); +int _vsnwprintf (wchar_t*, size_t, const wchar_t*, va_list); /* Wide character versions */ -int fwprintf (FILE* filePrintTo, const wchar_t* wsFormat, ...); -int wprintf (const wchar_t* wsFormat, ...); -int swprintf (wchar_t* wcaBuffer, const wchar_t* wsFormat, ...); -int vfwprintf (FILE* filePrintTo, const wchar_t* wsFormat, va_list varg); -int vwprintf (const wchar_t* wsFormat, va_list varg); -int vswprintf (wchar_t* wcaBuffer, const wchar_t* wsFormat, va_list varg); +int fwprintf(FILE* filePrintTo, const wchar_t* wsFormat, ...); +int wprintf(const wchar_t* wsFormat, ...); +int swprintf(wchar_t* wcaBuffer, const wchar_t* wsFormat, ...); +int vfwprintf(FILE* filePrintTo, const wchar_t* wsFormat, va_list varg); +int vwprintf(const wchar_t* wsFormat, va_list varg); +int vswprintf(wchar_t* wcaBuffer, const wchar_t* wsFormat, va_list varg); /* * Formatted Input */ -int fscanf (FILE* fileReadFrom, const char* szFormat, ...); -int scanf (const char* szFormat, ...); -int sscanf (const char* szReadFrom, const char* szFormat, ...); +int fscanf(FILE* fileReadFrom, const char* szFormat, ...); +int scanf(const char* szFormat, ...); +int sscanf(const char* szReadFrom, const char* szFormat, ...); /* Wide character versions */ -int fwscanf (FILE* fileReadFrom, const wchar_t* wsFormat, ...); -int wscanf (const wchar_t* wsFormat, ...); -int swscanf (const wchar_t* wsReadFrom, const wchar_t* wsFormat, ...); +int fwscanf(FILE* fileReadFrom, const wchar_t* wsFormat, ...); +int wscanf(const wchar_t* wsFormat, ...); +int swscanf(const wchar_t* wsReadFrom, const wchar_t* wsFormat, ...); /* * Character Input and Output Functions */ -int fgetc (FILE* fileRead); -char* fgets (char* caBuffer, int nBufferSize, FILE* fileRead); -int fputc (int c, FILE* fileWrite); -int fputs (const char* szOutput, FILE* fileWrite); -int getc (FILE* fileRead); -int getchar (void); -char* gets (char* caBuffer); /* Unsafe: how does gets know how long the - * buffer is? */ -int putc (int c, FILE* fileWrite); -int putchar (int c); -int puts (const char* szOutput); -int ungetc (int c, FILE* fileWasRead); +int fgetc(FILE* fileRead); +char* fgets(char* caBuffer, int nBufferSize, FILE* fileRead); +int fputc(int c, FILE* fileWrite); +int fputs(const char* szOutput, FILE* fileWrite); +int getc(FILE* fileRead); +int getchar(void); +char* gets(char* caBuffer); /* Unsafe: how does gets know how long the buffer is? */ +int putc(int c, FILE* fileWrite); +int putchar(int c); +int puts(const char* szOutput); +int ungetc(int c, FILE* fileWasRead); /* Wide character versions */ -wint_t fgetwc (FILE* fileRead); -wint_t fputwc (wchar_t wc, FILE* fileWrite); -wint_t getwc (FILE *fileRead); -wint_t putwc (wint_t wc, FILE* fileWrite); -wint_t putwchar (wint_t c); -int _putws (const wchar_t* ws); -wint_t ungetwc (wchar_t wc, FILE* fileWasRead); +wint_t fgetwc(FILE* fileRead); +wint_t fputwc(wchar_t wc, FILE* fileWrite); +wint_t getwc(FILE *fileRead); // not exported from crtdll + +// TODO: check type wint_t, why doesn't compare to WEOF correctly ??? +//wint_t putwc(wint_t wc, FILE* fileWrite); +int putwc(wint_t wc, FILE* fileWrite); + +wint_t putwchar(wint_t c); +int _putws(const wchar_t* ws); -wint_t _filwbuf(FILE *f); -wint_t _flswbuf(wchar_t c, FILE *f); +wint_t ungetwc(wchar_t wc, FILE* fileWasRead); + +wint_t _filwbuf(FILE *f); +wint_t _flswbuf(wchar_t c, FILE *f); /* * Not exported by CRTDLL.DLL included for reference purposes. */ #if 0 -wchar_t* fgetws (wchar_t* wcaBuffer, int nBufferSize, FILE* fileRead); -int fputws (const wchar_t* wsOutput, FILE* fileWrite); -int getwc (FILE* fileRead); -int getwchar (); -wchar_t* getws (wchar_t* wcaBuffer); -#endif /* 0 */ +wchar_t* fgetws(wchar_t* wcaBuffer, int nBufferSize, FILE* fileRead); +int fputws(const wchar_t* wsOutput, FILE* fileWrite); +int getwc(FILE* fileRead); +int getwchar(); +wchar_t* getws(wchar_t* wcaBuffer); +#endif /* 0 */ /* NOTE: putchar has no wide char equivalent even in tchar.h */ - /* * Direct Input and Output Functions */ -size_t fread (void* pBuffer, size_t sizeObject, size_t sizeObjCount, - FILE* fileRead); -size_t fwrite (const void* pObjArray, size_t sizeObject, size_t sizeObjCount, - FILE* fileWrite); - +size_t fread(void* pBuffer, size_t sizeObject, size_t sizeObjCount, FILE* fileRead); +size_t fwrite(const void* pObjArray, size_t sizeObject, size_t sizeObjCount, FILE* fileWrite); /* * File Positioning Functions @@ -304,21 +301,21 @@ size_t fwrite (const void* pObjArray, size_t sizeObject, size_t sizeObjCount, /* Constants for nOrigin indicating the position relative to which fseek * sets the file position. Enclosed in ifdefs because io.h could also * define them. (Though not anymore since io.h includes this file now.) */ -#ifndef SEEK_SET -#define SEEK_SET (0) +#ifndef SEEK_SET +#define SEEK_SET (0) #endif -#ifndef SEEK_CUR -#define SEEK_CUR (1) +#ifndef SEEK_CUR +#define SEEK_CUR (1) #endif -#ifndef SEEK_END -#define SEEK_END (2) +#ifndef SEEK_END +#define SEEK_END (2) #endif -int fseek (FILE* fileSetPosition, long lnOffset, int nOrigin); -long ftell (FILE* fileGetPosition); -void rewind (FILE* fileRewind); +int fseek(FILE* fileSetPosition, long lnOffset, int nOrigin); +long ftell(FILE* fileGetPosition); +void rewind(FILE* fileRewind); /* * An opaque data type used for storing file positions... The contents of @@ -328,45 +325,45 @@ void rewind (FILE* fileRewind); * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). * Perhaps an unsigned long? TODO? */ -typedef long fpos_t; - -int fgetpos (FILE* fileGetPosition, fpos_t* pfpos); -int fsetpos (FILE* fileSetPosition, const fpos_t* pfpos); +typedef long fpos_t; +int fgetpos(FILE* fileGetPosition, fpos_t* pfpos); +int fsetpos(FILE* fileSetPosition, const fpos_t* pfpos); /* * Error Functions */ #if 0 -void clearerr (FILE* fileClearErrors); -int feof (FILE* fileIsAtEnd); -int ferror (FILE* fileIsError); -void perror (const char* szErrorMessage); - +void clearerr(FILE* fileClearErrors); +int feof(FILE* fileIsAtEnd); +int ferror(FILE* fileIsError); +void perror(const char* szErrorMessage); #endif + void _wperror(const wchar_t *s); +#define clearerr(f) (((f)->_flag) &= ~(_IOERR|_IOEOF)) +#define feof(f) (((f)->_flag&_IOEOF)!=0) +//#define ferror(f) (((f)->_flag&_IOERR)!=0) +int ferror(FILE* fileIsError); +#define perror(s) (fprintf(stderr, "%s: %s\n", (s), _strerror(NULL))) -#define clearerr(f) (((f)->_flag) &= ~(_IOERR|_IOEOF)) -#define feof(f) (((f)->_flag&_IOEOF)!=0) -#define ferror(f) (((f)->_flag&_IOERR)!=0) -#define perror(s) (fprintf(stderr, "%s: %s\n", (s), _strerror(NULL))) /* * Non ANSI functions */ #ifndef __STRICT_ANSI__ -int _fgetchar (void); -int _fputchar (int c); -FILE* _fdopen (int nHandle, char* szMode); +int _fgetchar(void); +int _fputchar(int c); +FILE* _fdopen(int nHandle, char* szMode); #ifndef _NO_OLDNAMES -#define fgetchar _fgetchar -#define fputchar _fputchar -#define fdopen _fdopen -#endif /* Not _NO_OLDNAMES */ +#define fgetchar _fgetchar +#define fputchar _fputchar +#define fdopen _fdopen +#endif /* Not _NO_OLDNAMES */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ #ifdef __cplusplus } diff --git a/include/msvcrt/stdlib.h b/include/msvcrt/stdlib.h index dc60319..a79ddd3 100644 --- a/include/msvcrt/stdlib.h +++ b/include/msvcrt/stdlib.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -30,6 +30,23 @@ #ifndef _STDLIB_H_ #define _STDLIB_H_ +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +#include + +/* + * RAND_MAX is the maximum value that may be returned by rand. + * The minimum is zero. + */ +#define RAND_MAX 0x7FFF + +/* + * These values may be used as exit status codes. + */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE -1 + #ifdef __cplusplus extern "C" { #endif @@ -40,92 +57,69 @@ extern "C" { * argc and argv. environ is a pointer to a table of environment variables. * NOTE: Strings in _argv and environ are ANSI strings. */ -extern int* __argc_dll; -extern char*** __argv_dll; -extern char*** _environ_dll; -#define __argc (*__argc_dll) -#define __argv (*__argv_dll) -#define _environ (*_environ_dll) +extern int* __argc_dll; +extern char*** __argv_dll; +extern char*** _environ_dll; +#define __argc (*__argc_dll) +#define __argv (*__argv_dll) +#define _environ (*_environ_dll) -#define __need_size_t -#define __need_wchar_t -#define __need_NULL -#include #include -#ifndef __ATTRIB_NORETURN -#ifdef __GNUC__ -#define _ATTRIB_NORETURN __attribute__ ((noreturn)) -#ifndef __int64 -#define __int64 long long -#endif /* Not __int64 */ -#else /* Not __GNUC__ */ -#define _ATTRIB_NORETURN -#endif /* __GNUC__ */ +#ifndef __ATTRIB_NORETURN +#ifdef __GNUC__ +#define _ATTRIB_NORETURN __attribute__ ((noreturn)) +#ifndef __int64 +#define __int64 long long +#endif /* Not __int64 */ +#else /* Not __GNUC__ */ +#define _ATTRIB_NORETURN +#endif /* __GNUC__ */ #endif -double atof (const char* szNumber); -int atoi (const char* szNumber); -long atol (const char* szNumber); - +double atof(const char* szNumber); +int atoi(const char* szNumber); +long atol(const char* szNumber); -double strtod (const char* szNumber, char** pszAfterNumber); -double wcstod (const wchar_t* wsNumber, wchar_t** pwsAfterNumber); -long strtol (const char* szNumber, char** pszAfterNumber, int nBase); -long wcstol (const wchar_t* wsNumber, wchar_t** pwsAfterNumber, int nBase); +double strtod(const char* szNumber, char** pszAfterNumber); +double wcstod(const wchar_t* wsNumber, wchar_t** pwsAfterNumber); +long strtol(const char* szNumber, char** pszAfterNumber, int nBase); +long wcstol(const wchar_t* wsNumber, wchar_t** pwsAfterNumber, int nBase); -unsigned long strtoul (const char* szNumber, char** pszAfterNumber, - int nBase); -unsigned long wcstoul (const wchar_t* wsNumber, wchar_t** pwsAfterNumber, - int nBase); +unsigned long strtoul(const char* szNumber, char** pszAfterNumber, int nBase); +unsigned long wcstoul(const wchar_t* wsNumber, wchar_t** pwsAfterNumber, int nBase); -size_t wcstombs (char* mbsDest, const wchar_t* wsConvert, size_t size); -int wctomb (char* mbDest, wchar_t wc); +size_t wcstombs(char* mbsDest, const wchar_t* wsConvert, size_t size); +int wctomb(char* mbDest, wchar_t wc); +int mblen(const char* mbs, size_t sizeString); +size_t mbstowcs(wchar_t* wcaDest, const char* mbsConvert, size_t size); +int mbtowc(wchar_t* wcDest, const char* mbConvert, size_t size); -int mblen (const char* mbs, size_t sizeString); -size_t mbstowcs (wchar_t* wcaDest, const char* mbsConvert, - size_t size); -int mbtowc (wchar_t* wcDest, const char* mbConvert, size_t size); +int rand(void); +void srand(unsigned int nSeed); +void* calloc(size_t sizeObjCnt, size_t sizeObject); +void* malloc(size_t sizeObject); +void* realloc(void* pObject, size_t sizeNew); +void free(void* pObject); -/* - * RAND_MAX is the maximum value that may be returned by rand. - * The minimum is zero. - */ -#define RAND_MAX 0x7FFF - -int rand (void); -void srand (unsigned int nSeed); +void abort(void) _ATTRIB_NORETURN; +void exit(int nStatus) _ATTRIB_NORETURN; +int atexit(void (*pfuncExitProcessing)(void)); +int system(const char* szCommand); // impl in process +char* getenv(const char* szVarName); // impl in stdio ??? +wchar_t* _wgetenv(const wchar_t* szVarName); -void* calloc (size_t sizeObjCnt, size_t sizeObject); -void* malloc (size_t sizeObject); -void* realloc (void* pObject, size_t sizeNew); -void free (void* pObject); +typedef int (*_pfunccmp_t)(const void*, const void*); -/* These values may be used as exit status codes. */ -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE -1 +void* bsearch(const void* pKey, const void* pBase, size_t cntObjects, size_t sizeObject, _pfunccmp_t pfuncCmp); +void qsort(const void* pBase, size_t cntObjects, size_t sizeObject, _pfunccmp_t pfuncCmp); -void abort (void) _ATTRIB_NORETURN; -void exit (int nStatus) _ATTRIB_NORETURN; -int atexit (void (*pfuncExitProcessing)(void)); - -int system (const char* szCommand); // impl in process -char* getenv (const char* szVarName); -wchar_t* _wgetenv (const wchar_t* szVarName); - -typedef int (*_pfunccmp_t)(const void*, const void*); - -void* bsearch (const void* pKey, const void* pBase, size_t cntObjects, - size_t sizeObject, _pfunccmp_t pfuncCmp); -void qsort (const void* pBase, size_t cntObjects, size_t sizeObject, - _pfunccmp_t pfuncCmp); - -int abs (int n); -long labs (long n); +int abs(int n); +long labs(long n); /* * div_t and ldiv_t are structures used to return the results of div and @@ -137,96 +131,99 @@ long labs (long n); */ typedef struct { int quot, rem; } div_t; typedef struct { long quot, rem; } ldiv_t; + +#ifdef __GNUC__ // robd typedef struct { long long quot, rem; } lldiv_t; +#else +typedef struct { double quot, rem; } lldiv_t; +#endif -div_t div (int nNumerator, int nDenominator); -ldiv_t ldiv (long lNumerator, long lDenominator); -lldiv_t lldiv (long long lNumerator, long long lDenominator); +div_t div(int nNumerator, int nDenominator); +ldiv_t ldiv(long lNumerator, long lDenominator); + +#ifdef __GNUC__ // robd +lldiv_t lldiv(long long lNumerator, long long lDenominator); +#else +lldiv_t lldiv(double lNumerator, double lDenominator); +#endif -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ /* * NOTE: Officially the three following functions are obsolete. The Win32 API * functions SetErrorMode, Beep and Sleep are their replacements. */ -void _beep (unsigned int, unsigned int); -void _seterrormode (int nMode); -void _sleep (unsigned long ulTime); - -void _exit (int nStatus) _ATTRIB_NORETURN; - -int _putenv (const char *val); -int _wputenv(const wchar_t *val); -void _searchenv (const char *file, const char *var, char *path); -void _wsearchenv (const wchar_t *file, const wchar_t *var, wchar_t *path); - -void _makepath( char *path, const char *drive, const char *dir, - const char *fname, const char *ext ); -void _wmakepath( wchar_t *path, const wchar_t *drive, const wchar_t *dir, - const wchar_t *fname, const wchar_t *ext ); -void _splitpath( const char *path, char *drive, char *dir, - char *fname, char *ext ); -char* _fullpath( char* caBuf, const char* szPath, size_t sizeMax ); -wchar_t *_wfullpath( wchar_t *absPath, const wchar_t *relPath, size_t maxLength ); - -char* _itoa (int nValue, char* sz, int nRadix); -char* _i64toa(__int64 value, char *string, int radix); -char* _ltoa (long lnValue, char* sz, int nRadix); -char* _ultoa(unsigned long value, char *string, int radix); -char* _ui64toa(unsigned __int64 value, char *string, int radix); - -wchar_t* _itow (int nValue, wchar_t* sz, int nRadix); -wchar_t* _i64tow(__int64 value, wchar_t *string, int radix); -wchar_t* _ltow (long lnValue, wchar_t* sz, int nRadix); -wchar_t* _ultow(unsigned long value, wchar_t *string, int radix); -wchar_t* _ui64tow(unsigned __int64 value, wchar_t *string, int radix); +void _beep(unsigned int, unsigned int); +void _seterrormode(int nMode); +void _sleep(unsigned long ulTime); -char* _ecvt (double dValue, int nDig, int* pnDec, int* pnSign); -char* _fcvt (double dValue, int nDig, int* pnDec, int* pnSign); -char* _gcvt (double dValue, int nDec, char* caBuf); +void _exit(int nStatus) _ATTRIB_NORETURN; -void _swab (const char* caFrom, char* caTo, size_t sizeToCopy); +int _putenv(const char *val); +void _searchenv(const char *file, const char *var, char *path); +void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext); -unsigned int _rotl( unsigned int value, int shift ); -unsigned int _rotr( unsigned int value, int shift ); -unsigned long _lrotl( unsigned long value, int shift ); -unsigned long _lrotr( unsigned long value, int shift ); +char* _itoa(int nValue, char* sz, int nRadix); +char* _ltoa(long lnValue, char* sz, int nRadix); -__int64 _atoi64(const char *szNumber); +int _wputenv(const wchar_t *val); +void _wsearchenv(const wchar_t *file, const wchar_t *var, wchar_t *path); +void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext); +void _wmakepath(wchar_t *path, const wchar_t *drive, const wchar_t *dir, const wchar_t *fname, const wchar_t *ext); +wchar_t* _wfullpath(wchar_t *absPath, const wchar_t *relPath, size_t maxLength); +char* _i64toa(__int64 value, char *string, int radix); +char* _ultoa(unsigned long value, char *string, int radix); +char* _ui64toa(unsigned __int64 value, char *string, int radix); -int _wtoi( const wchar_t *str ); -__int64 _wtoi64(const wchar_t *str); -long _wtol( const wchar_t *str ); - - -#ifndef _NO_OLDNAMES -#define beep _beep -#define seterrormode _seterrormode -#define sleep _sleep -#define putenv _putenv -#define searchenv _searchenv -#define splitpath _splitpath - -#define itoa _itoa -#define ltoa _ltoa - -#define ecvt _ecvt -#define fcvt _fcvt -#define gcvt _gcvt - -#define swab _swab -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ +wchar_t* _itow(int nValue, wchar_t* sz, int nRadix); +wchar_t* _i64tow(__int64 value, wchar_t *string, int radix); +wchar_t* _ltow(long lnValue, wchar_t* sz, int nRadix); +wchar_t* _ultow(unsigned long value, wchar_t *string, int radix); +wchar_t* _ui64tow(unsigned __int64 value, wchar_t *string, int radix); +__int64 _atoi64(const char *szNumber); +int _wtoi(const wchar_t *str); +__int64 _wtoi64(const wchar_t *str); +long _wtol(const wchar_t *str); + +char* _ecvt(double dValue, int nDig, int* pnDec, int* pnSign); +char* _fcvt(double dValue, int nDig, int* pnDec, int* pnSign); +char* _gcvt(double dValue, int nDec, char* caBuf); +char* _fullpath(char* caBuf, const char* szPath, size_t sizeMax); +void _swab(const char* caFrom, char* caTo, size_t sizeToCopy); + +unsigned int _rotl(unsigned int value, int shift); +unsigned int _rotr(unsigned int value, int shift); +unsigned long _lrotl(unsigned long value, int shift); +unsigned long _lrotr(unsigned long value, int shift); + + +#ifndef _NO_OLDNAMES +#define beep _beep +#define seterrormode _seterrormode +#define sleep _sleep +#define putenv _putenv +#define searchenv _searchenv +#define splitpath _splitpath +#define itoa _itoa +#define ltoa _ltoa +#define ecvt _ecvt +#define fcvt _fcvt +#define gcvt _gcvt +#define swab _swab +#endif /* Not _NO_OLDNAMES */ + + +#endif /* Not __STRICT_ANSI__ */ /* * Undefine the no return attribute used in some function definitions */ -#undef _ATTRIB_NORETURN +#undef _ATTRIB_NORETURN #ifdef __cplusplus } #endif -#endif /* _STDLIB_H_ */ +#endif /* Not _STDLIB_H_ */ + diff --git a/include/msvcrt/string.h b/include/msvcrt/string.h index 80050af..c471845 100644 --- a/include/msvcrt/string.h +++ b/include/msvcrt/string.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -29,124 +29,118 @@ #ifndef _STRING_H_ -#define _STRING_H_ +#define _STRING_H_ -#ifdef __cplusplus -extern "C" { -#endif /* * Define size_t, wchar_t and NULL */ #define __need_size_t #define __need_wchar_t -#define __need_NULL +#define __need_NULL #include +#ifdef __cplusplus +extern "C" { +#endif + char * ___strtok; // removed extern specifier 02-06-98, BD /* * Prototypes of the ANSI Standard C library string functions. */ -void* memchr (const void* p, int cSearchFor, size_t sizeSearch); -int memcmp (const void* p1, const void* p2, size_t sizeSearch); -void* memcpy (void* pCopyTo, const void* pSource, size_t sizeSource); -void* memmove (void* pMoveTo, const void* pSource, size_t sizeSource); -void* memset (void* p, int cFill, size_t sizeRepeatCount); -char* strcat (char* szAddTo, const char* szAdd); -char* strchr (const char* szSearch, int cFor); -int strcmp (const char* sz1, const char* sz2); -int strcoll (const char* sz1, const char* sz2); /* Compare using locale */ -char* strcpy (char* szCopyTo, const char* szSource); -size_t strcspn (const char* szGetPrefix, const char* szNotIncluding); -char* strerror (int nError); /* NOTE: NOT an old name wrapper. */ +void* memchr(const void* p, int cSearchFor, size_t sizeSearch); +int memcmp(const void* p1, const void* p2, size_t sizeSearch); +void* memcpy(void* pCopyTo, const void* pSource, size_t sizeSource); +void* memmove(void* pMoveTo, const void* pSource, size_t sizeSource); +void* memset(void* p, int cFill, size_t sizeRepeatCount); +char* strcat(char* szAddTo, const char* szAdd); +char* strchr(const char* szSearch, int cFor); +int strcmp(const char* sz1, const char* sz2); +int strcoll(const char* sz1, const char* sz2); /* Compare using locale */ +char* strcpy(char* szCopyTo, const char* szSource); +size_t strcspn(const char* szGetPrefix, const char* szNotIncluding); +char* strerror(int nError); /* NOTE: NOT an old name wrapper. */ char * _strerror(const char *s); -size_t strlen (const char* sz); -size_t strnlen (const char* sz, size_t count); // not exported -char* strncat (char* szAddTo, const char* szAdd, size_t sizeMaxAdd); -int strncmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -char* strncpy (char* szCopyTo, const char* szSource, size_t sizeMaxCopy); -char* strpbrk (const char* szSearch, const char* szAnyOf); -char* strrchr (const char* szSearch, int cFor); -size_t strspn (const char* szGetPrefix, const char *szIncluding); -char* strstr (const char* szSearch, const char *szFor); -char* strtok (char* szTokenize, const char* szDelimiters); -size_t strxfrm (char* szTransformed, const char *szSource, - size_t sizeTransform); +size_t strlen(const char* sz); +size_t strnlen(const char* sz, size_t count); // not exported +char* strncat(char* szAddTo, const char* szAdd, size_t sizeMaxAdd); +int strncmp(const char* sz1, const char* sz2, size_t sizeMaxCompare); +char* strncpy(char* szCopyTo, const char* szSource, size_t sizeMaxCopy); +char* strpbrk(const char* szSearch, const char* szAnyOf); +char* strrchr(const char* szSearch, int cFor); +size_t strspn(const char* szGetPrefix, const char *szIncluding); +char* strstr(const char* szSearch, const char *szFor); +char* strtok(char* szTokenize, const char* szDelimiters); +size_t strxfrm(char* szTransformed, const char *szSource, size_t sizeTransform); #ifndef __STRICT_ANSI__ /* * Extra non-ANSI functions provided by the CRTDLL library */ -void* _memccpy (void* pCopyTo, const void* pSource, int cTerminator, - size_t sizeMaxCopy); -int _memicmp (const void* p1, const void* p2, size_t sizeSearch); -char* _strdup (const char *szDuplicate); -int _strcmpi (const char* sz1, const char* sz2); -int _stricmp (const char* sz1, const char* sz2); -int _stricoll (const char* sz1, const char* sz2); -char* _strlwr (char* szToConvert); -int _strnicmp (const char* sz1, const char* sz2, - size_t sizeMaxCompare); -char* _strnset (char* szToFill, int cFill, size_t sizeMaxFill); -char* _strrev (char* szToReverse); -char* _strset (char* szToFill, int cFill); -char* _strupr (char* szToConvert); - - -#endif /* Not __STRICT_ANSI__ */ +void* _memccpy(void* pCopyTo, const void* pSource, int cTerminator, size_t sizeMaxCopy); +int _memicmp(const void* p1, const void* p2, size_t sizeSearch); +char* _strdup(const char *szDuplicate); +int _strcmpi(const char* sz1, const char* sz2); +int _stricmp(const char* sz1, const char* sz2); +int _stricoll(const char* sz1, const char* sz2); +char* _strlwr(char* szToConvert); +int _strnicmp(const char* sz1, const char* sz2, size_t sizeMaxCompare); +char* _strnset(char* szToFill, int cFill, size_t sizeMaxFill); +char* _strrev(char* szToReverse); +char* _strset(char* szToFill, int cFill); +char* _strupr(char* szToConvert); + +#endif /* Not __STRICT_ANSI__ */ /* * Unicode versions of the standard calls. */ -wchar_t* wcscat (wchar_t* wsAddTo, const wchar_t* wsAdd); -wchar_t* wcschr (const wchar_t* wsSearch, wchar_t wcFor); -int wcscmp (const wchar_t* ws1, const wchar_t* ws2); -int wcscoll (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcscpy (wchar_t* wsCopyTo, const wchar_t* wsSource); -size_t wcscspn (const wchar_t* wsGetPrefix, const wchar_t* wsNotIncluding); +wchar_t* wcscat(wchar_t* wsAddTo, const wchar_t* wsAdd); +wchar_t* wcschr(const wchar_t* wsSearch, wchar_t wcFor); +int wcscmp(const wchar_t* ws1, const wchar_t* ws2); +int wcscoll(const wchar_t* ws1, const wchar_t* ws2); +wchar_t* wcscpy(wchar_t* wsCopyTo, const wchar_t* wsSource); +size_t wcscspn(const wchar_t* wsGetPrefix, const wchar_t* wsNotIncluding); /* Note: No wcserror in CRTDLL. */ -size_t wcslen (const wchar_t* ws); -wchar_t* wcsncat (wchar_t* wsAddTo, const wchar_t* wsAdd, size_t sizeMaxAdd); -int wcsncmp(const wchar_t* ws1, const wchar_t* ws2, size_t sizeMaxCompare); -wchar_t* wcsncpy(wchar_t* wsCopyTo, const wchar_t* wsSource, - size_t sizeMaxCopy); +size_t wcslen(const wchar_t* ws); +wchar_t* wcsncat(wchar_t* wsAddTo, const wchar_t* wsAdd, size_t sizeMaxAdd); +int wcsncmp(const wchar_t* ws1, const wchar_t* ws2, size_t sizeMaxCompare); +wchar_t* wcsncpy(wchar_t* wsCopyTo, const wchar_t* wsSource, size_t sizeMaxCopy); wchar_t* wcspbrk(const wchar_t* wsSearch, const wchar_t* wsAnyOf); wchar_t* wcsrchr(const wchar_t* wsSearch, wchar_t wcFor); -size_t wcsspn(const wchar_t* wsGetPrefix, const wchar_t* wsIncluding); +size_t wcsspn(const wchar_t* wsGetPrefix, const wchar_t* wsIncluding); wchar_t* wcsstr(const wchar_t* wsSearch, const wchar_t* wsFor); wchar_t* wcstok(wchar_t* wsTokenize, const wchar_t* wsDelimiters); -size_t wcsxfrm(wchar_t* wsTransformed, const wchar_t *wsSource, - size_t sizeTransform); +size_t wcsxfrm(wchar_t* wsTransformed, const wchar_t *wsSource, size_t sizeTransform); -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ /* * Unicode versions of non-ANSI functions provided by CRTDLL. */ /* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */ -#define _wcscmpi _wcsicmp +#define _wcscmpi _wcsicmp -wchar_t* _wcsdup (const wchar_t* wsToDuplicate); -int _wcsicmp (const wchar_t* ws1, const wchar_t* ws2); -int _wcsicoll (const wchar_t* ws1, const wchar_t* ws2); -int _wcsncoll (const wchar_t *s1, const wchar_t *s2, size_t c); -int _wcsnicoll (const wchar_t *s1, const wchar_t *s2, size_t c); -wchar_t* _wcslwr (wchar_t* wsToConvert); -int _wcsnicmp (const wchar_t* ws1, const wchar_t* ws2, - size_t sizeMaxCompare); -wchar_t* _wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); -wchar_t* _wcsrev (wchar_t* wsToReverse); -wchar_t* _wcsset (wchar_t* wsToFill, wchar_t wcToFill); -wchar_t* _wcsupr (wchar_t* wsToConvert); +wchar_t* _wcsdup(const wchar_t* wsToDuplicate); +int _wcsicmp(const wchar_t* ws1, const wchar_t* ws2); +int _wcsicoll(const wchar_t* ws1, const wchar_t* ws2); +int _wcsncoll(const wchar_t *s1, const wchar_t *s2, size_t c); +int _wcsnicoll(const wchar_t *s1, const wchar_t *s2, size_t c); +wchar_t* _wcslwr(wchar_t* wsToConvert); +int _wcsnicmp(const wchar_t* ws1, const wchar_t* ws2, size_t sizeMaxCompare); +wchar_t* _wcsnset(wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); +wchar_t* _wcsrev(wchar_t* wsToReverse); +wchar_t* _wcsset(wchar_t* wsToFill, wchar_t wcToFill); +wchar_t* _wcsupr(wchar_t* wsToConvert); -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES +#ifndef __STRICT_ANSI__ +#ifndef _NO_OLDNAMES /* * Non-underscored versions of non-ANSI functions. They live in liboldnames.a @@ -154,41 +148,41 @@ wchar_t* _wcsupr (wchar_t* wsToConvert); * strcasecmp. */ -void* memccpy (void* pCopyTo, const void* pSource, int cTerminator, - size_t sizeMaxCopy); -int memicmp (const void* p1, const void* p2, size_t sizeSearch); -#define strdup(szDuplicate) _strdup(szDuplicate) -int strcmpi (const char* sz1, const char* sz2); -int stricmp (const char* sz1, const char* sz2); -int strcasecmp (const char* sz1, const char* sz2); -int stricoll (const char* sz1, const char* sz2); -char* strlwr (char* szToConvert); -int strnicmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -int strncasecmp (const char* sz1, const char* sz2, size_t sizeMaxCompare); -char* strnset (char* szToFill, int cFill, size_t sizeMaxFill); -char* strrev (char* szToReverse); -char* strset (char* szToFill, int cFill); -char* strupr (char* szToConvert); +void* memccpy(void* pCopyTo, const void* pSource, int cTerminator, size_t sizeMaxCopy); +int memicmp(const void* p1, const void* p2, size_t sizeSearch); +#define strdup(szDuplicate) _strdup(szDuplicate) +int strcmpi(const char* sz1, const char* sz2); +int stricmp(const char* sz1, const char* sz2); +int strcasecmp(const char* sz1, const char* sz2); +int stricoll(const char* sz1, const char* sz2); +char* strlwr(char* szToConvert); +int strnicmp(const char* sz1, const char* sz2, size_t sizeMaxCompare); +int strncasecmp(const char* sz1, const char* sz2, size_t sizeMaxCompare); +char* strnset(char* szToFill, int cFill, size_t sizeMaxFill); +char* strrev(char* szToReverse); +char* strset(char* szToFill, int cFill); +char* strupr(char* szToConvert); /* NOTE: There is no _wcscmpi, but this is for compatibility. */ -int wcscmpi (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcsdup (const wchar_t* wsToDuplicate); -int wcsicmp (const wchar_t* ws1, const wchar_t* ws2); -int wcsicoll (const wchar_t* ws1, const wchar_t* ws2); -wchar_t* wcslwr (wchar_t* wsToConvert); -int wcsnicmp (const wchar_t* ws1, const wchar_t* ws2, - size_t sizeMaxCompare); -wchar_t* wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); -wchar_t* wcsrev (wchar_t* wsToReverse); -wchar_t* wcsset (wchar_t* wsToFill, wchar_t wcToFill); -wchar_t* wcsupr (wchar_t* wsToConvert); - -#endif /* Not _NO_OLDNAMES */ -#endif /* Not strict ANSI */ +int wcscmpi(const wchar_t* ws1, const wchar_t* ws2); +wchar_t* wcsdup(const wchar_t* wsToDuplicate); +int wcsicmp(const wchar_t* ws1, const wchar_t* ws2); +int wcsicoll(const wchar_t* ws1, const wchar_t* ws2); +wchar_t* wcslwr(wchar_t* wsToConvert); +int wcsnicmp(const wchar_t* ws1, const wchar_t* ws2, size_t sizeMaxCompare); +wchar_t* wcsnset(wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill); +wchar_t* wcsrev(wchar_t* wsToReverse); +wchar_t* wcsset(wchar_t* wsToFill, wchar_t wcToFill); +wchar_t* wcsupr(wchar_t* wsToConvert); + +#endif /* Not _NO_OLDNAMES */ +#endif /* Not strict ANSI */ -#endif #ifdef __cplusplus -extern "C" } +} #endif + +#endif /* Not _STRING_H_ */ + diff --git a/include/msvcrt/sys/locking.h b/include/msvcrt/sys/locking.h index d279c6d..69d458c 100644 --- a/include/msvcrt/sys/locking.h +++ b/include/msvcrt/sys/locking.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,15 +24,26 @@ * */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ -#ifndef _LOCKING_H_ -#define _LOCKING_H_ +#ifndef _LOCKING_H_ +#define _LOCKING_H_ -/* - * TODO: Define LK_... constants. - */ -#endif /* Not _LOCKING_H_ */ +#define _LK_UNLCK 0 /* Unlock */ +#define _LK_LOCK 1 /* Lock */ +#define _LK_NBLCK 2 /* Non-blocking lock */ +#define _LK_RLCK 3 /* Lock for read only */ +#define _LK_NBRLCK 4 /* Non-blocking lock for read only */ + +#ifndef NO_OLDNAMES +#define LK_UNLCK _LK_UNLCK +#define LK_LOCK _LK_LOCK +#define LK_NBLCK _LK_NBLCK +#define LK_RLCK _LK_RLCK +#define LK_NBRLCK _LK_NBRLCK +#endif /* Not NO_OLDNAMES */ + +#endif /* Not _LOCKING_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/sys/stat.h b/include/msvcrt/sys/stat.h index 997ace7..ab7dfed 100644 --- a/include/msvcrt/sys/stat.h +++ b/include/msvcrt/sys/stat.h @@ -16,7 +16,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -32,52 +32,49 @@ #include -#ifdef __cplusplus -extern "C" { -#endif #ifndef _WCHAR_T_ #define _WCHAR_T_ #define _WCHAR_T #define _WCHAR_T_DEFINED #ifndef __WCHAR_TYPE__ -#define __WCHAR_TYPE__ short unsigned int +#define __WCHAR_TYPE__ short unsigned int #endif #ifndef __cplusplus -typedef __WCHAR_TYPE__ wchar_t; -#endif /* C++ */ -#endif /* wchar_t not already defined */ +typedef __WCHAR_TYPE__ wchar_t; +#endif /* C++ */ +#endif /* wchar_t not already defined */ /* * Constants for the stat st_mode member. */ -#define S_IFIFO 0x1000 /* FIFO */ -#define S_IFCHR 0x2000 /* Character */ -#define S_IFBLK 0x3000 /* Block */ -#define S_IFDIR 0x4000 /* Directory */ -#define S_IFREG 0x8000 /* Regular */ +#define S_IFIFO 0x1000 /* FIFO */ +#define S_IFCHR 0x2000 /* Character */ +#define S_IFBLK 0x3000 /* Block */ +#define S_IFDIR 0x4000 /* Directory */ +#define S_IFREG 0x8000 /* Regular */ -#define S_IFMT 0xF000 /* File type mask */ +#define S_IFMT 0xF000 /* File type mask */ -#define S_IEXEC 0x0040 -#define S_IWRITE 0x0080 -#define S_IREAD 0x0100 +#define S_IEXEC 0x0040 +#define S_IWRITE 0x0080 +#define S_IREAD 0x0100 -#define S_ISDIR(m) ((m) & S_IFDIR) -#define S_ISFIFO(m) ((m) & S_IFIFO) -#define S_ISCHR(m) ((m) & S_IFCHR) -#define S_ISBLK(m) ((m) & S_IFBLK) -#define S_ISREG(m) ((m) & S_IFREG) +#define S_ISDIR(m) ((m) & S_IFDIR) +#define S_ISFIFO(m) ((m) & S_IFIFO) +#define S_ISCHR(m) ((m) & S_IFCHR) +#define S_ISBLK(m) ((m) & S_IFBLK) +#define S_ISREG(m) ((m) & S_IFREG) -#define S_IRWXU (S_IREAD | S_IWRITE | S_IEXEC) -#define S_IXUSR S_IEXEC -#define S_IWUSR S_IWRITE -#define S_IRUSR S_IREAD +#define S_IRWXU (S_IREAD | S_IWRITE | S_IEXEC) +#define S_IXUSR S_IEXEC +#define S_IWUSR S_IWRITE +#define S_IRUSR S_IREAD -#define _S_IEXEC S_IEXEC -#define _S_IREAD S_IREAD -#define _S_IWRITE S_IWRITE +#define _S_IEXEC S_IEXEC +#define _S_IREAD S_IREAD +#define _S_IWRITE S_IWRITE /* * The structure manipulated and returned by stat and fstat. @@ -88,55 +85,65 @@ typedef __WCHAR_TYPE__ wchar_t; */ struct stat { - long st_dev; /* Equivalent to drive number 0=A 1=B ... */ - short st_ino; /* Always zero ? */ - short st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - int st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - short st_rdev; /* Seems useless (not even filled in) */ - long st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ +#ifdef _MSVCRT_LIB_ + long st_dev; /* Equivalent to drive number 0=A 1=B ... */ +#else + short st_dev; /* Equivalent to drive number 0=A 1=B ... */ + short st_padding; /* Pad structure to equal msvcrt version req */ +#endif + short st_ino; /* Always zero ? */ + short st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + int st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + short st_rdev; /* Seems useless (not even filled in) */ + long st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ }; + struct _stati64 { - short st_dev; /* Equivalent to drive number 0=A 1=B ... */ - short st_ino; /* Always zero ? */ - short st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - int st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - short st_rdev; /* Seems useless (not even filled in) */ - __int64 st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ + short st_dev; /* Equivalent to drive number 0=A 1=B ... */ + short st_ino; /* Always zero ? */ + short st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + int st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + short st_rdev; /* Seems useless (not even filled in) */ + __int64 st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ }; -int _fstat (int nFileNo, struct stat* pstat); -__int64 _fstati64 (int nFileNo, struct _stati64* pstat); -int _stat (const char* szPath, struct stat* pstat); -__int64 _stati64 (const char* szPath, struct _stati64* pstat); -int _wstat (const wchar_t* szPath, struct stat* pstat); -__int64 _wstati64 (const wchar_t* szPath, struct _stati64* pstat); +#ifdef __cplusplus +extern "C" { +#endif + +int _fstat(int, struct stat*); +int _stat(const char*, struct stat*); + +__int64 _fstati64(int nFileNo, struct _stati64* pstat); +__int64 _stati64(const char* szPath, struct _stati64* pstat); +int _wstat(const wchar_t* szPath, struct stat* pstat); +__int64 _wstati64(const wchar_t* szPath, struct _stati64* pstat); + -#ifndef _NO_OLDNAMES +#ifndef _NO_OLDNAMES -#define fstat(nFileNo, pstat) _fstat(nFileNo, pstat) -#define stat(szPath,pstat) _stat(szPath,pstat) +#define fstat(nFileNo, pstat) _fstat(nFileNo, pstat) +#define stat(szPath,pstat) _stat(szPath,pstat) -#endif /* Not _NO_OLDNAMES */ +#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not _STAT_H_ */ +#endif /* Not _STAT_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/sys/timeb.h b/include/msvcrt/sys/timeb.h index 85e57ed..0c80891 100644 --- a/include/msvcrt/sys/timeb.h +++ b/include/msvcrt/sys/timeb.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,37 +24,38 @@ * */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ -#ifndef _TIMEB_H_ -#define _TIMEB_H_ +#ifndef _TIMEB_H_ +#define _TIMEB_H_ -#ifdef __cplusplus -extern "C" { -#endif /* * TODO: Structure not tested. */ struct timeb { - long time; - short millitm; - short _timezone; - short dstflag; + long time; + short millitm; + short _timezone; + short dstflag; }; +#ifdef __cplusplus +extern "C" { +#endif + /* TODO: Not tested. */ -void _ftime (struct timeb* timebBuffer); +void _ftime(struct timeb*); -#ifndef _NO_OLDNAMES -void ftime (struct timeb* timebBuffer); -#endif /* Not _NO_OLDNAMES */ +#ifndef _NO_OLDNAMES +void ftime(struct timeb*); +#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not _TIMEB_H_ */ +#endif /* Not _TIMEB_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/sys/types.h b/include/msvcrt/sys/types.h index 234e1d0..5444e2f 100644 --- a/include/msvcrt/sys/types.h +++ b/include/msvcrt/sys/types.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warrenties of + * DISCLAIMED. This includes but is not limited to warrenties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,59 +24,45 @@ * */ -#ifndef _TYPES_H_ -#define _TYPES_H_ +#ifndef _TYPES_H_ +#define _TYPES_H_ -#ifdef __GNUC__ -#undef __int64 -#define __int64 long long +#ifdef __GNUC__ +#undef __int64 +#define __int64 long long #endif -#ifndef _TIME_T_ -#define _TIME_T_ -typedef long time_t; +#ifndef _TIME_T_ +#define _TIME_T_ +typedef long time_t; #endif +#ifndef __STRICT_ANSI__ -#ifndef __STRICT_ANSI__ - -#ifndef _OFF_T_DEFINED +#ifndef _OFF_T_DEFINED typedef long _off_t; - -#ifndef _NO_OLDNAMES -#define off_t _off_t +#ifndef _NO_OLDNAMES +#define off_t _off_t #endif - -#define _OFF_T_DEFINED - -#endif /* Not _OFF_T_DEFINED */ - +#define _OFF_T_DEFINED +#endif /* Not _OFF_T_DEFINED */ #ifndef _DEV_T_DEFINED typedef short _dev_t; - -#ifndef _NO_OLDNAMES -#define dev_t _dev_t +#ifndef _NO_OLDNAMES +#define dev_t _dev_t #endif - -#define _DEV_T_DEFINED - -#endif /* Not _DEV_T_DEFINED */ - +#define _DEV_T_DEFINED +#endif /* Not _DEV_T_DEFINED */ #ifndef _INO_T_DEFINED typedef short _ino_t; - -#ifndef _NO_OLDNAMES -#define ino_t _ino_t +#ifndef _NO_OLDNAMES +#define ino_t _ino_t #endif +#define _INO_T_DEFINED +#endif /* Not _INO_T_DEFINED */ -#define _INO_T_DEFINED - -#endif /* Not _INO_T_DEFINED */ - - -#endif /* Not __STRICT_ANSI__ */ - +#endif /* Not __STRICT_ANSI__ */ -#endif /* Not _TYPES_H_ */ +#endif /* Not _TYPES_H_ */ diff --git a/include/msvcrt/sys/utime.h b/include/msvcrt/sys/utime.h index a2d162d..ab239d5 100644 --- a/include/msvcrt/sys/utime.h +++ b/include/msvcrt/sys/utime.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,52 +24,57 @@ * */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ -#ifndef _UTIME_H_ -#define _UTIME_H_ +#ifndef _UTIME_H_ +#define _UTIME_H_ #define __need_wchar_t #define __need_size_t #include #include -#ifdef __cplusplus -extern "C" { -#endif /* * Structure used by _utime function. */ struct _utimbuf { - time_t actime; /* Access time */ - time_t modtime; /* Modification time */ + time_t actime; /* Access time */ + time_t modtime; /* Modification time */ }; -int _utime (const char* szFileName, struct _utimbuf* pTimes); -int _futime (int nHandle, struct _utimbuf *pTimes); -/* Wide character version */ -int _wutime (const wchar_t *szFileName, struct _utimbuf *times); - -#ifndef _NO_OLDNAMES +#ifndef _NO_OLDNAMES /* NOTE: Must be the same as _utimbuf above. */ struct utimbuf { - time_t actime; - time_t modtime; + time_t actime; + time_t modtime; }; +#endif /* Not _NO_OLDNAMES */ + + +#ifdef __cplusplus +extern "C" { +#endif + +int _utime(const char*, struct _utimbuf*); +int _futime(int, struct _utimbuf*); -int utime (const char* szFileName, struct utimbuf* pTimes); +/* The wide character version, only available for MSVCRT versions of the + * C runtime library. */ +int _wutime(const wchar_t*, struct _utimbuf*); -#endif /* Not _NO_OLDNAMES */ +#ifndef _NO_OLDNAMES +int utime(const char*, struct utimbuf*); +#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not _UTIME_H_ */ -#endif /* Not __STRICT_ANSI__ */ +#endif /* Not _UTIME_H_ */ +#endif /* Not __STRICT_ANSI__ */ diff --git a/include/msvcrt/time.h b/include/msvcrt/time.h index ca4df43..94ceea7 100644 --- a/include/msvcrt/time.h +++ b/include/msvcrt/time.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,31 +24,21 @@ * */ /* Appropriated for Reactos Crtdll by Ariadne */ -#ifndef _TIME_H_ -#define _TIME_H_ +#ifndef _TIME_H_ +#define _TIME_H_ #define __need_wchar_t #define __need_size_t #include -#ifdef __cplusplus -extern "C" { -#endif /* * Number of clock ticks per second. A clock tick is the unit by which * processor time is measured and is returned by 'clock'. */ -#define CLOCKS_PER_SEC 1000.0 -#define CLK_TICK CLOCKS_PER_SEC +#define CLOCKS_PER_SEC 1000.0 +#define CLK_TICK CLOCKS_PER_SEC -/* - * A type for measuring processor time (in clock ticks). - */ -#ifndef _CLOCK_T_ -#define _CLOCK_T_ -typedef long clock_t; -#endif /* * Need a definition of time_t. @@ -61,34 +51,46 @@ typedef long clock_t; * NOTE: Normally this is defined by the above include of sys/types.h */ #ifndef _TIME_T_ +typedef long time_t; #define _TIME_T_ -typedef long time_t; +#endif + +/* + * A type for measuring processor time (in clock ticks). + */ +#ifndef _CLOCK_T_ +typedef long clock_t; +#define _CLOCK_T_ #endif /* * A structure for storing all kinds of useful information about the * current (or another) time. */ -struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - char *tm_zone; - int tm_gmtoff; +struct tm +{ + int tm_sec; /* Seconds: 0-59 (K&R says 0-61?) */ + int tm_min; /* Minutes: 0-59 */ + int tm_hour; /* Hours since midnight: 0-23 */ + int tm_mday; /* Day of the month: 1-31 */ + int tm_mon; /* Months *since* january: 0-11 */ + int tm_year; /* Years since 1900 */ + int tm_wday; /* Days since Sunday (0-6) */ + int tm_yday; /* Days since Jan. 1: 0-365 */ + int tm_isdst; /* +1 Daylight Savings Time, 0 No DST, + * -1 don't know */ + char *tm_zone; + int tm_gmtoff; }; +#ifdef __cplusplus +extern "C" { +#endif - -clock_t clock (void); -time_t time (time_t* tp); -double difftime (time_t t2, time_t t1); -time_t mktime (struct tm* tmsp); +clock_t clock(void); +time_t time(time_t*); +double difftime(time_t, time_t); +time_t mktime(struct tm*); /* * These functions write to and return pointers to static buffers that may @@ -100,27 +102,24 @@ time_t mktime (struct tm* tmsp); * Fault and crap out your program. Guess how I know. Hint: stat called on * a directory gives 'invalid' times in st_atime etc... */ -char* asctime (const struct tm* tmsp); -wchar_t* _wasctime(const struct tm *timeptr); -char* ctime (const time_t* tp); -wchar_t* _wctime(const time_t * const timep); -struct tm* gmtime (const time_t* tm); -struct tm* localtime (const time_t* tm); - -char* _strdate(const char *datestr); -wchar_t* _wstrdate(const wchar_t *datestr); - -size_t strftime (char* caBuffer, size_t sizeMax, const char* szFormat, - const struct tm* tpPrint); - -size_t wcsftime (wchar_t* wcaBuffer, size_t sizeMax, - const wchar_t* wsFormat, const struct tm* tpPrint); - -char* _strtime(char* buf); -wchar_t* _wstrtime(wchar_t* buf); - -#ifdef __cplusplus +char* asctime(const struct tm*); +char* ctime(const time_t*); +struct tm* gmtime(const time_t*); +struct tm* localtime(const time_t*); + +size_t strftime(char*, size_t, const char*, const struct tm*); +size_t wcsftime(wchar_t*, size_t, const wchar_t*, const struct tm*); + +wchar_t* _wasctime(const struct tm *timeptr); +wchar_t* _wctime(const time_t * const timep); +char* _strdate(const char *datestr); +wchar_t* _wstrdate(const wchar_t *datestr); +char* _strtime(char* buf); +wchar_t* _wstrtime(wchar_t* buf); + +#ifdef __cplusplus } #endif -#endif +#endif /* Not _TIME_H_ */ + diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index 6699c37..5ccb764 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -15,7 +15,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -24,9 +24,16 @@ * */ +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + + #include #include #include #include #include + +#endif /* not _WCHAR_H_ */ + diff --git a/include/napi/lpc.h b/include/napi/lpc.h index a99c919..f136bf5 100644 --- a/include/napi/lpc.h +++ b/include/napi/lpc.h @@ -1,10 +1,16 @@ #ifndef __INCLUDE_NAPI_LPC_H #define __INCLUDE_NAPI_LPC_H +#ifdef __USE_W32API +#include +#endif /* !__USE_W32API */ + #include #define MAX_MESSAGE_DATA (0x130) +#ifndef __USE_W32API + typedef enum { UNUSED_MSG_TYPE = 0x0, /* ReactOS */ @@ -52,6 +58,8 @@ typedef struct _LPC_MESSAGE_HEADER ULONG SharedSectionSize; } LPC_MESSAGE, *PLPC_MESSAGE; +#endif /* !__USE_W32API */ + typedef struct _LPC_TERMINATION_MESSAGE { LPC_MESSAGE Header; diff --git a/include/napi/npipe.h b/include/napi/npipe.h index b89972f..58c1b1a 100644 --- a/include/napi/npipe.h +++ b/include/napi/npipe.h @@ -135,9 +135,11 @@ typedef struct _NPFS_WAIT_PIPE LARGE_INTEGER Timeout; } NPFS_WAIT_PIPE, *PNPFS_WAIT_PIPE; +#ifdef __GNUC__ // robd typedef struct _NPFS_LISTEN { } NPFS_LISTEN, *PNPFS_LISTEN; +#endif typedef struct _NPFS_SET_STATE { diff --git a/include/napi/shared_data.h b/include/napi/shared_data.h index 2387273..a44b154 100644 --- a/include/napi/shared_data.h +++ b/include/napi/shared_data.h @@ -15,9 +15,9 @@ typedef struct _KUSER_SHARED_DATA { volatile ULONG TickCountLow; ULONG TickCountMultiplier; - volatile KSYSTEM_TIME InterruptTime; - volatile KSYSTEM_TIME SystemTime; - volatile KSYSTEM_TIME TimeZoneBias; + volatile ULARGE_INTEGER InterruptTime; + volatile ULARGE_INTEGER SystemTime; + volatile ULARGE_INTEGER TimeZoneBias; USHORT ImageNumberLow; USHORT ImageNumberHigh; WCHAR NtSystemRoot[260]; @@ -61,7 +61,9 @@ typedef struct _KUSER_SHARED_DATA #define KI_USER_SHARED_DATA (0xFFDF0000) #define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA) #else +#ifndef __USE_W32API #define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA) +#endif /* !__USE_W32API */ #endif diff --git a/include/napi/teb.h b/include/napi/teb.h index 05962c2..b570639 100644 --- a/include/napi/teb.h +++ b/include/napi/teb.h @@ -1,233 +1,246 @@ -/* TEB/PEB parameters */ -#ifndef __INCLUDE_INTERNAL_TEB -#define __INCLUDE_INTERNAL_TEB - -#include - -typedef struct _CLIENT_ID -{ - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID, *PCLIENT_ID; - -typedef struct _CURDIR -{ - UNICODE_STRING DosPath; - PVOID Handle; -} CURDIR, *PCURDIR; - -typedef struct RTL_DRIVE_LETTER_CURDIR -{ - USHORT Flags; - USHORT Length; - ULONG TimeStamp; - UNICODE_STRING DosPath; -} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; - -typedef struct _PEB_FREE_BLOCK -{ - struct _PEB_FREE_BLOCK* Next; - ULONG Size; -} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; - -/* RTL_USER_PROCESS_PARAMETERS.Flags */ -#define PPF_NORMALIZED (1) - -typedef struct _RTL_USER_PROCESS_PARAMETERS { - ULONG AllocationSize; - ULONG Size; - ULONG Flags; - ULONG DebugFlags; - HANDLE hConsole; - ULONG ProcessGroup; - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; - UNICODE_STRING CurrentDirectoryName; - HANDLE CurrentDirectoryHandle; - UNICODE_STRING DllPath; - UNICODE_STRING ImagePathName; - UNICODE_STRING CommandLine; - PWSTR Environment; - ULONG dwX; - ULONG dwY; - ULONG dwXSize; - ULONG dwYSize; - ULONG dwXCountChars; - ULONG dwYCountChars; - ULONG dwFillAttribute; - ULONG dwFlags; - ULONG wShowWindow; - UNICODE_STRING WindowTitle; - UNICODE_STRING DesktopInfo; - UNICODE_STRING ShellInfo; - UNICODE_STRING RuntimeInfo; -} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; - -#define PEB_BASE (0x7FFDF000) - -typedef struct _PEB_LDR_DATA -{ - ULONG Length; - BOOLEAN Initialized; - PVOID SsHandle; - LIST_ENTRY InLoadOrderModuleList; - LIST_ENTRY InMemoryOrderModuleList; - LIST_ENTRY InInitializationOrderModuleList; -} PEB_LDR_DATA, *PPEB_LDR_DATA; - -typedef VOID STDCALL (*PPEBLOCKROUTINE)(PVOID); - -typedef struct _PEB -{ - UCHAR InheritedAddressSpace; // 00h - UCHAR ReadImageFileExecOptions; // 01h - UCHAR BeingDebugged; // 02h - UCHAR Spare; // 03h - PVOID Mutant; // 04h - PVOID ImageBaseAddress; // 08h - PPEB_LDR_DATA Ldr; // 0Ch - PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // 10h - PVOID SubSystemData; // 14h - PVOID ProcessHeap; // 18h - PVOID FastPebLock; // 1Ch - PPEBLOCKROUTINE FastPebLockRoutine; // 20h - PPEBLOCKROUTINE FastPebUnlockRoutine; // 24h - ULONG EnvironmentUpdateCount; // 28h - PVOID* KernelCallbackTable; // 2Ch - PVOID EventLogSection; // 30h - PVOID EventLog; // 34h - PPEB_FREE_BLOCK FreeList; // 38h - ULONG TlsExpansionCounter; // 3Ch - PVOID TlsBitmap; // 40h - ULONG TlsBitmapBits[0x2]; // 44h - PVOID ReadOnlySharedMemoryBase; // 4Ch - PVOID ReadOnlySharedMemoryHeap; // 50h - PVOID* ReadOnlyStaticServerData; // 54h - PVOID AnsiCodePageData; // 58h - PVOID OemCodePageData; // 5Ch - PVOID UnicodeCaseTableData; // 60h - ULONG NumberOfProcessors; // 64h - ULONG NtGlobalFlag; // 68h - UCHAR Spare2[0x4]; // 6Ch - LARGE_INTEGER CriticalSectionTimeout; // 70h - ULONG HeapSegmentReserve; // 78h - ULONG HeapSegmentCommit; // 7Ch - ULONG HeapDeCommitTotalFreeThreshold; // 80h - ULONG HeapDeCommitFreeBlockThreshold; // 84h - ULONG NumberOfHeaps; // 88h - ULONG MaximumNumberOfHeaps; // 8Ch - PVOID** ProcessHeaps; // 90h - PVOID GdiSharedHandleTable; // 94h - PVOID ProcessStarterHelper; // 98h - PVOID GdiDCAttributeList; // 9Ch - PVOID LoaderLock; // A0h - ULONG OSMajorVersion; // A4h - ULONG OSMinorVersion; // A8h - ULONG OSBuildNumber; // ACh - ULONG OSPlatformId; // B0h - ULONG ImageSubSystem; // B4h - ULONG ImageSubSystemMajorVersion; // B8h - ULONG ImageSubSystemMinorVersion; // C0h - ULONG GdiHandleBuffer[0x22]; // C4h -} PEB, *PPEB; - - -typedef struct _NT_TIB { - struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList; // 00h - PVOID StackBase; // 04h - PVOID StackLimit; // 08h - PVOID SubSystemTib; // 0Ch - union { - PVOID FiberData; // 10h - ULONG Version; // 10h - } Fib; - PVOID ArbitraryUserPointer; // 14h - struct _NT_TIB *Self; // 18h -} NT_TIB, *PNT_TIB; - -typedef struct _GDI_TEB_BATCH -{ - ULONG Offset; - ULONG HDC; - ULONG Buffer[0x136]; -} GDI_TEB_BATCH, *PGDI_TEB_BATCH; - -typedef struct _TEB -{ - NT_TIB Tib; // 00h - PVOID EnvironmentPointer; // 1Ch - CLIENT_ID Cid; // 20h - PVOID ActiveRpcInfo; // 28h - PVOID ThreadLocalStoragePointer; // 2Ch - PPEB Peb; // 30h - ULONG LastErrorValue; // 34h - ULONG CountOfOwnedCriticalSections; // 38h - PVOID CsrClientThread; // 3Ch - struct _W32THREAD* Win32ThreadInfo; // 40h - ULONG Win32ClientInfo[0x1F]; // 44h - PVOID WOW32Reserved; // C0h - ULONG CurrentLocale; // C4h - ULONG FpSoftwareStatusRegister; // C8h - PVOID SystemReserved1[0x36]; // CCh - PVOID Spare1; // 1A4h - LONG ExceptionCode; // 1A8h - ULONG SpareBytes1[0x28]; // 1ACh - PVOID SystemReserved2[0xA]; // 1D4h -// GDI_TEB_BATCH GdiTebBatch; // 1FCh - ULONG gdiRgn; // 6DCh - ULONG gdiPen; // 6E0h - ULONG gdiBrush; // 6E4h - CLIENT_ID RealClientId; // 6E8h - PVOID GdiCachedProcessHandle; // 6F0h - ULONG GdiClientPID; // 6F4h - ULONG GdiClientTID; // 6F8h - PVOID GdiThreadLocaleInfo; // 6FCh - PVOID UserReserved[5]; // 700h - PVOID glDispatchTable[0x118]; // 714h - ULONG glReserved1[0x1A]; // B74h - PVOID glReserved2; // BDCh - PVOID glSectionInfo; // BE0h - PVOID glSection; // BE4h - PVOID glTable; // BE8h - PVOID glCurrentRC; // BECh - PVOID glContext; // BF0h - NTSTATUS LastStatusValue; // BF4h - UNICODE_STRING StaticUnicodeString; // BF8h - WCHAR StaticUnicodeBuffer[0x105]; // C00h - PVOID DeallocationStack; // E0Ch - PVOID TlsSlots[0x40]; // E10h - LIST_ENTRY TlsLinks; // F10h - PVOID Vdm; // F18h - PVOID ReservedForNtRpc; // F1Ch - PVOID DbgSsReserved[0x2]; // F20h - ULONG HardErrorDisabled; // F28h - PVOID Instrumentation[0x10]; // F2Ch - PVOID WinSockData; // F6Ch - ULONG GdiBatchCount; // F70h - ULONG Spare2; // F74h - ULONG Spare3; // F78h - ULONG Spare4; // F7Ch - PVOID ReservedForOle; // F80h - ULONG WaitingOnLoaderLock; // F84h - PVOID WineDebugInfo; // Needed for WINE DLL's -} TEB, *PTEB; - - -#define NtCurrentPeb() (NtCurrentTeb()->Peb) - -static inline PTEB NtCurrentTeb(VOID) -{ - int x; - - __asm__ __volatile__("movl %%fs:0x18, %0\n\t" - : "=r" (x) /* can't have two memory operands */ - : /* no inputs */ - ); - - return((PTEB)x); -} - - - -#endif /* __INCLUDE_INTERNAL_TEB */ +/* TEB/PEB parameters */ +#ifndef __INCLUDE_INTERNAL_TEB +#define __INCLUDE_INTERNAL_TEB + +#include + +#ifdef __USE_W32API +#include +#endif /* !__USE_W32API */ + +#ifndef __USE_W32API + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + ULONG AllocationSize; + ULONG Size; + ULONG Flags; + ULONG DebugFlags; + HANDLE hConsole; + ULONG ProcessGroup; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + UNICODE_STRING CurrentDirectoryName; + HANDLE CurrentDirectoryHandle; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + PWSTR Environment; + ULONG dwX; + ULONG dwY; + ULONG dwXSize; + ULONG dwYSize; + ULONG dwXCountChars; + ULONG dwYCountChars; + ULONG dwFillAttribute; + ULONG dwFlags; + ULONG wShowWindow; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeInfo; +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +typedef struct _NT_TIB { + struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList; // 00h + PVOID StackBase; // 04h + PVOID StackLimit; // 08h + PVOID SubSystemTib; // 0Ch + union { + PVOID FiberData; // 10h + ULONG Version; // 10h + } Fib; + PVOID ArbitraryUserPointer; // 14h + struct _NT_TIB *Self; // 18h +} NT_TIB, *PNT_TIB; + +#endif /* !__USE_W32API */ + +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; + PVOID Handle; +} CURDIR, *PCURDIR; + +typedef struct RTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + UNICODE_STRING DosPath; +} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; + +typedef struct _PEB_FREE_BLOCK +{ + struct _PEB_FREE_BLOCK* Next; + ULONG Size; +} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; + +/* RTL_USER_PROCESS_PARAMETERS.Flags */ +#define PPF_NORMALIZED (1) + +#define PEB_BASE (0x7FFDF000) + +typedef struct _PEB_LDR_DATA +{ + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; +} PEB_LDR_DATA, *PPEB_LDR_DATA; + +typedef VOID STDCALL_FUNC (*PPEBLOCKROUTINE)(PVOID); + +typedef struct _PEB +{ + UCHAR InheritedAddressSpace; // 00h + UCHAR ReadImageFileExecOptions; // 01h + UCHAR BeingDebugged; // 02h + UCHAR Spare; // 03h + PVOID Mutant; // 04h + PVOID ImageBaseAddress; // 08h + PPEB_LDR_DATA Ldr; // 0Ch + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // 10h + PVOID SubSystemData; // 14h + PVOID ProcessHeap; // 18h + PVOID FastPebLock; // 1Ch + PPEBLOCKROUTINE FastPebLockRoutine; // 20h + PPEBLOCKROUTINE FastPebUnlockRoutine; // 24h + ULONG EnvironmentUpdateCount; // 28h + PVOID* KernelCallbackTable; // 2Ch + PVOID EventLogSection; // 30h + PVOID EventLog; // 34h + PPEB_FREE_BLOCK FreeList; // 38h + ULONG TlsExpansionCounter; // 3Ch + PVOID TlsBitmap; // 40h + ULONG TlsBitmapBits[0x2]; // 44h + PVOID ReadOnlySharedMemoryBase; // 4Ch + PVOID ReadOnlySharedMemoryHeap; // 50h + PVOID* ReadOnlyStaticServerData; // 54h + PVOID AnsiCodePageData; // 58h + PVOID OemCodePageData; // 5Ch + PVOID UnicodeCaseTableData; // 60h + ULONG NumberOfProcessors; // 64h + ULONG NtGlobalFlag; // 68h + UCHAR Spare2[0x4]; // 6Ch + LARGE_INTEGER CriticalSectionTimeout; // 70h + ULONG HeapSegmentReserve; // 78h + ULONG HeapSegmentCommit; // 7Ch + ULONG HeapDeCommitTotalFreeThreshold; // 80h + ULONG HeapDeCommitFreeBlockThreshold; // 84h + ULONG NumberOfHeaps; // 88h + ULONG MaximumNumberOfHeaps; // 8Ch + PVOID** ProcessHeaps; // 90h + PVOID GdiSharedHandleTable; // 94h + PVOID ProcessStarterHelper; // 98h + PVOID GdiDCAttributeList; // 9Ch + PVOID LoaderLock; // A0h + ULONG OSMajorVersion; // A4h + ULONG OSMinorVersion; // A8h + USHORT OSBuildNumber; // ACh + UCHAR SPMajorVersion; // AEh + UCHAR SPMinorVersion; // AFh + ULONG OSPlatformId; // B0h + ULONG ImageSubSystem; // B4h + ULONG ImageSubSystemMajorVersion; // B8h + ULONG ImageSubSystemMinorVersion; // C0h + ULONG GdiHandleBuffer[0x22]; // C4h +} PEB; + +#ifndef __USE_W32API + +typedef PEB *PPEB; + +#endif /* !__USE_W32API */ + +typedef struct _GDI_TEB_BATCH +{ + ULONG Offset; + ULONG HDC; + ULONG Buffer[0x136]; +} GDI_TEB_BATCH, *PGDI_TEB_BATCH; + +typedef struct _TEB +{ + NT_TIB Tib; // 00h + PVOID EnvironmentPointer; // 1Ch + CLIENT_ID Cid; // 20h + PVOID ActiveRpcInfo; // 28h + PVOID ThreadLocalStoragePointer; // 2Ch + PPEB Peb; // 30h + ULONG LastErrorValue; // 34h + ULONG CountOfOwnedCriticalSections; // 38h + PVOID CsrClientThread; // 3Ch + struct _W32THREAD* Win32ThreadInfo; // 40h + ULONG Win32ClientInfo[0x1F]; // 44h + PVOID WOW32Reserved; // C0h + ULONG CurrentLocale; // C4h + ULONG FpSoftwareStatusRegister; // C8h + PVOID SystemReserved1[0x36]; // CCh + PVOID Spare1; // 1A4h + LONG ExceptionCode; // 1A8h + ULONG SpareBytes1[0x28]; // 1ACh + PVOID SystemReserved2[0xA]; // 1D4h +// GDI_TEB_BATCH GdiTebBatch; // 1FCh + ULONG gdiRgn; // 6DCh + ULONG gdiPen; // 6E0h + ULONG gdiBrush; // 6E4h + CLIENT_ID RealClientId; // 6E8h + PVOID GdiCachedProcessHandle; // 6F0h + ULONG GdiClientPID; // 6F4h + ULONG GdiClientTID; // 6F8h + PVOID GdiThreadLocaleInfo; // 6FCh + PVOID UserReserved[5]; // 700h + PVOID glDispatchTable[0x118]; // 714h + ULONG glReserved1[0x1A]; // B74h + PVOID glReserved2; // BDCh + PVOID glSectionInfo; // BE0h + PVOID glSection; // BE4h + PVOID glTable; // BE8h + PVOID glCurrentRC; // BECh + PVOID glContext; // BF0h + NTSTATUS LastStatusValue; // BF4h + UNICODE_STRING StaticUnicodeString; // BF8h + WCHAR StaticUnicodeBuffer[0x105]; // C00h + PVOID DeallocationStack; // E0Ch + PVOID TlsSlots[0x40]; // E10h + LIST_ENTRY TlsLinks; // F10h + PVOID Vdm; // F18h + PVOID ReservedForNtRpc; // F1Ch + PVOID DbgSsReserved[0x2]; // F20h + ULONG HardErrorDisabled; // F28h + PVOID Instrumentation[0x10]; // F2Ch + PVOID WinSockData; // F6Ch + ULONG GdiBatchCount; // F70h + ULONG Spare2; // F74h + ULONG Spare3; // F78h + ULONG Spare4; // F7Ch + PVOID ReservedForOle; // F80h + ULONG WaitingOnLoaderLock; // F84h + PVOID WineDebugInfo; // Needed for WINE DLL's +} TEB, *PTEB; + + +#define NtCurrentPeb() (NtCurrentTeb()->Peb) + +static inline PTEB NtCurrentTeb(VOID) +{ + int x; + + __asm__ __volatile__("movl %%fs:0x18, %0\n\t" + : "=r" (x) /* can't have two memory operands */ + : /* no inputs */ + ); + + return((PTEB)x); +} + +#endif /* __INCLUDE_INTERNAL_TEB */ diff --git a/include/napi/types.h b/include/napi/types.h index 694ae40..01560e1 100644 --- a/include/napi/types.h +++ b/include/napi/types.h @@ -3,16 +3,6 @@ // these should be moved to a file like ntdef.h -typedef const int CINT; - -typedef LONG NTSTATUS, *PNTSTATUS; - -typedef ULONG DEVICE_TYPE; - - - - - enum { DIRECTORY_QUERY, @@ -25,19 +15,6 @@ enum /* * General type for status information */ -//typedef LONG NTSTATUS; - -typedef struct _UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -typedef enum _SECTION_INHERIT { - ViewShare = 1, - ViewUnmap = 2 -} SECTION_INHERIT; typedef enum _NT_PRODUCT_TYPE { @@ -46,6 +23,14 @@ typedef enum _NT_PRODUCT_TYPE NtProductServer } NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE; +typedef ULARGE_INTEGER TIME, *PTIME; + +#ifndef __USE_W32API + +typedef const int CINT; +typedef LONG NTSTATUS, *PNTSTATUS; +typedef ULONG DEVICE_TYPE; + /* File information for IRP_MJ_QUERY_INFORMATION (and SET) */ typedef enum _FILE_INFORMATION_CLASS { @@ -92,17 +77,11 @@ typedef enum _FILE_INFORMATION_CLASS FileMaximumInformation, } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; -typedef ULONG WAIT_TYPE; -typedef USHORT CSHORT; - - -#if 0 -typedef struct _TIME { - DWORD LowPart; - LONG HighPart; -} TIME, *PTIME; -#endif +typedef enum _SECTION_INHERIT { + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT; -typedef ULARGE_INTEGER TIME, *PTIME; +#endif /* !__USE_W32API */ #endif /* __INCLUDE_NAPI_TYPES_H */ diff --git a/include/net/ndis.h b/include/net/ndis.h index a018457..168ff97 100644 --- a/include/net/ndis.h +++ b/include/net/ndis.h @@ -3535,9 +3535,6 @@ typedef NDIS_STATUS (*WM_TRANSFER_DATA_HANDLER)( #define DECLARE_UNKNOWN_STRUCT(BaseName) \ typedef struct _##BaseName BaseName, *P##BaseName; -#define DECLARE_UNKNOWN_PROTOTYPE(Name) \ - typedef VOID (*##Name)(VOID); - /* ARCnet */ @@ -3572,9 +3569,9 @@ ArcFilterDprIndicateReceiveComplete( DECLARE_UNKNOWN_STRUCT(ETH_BINDING_INFO); -DECLARE_UNKNOWN_PROTOTYPE(ETH_ADDRESS_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(ETH_FILTER_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(ETH_DEFERRED_CLOSE) +typedef VOID (*ETH_ADDRESS_CHANGE)(VOID); +typedef VOID (*ETH_FILTER_CHANGE)(VOID); +typedef VOID (*ETH_DEFERRED_CLOSE)(VOID); typedef struct _ETH_FILTER { @@ -3710,9 +3707,9 @@ EthShouldAddressLoopBack( DECLARE_UNKNOWN_STRUCT(FDDI_FILTER) -DECLARE_UNKNOWN_PROTOTYPE(FDDI_ADDRESS_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(FDDI_FILTER_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(FDDI_DEFERRED_CLOSE) +typedef VOID (*FDDI_ADDRESS_CHANGE)(VOID); +typedef VOID (*FDDI_FILTER_CHANGE)(VOID); +typedef VOID (*FDDI_DEFERRED_CLOSE)(VOID); NDIS_STATUS @@ -3860,10 +3857,10 @@ FddiShouldAddressLoopBack( DECLARE_UNKNOWN_STRUCT(TR_FILTER) -DECLARE_UNKNOWN_PROTOTYPE(TR_ADDRESS_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(TR_GROUP_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(TR_FILTER_CHANGE) -DECLARE_UNKNOWN_PROTOTYPE(TR_DEFERRED_CLOSE) +typedef VOID (*TR_ADDRESS_CHANGE)(VOID); +typedef VOID (*TR_GROUP_CHANGE)(VOID); +typedef VOID (*TR_FILTER_CHANGE)(VOID); +typedef VOID (*TR_DEFERRED_CLOSE)(VOID); NDIS_STATUS diff --git a/include/net/ntddndis.h b/include/net/ntddndis.h index e3d6a82..5916792 100644 --- a/include/net/ntddndis.h +++ b/include/net/ntddndis.h @@ -7,6 +7,8 @@ #ifndef __NTDDNDIS_H #define __NIDDNDIS_H +#include + typedef enum _NDIS_DEVICE_POWER_STATE { NdisDeviceStateUnspecified = 0, diff --git a/include/ntdll/ldr.h b/include/ntdll/ldr.h index 85c0752..1112626 100644 --- a/include/ntdll/ldr.h +++ b/include/ntdll/ldr.h @@ -3,6 +3,7 @@ #include #include +#include typedef NTSTATUS STDCALL (*PEPFUNC)(PPEB); diff --git a/include/ntdll/rtl.h b/include/ntdll/rtl.h index 97c0da2..b42877f 100644 --- a/include/ntdll/rtl.h +++ b/include/ntdll/rtl.h @@ -5,13 +5,18 @@ #ifndef __INCLUDE_NTDLL_RTL_H #define __INCLUDE_NTDLL_RTL_H +#include #include #include +#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ + +#ifndef __USE_W32API + typedef struct _DEBUG_BUFFER { HANDLE SectionHandle; @@ -52,6 +57,9 @@ typedef struct _CRITICAL_SECTION { DWORD Reserved; } CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION; +#endif /* !__USE_W32API */ + + typedef struct _RTL_PROCESS_INFO { ULONG Size; @@ -374,7 +382,7 @@ RtlDeNormalizeProcessParams ( IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters ); -VOID +NTSTATUS STDCALL RtlDestroyProcessParameters ( IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters @@ -569,6 +577,10 @@ RtlpNtSetValueKey ( ); #ifndef __NTDRIVER__ + +#ifndef __INTERLOCKED_DECLARED +#define __INTERLOCKED_DECLARED + LONG STDCALL InterlockedIncrement ( @@ -603,6 +615,7 @@ InterlockedExchangeAdd ( LONG Increment ); +#endif /* __INTERLOCKED_DECLARED */ #endif /* __NTDRIVER__ */ diff --git a/include/ntos.h b/include/ntos.h index 25a6af8..145ab5d 100644 --- a/include/ntos.h +++ b/include/ntos.h @@ -6,6 +6,7 @@ // include windows.h before ntddk.h to get user mode prototype for InterlockedXxx functions #include #include +#include #include "ntos/types.h" #include "ntos/cdrom.h" #include "ntos/console.h" @@ -33,6 +34,10 @@ #include "napi/npipe.h" #include "napi/shared_data.h" #include "napi/win32.h" +#include "ntos/rtltypes.h" +#include "ntos/rtl.h" +#include "ntos/zwtypes.h" +#include "ntos/zw.h" #include "ntdll/csr.h" #include "ntdll/dbg.h" #include "ntdll/ldr.h" @@ -42,6 +47,7 @@ #include "kernel32/error.h" #else // Assume kernel mode #include +//#include "ntos/types.h" // robd #include #include "ntos/types.h" #include "ntos/cdrom.h" @@ -70,6 +76,10 @@ #include "napi/npipe.h" #include "napi/shared_data.h" #include "napi/win32.h" +#include "ntos/rtltypes.h" +#include "ntos/rtl.h" +#include "ntos/zwtypes.h" +#include "ntos/zw.h" #endif #endif /* ndef _NTOS_H */ diff --git a/include/ntos/cdrom.h b/include/ntos/cdrom.h index c1a5c2a..23225e1 100644 --- a/include/ntos/cdrom.h +++ b/include/ntos/cdrom.h @@ -5,7 +5,7 @@ * FILE: include/ntos/cdrom.h * PURPOSE: CD-ROM related definitions used by all the parts of the system * PROGRAMMER: Eric Kohl - * UPDATE HISTORY: + * UPDATE HISTORY: * 10/04/2002: Created */ @@ -13,13 +13,14 @@ #define __INCLUDE_NTOS_CDROM_H #define IOCTL_CDROM_READ_TOC CTL_CODE(FILE_DEVICE_CD_ROM, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) -#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(FILE_DEVICE_CD_ROM, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(FILE_DEVICE_CD_ROM, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS) #define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_CD_ROM, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) #define MAXIMUM_NUMBER_TRACKS 100 -#define MAXIMUM_CDROM_SIZE 804 +#define MAXIMUM_CDROM_SIZE 804 -typedef struct _TRACK_DATA { +typedef struct _TRACK_DATA +{ UCHAR Reserved; UCHAR Control : 4; UCHAR Adr : 4; @@ -28,7 +29,8 @@ typedef struct _TRACK_DATA { UCHAR Address[4]; } TRACK_DATA, *PTRACK_DATA; -typedef struct _CDROM_TOC { +typedef struct _CDROM_TOC +{ UCHAR Length[2]; UCHAR FirstTrack; UCHAR LastTrack; @@ -37,8 +39,6 @@ typedef struct _CDROM_TOC { #define CDROM_TOC_SIZE sizeof(CDROM_TOC) - - #endif /* __INCLUDE_NTOS_CDROM_H */ /* EOF */ diff --git a/include/ntos/console.h b/include/ntos/console.h index 294d003..fde2458 100644 --- a/include/ntos/console.h +++ b/include/ntos/console.h @@ -14,16 +14,31 @@ #define __INCLUDE_CONSOLE_H /* GetConsoleMode */ -#define ENABLE_LINE_INPUT (0x02) -#define ENABLE_ECHO_INPUT (0x04) -#define ENABLE_PROCESSED_INPUT (0x01) -#define ENABLE_WINDOW_INPUT (0x08) -#define ENABLE_MOUSE_INPUT (0x0f) #define CONSOLE_INPUT_MODE_VALID (0x0f) -#define ENABLE_PROCESSED_OUTPUT (0x01) -#define ENABLE_WRAP_AT_EOL_OUTPUT (0x02) #define CONSOLE_OUTPUT_MODE_VALID (0x03) +typedef struct _CONSOLE_FONT_INFO { + DWORD nFont; + COORD dwFontSize; +} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO; + +typedef struct _CONSOLE_SELECTION_INFO { + DWORD dwFlags; + COORD dwSelectionAnchor; + SMALL_RECT srSelection; +} CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO; + +#ifndef __USE_W32API + +/* GetConsoleMode */ +#define ENABLE_LINE_INPUT (0x02) +#define ENABLE_ECHO_INPUT (0x04) +#define ENABLE_PROCESSED_INPUT (0x01) +#define ENABLE_WINDOW_INPUT (0x08) +#define ENABLE_MOUSE_INPUT (0x0f) +#define ENABLE_PROCESSED_OUTPUT (0x01) +#define ENABLE_WRAP_AT_EOL_OUTPUT (0x02) + typedef struct _CONSOLE_SCREEN_BUFFER_INFO { COORD dwSize; COORD dwCursorPosition; @@ -37,18 +52,6 @@ typedef struct _CONSOLE_CURSOR_INFO { BOOL bVisible; } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; -typedef struct _CONSOLE_FONT_INFO { - DWORD nFont; - COORD dwFontSize; -} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO; - -typedef struct _CONSOLE_SELECTION_INFO { - DWORD dwFlags; - COORD dwSelectionAnchor; - SMALL_RECT srSelection; -} CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO; +#endif /* !__USE_W32API */ #endif /* __INCLUDE_CONSOLE_H */ - - - diff --git a/include/ntos/disk.h b/include/ntos/disk.h index 4e16cbd..b9254de 100644 --- a/include/ntos/disk.h +++ b/include/ntos/disk.h @@ -134,13 +134,6 @@ typedef struct _PARTITION_INFORMATION BOOLEAN RewritePartition; } PARTITION_INFORMATION, *PPARTITION_INFORMATION; -typedef struct _DRIVE_LAYOUT_INFORMATION -{ - DWORD PartitionCount; - DWORD Signature; - PARTITION_INFORMATION PartitionEntry[1]; -} DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION; - typedef struct _SET_PARTITION_INFORMATION { ULONG PartitionType; @@ -155,6 +148,17 @@ typedef struct _DISK_GEOMETRY DWORD BytesPerSector; } DISK_GEOMETRY, *PDISK_GEOMETRY; +#ifndef __USE_W32API + +typedef struct _DRIVE_LAYOUT_INFORMATION +{ + DWORD PartitionCount; + DWORD Signature; + PARTITION_INFORMATION PartitionEntry[1]; +} DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION; + +#endif /* !__USE_W32API */ + #endif /* __INCLUDE_DISK_H */ /* EOF */ diff --git a/include/ntos/except.h b/include/ntos/except.h index c34b62d..d464c56 100644 --- a/include/ntos/except.h +++ b/include/ntos/except.h @@ -25,12 +25,21 @@ struct _EXCEPTION_REGISTRATION; * The type of function that is expected as an exception handler to be * installed with _try1. */ -typedef EXCEPTION_DISPOSITION CDECL (*PEXCEPTION_HANDLER)( +#ifdef __GNUC__ +typedef EXCEPTION_DISPOSITION (CDECL *PEXCEPTION_HANDLER)( struct _EXCEPTION_RECORD* ExceptionRecord, struct _EXCEPTION_REGISTRATION* ExceptionRegistration, PCONTEXT Context, PVOID DispatcherContext); +#else +typedef EXCEPTION_DISPOSITION (CDECL *PEXCEPTION_HANDLER)( + struct _EXCEPTION_RECORD* ExceptionRecord, + struct _EXCEPTION_REGISTRATION* ExceptionRegistration, + PCONTEXT Context, + PVOID DispatcherContext); +#endif /*__GNUC__*/ +#ifndef __USE_W32API #define EXCEPTION_MAXIMUM_PARAMETERS (15) @@ -43,6 +52,8 @@ typedef struct _EXCEPTION_RECORD { DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD, *PEXCEPTION_RECORD, *LPEXCEPTION_RECORD; +#endif /* !__USE_W32API */ + /* ExceptionFlags */ #ifndef _GNU_H_WINDOWS32_DEFINES #ifdef __NTOSKRNL__ @@ -55,12 +66,6 @@ typedef struct _EXCEPTION_RECORD { #define EXCEPTION_NESTED_CALL 0x10 -typedef struct _EXCEPTION_POINTERS { - PEXCEPTION_RECORD ExceptionRecord; - PCONTEXT ContextRecord; -} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS; - - typedef struct _EXCEPTION_REGISTRATION { struct _EXCEPTION_REGISTRATION* prev; @@ -111,8 +116,13 @@ typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; #endif /* _GNU_H_WINDOWS32_DEFINES */ // Functions of the following prototype return one of the above constants +#ifdef __GNUC__ typedef DWORD CDECL (*PSCOPE_EXCEPTION_FILTER)(VOID); typedef VOID CDECL (*PSCOPE_EXCEPTION_HANDLER)(VOID); +#else +typedef DWORD (CDECL *PSCOPE_EXCEPTION_FILTER)(VOID); +typedef VOID (CDECL *PSCOPE_EXCEPTION_HANDLER)(VOID); +#endif /*__GNUC__*/ typedef struct _SCOPETABLE_ENTRY { @@ -142,4 +152,15 @@ typedef PRTL_EXCEPTION_REGISTRATION_I386 PRTL_EXCEPTION_REGISTRATION; #endif +#ifndef __USE_W32API + +#define EXCEPTION_MAXIMUM_PARAMETERS (15) + +typedef struct _EXCEPTION_POINTERS { + PEXCEPTION_RECORD ExceptionRecord; + PCONTEXT ContextRecord; +} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS; + +#endif /* !__USE_W32API */ + #endif /* __INCLUDE_EXCEPT_H */ diff --git a/include/ntos/file.h b/include/ntos/file.h index eed866d..3899f8b 100644 --- a/include/ntos/file.h +++ b/include/ntos/file.h @@ -13,6 +13,8 @@ #ifndef __INCLUDE_FILE_H #define __INCLUDE_FILE_H +#ifndef __USE_W32API + #define GENERIC_READ (0x80000000L) #define GENERIC_WRITE (0x40000000L) #define FILE_READ_DATA ( 0x0001 ) /* file & pipe */ @@ -40,28 +42,6 @@ #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) /* all */ -#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) - -#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\ - FILE_READ_DATA |\ - FILE_READ_ATTRIBUTES |\ - FILE_READ_EA |\ - SYNCHRONIZE) - - -#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\ - FILE_WRITE_DATA |\ - FILE_WRITE_ATTRIBUTES |\ - FILE_WRITE_EA |\ - FILE_APPEND_DATA |\ - SYNCHRONIZE) - - -#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\ - FILE_READ_ATTRIBUTES |\ - FILE_EXECUTE |\ - SYNCHRONIZE) - #define FILE_SHARE_DELETE (4) #define FILE_SHARE_READ (1) #define FILE_SHARE_WRITE (2) @@ -112,5 +92,28 @@ #define FILE_FILE_COMPRESSION (0x00000010) #define FILE_VOLUME_IS_COMPRESSED (0x00008000) +#endif /* !__USE_W32API */ + +#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) + +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\ + FILE_READ_DATA |\ + FILE_READ_ATTRIBUTES |\ + FILE_READ_EA |\ + SYNCHRONIZE) + + +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\ + FILE_WRITE_DATA |\ + FILE_WRITE_ATTRIBUTES |\ + FILE_WRITE_EA |\ + FILE_APPEND_DATA |\ + SYNCHRONIZE) + + +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\ + FILE_READ_ATTRIBUTES |\ + FILE_EXECUTE |\ + SYNCHRONIZE) #endif /* __INCLUDE_FILE_H */ diff --git a/include/ntos/gditypes.h b/include/ntos/gditypes.h index 180fd40..3932cf9 100644 --- a/include/ntos/gditypes.h +++ b/include/ntos/gditypes.h @@ -11,6 +11,8 @@ #ifndef __INCLUDE_NTOS_GDITYPES_H #define __INCLUDE_NTOS_GDITYPES_H +#ifndef __USE_W32API + #define CCHDEVICENAME (32) #define CCHFORMNAME (32) @@ -86,6 +88,8 @@ typedef struct _devicemodeW DWORD dmICCModel; } DEVMODEW,*LPDEVMODEW,*PDEVMODEW; +#endif /* !__USE_W32API */ + #endif /* __INCLUDE_NTOS_GDITYPES_H */ /* EOF */ diff --git a/include/ntos/heap.h b/include/ntos/heap.h index 391d638..9eb1796 100644 --- a/include/ntos/heap.h +++ b/include/ntos/heap.h @@ -9,16 +9,20 @@ * 27/06/00: Created */ - #ifndef __INCLUDE_HEAP_H #define __INCLUDE_HEAP_H /* HeapAlloc, HeapReAlloc */ +#define HEAP_NO_VALLOC (64) + +#ifndef __USE_W32API + #define HEAP_GENERATE_EXCEPTIONS (4) #define HEAP_NO_SERIALIZE (1) #define HEAP_ZERO_MEMORY (8) #define HEAP_REALLOC_IN_PLACE_ONLY (16) -#define HEAP_GROWABLE (2) -#define HEAP_NO_VALLOC (64) +#define HEAP_GROWABLE (32) + +#endif /* !__USE_W32API */ #endif /* __INCLUDE_HEAP_H */ diff --git a/include/ntos/kdbgsyms.h b/include/ntos/kdbgsyms.h index 79c19ec..79cf902 100644 --- a/include/ntos/kdbgsyms.h +++ b/include/ntos/kdbgsyms.h @@ -2,7 +2,7 @@ #ifndef __KDBGSYMS_H #define __KDBGSYMS_H -#include +#include #define ST_FILENAME 0x00 #define ST_FUNCTION 0x01 @@ -43,4 +43,3 @@ typedef struct _IMAGE_SYMBOL_INFO || (si)->LineNumberSymbols.Symbols) #endif - diff --git a/include/ntos/keyboard.h b/include/ntos/keyboard.h index 2945a73..5dcdfb0 100644 --- a/include/ntos/keyboard.h +++ b/include/ntos/keyboard.h @@ -15,6 +15,46 @@ #include +/* Virtual Key codes */ +#define VK_0 (48) +#define VK_1 (49) +#define VK_2 (50) +#define VK_3 (51) +#define VK_4 (52) +#define VK_5 (53) +#define VK_6 (54) +#define VK_7 (55) +#define VK_8 (56) +#define VK_9 (57) +#define VK_A (65) +#define VK_B (66) +#define VK_C (67) +#define VK_D (68) +#define VK_E (69) +#define VK_F (70) +#define VK_G (71) +#define VK_H (72) +#define VK_I (73) +#define VK_J (74) +#define VK_K (75) +#define VK_L (76) +#define VK_M (77) +#define VK_N (78) +#define VK_O (79) +#define VK_P (80) +#define VK_Q (81) +#define VK_R (82) +#define VK_S (83) +#define VK_T (84) +#define VK_U (85) +#define VK_V (86) +#define VK_W (87) +#define VK_X (88) +#define VK_Y (89) +#define VK_Z (90) + +#ifndef __USE_W32API + /* KEY_EVENT_RECORD structure */ #define CAPSLOCK_ON (128) #define ENHANCED_KEY (256) @@ -43,50 +83,58 @@ #define FOCUS_EVENT (16) -typedef struct _KEY_EVENT_RECORD { - BOOL bKeyDown; - WORD wRepeatCount; - WORD wVirtualKeyCode; - WORD wVirtualScanCode; - union { - WCHAR UnicodeChar; - CHAR AsciiChar; - } uChar; +typedef struct _KEY_EVENT_RECORD +{ + BOOL bKeyDown; + WORD wRepeatCount; + WORD wVirtualKeyCode; + WORD wVirtualScanCode; + union + { + WCHAR UnicodeChar; + CHAR AsciiChar; + } uChar; DWORD dwControlKeyState; } KEY_EVENT_RECORD PACKED; -typedef struct _MOUSE_EVENT_RECORD { - COORD dwMousePosition; - DWORD dwButtonState; - DWORD dwControlKeyState; - DWORD dwEventFlags; -} MOUSE_EVENT_RECORD; +typedef struct _MOUSE_EVENT_RECORD +{ + COORD dwMousePosition; + DWORD dwButtonState; + DWORD dwControlKeyState; + DWORD dwEventFlags; +} MOUSE_EVENT_RECORD; -typedef struct _WINDOW_BUFFER_SIZE_RECORD { - COORD dwSize; -} WINDOW_BUFFER_SIZE_RECORD; +typedef struct _WINDOW_BUFFER_SIZE_RECORD +{ + COORD dwSize; +} WINDOW_BUFFER_SIZE_RECORD; -typedef struct _MENU_EVENT_RECORD { +typedef struct _MENU_EVENT_RECORD +{ UINT dwCommandId; -} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD; - -typedef struct _FOCUS_EVENT_RECORD { - BOOL bSetFocus; -} FOCUS_EVENT_RECORD; - -typedef struct _INPUT_RECORD { - WORD EventType; - union { +} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD; + +typedef struct _FOCUS_EVENT_RECORD +{ + BOOL bSetFocus; +} FOCUS_EVENT_RECORD; + +typedef struct _INPUT_RECORD +{ + WORD EventType; + union + { #ifndef __cplus_plus /* this will be the wrong size in c++ */ - KEY_EVENT_RECORD KeyEvent; + KEY_EVENT_RECORD KeyEvent; #endif - MOUSE_EVENT_RECORD MouseEvent; - WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; - MENU_EVENT_RECORD MenuEvent; - FOCUS_EVENT_RECORD FocusEvent; - } Event; -} INPUT_RECORD, *PINPUT_RECORD; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + } Event; +} INPUT_RECORD, *PINPUT_RECORD; /* Virtual Key codes */ #define VK_LBUTTON (1) @@ -119,42 +167,6 @@ typedef struct _INPUT_RECORD { #define VK_INSERT (45) #define VK_DELETE (46) #define VK_HELP (47) -#define VK_0 (48) -#define VK_1 (49) -#define VK_2 (50) -#define VK_3 (51) -#define VK_4 (52) -#define VK_5 (53) -#define VK_6 (54) -#define VK_7 (55) -#define VK_8 (56) -#define VK_9 (57) -#define VK_A (65) -#define VK_B (66) -#define VK_C (67) -#define VK_D (68) -#define VK_E (69) -#define VK_F (70) -#define VK_G (71) -#define VK_H (72) -#define VK_I (73) -#define VK_J (74) -#define VK_K (75) -#define VK_L (76) -#define VK_M (77) -#define VK_N (78) -#define VK_O (79) -#define VK_P (80) -#define VK_Q (81) -#define VK_R (82) -#define VK_S (83) -#define VK_T (84) -#define VK_U (85) -#define VK_V (86) -#define VK_W (87) -#define VK_X (88) -#define VK_Y (89) -#define VK_Z (90) #define VK_NUMPAD0 (96) #define VK_NUMPAD1 (97) #define VK_NUMPAD2 (98) @@ -206,6 +218,7 @@ typedef struct _INPUT_RECORD { #define VK_RCONTROL (163) #define VK_RMENU (165) +#endif /* !__USE_W32API */ #endif /* __INCLUDE_KEYBOARD_H */ diff --git a/include/ddk/ldrtypes.h b/include/ntos/ldrtypes.h old mode 100644 new mode 100755 similarity index 99% rename from include/ddk/ldrtypes.h rename to include/ntos/ldrtypes.h index 6e1209a..74501a3 --- a/include/ddk/ldrtypes.h +++ b/include/ntos/ldrtypes.h @@ -1,6 +1,7 @@ +/* $Id$ */ + #ifndef __INCLUDE_DDK_LDRTYPES_H #define __INCLUDE_DDK_LDRTYPES_H -/* $Id$ */ typedef struct _LDR_RESOURCE_INFO { diff --git a/include/ntos/minmax.h b/include/ntos/minmax.h index 37d9ff3..1ee3dd5 100644 --- a/include/ntos/minmax.h +++ b/include/ntos/minmax.h @@ -1,7 +1,7 @@ #ifndef max -#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) #endif diff --git a/include/ntos/mm.h b/include/ntos/mm.h index 7ed75b4..706ee37 100644 --- a/include/ntos/mm.h +++ b/include/ntos/mm.h @@ -13,12 +13,8 @@ #ifndef __INCLUDE_MM_H #define __INCLUDE_MM_H -#if 0 -#define SEC_COMMIT (134217728) -#define SEC_IMAGE (16777216) -#define SEC_NOCACHE (268435456) -#define SEC_RESERVE (67108864) -#else +#ifndef __USE_W32API + #define SEC_BASED (0x00200000) #define SEC_NO_CHANGE (0x00400000) #define SEC_IMAGE (0x01000000) @@ -26,7 +22,6 @@ #define SEC_RESERVE (0x04000000) #define SEC_COMMIT (0x08000000) #define SEC_NOCACHE (0x10000000) -#endif #define PAGE_READONLY (2) #define PAGE_READWRITE (4) #define PAGE_WRITECOPY (8) @@ -58,6 +53,10 @@ #define FILE_MAP_READ (4) #define FILE_MAP_WRITE (2) #define FILE_MAP_COPY (1) +#else /* __USE_W32API */ + +#include +#endif /* __USE_W32API */ #endif /* __INCLUDE_MM_H */ diff --git a/include/ntos/ntdef.h b/include/ntos/ntdef.h index c3356c8..2f49140 100644 --- a/include/ntos/ntdef.h +++ b/include/ntos/ntdef.h @@ -11,6 +11,12 @@ #ifndef __INCLUDE_NTDEF_H #define __INCLUDE_NTDEF_H +#define PACKED __attribute__((packed)) + +#define EX_MAXIMUM_WAIT_OBJECTS (64) + +#ifndef __USE_W32API + #define ANYSIZE_ARRAY (1) #define DELETE (0x00010000L) @@ -20,10 +26,8 @@ #define DUPLICATE_CLOSE_SOURCE (1) #define DUPLICATE_SAME_ACCESS (2) -#define PACKED __attribute__((packed)) - #define INVALID_HANDLE_VALUE ((HANDLE)-1) -#define EX_MAXIMUM_WAIT_OBJECTS (64) +#endif /* !__USE_W32API */ #endif /* __INCLUDE_NTDEF_H */ diff --git a/include/ntos/port.h b/include/ntos/port.h index 34eda0c..805dd6c 100644 --- a/include/ntos/port.h +++ b/include/ntos/port.h @@ -13,11 +13,18 @@ #ifndef __INCLUDE_PORT_H #define __INCLUDE_PORT_H +#ifndef __USE_W32API /* Port Object Access */ #define PORT_ALL_ACCESS (0x1) +#else /* __USE_W32API */ + +#include + +#endif /* __USE_W32API */ + #endif /* __INCLUDE_PORT_H */ /* EOF */ diff --git a/include/ntos/ps.h b/include/ntos/ps.h index c9e8171..e216921 100644 --- a/include/ntos/ps.h +++ b/include/ntos/ps.h @@ -13,6 +13,21 @@ #ifndef __INCLUDE_PS_H #define __INCLUDE_PS_H +#define THREAD_READ (0x020048L) +#define THREAD_WRITE (0x020037L) +#define THREAD_EXECUTE (0x120000L) + +#define PROCESS_READ (0x020410L) +#define PROCESS_WRITE (0x020bebL) +#define PROCESS_EXECUTE (0x120000L) + +/* Thread priorities */ +#define THREAD_PRIORITY_BELOW_NORMAL (-1) +#define THREAD_PRIORITY_IDLE (-15) +#define THREAD_PRIORITY_LOWEST (-2) + +#ifndef __USE_W32API + /* Thread access rights */ #define THREAD_TERMINATE (0x0001L) #define THREAD_SUSPEND_RESUME (0x0002L) @@ -25,9 +40,6 @@ #define THREAD_DIRECT_IMPERSONATION (0x0200L) #define THREAD_ALL_ACCESS (0x1f03ffL) -#define THREAD_READ (0x020048L) -#define THREAD_WRITE (0x020037L) -#define THREAD_EXECUTE (0x120000L) /* Process access rights */ #define PROCESS_TERMINATE (0x0001L) @@ -43,16 +55,10 @@ #define PROCESS_QUERY_INFORMATION (0x0400L) #define PROCESS_ALL_ACCESS (0x1f0fffL) -#define PROCESS_READ (0x020410L) -#define PROCESS_WRITE (0x020bebL) -#define PROCESS_EXECUTE (0x120000L) /* Thread priorities */ #define THREAD_PRIORITY_ABOVE_NORMAL (1) -#define THREAD_PRIORITY_BELOW_NORMAL (-1) #define THREAD_PRIORITY_HIGHEST (2) -#define THREAD_PRIORITY_IDLE (-15) -#define THREAD_PRIORITY_LOWEST (-2) #define THREAD_PRIORITY_NORMAL (0) #define THREAD_PRIORITY_TIME_CRITICAL (15) #define THREAD_PRIORITY_ERROR_RETURN (2147483647) @@ -75,4 +81,6 @@ /* ResumeThread / SuspendThread */ #define MAXIMUM_SUSPEND_COUNT (0x7f) +#endif /* !__USE_W32API */ + #endif /* __INCLUDE_PS_H */ diff --git a/include/ntos/registry.h b/include/ntos/registry.h index c714dde..e822343 100644 --- a/include/ntos/registry.h +++ b/include/ntos/registry.h @@ -13,6 +13,8 @@ #ifndef __INCLUDE_NTOS_REGISTRY_H #define __INCLUDE_NTOS_REGISTRY_H +#ifndef __USE_W32API + /* Key access rights */ #define KEY_QUERY_VALUE (1) #define KEY_SET_VALUE (2) @@ -51,5 +53,6 @@ #define REG_FULL_RESOURCE_DESCRIPTOR (9) #define REG_RESOURCE_REQUIREMENTS_LIST (10) +#endif /* !__USE_W32API */ #endif /* __INCLUDE_NTOS_REGISTRY_H */ diff --git a/include/ddk/rtl.h b/include/ntos/rtl.h old mode 100644 new mode 100755 similarity index 95% rename from include/ddk/rtl.h rename to include/ntos/rtl.h index 178977d..a1f0f2e --- a/include/ddk/rtl.h +++ b/include/ntos/rtl.h @@ -15,6 +15,7 @@ #include +#ifndef __USE_W32API /* * PURPOSE: Flags for RtlQueryRegistryValues @@ -27,67 +28,6 @@ #define RTL_QUERY_REGISTRY_DIRECT (0x00000020) #define RTL_QUERY_REGISTRY_DELETE (0x00000040) - -/* - * PURPOSE: Used with RtlCheckRegistryKey, RtlCreateRegistryKey, - * RtlDeleteRegistryKey - */ -#define RTL_REGISTRY_ABSOLUTE 0 -#define RTL_REGISTRY_SERVICES 1 -#define RTL_REGISTRY_CONTROL 2 -#define RTL_REGISTRY_WINDOWS_NT 3 -#define RTL_REGISTRY_DEVICEMAP 4 -#define RTL_REGISTRY_USER 5 -#define RTL_REGISTRY_ENUM 6 // ReactOS specific: Used internally in kernel only -#define RTL_REGISTRY_MAXIMUM 7 - -#define RTL_REGISTRY_HANDLE 0x40000000 -#define RTL_REGISTRY_OPTIONAL 0x80000000 - - -#define SHORT_SIZE (sizeof(USHORT)) -#define SHORT_MASK (SHORT_SIZE-1) -#define LONG_SIZE (sizeof(ULONG)) -#define LONG_MASK (LONG_SIZE-1) -#define LOWBYTE_MASK 0x00FF - -#define FIRSTBYTE(Value) ((Value) & LOWBYTE_MASK) -#define SECONDBYTE(Value) (((Value) >> 8) & LOWBYTE_MASK) -#define THIRDBYTE(Value) (((Value) >> 16) & LOWBYTE_MASK) -#define FOURTHBYTE(Value) (((Value) >> 24) & LOWBYTE_MASK) - -/* FIXME: reverse byte-order on big-endian machines (e.g. MIPS) */ -#define SHORT_LEAST_SIGNIFICANT_BIT 0 -#define SHORT_MOST_SIGNIFICANT_BIT 1 - -#define LONG_LEAST_SIGNIFICANT_BIT 0 -#define LONG_3RD_MOST_SIGNIFICANT_BIT 1 -#define LONG_2RD_MOST_SIGNIFICANT_BIT 2 -#define LONG_MOST_SIGNIFICANT_BIT 3 - - - -#if defined(__NTOSKRNL__) || defined(__NTDLL__) -#define NLS_MB_CODE_PAGE_TAG NlsMbCodePageTag -#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag -#else -#define NLS_MB_CODE_PAGE_TAG (*NlsMbCodePageTag) -#define NLS_MB_OEM_CODE_PAGE_TAG (*NlsMbOemCodePageTag) -#endif /* __NTOSKRNL__ || __NTDLL__ */ - -extern BOOLEAN NLS_MB_CODE_PAGE_TAG; -extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; - - -/* - * NOTE: ReactOS extensions - */ -#define RtlMin(X,Y) (((X) < (Y))? (X) : (Y)) -#define RtlMax(X,Y) (((X) > (Y))? (X) : (Y)) -#define RtlMin3(X,Y,Z) (((X) < (Y)) ? RtlMin(X,Z) : RtlMin(Y,Z)) -#define RtlMax3(X,Y,Z) (((X) > (Y)) ? RtlMax(X,Z) : RtlMax(Y,Z)) - - /* * VOID * InitializeObjectAttributes ( @@ -236,35 +176,23 @@ extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; } \ } */ -static -inline -PSINGLE_LIST_ENTRY - PopEntryList( - PSINGLE_LIST_ENTRY ListHead - ) +static inline PSINGLE_LIST_ENTRY +PopEntryList(PSINGLE_LIST_ENTRY ListHead) { - PSINGLE_LIST_ENTRY ListEntry; + PSINGLE_LIST_ENTRY ListEntry; - ListEntry = ListHead->Next; - if (ListEntry!=NULL) - { - ListHead->Next = ListEntry->Next; - } - return ListEntry; + ListEntry = ListHead->Next; + if (ListEntry!=NULL) + { + ListHead->Next = ListEntry->Next; + } + + return(ListEntry); } -/* -VOID -PushEntryList ( - PSINGLE_LIST_ENTRY ListHead, - PSINGLE_LIST_ENTRY Entry - ); -*/ -/* -#define PushEntryList(ListHead,Entry) \ - (Entry)->Next = (ListHead)->Next; \ - (ListHead)->Next = (Entry) -*/ +#define RtlCopyMemory(Destination,Source,Length) \ + memcpy((Destination),(Source),(Length)) + static inline VOID @@ -277,48 +205,6 @@ PushEntryList ( ListHead->Next = Entry; } - -/* - * An ReactOS extension - */ -static -inline -PSINGLE_LIST_ENTRY - PopEntrySList( - PSLIST_HEADER ListHead - ) -{ - PSINGLE_LIST_ENTRY ListEntry; - - ListEntry = ListHead->s.Next.Next; - if (ListEntry!=NULL) - { - ListHead->s.Next.Next = ListEntry->Next; - ListHead->s.Depth++; - ListHead->s.Sequence++; - } - return ListEntry; -} - - -/* - * An ReactOS extension - */ -static -inline -VOID -PushEntrySList ( - PSLIST_HEADER ListHead, - PSINGLE_LIST_ENTRY Entry - ) -{ - Entry->Next = ListHead->s.Next.Next; - ListHead->s.Next.Next = Entry; - ListHead->s.Depth++; - ListHead->s.Sequence++; -} - - /* *VOID *RemoveEntryList ( @@ -370,92 +256,395 @@ PushEntrySList ( {RemoveEntryList((ListHead)->Flink)} */ /* -PLIST_ENTRY -RemoveHeadList ( - PLIST_ENTRY ListHead +PLIST_ENTRY +RemoveHeadList ( + PLIST_ENTRY ListHead + ); +*/ + +static +inline +PLIST_ENTRY +RemoveHeadList ( + PLIST_ENTRY ListHead + ) +{ + PLIST_ENTRY Old; + PLIST_ENTRY OldFlink; + PLIST_ENTRY OldBlink; + + Old = ListHead->Flink; + + OldFlink = ListHead->Flink->Flink; + OldBlink = ListHead->Flink->Blink; + OldFlink->Blink = OldBlink; + OldBlink->Flink = OldFlink; + if (Old != ListHead) + { + Old->Flink = NULL; + Old->Blink = NULL; + } + + return(Old); +} + + +/* + * PLIST_ENTRY + * RemoveTailList ( + * PLIST_ENTRY ListHead + * ); + * + * FUNCTION: + * Removes the tail entry from a double linked list + * + * ARGUMENTS: + * ListHead = Head of the list + * + * RETURNS: + * The removed entry + */ +/* +#define RemoveTailList(ListHead) \ + (ListHead)->Blink; \ + {RemoveEntryList((ListHead)->Blink)} +*/ +/* +PLIST_ENTRY +RemoveTailList ( + PLIST_ENTRY ListHead + ); +*/ + +static +inline +PLIST_ENTRY +RemoveTailList ( + PLIST_ENTRY ListHead + ) +{ + PLIST_ENTRY Old; + PLIST_ENTRY OldFlink; + PLIST_ENTRY OldBlink; + + Old = ListHead->Blink; + + OldFlink = ListHead->Blink->Flink; + OldBlink = ListHead->Blink->Blink; + OldFlink->Blink = OldBlink; + OldBlink->Flink = OldFlink; + if (Old != ListHead) + { + Old->Flink = NULL; + Old->Blink = NULL; + } + + return(Old); +} + +NTSTATUS +STDCALL +RtlAppendUnicodeToString ( + PUNICODE_STRING Destination, + PWSTR Source + ); + +ULONG +STDCALL +RtlCompareMemory ( + PVOID Source1, + PVOID Source2, + ULONG Length + ); + +BOOLEAN +STDCALL +RtlEqualUnicodeString ( + PUNICODE_STRING String1, + PUNICODE_STRING String2, + BOOLEAN CaseInSensitive + ); + +VOID +RtlGetCallersAddress ( + PVOID * CallersAddress + ); + +NTSTATUS +STDCALL +RtlQueryRegistryValues ( + IN ULONG RelativeTo, + IN PWSTR Path, + IN PRTL_QUERY_REGISTRY_TABLE QueryTable, + IN PVOID Context, + IN PVOID Environment + ); + +NTSTATUS +STDCALL +RtlWriteRegistryValue ( + ULONG RelativeTo, + PWSTR Path, + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength + ); + +NTSTATUS STDCALL +RtlDeleteRegistryValue(IN ULONG RelativeTo, + IN PWSTR Path, + IN PWSTR ValueName); + +VOID STDCALL +RtlMoveMemory (PVOID Destination, CONST VOID* Source, ULONG Length); + +BOOLEAN STDCALL +RtlEqualLuid(IN PLUID Luid1, + IN PLUID Luid2); + +VOID +STDCALL +RtlFillMemory ( + PVOID Destination, + ULONG Length, + UCHAR Fill + ); + +VOID STDCALL +RtlZeroMemory (PVOID Destination, ULONG Length); + +#else /* __USE_W32API */ + +#include + +#endif /* __USE_W32API */ + + +/* + * PURPOSE: Used with RtlCheckRegistryKey, RtlCreateRegistryKey, + * RtlDeleteRegistryKey + */ +#define RTL_REGISTRY_ABSOLUTE 0 +#define RTL_REGISTRY_SERVICES 1 +#define RTL_REGISTRY_CONTROL 2 +#define RTL_REGISTRY_WINDOWS_NT 3 +#define RTL_REGISTRY_DEVICEMAP 4 +#define RTL_REGISTRY_USER 5 +#define RTL_REGISTRY_ENUM 6 // ReactOS specific: Used internally in kernel only +#define RTL_REGISTRY_MAXIMUM 7 + +#define RTL_REGISTRY_HANDLE 0x40000000 +#define RTL_REGISTRY_OPTIONAL 0x80000000 + + +#define SHORT_SIZE (sizeof(USHORT)) +#define SHORT_MASK (SHORT_SIZE-1) +#define LONG_SIZE (sizeof(ULONG)) +#define LONG_MASK (LONG_SIZE-1) +#define LOWBYTE_MASK 0x00FF + +#define FIRSTBYTE(Value) ((Value) & LOWBYTE_MASK) +#define SECONDBYTE(Value) (((Value) >> 8) & LOWBYTE_MASK) +#define THIRDBYTE(Value) (((Value) >> 16) & LOWBYTE_MASK) +#define FOURTHBYTE(Value) (((Value) >> 24) & LOWBYTE_MASK) + +/* FIXME: reverse byte-order on big-endian machines (e.g. MIPS) */ +#define SHORT_LEAST_SIGNIFICANT_BIT 0 +#define SHORT_MOST_SIGNIFICANT_BIT 1 + +#define LONG_LEAST_SIGNIFICANT_BIT 0 +#define LONG_3RD_MOST_SIGNIFICANT_BIT 1 +#define LONG_2RD_MOST_SIGNIFICANT_BIT 2 +#define LONG_MOST_SIGNIFICANT_BIT 3 + + + +#if defined(__NTOSKRNL__) || defined(__NTDLL__) +#define NLS_MB_CODE_PAGE_TAG NlsMbCodePageTag +#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag +#else +#define NLS_MB_CODE_PAGE_TAG (*NlsMbCodePageTag) +#define NLS_MB_OEM_CODE_PAGE_TAG (*NlsMbOemCodePageTag) +#endif /* __NTOSKRNL__ || __NTDLL__ */ + +extern BOOLEAN NLS_MB_CODE_PAGE_TAG; +extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; + + +/* + * NOTE: ReactOS extensions + */ +#define RtlMin(X,Y) (((X) < (Y))? (X) : (Y)) +#define RtlMax(X,Y) (((X) > (Y))? (X) : (Y)) +#define RtlMin3(X,Y,Z) (((X) < (Y)) ? RtlMin(X,Z) : RtlMin(Y,Z)) +#define RtlMax3(X,Y,Z) (((X) > (Y)) ? RtlMax(X,Z) : RtlMax(Y,Z)) + + +/* + * VOID + * InitializeUnicodeString(PUNICODE_STRING DestinationString, + * USHORT Lenght, + * USHORT MaximumLength, + * PCWSTR Buffer); + * + * Initialize n UNICODE_STRING from its fields. Use when you know the values of + * all the fields in advance + */ + +#define InitializeUnicodeString(__PDEST_STRING__,__LENGTH__,__MAXLENGTH__,__BUFFER__) \ +{ \ + (__PDEST_STRING__)->Length = (__LENGTH__); \ + (__PDEST_STRING__)->MaximumLength = (__MAXLENGTH__); \ + (__PDEST_STRING__)->Buffer = (__BUFFER__); \ +} + + +/* + * VOID + * RtlInitUnicodeStringFromLiteral(PUNICODE_STRING DestinationString, + * PCWSTR SourceString); + * + * Initialize a UNICODE_STRING from a wide string literal. WARNING: use only with + * string literals and statically initialized arrays, it will calculate the wrong + * length otherwise + */ + +#define RtlInitUnicodeStringFromLiteral(__PDEST_STRING__,__SOURCE_STRING__) \ + InitializeUnicodeString( \ + (__PDEST_STRING__), \ + sizeof(__SOURCE_STRING__) - sizeof(WCHAR), \ + sizeof(__SOURCE_STRING__), \ + (__SOURCE_STRING__) \ +) + + +/* + * Static initializer for UNICODE_STRING variables. + * + * Usage: + * UNICODE_STRING wstr = UNICODE_STRING_INITIALIZER(L"string"); + */ + +#define UNICODE_STRING_INITIALIZER(__SOURCE_STRING__) \ +{ \ + sizeof((__SOURCE_STRING__)) - sizeof(WCHAR), \ + sizeof((__SOURCE_STRING__)), \ + (__SOURCE_STRING__) \ +} + + +/* + * Initializer for empty UNICODE_STRING variables. + * + * Usage: + * UNICODE_STRING wstr = EMPTY_UNICODE_STRING; + */ + +#define EMPTY_UNICODE_STRING {0, 0, NULL} + + +/* +VOID +PushEntryList ( + PSINGLE_LIST_ENTRY ListHead, + PSINGLE_LIST_ENTRY Entry ); */ +/* +#define PushEntryList(ListHead,Entry) \ + (Entry)->Next = (ListHead)->Next; \ + (ListHead)->Next = (Entry) +*/ + + +#ifndef __USE_W32API + +/* + * An ReactOS extension + */ static inline -PLIST_ENTRY -RemoveHeadList ( - PLIST_ENTRY ListHead +PSINGLE_LIST_ENTRY + PopEntrySList( + PSLIST_HEADER ListHead ) { - PLIST_ENTRY Old; - PLIST_ENTRY OldFlink; - PLIST_ENTRY OldBlink; - - Old = ListHead->Flink; + PSINGLE_LIST_ENTRY ListEntry; - OldFlink = ListHead->Flink->Flink; - OldBlink = ListHead->Flink->Blink; - OldFlink->Blink = OldBlink; - OldBlink->Flink = OldFlink; - if (Old != ListHead) - { - Old->Flink = NULL; - Old->Blink = NULL; - } - - return(Old); + ListEntry = ListHead->s.Next.Next; + if (ListEntry!=NULL) + { + ListHead->s.Next.Next = ListEntry->Next; + ListHead->s.Depth++; + ListHead->s.Sequence++; + } + return ListEntry; } /* - * PLIST_ENTRY - * RemoveTailList ( - * PLIST_ENTRY ListHead - * ); - * - * FUNCTION: - * Removes the tail entry from a double linked list - * - * ARGUMENTS: - * ListHead = Head of the list - * - * RETURNS: - * The removed entry + * An ReactOS extension */ -/* -#define RemoveTailList(ListHead) \ - (ListHead)->Blink; \ - {RemoveEntryList((ListHead)->Blink)} -*/ -/* -PLIST_ENTRY -RemoveTailList ( - PLIST_ENTRY ListHead - ); -*/ +static +inline +VOID +PushEntrySList ( + PSLIST_HEADER ListHead, + PSINGLE_LIST_ENTRY Entry + ) +{ + Entry->Next = ListHead->s.Next.Next; + ListHead->s.Next.Next = Entry; + ListHead->s.Depth++; + ListHead->s.Sequence++; +} +#else /* __USE_W32API */ + +/* + * An ReactOS extension + */ static inline -PLIST_ENTRY -RemoveTailList ( - PLIST_ENTRY ListHead +PSINGLE_LIST_ENTRY + PopEntrySList( + PSLIST_HEADER ListHead ) { - PLIST_ENTRY Old; - PLIST_ENTRY OldFlink; - PLIST_ENTRY OldBlink; + PSINGLE_LIST_ENTRY ListEntry; - Old = ListHead->Blink; + ListEntry = ListHead->Next.Next; + if (ListEntry!=NULL) + { + ListHead->Next.Next = ListEntry->Next; + ListHead->Depth++; + ListHead->Sequence++; + } + return ListEntry; +} - OldFlink = ListHead->Blink->Flink; - OldBlink = ListHead->Blink->Blink; - OldFlink->Blink = OldBlink; - OldBlink->Flink = OldFlink; - if (Old != ListHead) - { - Old->Flink = NULL; - Old->Blink = NULL; - } - - return(Old); + +/* + * An ReactOS extension + */ +static +inline +VOID +PushEntrySList ( + PSLIST_HEADER ListHead, + PSINGLE_LIST_ENTRY Entry + ) +{ + Entry->Next = ListHead->Next.Next; + ListHead->Next.Next = Entry; + ListHead->Depth++; + ListHead->Sequence++; } +#endif /* __USE_W32API */ + NTSTATUS STDCALL @@ -513,13 +702,6 @@ RtlAppendUnicodeStringToString ( PUNICODE_STRING Source ); -NTSTATUS -STDCALL -RtlAppendUnicodeToString ( - PUNICODE_STRING Destination, - PWSTR Source - ); - BOOLEAN STDCALL RtlAreBitsClear ( @@ -581,14 +763,6 @@ RtlCompactHeap ( DWORD flags ); -ULONG -STDCALL -RtlCompareMemory ( - PVOID Source1, - PVOID Source2, - ULONG Length - ); - LONG STDCALL RtlCompareString ( @@ -602,7 +776,7 @@ STDCALL RtlCompareUnicodeString ( PUNICODE_STRING String1, PUNICODE_STRING String2, - BOOLEAN BaseInsensitive + BOOLEAN CaseInsensitive ); NTSTATUS STDCALL @@ -651,9 +825,6 @@ RtlCopyMemory ( ); #endif -#define RtlCopyMemory(Destination,Source,Length) \ - memcpy((Destination),(Source),(Length)) - #define RtlCopyBytes RtlCopyMemory VOID STDCALL @@ -696,8 +867,8 @@ STDCALL RtlCreateHeap ( ULONG Flags, PVOID BaseAddress, - ULONG SizeToReserve, - ULONG SizeToCommit, + ULONG SizeToReserve, // dwMaximumSize + ULONG SizeToCommit, // dwInitialSize PVOID Unknown, PRTL_HEAP_DEFINITION Definition ); @@ -770,11 +941,6 @@ RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN RTL_ATOM Atom); NTSTATUS STDCALL -RtlDeleteRegistryValue(IN ULONG RelativeTo, - IN PWSTR Path, - IN PWSTR ValueName); - -NTSTATUS STDCALL RtlDescribeChunk(IN USHORT CompressionFormat, IN OUT PUCHAR *CompressedBuffer, IN PUCHAR EndOfCompressedBufferPlus1, @@ -824,10 +990,6 @@ RtlEnlargedUnsignedMultiply ( ULONG Multiplier ); -BOOLEAN STDCALL -RtlEqualLuid(IN PLUID Luid1, - IN PLUID Luid2); - BOOLEAN STDCALL RtlEqualString ( @@ -836,14 +998,6 @@ RtlEqualString ( BOOLEAN CaseInSensitive ); -BOOLEAN -STDCALL -RtlEqualUnicodeString ( - PUNICODE_STRING String1, - PUNICODE_STRING String2, - BOOLEAN CaseInSensitive - ); - LARGE_INTEGER STDCALL RtlExtendedIntegerMultiply ( @@ -869,14 +1023,6 @@ RtlExtendedMagicDivide ( VOID STDCALL -RtlFillMemory ( - PVOID Destination, - ULONG Length, - UCHAR Fill - ); - -VOID -STDCALL RtlFillMemoryUlong ( PVOID Destination, ULONG Length, @@ -991,11 +1137,6 @@ RtlGenerate8dot3Name(IN PUNICODE_STRING Name, IN OUT PGENERATE_NAME_CONTEXT Context, OUT PUNICODE_STRING Name8dot3); -VOID -RtlGetCallersAddress ( - PVOID * CallersAddress - ); - NTSTATUS STDCALL RtlGetCompressionWorkSpaceSize(IN USHORT CompressionFormatAndEngine, OUT PULONG CompressBufferAndWorkSpaceSize, @@ -1008,8 +1149,6 @@ RtlGetDefaultCodePage ( PUSHORT OemCodePage ); -#define RtlGetProcessHeap() (NtCurrentPeb()->ProcessHeap) - PVOID STDCALL RtlImageDirectoryEntryToData ( @@ -1063,70 +1202,6 @@ RtlInitUnicodeString ( PCWSTR SourceString ); -/* -VOID -InitializeUnicodeString ( - PUNICODE_STRING DestinationString, - USHORT Lenght, - USHORT MaximumLength, - PCWSTR Buffer - ); - - Initialize an UNICODE_STRING from its fields. Use when you know the values of - all the fields in advance - - */ - -#define InitializeUnicodeString(__PDEST_STRING__,__LENGTH__,__MAXLENGTH__,__BUFFER__) \ -{ \ - (__PDEST_STRING__)->Length = (__LENGTH__); \ - (__PDEST_STRING__)->MaximumLength = (__MAXLENGTH__); \ - (__PDEST_STRING__)->Buffer = (__BUFFER__); \ -} - -/* -VOID -RtlInitUnicodeStringFromLiteral ( - PUNICODE_STRING DestinationString, - PCWSTR SourceString - ); - - Initialize an UNICODE_STRING from a wide string literal. WARNING: use only with - string literals and statically initialized arrays, it will calculate the wrong - length otherwise - - */ - -#define RtlInitUnicodeStringFromLiteral(__PDEST_STRING__,__SOURCE_STRING__) \ - InitializeUnicodeString( \ - (__PDEST_STRING__), \ - sizeof(__SOURCE_STRING__) - sizeof(WCHAR), \ - sizeof(__SOURCE_STRING__), \ - (__SOURCE_STRING__) \ - ) - -/* - Static initializer for UNICODE_STRING variables. Usage: - - UNICODE_STRING wstr = UNICODE_STRING_INITIALIZER(L"string"); - -*/ - -#define UNICODE_STRING_INITIALIZER(__SOURCE_STRING__) \ -{ \ - sizeof((__SOURCE_STRING__)) - sizeof(WCHAR), \ - sizeof((__SOURCE_STRING__)), \ - (__SOURCE_STRING__) \ -} - -/* - Initializer for empty UNICODE_STRING variables. Usage: - - UNICODE_STRING wstr = EMPTY_UNICODE_STRING; - -*/ -#define EMPTY_UNICODE_STRING {0, 0, NULL} - VOID STDCALL RtlInitializeBitMap ( @@ -1394,9 +1469,6 @@ RtlLookupAtomInAtomTable ( OUT PRTL_ATOM Atom ); -VOID STDCALL -RtlMoveMemory (PVOID Destination, CONST VOID* Source, ULONG Length); - NTSTATUS STDCALL RtlMultiByteToUnicodeN ( @@ -1475,13 +1547,6 @@ RtlOemToUnicodeN ( ULONG OemSize ); -NTSTATUS -STDCALL -RtlOpenCurrentUser ( - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE KeyHandle - ); - NTSTATUS STDCALL RtlPinAtomInAtomTable ( IN PRTL_ATOM_TABLE AtomTable, @@ -1517,16 +1582,6 @@ RtlQueryAtomInAtomTable ( NTSTATUS STDCALL -RtlQueryRegistryValues ( - IN ULONG RelativeTo, - IN PWSTR Path, - IN PRTL_QUERY_REGISTRY_TABLE QueryTable, - IN PVOID Context, - IN PVOID Environment - ); - -NTSTATUS -STDCALL RtlQueryTimeZoneInformation ( IN OUT PTIME_ZONE_INFORMATION TimeZoneInformation ); @@ -1905,20 +1960,6 @@ RtlValidSecurityDescriptor ( BOOLEAN STDCALL RtlValidSid(IN PSID Sid); -NTSTATUS -STDCALL -RtlWriteRegistryValue ( - ULONG RelativeTo, - PWSTR Path, - PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength - ); - -VOID STDCALL -RtlZeroMemory (PVOID Destination, ULONG Length); - ULONG STDCALL RtlxAnsiStringToUnicodeSize ( diff --git a/include/ddk/rtltypes.h b/include/ntos/rtltypes.h old mode 100644 new mode 100755 similarity index 93% rename from include/ddk/rtltypes.h rename to include/ntos/rtltypes.h index ea718ad..7532839 --- a/include/ddk/rtltypes.h +++ b/include/ntos/rtltypes.h @@ -5,6 +5,7 @@ #ifndef __DDK_RTLTYPES_H #define __DDK_RTLTYPES_H +#ifndef __USE_W32API #define COMPRESSION_FORMAT_NONE 0x0000 #define COMPRESSION_FORMAT_DEFAULT 0x0001 @@ -14,16 +15,6 @@ #define COMPRESSION_ENGINE_MAXIMUM 0x0100 #define COMPRESSION_ENGINE_HIBER 0x0200 - -typedef struct _INITIAL_TEB -{ - ULONG StackCommit; - ULONG StackReserve; - PVOID StackBase; - PVOID StackLimit; - PVOID StackAllocate; -} INITIAL_TEB, *PINITIAL_TEB; - typedef struct _CONTROLLER_OBJECT { CSHORT Type; @@ -58,7 +49,6 @@ typedef PSTRING PANSI_STRING; typedef STRING OEM_STRING; typedef PSTRING POEM_STRING; - typedef struct _TIME_FIELDS { CSHORT Year; @@ -77,6 +67,77 @@ typedef struct _RTL_BITMAP PULONG Buffer; } RTL_BITMAP, *PRTL_BITMAP; + +#ifdef __GNUC__ +#define STDCALL_FUNC STDCALL +#else +#define STDCALL_FUNC(a) (__stdcall a ) +#endif /*__GNUC__*/ + + +typedef NTSTATUS STDCALL_FUNC +(*PRTL_QUERY_REGISTRY_ROUTINE) (PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext); + +typedef struct _RTL_QUERY_REGISTRY_TABLE +{ + PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; + ULONG Flags; + PWSTR Name; + PVOID EntryContext; + ULONG DefaultType; + PVOID DefaultData; + ULONG DefaultLength; +} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; + +typedef struct _COMPRESSED_DATA_INFO +{ + USHORT CompressionFormatAndEngine; + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved; + USHORT NumberOfChunks; + ULONG CompressedChunkSizes[1]; +} COMPRESSED_DATA_INFO, *PCOMPRESSED_DATA_INFO; + +typedef struct _GENERATE_NAME_CONTEXT +{ + USHORT Checksum; + BOOLEAN CheckSumInserted; + UCHAR NameLength; + WCHAR NameBuffer[8]; + ULONG ExtensionLength; + WCHAR ExtensionBuffer[4]; + ULONG LastIndexValue; +} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT; + +typedef struct _RTL_SPLAY_LINKS +{ + struct _RTL_SPLAY_LINKS *Parent; + struct _RTL_SPLAY_LINKS *LeftChild; + struct _RTL_SPLAY_LINKS *RightChild; +} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; + +#else /* __USE_W32API */ + +#include + +#endif /* __USE_W32API */ + +typedef struct _INITIAL_TEB +{ + ULONG StackCommit; + ULONG StackReserve; + PVOID StackBase; + PVOID StackLimit; + PVOID StackAllocate; +} INITIAL_TEB, *PINITIAL_TEB; + typedef struct _RTL_HEAP_DEFINITION { ULONG Length; @@ -124,14 +185,6 @@ typedef struct _RTL_NLS_TABLE } RTL_NLS_TABLE, *PRTL_NLS_TABLE; -typedef struct _RTL_SPLAY_LINKS -{ - struct _RTL_SPLAY_LINKS *Parent; - struct _RTL_SPLAY_LINKS *LeftChild; - struct _RTL_SPLAY_LINKS *RightChild; -} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; - - typedef struct _RTL_GENERIC_TABLE { PVOID RootElement; @@ -167,48 +220,4 @@ typedef struct _RTL_MESSAGE_RESOURCE_DATA RTL_MESSAGE_RESOURCE_BLOCK Blocks[1]; } RTL_MESSAGE_RESOURCE_DATA, *PRTL_MESSAGE_RESOURCE_DATA; - -typedef NTSTATUS STDCALL -(*PRTL_QUERY_REGISTRY_ROUTINE)(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext); - -typedef struct _RTL_QUERY_REGISTRY_TABLE -{ - PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; - ULONG Flags; - PWSTR Name; - PVOID EntryContext; - ULONG DefaultType; - PVOID DefaultData; - ULONG DefaultLength; -} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; - - -typedef struct _GENERATE_NAME_CONTEXT -{ - USHORT Checksum; - BOOLEAN CheckSumInserted; - UCHAR NameLength; - WCHAR NameBuffer[8]; - ULONG ExtensionLength; - WCHAR ExtensionBuffer[4]; - ULONG LastIndexValue; -} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT; - - -typedef struct _COMPRESSED_DATA_INFO -{ - USHORT CompressionFormatAndEngine; - UCHAR CompressionUnitShift; - UCHAR ChunkShift; - UCHAR ClusterShift; - UCHAR Reserved; - USHORT NumberOfChunks; - ULONG CompressedChunkSizes[1]; -} COMPRESSED_DATA_INFO, *PCOMPRESSED_DATA_INFO; - #endif /* __DDK_RTLTYPES_H */ diff --git a/include/ntos/security.h b/include/ntos/security.h index c88df82..6fc42b5 100644 --- a/include/ntos/security.h +++ b/include/ntos/security.h @@ -4,6 +4,73 @@ #include #include +/* Privileges */ +#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L) +#define SE_CREATE_TOKEN_PRIVILEGE (2L) +#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L) +#define SE_LOCK_MEMORY_PRIVILEGE (4L) +#define SE_INCREASE_QUOTA_PRIVILEGE (5L) +#define SE_UNSOLICITED_INPUT_PRIVILEGE (6L) /* unused */ +#define SE_MACHINE_ACCOUNT_PRIVILEGE (6L) +#define SE_TCB_PRIVILEGE (7L) +#define SE_SECURITY_PRIVILEGE (8L) +#define SE_TAKE_OWNERSHIP_PRIVILEGE (9L) +#define SE_LOAD_DRIVER_PRIVILEGE (10L) +#define SE_SYSTEM_PROFILE_PRIVILEGE (11L) +#define SE_SYSTEMTIME_PRIVILEGE (12L) +#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L) +#define SE_INC_BASE_PRIORITY_PRIVILEGE (14L) +#define SE_CREATE_PAGEFILE_PRIVILEGE (15L) +#define SE_CREATE_PERMANENT_PRIVILEGE (16L) +#define SE_BACKUP_PRIVILEGE (17L) +#define SE_RESTORE_PRIVILEGE (18L) +#define SE_SHUTDOWN_PRIVILEGE (19L) +#define SE_DEBUG_PRIVILEGE (20L) +#define SE_AUDIT_PRIVILEGE (21L) +#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L) +#define SE_CHANGE_NOTIFY_PRIVILEGE (23L) +#define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L) +#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_REMOTE_SHUTDOWN_PRIVILEGE + +#if 0 +/* Security descriptor control. */ +#define SECURITY_DESCRIPTOR_REVISION (1) +#define SECURITY_DESCRIPTOR_MIN_LENGTH (20) +#define SE_OWNER_DEFAULTED (1) +#define SE_GROUP_DEFAULTED (2) +#define SE_DACL_PRESENT (4) +#define SE_DACL_DEFAULTED (8) +#define SE_SACL_PRESENT (16) +#define SE_SACL_DEFAULTED (32) +#define SE_SELF_RELATIVE (32768) +#endif + +typedef ULONG ACCESS_MODE, *PACCESS_MODE; + +#if 0 +typedef struct _ACE_HEADER +{ + CHAR AceType; + CHAR AceFlags; + USHORT AceSize; + ACCESS_MASK AccessMask; +} ACE_HEADER, *PACE_HEADER; + +typedef struct +{ + ACE_HEADER Header; +} ACE, *PACE; +#endif + +#ifdef __GNU__ +typedef struct _SECURITY_DESCRIPTOR_CONTEXT +{ +} SECURITY_DESCRIPTOR_CONTEXT, *PSECURITY_DESCRIPTOR_CONTEXT; +#endif + + +#ifndef __USE_W32API + /* SID Auhority */ #define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} #define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} @@ -51,47 +118,6 @@ #define DOMAIN_ALIAS_RID_BACKUP_OPS (0x227L) #define DOMAIN_ALIAS_RID_REPLICATOR (0x228L) -/* Privileges */ -#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L) -#define SE_CREATE_TOKEN_PRIVILEGE (2L) -#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L) -#define SE_LOCK_MEMORY_PRIVILEGE (4L) -#define SE_INCREASE_QUOTA_PRIVILEGE (5L) -#define SE_UNSOLICITED_INPUT_PRIVILEGE (6L) /* unused */ -#define SE_MACHINE_ACCOUNT_PRIVILEGE (6L) -#define SE_TCB_PRIVILEGE (7L) -#define SE_SECURITY_PRIVILEGE (8L) -#define SE_TAKE_OWNERSHIP_PRIVILEGE (9L) -#define SE_LOAD_DRIVER_PRIVILEGE (10L) -#define SE_SYSTEM_PROFILE_PRIVILEGE (11L) -#define SE_SYSTEMTIME_PRIVILEGE (12L) -#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L) -#define SE_INC_BASE_PRIORITY_PRIVILEGE (14L) -#define SE_CREATE_PAGEFILE_PRIVILEGE (15L) -#define SE_CREATE_PERMANENT_PRIVILEGE (16L) -#define SE_BACKUP_PRIVILEGE (17L) -#define SE_RESTORE_PRIVILEGE (18L) -#define SE_SHUTDOWN_PRIVILEGE (19L) -#define SE_DEBUG_PRIVILEGE (20L) -#define SE_AUDIT_PRIVILEGE (21L) -#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L) -#define SE_CHANGE_NOTIFY_PRIVILEGE (23L) -#define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L) -#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_REMOTE_SHUTDOWN_PRIVILEGE - -#if 0 -/* Security descriptor control. */ -#define SECURITY_DESCRIPTOR_REVISION (1) -#define SECURITY_DESCRIPTOR_MIN_LENGTH (20) -#define SE_OWNER_DEFAULTED (1) -#define SE_GROUP_DEFAULTED (2) -#define SE_DACL_PRESENT (4) -#define SE_DACL_DEFAULTED (8) -#define SE_SACL_PRESENT (16) -#define SE_SACL_DEFAULTED (32) -#define SE_SELF_RELATIVE (32768) -#endif - /* ACCESS_MASK */ #define MAXIMUM_ALLOWED (0x2000000L) #define GENERIC_ALL (0x10000000L) @@ -148,19 +174,12 @@ typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; #define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)3) #define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)4) +typedef ULONG ACCESS_MASK, *PACCESS_MASK; typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE; #define TokenPrimary ((TOKEN_TYPE)1) #define TokenImpersonation ((TOKEN_TYPE)2) -//typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE; - -//#define SECURITY_DYNAMIC_TRACKING (TRUE) -//#define SECURITY_STATIC_TRACKING (FALSE) - -typedef ULONG ACCESS_MASK, *PACCESS_MASK; -typedef ULONG ACCESS_MODE, *PACCESS_MODE; - typedef struct _SECURITY_QUALITY_OF_SERVICE { ULONG Length; @@ -178,12 +197,6 @@ typedef struct _ACE_HEADER WORD AceSize; } ACE_HEADER, *PACE_HEADER; -typedef struct -{ - ACE_HEADER Header; - ACCESS_MASK AccessMask; -} ACE, *PACE; - typedef struct _SID_IDENTIFIER_AUTHORITY { BYTE Value[6]; @@ -226,10 +239,6 @@ typedef enum _ACL_INFORMATION_CLASS typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; -typedef struct _SECURITY_DESCRIPTOR_CONTEXT -{ -} SECURITY_DESCRIPTOR_CONTEXT, *PSECURITY_DESCRIPTOR_CONTEXT; - typedef LARGE_INTEGER LUID, *PLUID; typedef struct _SECURITY_DESCRIPTOR @@ -340,5 +349,12 @@ typedef struct _SECURITY_ATTRIBUTES BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; +#endif /* !__USE_W32API */ + +typedef struct +{ + ACE_HEADER Header; + ACCESS_MASK AccessMask; +} ACE, *PACE; #endif /* __INCLUDE_SECURITY_H */ diff --git a/include/ntos/synch.h b/include/ntos/synch.h index 85d1a3b..be138d4 100644 --- a/include/ntos/synch.h +++ b/include/ntos/synch.h @@ -12,13 +12,13 @@ #ifndef __INCLUDE_SYNCH_H #define __INCLUDE_SYNCH_H +#ifndef __USE_W32API #define EVENT_ALL_ACCESS (0x1f0003L) -#define EVENT_QUERY_STATE (1) #define EVENT_MODIFY_STATE (2) +#define EVENT_QUERY_STATE (1) #define EVENT_PAIR_ALL_ACCESS (0x1f0000L) #define MUTEX_ALL_ACCESS (0x1f0001L) -#define MUTEX_QUERY_STATE (1) #define MUTANT_ALL_ACCESS (0x1f0001L) #define MUTANT_QUERY_STATE (1) #define SEMAPHORE_ALL_ACCESS (0x1f0003L) @@ -28,5 +28,8 @@ #define TIMER_QUERY_STATE (1) #define TIMER_MODIFY_STATE (2) +#endif /* !__USE_W32API */ + +#define MUTEX_QUERY_STATE (1) #endif /* __INCLUDE_SYNCH_H */ diff --git a/include/ntos/time.h b/include/ntos/time.h index 8387a89..3c77ab3 100644 --- a/include/ntos/time.h +++ b/include/ntos/time.h @@ -14,6 +14,8 @@ #include +#ifndef __USE_W32API + typedef struct _SYSTEMTIME { WORD wYear; @@ -37,4 +39,13 @@ typedef struct _TIME_ZONE_INFORMATION LONG DaylightBias; } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; +#else /* __USE_W32API */ + +#include + +typedef LPTIME_ZONE_INFORMATION PTIME_ZONE_INFORMATION; + +#endif /* __USE_W32API */ + + #endif /* __INCLUDE_NTOS_TIME_H */ diff --git a/include/ntos/types.h b/include/ntos/types.h index ebdf60f..3efeef3 100644 --- a/include/ntos/types.h +++ b/include/ntos/types.h @@ -14,20 +14,52 @@ #ifndef __INCLUDE_TYPES_H #define __INCLUDE_TYPES_H +#include + +#ifdef __GNUC__ +#define STDCALL_FUNC STDCALL +#else +#define STDCALL_FUNC(a) (__stdcall a ) +#endif /*__GNUC__*/ + /* Fixed precision types */ typedef signed char INT8, *PINT8; typedef signed short INT16, *PINT16; -typedef signed int INT32, *PINT32; -typedef signed long long INT64, *PINT64; + typedef unsigned char UINT8, *PUINT8; typedef unsigned short UINT16, *PUINT16; -typedef unsigned int UINT32, *PUINT32; -typedef unsigned long long UINT64, *PUINT64; -typedef signed long int LONG32, *PLONG32; -typedef unsigned long int ULONG32, *PULONG32; -typedef unsigned long int DWORD32, *PDWORD32; +/* Check VOID before defining CHAR, SHORT */ +#ifndef VOID +#define VOID void +typedef char CHAR; +typedef short SHORT; +#endif + + +#ifndef __USE_W32API + +#ifdef i386 +#define STDCALL __attribute__ ((stdcall)) +#define CDECL __attribute__ ((cdecl)) +#define CALLBACK WINAPI +#define PASCAL WINAPI +#else + +#ifdef __GNUC__ +#define STDCALL +#define CDECL +#define CALLBACK +#define PASCAL +#else +#define STDCALL __stdcall +#define CDECL __cdecl +#define CALLBACK +#define PASCAL +#endif /*__GNUC__*/ + +#endif /*i386*/ #ifdef _WIN64 @@ -39,15 +71,6 @@ typedef DWORD64 DWORD, *PDWORD; typedef UINT64 UINT, *PUINT; typedef ULONG64 ULONG, *PULONG; -/* Pointer precision types */ -typedef long long INT_PTR, *PINT_PTR; -typedef unsigned long long UINT_PTR, *PUINT_PTR; -typedef long long LONG_PTR, *PLONG_PTR; -typedef unsigned long long ULONG_PTR, *PULONG_PTR; -typedef unsigned long long HANDLE_PTR; -typedef unsigned int UHALF_PTR, *PUHALF_PTR; -typedef int HALF_PTR, *PHALF_PTR; - #else /* _WIN64 */ /* 32-bit architecture */ @@ -58,77 +81,75 @@ typedef DWORD32 DWORD, *PDWORD; typedef UINT32 UINT, *PUINT; typedef ULONG32 ULONG, *PULONG; - -/* Pointer precision types */ -typedef int INT_PTR, *PINT_PTR; -typedef unsigned int UINT_PTR, *PUINT_PTR; -typedef long LONG_PTR, *PLONG_PTR; -typedef unsigned long ULONG_PTR, *PULONG_PTR; -typedef unsigned short UHALF_PTR, *PUHALF_PTR; -typedef short HALF_PTR, *PHALF_PTR; -typedef unsigned long HANDLE_PTR; - #endif /* _WIN64 */ -typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; +#ifndef _WCHAR_T_ +#define _WCHAR_T_ +#define _WCHAR_T +#define _WCHAR_T_DEFINED +#ifndef __WCHAR_TYPE__ +#define __WCHAR_TYPE__ short unsigned int +#endif -typedef long long LONG64, *PLONG64; +#ifndef __cplusplus +typedef __WCHAR_TYPE__ wchar_t; +#endif /* C++ */ -typedef unsigned long long ULONG64, *PULONG64; -typedef unsigned long long DWORD64, *PDWORD64; +#endif /* wchar_t not already defined */ +//#ifndef __cplusplus +//#ifndef _WCHAR_T_DEFINED +//#define _WCHAR_T_DEFINED +//typedef unsigned short wchar_t; +//#endif +//#endif + typedef unsigned char UCHAR; typedef unsigned short USHORT; -typedef unsigned short WCHAR; +typedef wchar_t WCHAR; typedef unsigned short WORD; typedef int BOOL; typedef unsigned char BOOLEAN; typedef BOOLEAN* PBOOLEAN; -typedef unsigned short *LPWSTR; -typedef unsigned short *PWSTR; +typedef wchar_t *LPWSTR; +typedef wchar_t *PWSTR; typedef unsigned char *PUCHAR; typedef unsigned short *PUSHORT; typedef void *PVOID; typedef unsigned char BYTE; typedef void *LPVOID; typedef float *PFLOAT; -typedef unsigned short *PWCH; +typedef wchar_t *PWCH; typedef unsigned short *PWORD; -typedef long long LONGLONG; -typedef unsigned long long ULONGLONG; -typedef long long *PLONGLONG; -typedef unsigned long long *PULONGLONG; - -/* Check VOID before defining CHAR, SHORT */ -#ifndef VOID -#define VOID void -typedef char CHAR; -typedef short SHORT; -#endif +#include // for definition of LONGLONG, PLONGLONG etc +typedef const void *LPCVOID; +typedef BYTE *LPBYTE, *PBYTE; +typedef BOOL *PBOOL; +typedef DWORD LCID; +typedef DWORD *PLCID; +typedef const char *LPCSTR; +typedef char *LPSTR; +typedef const wchar_t *LPCWSTR; typedef CHAR *PCHAR; typedef CHAR *PCH; typedef void *HANDLE; +typedef HANDLE *PHANDLE; typedef char CCHAR; typedef CCHAR *PCCHAR; +typedef wchar_t *PWCHAR; +typedef ULONG WAIT_TYPE; +typedef USHORT CSHORT; +typedef const wchar_t *PCWSTR; +typedef char* PCSZ; - -#define FALSE 0 -#define TRUE 1 - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 +#ifdef __GNUC__ +typedef DWORD STDCALL (*PTHREAD_START_ROUTINE) (LPVOID); #else -#define NULL ((void*)0) -#endif /* __cplusplus */ -#endif /* NULL */ - -typedef const unsigned short *PCWSTR; - -typedef char* PCSZ; +typedef DWORD (STDCALL *PTHREAD_START_ROUTINE) (LPVOID); +#endif /*__GNUC__*/ typedef union _LARGE_INTEGER { @@ -166,37 +187,62 @@ typedef union _ULARGE_INTEGER typedef struct _FILETIME { - DWORD dwLowDateTime; - DWORD dwHighDateTime; + DWORD dwLowDateTime; + DWORD dwHighDateTime; } FILETIME, *LPFILETIME, *PFILETIME; -#define CONST const - -#ifdef i386 -#define STDCALL __attribute__ ((stdcall)) -#define CDECL __attribute((cdecl)) -#define CALLBACK WINAPI -#define PASCAL WINAPI -#else -#define STDCALL -#define CDECL -#define CALLBACK -#define PASCAL -#endif - -typedef struct _LIST_ENTRY { +typedef struct _LIST_ENTRY +{ struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY; -typedef struct _SINGLE_LIST_ENTRY { +typedef struct _SINGLE_LIST_ENTRY +{ struct _SINGLE_LIST_ENTRY *Next; } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; -typedef DWORD STDCALL (*PTHREAD_START_ROUTINE) (LPVOID); -typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, *PUNICODE_STRING; -typedef unsigned short *PWCHAR; +typedef struct _FLOATING_SAVE_AREA +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[80]; + DWORD Cr0NpxState; +} FLOATING_SAVE_AREA; + +typedef unsigned short RTL_ATOM; +typedef unsigned short *PRTL_ATOM; + +#else /* __USE_W32API */ + +#include + +#endif /* __USE_W32API */ + +#define FALSE 0 +#define TRUE 1 + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void*)0) +#endif /* __cplusplus */ +#endif /* NULL */ + +#define CONST const #ifdef __PPC__ #define CONTEXT_CONTROL 1L @@ -208,163 +254,171 @@ typedef unsigned short *PWCHAR; #define CONTEXT_DEBUGGER (CONTEXT_FULL) #else /* x86 */ -/* The doc refered me to winnt.h, so I had to look... */ + #define SIZE_OF_80387_REGISTERS 80 /* Values for contextflags */ #define CONTEXT_i386 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386 | 1) -#define CONTEXT_INTEGER (CONTEXT_i386 | 2) -#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8) + +#ifndef __USE_W32API + +#define CONTEXT_CONTROL (CONTEXT_i386 | 1) +#define CONTEXT_INTEGER (CONTEXT_i386 | 2) +#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4) +#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8) #define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10) #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) +#endif /* !__USE_W32API */ + /* our own invention */ #define FLAG_TRACE_BIT 0x100 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) #endif -typedef struct _FLOATING_SAVE_AREA { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - BYTE RegisterArea[80]; - DWORD Cr0NpxState; -} FLOATING_SAVE_AREA; - -typedef struct _CONTEXT_X86 { - DWORD ContextFlags; - - DWORD Dr0; - DWORD Dr1; - DWORD Dr2; - DWORD Dr3; - DWORD Dr6; - DWORD Dr7; - - FLOATING_SAVE_AREA FloatSave; - - DWORD SegGs; - DWORD SegFs; - DWORD SegEs; - DWORD SegDs; - - DWORD Edi; - DWORD Esi; - DWORD Ebx; - DWORD Edx; - DWORD Ecx; - DWORD Eax; - - DWORD Ebp; - DWORD Eip; - DWORD SegCs; - DWORD EFlags; - DWORD Esp; - DWORD SegSs; +typedef struct _CONTEXT_X86 +{ + DWORD ContextFlags; + + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + + FLOATING_SAVE_AREA FloatSave; + + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; } CONTEXT_X86, *PCONTEXT_X86, *LPCONTEXT_X86; typedef struct _CONTEXT_PPC - { - /* Floating point registers returned when CONTEXT_FLOATING_POINT is set */ - double Fpr0; - double Fpr1; - double Fpr2; - double Fpr3; - double Fpr4; - double Fpr5; - double Fpr6; - double Fpr7; - double Fpr8; - double Fpr9; - double Fpr10; - double Fpr11; - double Fpr12; - double Fpr13; - double Fpr14; - double Fpr15; - double Fpr16; - double Fpr17; - double Fpr18; - double Fpr19; - double Fpr20; - double Fpr21; - double Fpr22; - double Fpr23; - double Fpr24; - double Fpr25; - double Fpr26; - double Fpr27; - double Fpr28; - double Fpr29; - double Fpr30; - double Fpr31; - double Fpscr; - - /* Integer registers returned when CONTEXT_INTEGER is set. */ - DWORD Gpr0; - DWORD Gpr1; - DWORD Gpr2; - DWORD Gpr3; - DWORD Gpr4; - DWORD Gpr5; - DWORD Gpr6; - DWORD Gpr7; - DWORD Gpr8; - DWORD Gpr9; - DWORD Gpr10; - DWORD Gpr11; - DWORD Gpr12; - DWORD Gpr13; - DWORD Gpr14; - DWORD Gpr15; - DWORD Gpr16; - DWORD Gpr17; - DWORD Gpr18; - DWORD Gpr19; - DWORD Gpr20; - DWORD Gpr21; - DWORD Gpr22; - DWORD Gpr23; - DWORD Gpr24; - DWORD Gpr25; - DWORD Gpr26; - DWORD Gpr27; - DWORD Gpr28; - DWORD Gpr29; - DWORD Gpr30; - DWORD Gpr31; - - DWORD Cr; /* Condition register */ - DWORD Xer; /* Fixed point exception register */ - - /* The following are set when CONTEXT_CONTROL is set. */ - DWORD Msr; /* Machine status register */ - DWORD Iar; /* Instruction address register */ - DWORD Lr; /* Link register */ - DWORD Ctr; /* Control register */ - - /* Control which context values are returned */ - DWORD ContextFlags; - DWORD Fill[3]; - - /* Registers returned if CONTEXT_DEBUG_REGISTERS is set. */ - DWORD Dr0; /* Breakpoint Register 1 */ - DWORD Dr1; /* Breakpoint Register 2 */ - DWORD Dr2; /* Breakpoint Register 3 */ - DWORD Dr3; /* Breakpoint Register 4 */ - DWORD Dr4; /* Breakpoint Register 5 */ - DWORD Dr5; /* Breakpoint Register 6 */ - DWORD Dr6; /* Debug Status Register */ - DWORD Dr7; /* Debug Control Register */ +{ + /* Floating point registers returned when CONTEXT_FLOATING_POINT is set */ + double Fpr0; + double Fpr1; + double Fpr2; + double Fpr3; + double Fpr4; + double Fpr5; + double Fpr6; + double Fpr7; + double Fpr8; + double Fpr9; + double Fpr10; + double Fpr11; + double Fpr12; + double Fpr13; + double Fpr14; + double Fpr15; + double Fpr16; + double Fpr17; + double Fpr18; + double Fpr19; + double Fpr20; + double Fpr21; + double Fpr22; + double Fpr23; + double Fpr24; + double Fpr25; + double Fpr26; + double Fpr27; + double Fpr28; + double Fpr29; + double Fpr30; + double Fpr31; + double Fpscr; + + /* Integer registers returned when CONTEXT_INTEGER is set. */ + DWORD Gpr0; + DWORD Gpr1; + DWORD Gpr2; + DWORD Gpr3; + DWORD Gpr4; + DWORD Gpr5; + DWORD Gpr6; + DWORD Gpr7; + DWORD Gpr8; + DWORD Gpr9; + DWORD Gpr10; + DWORD Gpr11; + DWORD Gpr12; + DWORD Gpr13; + DWORD Gpr14; + DWORD Gpr15; + DWORD Gpr16; + DWORD Gpr17; + DWORD Gpr18; + DWORD Gpr19; + DWORD Gpr20; + DWORD Gpr21; + DWORD Gpr22; + DWORD Gpr23; + DWORD Gpr24; + DWORD Gpr25; + DWORD Gpr26; + DWORD Gpr27; + DWORD Gpr28; + DWORD Gpr29; + DWORD Gpr30; + DWORD Gpr31; + + DWORD Cr; /* Condition register */ + DWORD Xer; /* Fixed point exception register */ + + /* The following are set when CONTEXT_CONTROL is set. */ + DWORD Msr; /* Machine status register */ + DWORD Iar; /* Instruction address register */ + DWORD Lr; /* Link register */ + DWORD Ctr; /* Control register */ + + /* Control which context values are returned */ + DWORD ContextFlags; + DWORD Fill[3]; + + /* Registers returned if CONTEXT_DEBUG_REGISTERS is set. */ + DWORD Dr0; /* Breakpoint Register 1 */ + DWORD Dr1; /* Breakpoint Register 2 */ + DWORD Dr2; /* Breakpoint Register 3 */ + DWORD Dr3; /* Breakpoint Register 4 */ + DWORD Dr4; /* Breakpoint Register 5 */ + DWORD Dr5; /* Breakpoint Register 6 */ + DWORD Dr6; /* Debug Status Register */ + DWORD Dr7; /* Debug Control Register */ } CONTEXT_PPC, *PCONTEXT_PPC, *LPCONTEXT_PPC; +typedef struct value_ent +{ + LPWSTR ve_valuename; + DWORD ve_valuelen; + DWORD ve_valueptr; + DWORD ve_type; +} WVALENT, *PWVALENT; + +//#include "except.h" + +#ifndef __USE_W32API + +typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + #ifdef __i386__ typedef CONTEXT_X86 CONTEXT; @@ -379,40 +433,16 @@ typedef LPCONTEXT_PPC LPCONTEXT; #endif -typedef HANDLE *PHANDLE; - -typedef struct value_ent { - LPWSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} WVALENT, *PWVALENT; - - -typedef const void *LPCVOID; -typedef BYTE *LPBYTE, *PBYTE; - -typedef BOOL *PBOOL; - -typedef DWORD LCID; -typedef DWORD *PLCID; - -typedef const char *LPCSTR; - -typedef char *LPSTR; - -typedef const unsigned short *LPCWSTR; - -typedef unsigned short RTL_ATOM; -typedef unsigned short *PRTL_ATOM; typedef WORD ATOM; -typedef struct _COORD { +typedef struct _COORD +{ SHORT X; SHORT Y; } COORD; -typedef struct _SMALL_RECT { +typedef struct _SMALL_RECT +{ SHORT Left; SHORT Top; SHORT Right; @@ -420,13 +450,30 @@ typedef struct _SMALL_RECT { } SMALL_RECT, *PSMALL_RECT; +#ifdef __GNUC__ typedef VOID STDCALL (*PTIMERAPCROUTINE)( LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue ); +#else +typedef VOID +(STDCALL *PTIMERAPCROUTINE)( + LPVOID lpArgToCompletionRoutine, + DWORD dwTimerLowValue, + DWORD dwTimerHighValue + ); +#endif /*__GNUC__*/ #include "except.h" +#else /* __USE_W32API */ + +typedef LPTHREAD_START_ROUTINE PTHREAD_START_ROUTINE; + +#include + +#endif /* __USE_W32API */ + #endif /* __INCLUDE_TYPES_H */ diff --git a/include/ddk/zw.h b/include/ntos/zw.h old mode 100644 new mode 100755 similarity index 97% rename from include/ddk/zw.h rename to include/ntos/zw.h index e1c2ad5..0799a2b --- a/include/ddk/zw.h +++ b/include/ntos/zw.h @@ -18,121 +18,43 @@ #define __DDK_ZW_H #include +#include #include -//#define LCID ULONG -//#define SECURITY_INFORMATION ULONG -//typedef ULONG SECURITY_INFORMATION; - - -/* - * FUNCTION: Checks a clients access rights to a object - * ARGUMENTS: - * SecurityDescriptor = Security information against which the access is checked - * ClientToken = Represents a client - * DesiredAcces = - * GenericMapping = - * PrivilegeSet = - * ReturnLength = Bytes written - * GrantedAccess = - * AccessStatus = Indicates if the ClientToken allows the requested access - * REMARKS: The arguments map to the win32 AccessCheck - * RETURNS: Status - */ - -NTSTATUS -STDCALL -NtAccessCheck( - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN HANDLE ClientToken, - IN ACCESS_MASK DesiredAcces, - IN PGENERIC_MAPPING GenericMapping, - OUT PPRIVILEGE_SET PrivilegeSet, - OUT PULONG ReturnLength, - OUT PULONG GrantedAccess, - OUT PBOOLEAN AccessStatus - ); - -NTSTATUS -STDCALL -ZwAccessCheck( - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN HANDLE ClientToken, - IN ACCESS_MASK DesiredAcces, - IN PGENERIC_MAPPING GenericMapping, - OUT PPRIVILEGE_SET PrivilegeSet, - OUT PULONG ReturnLength, - OUT PULONG GrantedAccess, - OUT PBOOLEAN AccessStatus - ); +#ifndef _RTLGETPROCESSHEAP_DEFINED_ +#define _RTLGETPROCESSHEAP_DEFINED_ +#define RtlGetProcessHeap() (NtCurrentPeb()->ProcessHeap) +#endif -/* - * FUNCTION: Checks a clients access rights to a object and issues a audit a alarm. ( it logs the access ) - * ARGUMENTS: - * SubsystemName = Specifies the name of the subsystem, can be "WIN32" or "DEBUG" - * ObjectHandle = - * ObjectAttributes = - * DesiredAcces = - * GenericMapping = - * ObjectCreation = - * GrantedAccess = - * AccessStatus = - * GenerateOnClose = - * REMARKS: The arguments map to the win32 AccessCheck - * RETURNS: Status - */ +// semaphore information -NTSTATUS -STDCALL -NtAccessCheckAndAuditAlarm( - IN PUNICODE_STRING SubsystemName, - IN PHANDLE ObjectHandle, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ACCESS_MASK DesiredAccess, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PULONG GrantedAccess, - OUT PBOOLEAN AccessStatus, - OUT PBOOLEAN GenerateOnClose - ); +typedef enum _SEMAPHORE_INFORMATION_CLASS +{ + SemaphoreBasicInformation = 0 +} SEMAPHORE_INFORMATION_CLASS; -NTSTATUS -STDCALL -ZwAccessCheckAndAuditAlarm( - IN PUNICODE_STRING SubsystemName, - IN PHANDLE ObjectHandle, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ACCESS_MASK DesiredAccess, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PULONG GrantedAccess, - OUT PBOOLEAN AccessStatus, - OUT PBOOLEAN GenerateOnClose - ); +typedef struct _SEMAPHORE_BASIC_INFORMATION +{ + LONG CurrentCount; + LONG MaximumCount; +} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION; -/* - * FUNCTION: Adds an atom to the global atom table - * ARGUMENTS: - * AtomString = The string to add to the atom table. - * Atom (OUT) = Caller supplies storage for the resulting atom. - * REMARKS: The arguments map to the win32 add GlobalAddAtom. - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtAddAtom( - IN PWSTR AtomName, - IN OUT PRTL_ATOM Atom - ); +// event information +typedef enum _EVENT_INFORMATION_CLASS +{ + EventBasicInformation = 0 +} EVENT_INFORMATION_CLASS; -NTSTATUS -STDCALL -ZwAddAtom( - IN PWSTR AtomName, - IN OUT PRTL_ATOM Atom - ); +typedef struct _EVENT_BASIC_INFORMATION +{ + EVENT_TYPE EventType; + LONG EventState; +} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION; +//#define LCID ULONG +//#define SECURITY_INFORMATION ULONG +//typedef ULONG SECURITY_INFORMATION; /* * FUNCTION: Adjusts the groups in an access token @@ -271,23 +193,6 @@ ZwAllocateLocallyUniqueId( OUT PLUID Luid ); -NTSTATUS -STDCALL -NtAllocateUuids( - PULARGE_INTEGER Time, - PULONG Range, - PULONG Sequence - ); - -NTSTATUS -STDCALL -ZwAllocateUuids( - PULARGE_INTEGER Time, - PULONG Range, - PULONG Sequence - ); - - /* * FUNCTION: Allocates a block of virtual memory in the process address space * ARGUMENTS: @@ -368,28 +273,7 @@ ZwCancelIoFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock ); -/* - * FUNCTION: Cancels a timer - * ARGUMENTS: - * TimerHandle = Handle to the timer - * CurrentState = Specifies the state of the timer when cancelled. - * REMARKS: - * The arguments to this function map to the function CancelWaitableTimer. - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtCancelTimer( - IN HANDLE TimerHandle, - OUT PBOOLEAN CurrentState OPTIONAL - ); -NTSTATUS -STDCALL -ZwCancelTimer( - IN HANDLE TimerHandle, - OUT ULONG ElapsedTime - ); /* * FUNCTION: Sets the status of the event back to non-signaled * ARGUMENTS: @@ -460,28 +344,6 @@ ZwCloseObjectAuditAlarm( ); /* - * FUNCTION: Continues a thread with the specified context - * ARGUMENTS: - * Context = Specifies the processor context - * IrqLevel = Specifies the Interupt Request Level to continue with. Can - * be PASSIVE_LEVEL or APC_LEVEL - * REMARKS - * NtContinue can be used to continue after an exception or apc. - * RETURNS: Status - */ -//FIXME This function might need another parameter - -NTSTATUS -STDCALL -NtContinue( - IN PCONTEXT Context, - IN BOOLEAN TestAlert - ); - -NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel); - - -/* * FUNCTION: Creates a directory object * ARGUMENTS: * DirectoryHandle (OUT) = Caller supplied storage for the resulting handle @@ -652,6 +514,53 @@ ZwCreateIoCompletion( /* + * FUNCTION: Creates a registry key + * ARGUMENTS: + * KeyHandle (OUT) = Caller supplied storage for the resulting handle + * DesiredAccess = Specifies the allowed or desired access to the key + * It can have a combination of the following values: + * KEY_READ | KEY_WRITE | KEY_EXECUTE | KEY_ALL_ACCESS + * or + * KEY_QUERY_VALUE The values of the key can be queried. + * KEY_SET_VALUE The values of the key can be modified. + * KEY_CREATE_SUB_KEYS The key may contain subkeys. + * KEY_ENUMERATE_SUB_KEYS Subkeys can be queried. + * KEY_NOTIFY + * KEY_CREATE_LINK A symbolic link to the key can be created. + * ObjectAttributes = The name of the key may be specified directly in the name field + * of object attributes or relative to a key in rootdirectory. + * TitleIndex = Might specify the position in the sequential order of subkeys. + * Class = Specifies the kind of data, for example REG_SZ for string data. [ ??? ] + * CreateOptions = Specifies additional options with which the key is created + * REG_OPTION_VOLATILE The key is not preserved across boots. + * REG_OPTION_NON_VOLATILE The key is preserved accross boots. + * REG_OPTION_CREATE_LINK The key is a symbolic link to another key. + * REG_OPTION_BACKUP_RESTORE Key is being opened or created for backup/restore operations. + * Disposition = Indicates if the call to NtCreateKey resulted in the creation of a key it + * can have the following values: REG_CREATED_NEW_KEY | REG_OPENED_EXISTING_KEY + * RETURNS: + * Status + */ + +NTSTATUS STDCALL +NtCreateKey(OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class OPTIONAL, + IN ULONG CreateOptions, + IN PULONG Disposition OPTIONAL); + +NTSTATUS STDCALL +ZwCreateKey(OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class OPTIONAL, + IN ULONG CreateOptions, + IN PULONG Disposition OPTIONAL); + +/* * FUNCTION: Creates a mail slot file * ARGUMENTS: * MailSlotFileHandle (OUT) = Caller supplied storage for the resulting handle @@ -724,34 +633,6 @@ ZwCreateMutant( IN BOOLEAN InitialOwner ); - -/* - * FUNCTION: Creates a paging file. - * ARGUMENTS: - * FileName = Name of the pagefile - * InitialSize = Specifies the initial size in bytes - * MaximumSize = Specifies the maximum size in bytes - * Reserved = Reserved for future use - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtCreatePagingFile( - IN PUNICODE_STRING FileName, - IN PLARGE_INTEGER InitialSize, - IN PLARGE_INTEGER MaxiumSize, - IN ULONG Reserved - ); - -NTSTATUS -STDCALL -ZwCreatePagingFile( - IN PUNICODE_STRING FileName, - IN PLARGE_INTEGER InitialSize, - IN PLARGE_INTEGER MaxiumSize, - IN ULONG Reserved - ); - /* * FUNCTION: Creates a process. * ARGUMENTS: @@ -795,50 +676,6 @@ ZwCreateProcess( ); /* - * FUNCTION: Creates a profile - * ARGUMENTS: - * ProfileHandle (OUT) = Caller supplied storage for the resulting handle - * ObjectAttribute = Initialized attributes for the object - * ImageBase = Start address of executable image - * ImageSize = Size of the image - * Granularity = Bucket size - * Buffer = Caller supplies buffer for profiling info - * ProfilingSize = Buffer size - * ClockSource = Specify 0 / FALSE ?? - * ProcessorMask = A value of -1 indicates disables per processor profiling, - otherwise bit set for the processor to profile. - * REMARKS: - * This function maps to the win32 CreateProcess. - * RETURNS: Status - */ - -NTSTATUS -STDCALL -NtCreateProfile(OUT PHANDLE ProfileHandle, - IN HANDLE ProcessHandle, - IN PVOID ImageBase, - IN ULONG ImageSize, - IN ULONG Granularity, - OUT PULONG Buffer, - IN ULONG ProfilingSize, - IN KPROFILE_SOURCE Source, - IN ULONG ProcessorMask); - -NTSTATUS -STDCALL -ZwCreateProfile( - OUT PHANDLE ProfileHandle, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG ImageBase, - IN ULONG ImageSize, - IN ULONG Granularity, - OUT PVOID Buffer, - IN ULONG ProfilingSize, - IN ULONG ClockSource, - IN ULONG ProcessorMask - ); - -/* * FUNCTION: Creates a section object. * ARGUMENTS: * SectionHandle (OUT) = Caller supplied storage for the resulting handle @@ -939,48 +776,7 @@ ZwCreateSymbolicLinkObject( ); /* - * FUNCTION: Creates a user mode thread - * ARGUMENTS: - * ThreadHandle (OUT) = Caller supplied storage for the resulting handle - * DesiredAccess = Specifies the allowed or desired access to the thread. - * ObjectAttributes = Initialized attributes for the object. - * ProcessHandle = Handle to the threads parent process. - * ClientId (OUT) = Caller supplies storage for returned process id and thread id. - * ThreadContext = Initial processor context for the thread. - * InitialTeb = Initial user mode stack context for the thread. - * CreateSuspended = Specifies if the thread is ready for scheduling - * REMARKS: - * This function maps to the win32 function CreateThread. - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtCreateThread( - OUT PHANDLE ThreadHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN HANDLE ProcessHandle, - OUT PCLIENT_ID ClientId, - IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, - IN BOOLEAN CreateSuspended - ); - -NTSTATUS -STDCALL -ZwCreateThread( - OUT PHANDLE ThreadHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN HANDLE ProcessHandle, - OUT PCLIENT_ID ClientId, - IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, - IN BOOLEAN CreateSuspended - ); - -/* - * FUNCTION: Creates a waitable timer. + * FUNCTION: Creates a waitable timer. * ARGUMENTS: * TimerHandle (OUT) = Caller supplied storage for the resulting handle * DesiredAccess = Specifies the allowed or desired access to the timer. @@ -1079,23 +875,6 @@ NtCurrentTeb(VOID #endif /* - * FUNCTION: Delays the execution of the calling thread. - * ARGUMENTS: - * Alertable = If TRUE the thread is alertable during is wait period - * Interval = Specifies the interval to wait. - * RETURNS: Status - */ -NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable, IN TIME* Interval); - -NTSTATUS -STDCALL -ZwDelayExecution( - IN BOOLEAN Alertable, - IN TIME *Interval - ); - - -/* * FUNCTION: Deletes an atom from the global atom table * ARGUMENTS: * Atom = Identifies the atom to delete @@ -1268,71 +1047,6 @@ ZwDisplayString( ); /* - * FUNCTION: Copies a handle from one process space to another - * ARGUMENTS: - * SourceProcessHandle = The source process owning the handle. The source process should have opened - * the SourceHandle with PROCESS_DUP_HANDLE access. - * SourceHandle = The handle to the object. - * TargetProcessHandle = The destination process owning the handle - * TargetHandle (OUT) = Caller should supply storage for the duplicated handle. - * DesiredAccess = The desired access to the handle. - * InheritHandle = Indicates wheter the new handle will be inheritable or not. - * Options = Specifies special actions upon duplicating the handle. Can be - * one of the values DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS. - * DUPLICATE_CLOSE_SOURCE specifies that the source handle should be - * closed after duplicating. DUPLICATE_SAME_ACCESS specifies to ignore - * the DesiredAccess paramter and just grant the same access to the new - * handle. - * RETURNS: Status - * REMARKS: This function maps to the win32 DuplicateHandle. - */ - -NTSTATUS -STDCALL -NtDuplicateObject( - IN HANDLE SourceProcessHandle, - IN HANDLE SourceHandle, - IN HANDLE TargetProcessHandle, - OUT PHANDLE TargetHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN InheritHandle, - IN ULONG Options - ); - -NTSTATUS -STDCALL -ZwDuplicateObject( - IN HANDLE SourceProcessHandle, - IN PHANDLE SourceHandle, - IN HANDLE TargetProcessHandle, - OUT PHANDLE TargetHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN InheritHandle, - IN ULONG Options - ); - -NTSTATUS -STDCALL -NtDuplicateToken( - IN HANDLE ExistingToken, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, - IN TOKEN_TYPE TokenType, - OUT PHANDLE NewToken - ); - -NTSTATUS -STDCALL -ZwDuplicateToken( - IN HANDLE ExistingToken, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, - IN TOKEN_TYPE TokenType, - OUT PHANDLE NewToken - ); -/* * FUNCTION: Returns information about the subkeys of an open key * ARGUMENTS: * KeyHandle = Handle of the key whose subkeys are to enumerated @@ -1404,48 +1118,6 @@ ZwEnumerateValueKey( IN ULONG Length, OUT PULONG ResultLength ); -/* - * FUNCTION: Extends a section - * ARGUMENTS: - * SectionHandle = Handle to the section - * NewMaximumSize = Adjusted size - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtExtendSection( - IN HANDLE SectionHandle, - IN ULONG NewMaximumSize - ); -NTSTATUS -STDCALL -ZwExtendSection( - IN HANDLE SectionHandle, - IN ULONG NewMaximumSize - ); - -/* - * FUNCTION: Finds a atom - * ARGUMENTS: - * AtomName = Name to search for. - * Atom = Caller supplies storage for the resulting atom - * RETURNS: Status - * REMARKS: - * This funciton maps to the win32 GlobalFindAtom - */ -NTSTATUS -STDCALL -NtFindAtom( - IN PWSTR AtomName, - OUT PRTL_ATOM Atom OPTIONAL - ); - -NTSTATUS -STDCALL -ZwFindAtom( - IN PWSTR AtomName, - OUT PRTL_ATOM Atom OPTIONAL - ); /* * FUNCTION: Flushes chached file data to disk @@ -1471,30 +1143,7 @@ ZwFlushBuffersFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock ); -/* - * FUNCTION: Flushes a the processors instruction cache - * ARGUMENTS: - * ProcessHandle = Points to the process owning the cache - * BaseAddress = // might this be a image address ???? - * NumberOfBytesToFlush = - * RETURNS: Status - * REMARKS: - * This funciton is used by debuggers - */ -NTSTATUS -STDCALL -NtFlushInstructionCache( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN UINT NumberOfBytesToFlush - ); -NTSTATUS -STDCALL -ZwFlushInstructionCache( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN UINT NumberOfBytesToFlush - ); + /* * FUNCTION: Flushes a registry key to disk * ARGUMENTS: @@ -1514,34 +1163,6 @@ STDCALL ZwFlushKey( IN HANDLE KeyHandle ); - -/* - * FUNCTION: Flushes virtual memory to file - * ARGUMENTS: - * ProcessHandle = Points to the process that allocated the virtual memory - * BaseAddress = Points to the memory address - * NumberOfBytesToFlush = Limits the range to flush, - * NumberOfBytesFlushed = Actual number of bytes flushed - * RETURNS: Status - * REMARKS: - * Check return status on STATUS_NOT_MAPPED_DATA - */ -NTSTATUS -STDCALL -NtFlushVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToFlush, - OUT PULONG NumberOfBytesFlushed OPTIONAL - ); -NTSTATUS -STDCALL -ZwFlushVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToFlush, - OUT PULONG NumberOfBytesFlushed OPTIONAL - ); /* * FUNCTION: Flushes the dirty pages to file @@ -1645,23 +1266,6 @@ ZwGetContextThread( IN HANDLE ThreadHandle, OUT PCONTEXT Context ); -/* - * FUNCTION: Retrieves the uptime of the system - * ARGUMENTS: - * UpTime = Number of clock ticks since boot. - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtGetTickCount( - PULONG UpTime - ); - -NTSTATUS -STDCALL -ZwGetTickCount( - PULONG UpTime - ); /* * FUNCTION: Sets a thread to impersonate another @@ -1724,67 +1328,20 @@ ZwLoadDriver( ); /* - * FUNCTION: Loads a registry key. - * ARGUMENTS: - * KeyHandle = Handle to the registry key - * ObjectAttributes = ??? - * REMARK: - * This procedure maps to the win32 procedure RegLoadKey - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtLoadKey( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes - ); -NTSTATUS -STDCALL -ZwLoadKey( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes - ); - -/* - * FUNCTION: Loads a registry key. - * ARGUMENTS: - * KeyHandle = Handle to the registry key - * ObjectAttributes = ??? - * Unknown3 = ??? - * REMARK: - * This procedure maps to the win32 procedure RegLoadKey - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtLoadKey2 ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG Unknown3 - ); -NTSTATUS -STDCALL -ZwLoadKey2 ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG Unknown3 - ); - -/* - * FUNCTION: Locks a range of bytes in a file. - * ARGUMENTS: - * FileHandle = Handle to the file - * Event = Should be null if apc is specified. - * ApcRoutine = Asynchroneous Procedure Callback - * ApcContext = Argument to the callback - * IoStatusBlock (OUT) = Caller should supply storage for a structure containing - * the completion status and information about the requested lock operation. - * ByteOffset = Offset - * Length = Number of bytes to lock. - * Key = Special value to give other threads the possibility to unlock the file - by supplying the key in a call to NtUnlockFile. - * FailImmediatedly = If false the request will block untill the lock is obtained. - * ExclusiveLock = Specifies whether a exclusive or a shared lock is obtained. + * FUNCTION: Locks a range of bytes in a file. + * ARGUMENTS: + * FileHandle = Handle to the file + * Event = Should be null if apc is specified. + * ApcRoutine = Asynchroneous Procedure Callback + * ApcContext = Argument to the callback + * IoStatusBlock (OUT) = Caller should supply storage for a structure containing + * the completion status and information about the requested lock operation. + * ByteOffset = Offset + * Length = Number of bytes to lock. + * Key = Special value to give other threads the possibility to unlock the file + by supplying the key in a call to NtUnlockFile. + * FailImmediatedly = If false the request will block untill the lock is obtained. + * ExclusiveLock = Specifies whether a exclusive or a shared lock is obtained. * REMARK: This procedure maps to the win32 procedure LockFileEx. STATUS_PENDING is returned if the lock could not be obtained immediately, the device queue is busy and the IRP is queued. @@ -1821,33 +1378,7 @@ ZwLockFile( IN BOOLEAN FailImmediatedly, IN BOOLEAN ExclusiveLock ); -/* - * FUNCTION: Locks a range of virtual memory. - * ARGUMENTS: - * ProcessHandle = Handle to the process - * BaseAddress = Lower boundary of the range of bytes to lock. - * NumberOfBytesLock = Offset to the upper boundary. - * NumberOfBytesLocked (OUT) = Number of bytes actually locked. - * REMARK: - This procedure maps to the win32 procedure VirtualLock - * RETURNS: Status [STATUS_SUCCESS | STATUS_WAS_LOCKED ] - */ -NTSTATUS -STDCALL -NtLockVirtualMemory( - HANDLE ProcessHandle, - PVOID BaseAddress, - ULONG NumberOfBytesToLock, - PULONG NumberOfBytesLocked - ); -NTSTATUS -STDCALL -ZwLockVirtualMemory( - HANDLE ProcessHandle, - PVOID BaseAddress, - ULONG NumberOfBytesToLock, - PULONG NumberOfBytesLocked - ); + /* * FUNCTION: Makes temporary object that will be removed at next boot. * ARGUMENTS: @@ -2209,35 +1740,6 @@ ZwOpenMutant( IN POBJECT_ATTRIBUTES ObjectAttributes ); -NTSTATUS -STDCALL -NtOpenObjectAuditAlarm( - IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN HANDLE ClientToken, - IN ULONG DesiredAccess, - IN ULONG GrantedAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN ObjectCreation, - IN BOOLEAN AccessGranted, - OUT PBOOLEAN GenerateOnClose - ); - -NTSTATUS -STDCALL -ZwOpenObjectAuditAlarm( - IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN HANDLE ClientToken, - IN ULONG DesiredAccess, - IN ULONG GrantedAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN ObjectCreation, - IN BOOLEAN AccessGranted, - OUT PBOOLEAN GenerateOnClose - ); /* * FUNCTION: Opens an existing process * ARGUMENTS: @@ -2506,41 +2008,6 @@ NtProcessStartup( IN PPEB Peb ); -/* - * FUNCTION: Set the access protection of a range of virtual memory - * ARGUMENTS: - * ProcessHandle = Handle to process owning the virtual address space - * BaseAddress = Start address - * NumberOfBytesToProtect = Delimits the range of virtual memory - * for which the new access protection holds - * NewAccessProtection = The new access proctection for the pages - * OldAccessProtection = Caller should supply storage for the old - * access protection - * - * REMARKS: - * The function maps to the win32 VirtualProtectEx - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtProtectVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToProtect, - IN ULONG NewAccessProtection, - OUT PULONG OldAccessProtection - ); - -NTSTATUS -STDCALL -ZwProtectVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToProtect, - IN ULONG NewAccessProtection, - OUT PULONG OldAccessProtection - ); - /* * FUNCTION: Signals an event and resets it afterwards. @@ -2661,42 +2128,6 @@ ZwQueryDirectoryFile( ); /* - * FUNCTION: Query information about the content of a directory object - * ARGUMENTS: - DirObjInformation = Buffer must be large enough to hold the name strings too - GetNextIndex = If TRUE :return the index of the next object in this directory in ObjectIndex - If FALSE: return the number of objects in this directory in ObjectIndex - IgnoreInputIndex= If TRUE: ignore input value of ObjectIndex always start at index 0 - If FALSE use input value of ObjectIndex - ObjectIndex = zero based index of object in the directory depends on GetNextIndex and IgnoreInputIndex - DataWritten = Actual size of the ObjectIndex ??? - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtQueryDirectoryObject( - IN HANDLE DirObjHandle, - OUT POBJDIR_INFORMATION DirObjInformation, - IN ULONG BufferLength, - IN BOOLEAN GetNextIndex, - IN BOOLEAN IgnoreInputIndex, - IN OUT PULONG ObjectIndex, - OUT PULONG DataWritten OPTIONAL - ); - -NTSTATUS -STDCALL -ZwQueryDirectoryObject( - IN HANDLE DirObjHandle, - OUT POBJDIR_INFORMATION DirObjInformation, - IN ULONG BufferLength, - IN BOOLEAN GetNextIndex, - IN BOOLEAN IgnoreInputIndex, - IN OUT PULONG ObjectIndex, - OUT PULONG DataWritten OPTIONAL - ); - -/* * FUNCTION: Queries the extended attributes of a file * ARGUMENTS: * FileHandle = Handle to the event @@ -2779,27 +2210,6 @@ NTSTATUS STDCALL ZwQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation); -NTSTATUS -STDCALL -NtQueryInformationAtom( - IN RTL_ATOM Atom, - IN ATOM_INFORMATION_CLASS AtomInformationClass, - OUT PVOID AtomInformation, - IN ULONG AtomInformationLength, - OUT PULONG ReturnLength OPTIONAL - ); - -NTSTATUS -STDCALL -NtQueryInformationAtom( - IN RTL_ATOM Atom, - IN ATOM_INFORMATION_CLASS AtomInformationClass, - OUT PVOID AtomInformation, - IN ULONG AtomInformationLength, - OUT PULONG ReturnLength OPTIONAL - ); - - /* * FUNCTION: Queries the information of a file object. * ARGUMENTS: @@ -2877,95 +2287,33 @@ ZwQueryInformationFile( FILE_INFORMATION_CLASS FileInformationClass ); + /* - * FUNCTION: Queries the information of a process object. + * FUNCTION: Queries the information of a thread object. * ARGUMENTS: - * ProcessHandle = Handle to the process object - * ProcessInformation = Index to a certain information structure + * ThreadHandle = Handle to the thread object + * ThreadInformationClass = Index to a certain information structure - ProcessBasicInformation PROCESS_BASIC_INFORMATION - ProcessQuotaLimits QUOTA_LIMITS - ProcessIoCounters IO_COUNTERS - ProcessVmCounters VM_COUNTERS - ProcessTimes KERNEL_USER_TIMES - ProcessBasePriority KPRIORITY - ProcessRaisePriority KPRIORITY - ProcessDebugPort HANDLE - ProcessExceptionPort HANDLE - ProcessAccessToken PROCESS_ACCESS_TOKEN - ProcessLdtInformation LDT_ENTRY ?? - ProcessLdtSize ULONG - ProcessDefaultHardErrorMode ULONG - ProcessIoPortHandlers // kernel mode only - ProcessPooledUsageAndLimits POOLED_USAGE_AND_LIMITS - ProcessWorkingSetWatch PROCESS_WS_WATCH_INFORMATION - ProcessUserModeIOPL (I/O Privilege Level) - ProcessEnableAlignmentFaultFixup BOOLEAN - ProcessPriorityClass ULONG - ProcessWx86Information ULONG - ProcessHandleCount ULONG - ProcessAffinityMask ULONG - ProcessPooledQuotaLimits QUOTA_LIMITS - MaxProcessInfoClass + ThreadBasicInformation THREAD_BASIC_INFORMATION + ThreadTimes KERNEL_USER_TIMES + ThreadPriority KPRIORITY + ThreadBasePriority KPRIORITY + ThreadAffinityMask KAFFINITY + ThreadImpersonationToken + ThreadDescriptorTableEntry + ThreadEnableAlignmentFaultFixup + ThreadEventPair + ThreadQuerySetWin32StartAddress + ThreadZeroTlsCell + ThreadPerformanceCount + ThreadAmILastThread BOOLEAN + ThreadIdealProcessor ULONG + ThreadPriorityBoost ULONG + MaxThreadInfoClass + - * ProcessInformation = Caller supplies storage for the process information structure - * ProcessInformationLength = Size of the process information structure - * ReturnLength = Actual number of bytes written - - * REMARK: - * This procedure maps to the win32 GetProcessTimes, GetProcessVersion, - GetProcessWorkingSetSize, GetProcessPriorityBoost, GetProcessAffinityMask, GetPriorityClass, - GetProcessShutdownParameters functions. - * RETURNS: Status -*/ - -NTSTATUS -STDCALL -NtQueryInformationProcess( - IN HANDLE ProcessHandle, - IN CINT ProcessInformationClass, - OUT PVOID ProcessInformation, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength - ); - -NTSTATUS -STDCALL -ZwQueryInformationProcess( - IN HANDLE ProcessHandle, - IN CINT ProcessInformationClass, - OUT PVOID ProcessInformation, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength - ); - - -/* - * FUNCTION: Queries the information of a thread object. - * ARGUMENTS: - * ThreadHandle = Handle to the thread object - * ThreadInformationClass = Index to a certain information structure - - ThreadBasicInformation THREAD_BASIC_INFORMATION - ThreadTimes KERNEL_USER_TIMES - ThreadPriority KPRIORITY - ThreadBasePriority KPRIORITY - ThreadAffinityMask KAFFINITY - ThreadImpersonationToken - ThreadDescriptorTableEntry - ThreadEnableAlignmentFaultFixup - ThreadEventPair - ThreadQuerySetWin32StartAddress - ThreadZeroTlsCell - ThreadPerformanceCount - ThreadAmILastThread BOOLEAN - ThreadIdealProcessor ULONG - ThreadPriorityBoost ULONG - MaxThreadInfoClass - - - * ThreadInformation = Caller supplies torage for the thread information - * ThreadInformationLength = Size of the thread information structure + * ThreadInformation = Caller supplies torage for the thread information + * ThreadInformationLength = Size of the thread information structure * ReturnLength = Actual number of bytes written * REMARK: @@ -3006,29 +2354,6 @@ ZwQueryInformationToken( OUT PULONG ReturnLength ); -/* - * FUNCTION: Query the interval and the clocksource for profiling - * ARGUMENTS: - Interval = - ClockSource = - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtQueryIntervalProfile( - OUT PULONG Interval, - OUT KPROFILE_SOURCE ClockSource - ); - -NTSTATUS -STDCALL -ZwQueryIntervalProfile( - OUT PULONG Interval, - OUT KPROFILE_SOURCE ClockSource - ); - - - NTSTATUS STDCALL NtQueryIoCompletion( @@ -3129,41 +2454,6 @@ ZwQueryMutant( IN ULONG Length, OUT PULONG ResultLength ); -/* - * FUNCTION: Queries the information of a object. - * ARGUMENTS: - ObjectHandle = Handle to a object - ObjectInformationClass = Index to a certain information structure - - ObjectBasicInformation - ObjectTypeInformation OBJECT_TYPE_INFORMATION - ObjectNameInformation OBJECT_NAME_INFORMATION - ObjectDataInformation OBJECT_DATA_INFORMATION - - ObjectInformation = Caller supplies storage for resulting information - Length = Size of the supplied storage - ResultLength = Bytes written - */ - -NTSTATUS -STDCALL -NtQueryObject( - IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); - -NTSTATUS -STDCALL -ZwQueryObject( - IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); /* * FUNCTION: Queries the system ( high-resolution ) performance counter. @@ -3189,57 +2479,6 @@ ZwQueryPerformanceCounter( IN PLARGE_INTEGER Counter, IN PLARGE_INTEGER Frequency ); -/* - * FUNCTION: Queries the information of a section object. - * ARGUMENTS: - * SectionHandle = Handle to the section link object - * SectionInformationClass = Index to a certain information structure - * SectionInformation (OUT)= Caller supplies storage for resulting information - * Length = Size of the supplied storage - * ResultLength = Data written - * RETURNS: Status - * -*/ -NTSTATUS -STDCALL -NtQuerySection( - IN HANDLE SectionHandle, - IN CINT SectionInformationClass, - OUT PVOID SectionInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); - -NTSTATUS -STDCALL -ZwQuerySection( - IN HANDLE SectionHandle, - IN CINT SectionInformationClass, - OUT PVOID SectionInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); - -NTSTATUS -STDCALL -NtQuerySecurityObject( - IN HANDLE Object, - IN CINT SecurityObjectInformationClass, - OUT PVOID SecurityObjectInformation, - IN ULONG Length, - OUT PULONG ReturnLength - ); - -NTSTATUS -STDCALL -ZwQuerySecurityObject( - IN HANDLE Object, - IN CINT SecurityObjectInformationClass, - OUT PVOID SecurityObjectInformation, - IN ULONG Length, - OUT PULONG ReturnLength - ); - /* * FUNCTION: Queries the information of a semaphore. @@ -3362,26 +2601,6 @@ ZwQuerySystemInformation( ); /* - * FUNCTION: Retrieves the system time - * ARGUMENTS: - * CurrentTime (OUT) = Caller should supply storage for the resulting time. - * RETURNS: Status - * -*/ - -NTSTATUS -STDCALL -NtQuerySystemTime ( - OUT TIME *CurrentTime - ); - -NTSTATUS -STDCALL -ZwQuerySystemTime ( - OUT TIME *CurrentTime - ); - -/* * FUNCTION: Queries information about a timer * ARGUMENTS: * TimerHandle = Handle to the timer @@ -3477,46 +2696,6 @@ ZwQueryValueKey( OUT PULONG ResultLength ); - - - -/* - * FUNCTION: Queries the virtual memory information. - * ARGUMENTS: - ProcessHandle = Process owning the virtual address space - BaseAddress = Points to the page where the information is queried for. - * VirtualMemoryInformationClass = Index to a certain information structure - - MemoryBasicInformation MEMORY_BASIC_INFORMATION - - * VirtualMemoryInformation = caller supplies storage for the information structure - * Length = size of the structure - ResultLength = Data written - * RETURNS: Status - * -*/ - -NTSTATUS -STDCALL -NtQueryVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID Address, - IN IN CINT VirtualMemoryInformationClass, - OUT PVOID VirtualMemoryInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); -NTSTATUS -STDCALL -ZwQueryVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID Address, - IN IN CINT VirtualMemoryInformationClass, - OUT PVOID VirtualMemoryInformation, - IN ULONG Length, - OUT PULONG ResultLength - ); - /* * FUNCTION: Queries the volume information * ARGUMENTS: @@ -3621,41 +2800,6 @@ ZwRaiseException( ); /* - * FUNCTION: Raises a hard error (stops the system) - * ARGUMENTS: - * Status = Status code of the hard error - * Unknown2 = ?? - * Unknown3 = ?? - * Unknown4 = ?? - * Unknown5 = ?? - * Unknown6 = ?? - * RETURNS: Status - * - */ - -NTSTATUS -STDCALL -NtRaiseHardError( - IN NTSTATUS Status, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4, - ULONG Unknown5, - ULONG Unknown6 - ); - -NTSTATUS -STDCALL -ZwRaiseHardError( - IN NTSTATUS Status, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4, - ULONG Unknown5, - ULONG Unknown6 - ); - -/* * FUNCTION: Read a file * ARGUMENTS: * FileHandle = Handle of a file to read @@ -4157,112 +3301,6 @@ ZwSetInformationFile( IN FILE_INFORMATION_CLASS FileInformationClass ); - - -/* - * FUNCTION: Sets the information of a registry key. - * ARGUMENTS: - * KeyHandle = Handle to the registry key - * KeyInformationClass = Index to the a certain information structure. - Can be one of the following values: - - * KeyWriteTimeInformation KEY_WRITE_TIME_INFORMATION - - KeyInformation = Storage for the new information - * KeyInformationLength = Size of the information strucure - * RETURNS: Status - */ - -NTSTATUS -STDCALL -NtSetInformationKey( - IN HANDLE KeyHandle, - IN CINT KeyInformationClass, - IN PVOID KeyInformation, - IN ULONG KeyInformationLength - ); - -NTSTATUS -STDCALL -ZwSetInformationKey( - IN HANDLE KeyHandle, - IN CINT KeyInformationClass, - IN PVOID KeyInformation, - IN ULONG KeyInformationLength - ); -/* - * FUNCTION: Changes a set of object specific parameters - * ARGUMENTS: - * ObjectHandle = - * ObjectInformationClass = Index to the set of parameters to change. - - - ObjectBasicInformation - ObjectTypeInformation OBJECT_TYPE_INFORMATION - ObjectAllInformation - ObjectDataInformation OBJECT_DATA_INFORMATION - ObjectNameInformation OBJECT_NAME_INFORMATION - - - * ObjectInformation = Caller supplies storage for parameters to set. - * Length = Size of the storage supplied - * RETURNS: Status -*/ -NTSTATUS -STDCALL -NtSetInformationObject( - IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - IN PVOID ObjectInformation, - IN ULONG Length - ); - -NTSTATUS -STDCALL -ZwSetInformationObject( - IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - IN PVOID ObjectInformation, - IN ULONG Length - ); - -/* - * FUNCTION: Changes a set of process specific parameters - * ARGUMENTS: - * ProcessHandle = Handle to the process - * ProcessInformationClass = Index to a information structure. - * - * ProcessBasicInformation PROCESS_BASIC_INFORMATION - * ProcessQuotaLimits QUOTA_LIMITS - * ProcessBasePriority KPRIORITY - * ProcessRaisePriority KPRIORITY - * ProcessDebugPort HANDLE - * ProcessExceptionPort HANDLE - * ProcessAccessToken PROCESS_ACCESS_TOKEN - * ProcessDefaultHardErrorMode ULONG - * ProcessPriorityClass ULONG - * ProcessAffinityMask KAFFINITY //?? - * - * ProcessInformation = Caller supplies storage for information to set. - * ProcessInformationLength = Size of the information structure - * RETURNS: Status -*/ -NTSTATUS -STDCALL -NtSetInformationProcess( - IN HANDLE ProcessHandle, - IN CINT ProcessInformationClass, - IN PVOID ProcessInformation, - IN ULONG ProcessInformationLength - ); -NTSTATUS -STDCALL -ZwSetInformationProcess( - IN HANDLE ProcessHandle, - IN CINT ProcessInformationClass, - IN PVOID ProcessInformation, - IN ULONG ProcessInformationLength - ); /* * FUNCTION: Changes a set of thread specific parameters * ARGUMENTS: @@ -4511,40 +3549,6 @@ ZwSetSystemTime( IN PLARGE_INTEGER SystemTime, IN PLARGE_INTEGER NewSystemTime OPTIONAL ); -/* - * FUNCTION: Sets the characteristics of a timer - * ARGUMENTS: - * TimerHandle = Handle to the timer - * DueTime = Time before the timer becomes signalled for the first time. - * TimerApcRoutine = Completion routine can be called on time completion - * TimerContext = Argument to the completion routine - * Resume = Specifies if the timer should repeated after completing one cycle - * Period = Cycle of the timer - * REMARKS: This routine maps to the win32 SetWaitableTimer. - * RETURNS: Status -*/ -NTSTATUS -STDCALL -NtSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMERAPCROUTINE TimerApcRoutine, - IN PVOID TimerContext, - IN BOOL WakeTimer, - IN ULONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL - ); -NTSTATUS -STDCALL -ZwSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMERAPCROUTINE TimerApcRoutine, - IN PVOID TimerContext, - IN BOOL WakeTimer, - IN ULONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL - ); /* * FUNCTION: Sets the frequency of the system timer @@ -4782,34 +3786,6 @@ ZwWriteVirtualMemory( ); /* - * FUNCTION: Unlocks a range of virtual memory. - * ARGUMENTS: - * ProcessHandle = Handle to the process - * BaseAddress = Lower boundary of the range of bytes to unlock. - * NumberOfBytesToUnlock = Offset to the upper boundary to unlock. - * NumberOfBytesUnlocked (OUT) = Number of bytes actually unlocked. - * REMARK: - This procedure maps to the win32 procedure VirtualUnlock - * RETURNS: Status [ STATUS_SUCCESS | STATUS_PAGE_WAS_ULOCKED ] - */ -NTSTATUS -STDCALL -NtUnlockVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToUnlock, - OUT PULONG NumberOfBytesUnlocked OPTIONAL - ); - -NTSTATUS -STDCALL -ZwUnlockVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToUnlock, - OUT PULONG NumberOfBytesUnlocked OPTIONAL - ); -/* * FUNCTION: Unmaps a piece of virtual memory backed by a file. * ARGUMENTS: * ProcessHandle = Handle to the process @@ -4861,38 +3837,6 @@ NtSignalAndWaitForSingleObject( ); /* - * FUNCTION: Waits for multiple objects to become signalled. - * ARGUMENTS: - * Count = The number of objects - * Object = The array of object handles - * WaitType = Can be one of the values UserMode or KernelMode - * Alertable = If true the wait is alertable. - * Time = The maximum wait time. - * REMARKS: - * This function maps to the win32 WaitForMultipleObjectEx. - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtWaitForMultipleObjects ( - IN ULONG Count, - IN HANDLE Object[], - IN CINT WaitType, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Time - ); - -NTSTATUS -STDCALL -ZwWaitForMultipleObjects ( - IN ULONG Count, - IN HANDLE Object[], - IN CINT WaitType, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Time - ); - -/* * FUNCTION: Waits for an object to become signalled. * ARGUMENTS: * Object = The object handle @@ -5173,35 +4117,6 @@ ZwYieldExecution( VOID ); - -/* - * --- Local Procedure Call Facility - * These prototypes are unknown as yet - * (stack sizes by Peter-Michael Hager) - */ - -/* --- REGISTRY --- */ - -/* - * FUNCTION: Unloads a registry key. - * ARGUMENTS: - * KeyHandle = Handle to the registry key - * REMARK: - * This procedure maps to the win32 procedure RegUnloadKey - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtUnloadKey( - HANDLE KeyHandle - ); -NTSTATUS -STDCALL -ZwUnloadKey( - HANDLE KeyHandle - ); - - /* --- PLUG AND PLAY --- */ NTSTATUS @@ -5298,11 +4213,1208 @@ NtSetLdtEntries ( PULONG Entries ); - NTSTATUS STDCALL NtQueryOleDirectoryFile ( VOID ); +/* + * FUNCTION: Checks a clients access rights to a object + * ARGUMENTS: + * SecurityDescriptor = Security information against which the access is checked + * ClientToken = Represents a client + * DesiredAcces = + * GenericMapping = + * PrivilegeSet = + * ReturnLength = Bytes written + * GrantedAccess = + * AccessStatus = Indicates if the ClientToken allows the requested access + * REMARKS: The arguments map to the win32 AccessCheck + * RETURNS: Status + */ + +NTSTATUS +STDCALL +NtAccessCheck( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN HANDLE ClientToken, + IN ACCESS_MASK DesiredAcces, + IN PGENERIC_MAPPING GenericMapping, + OUT PPRIVILEGE_SET PrivilegeSet, + OUT PULONG ReturnLength, + OUT PULONG GrantedAccess, + OUT PBOOLEAN AccessStatus + ); + +NTSTATUS +STDCALL +ZwAccessCheck( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN HANDLE ClientToken, + IN ACCESS_MASK DesiredAcces, + IN PGENERIC_MAPPING GenericMapping, + OUT PPRIVILEGE_SET PrivilegeSet, + OUT PULONG ReturnLength, + OUT PULONG GrantedAccess, + OUT PBOOLEAN AccessStatus + ); + +NTSTATUS +STDCALL +RtlOpenCurrentUser( + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE KeyHandle); + + +#ifndef __USE_W32API + +/* + * FUNCTION: Continues a thread with the specified context + * ARGUMENTS: + * Context = Specifies the processor context + * IrqLevel = Specifies the Interupt Request Level to continue with. Can + * be PASSIVE_LEVEL or APC_LEVEL + * REMARKS + * NtContinue can be used to continue after an exception or apc. + * RETURNS: Status + */ +//FIXME This function might need another parameter + +NTSTATUS +STDCALL +NtContinue( + IN PCONTEXT Context, + IN BOOLEAN TestAlert + ); + +NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel); + +/* + * FUNCTION: Retrieves the system time + * ARGUMENTS: + * CurrentTime (OUT) = Caller should supply storage for the resulting time. + * RETURNS: Status + * +*/ + +NTSTATUS +STDCALL +NtQuerySystemTime ( + OUT TIME *CurrentTime + ); + +NTSTATUS +STDCALL +ZwQuerySystemTime ( + OUT TIME *CurrentTime + ); + +/* + * FUNCTION: Loads a registry key. + * ARGUMENTS: + * KeyHandle = Handle to the registry key + * ObjectAttributes = ??? + * Unknown3 = ??? + * REMARK: + * This procedure maps to the win32 procedure RegLoadKey + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtLoadKey2 ( + PHANDLE KeyHandle, + POBJECT_ATTRIBUTES ObjectAttributes, + ULONG Unknown3 + ); +NTSTATUS +STDCALL +ZwLoadKey2 ( + PHANDLE KeyHandle, + POBJECT_ATTRIBUTES ObjectAttributes, + ULONG Unknown3 + ); + +/* + * FUNCTION: Copies a handle from one process space to another + * ARGUMENTS: + * SourceProcessHandle = The source process owning the handle. The source process should have opened + * the SourceHandle with PROCESS_DUP_HANDLE access. + * SourceHandle = The handle to the object. + * TargetProcessHandle = The destination process owning the handle + * TargetHandle (OUT) = Caller should supply storage for the duplicated handle. + * DesiredAccess = The desired access to the handle. + * InheritHandle = Indicates wheter the new handle will be inheritable or not. + * Options = Specifies special actions upon duplicating the handle. Can be + * one of the values DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS. + * DUPLICATE_CLOSE_SOURCE specifies that the source handle should be + * closed after duplicating. DUPLICATE_SAME_ACCESS specifies to ignore + * the DesiredAccess paramter and just grant the same access to the new + * handle. + * RETURNS: Status + * REMARKS: This function maps to the win32 DuplicateHandle. + */ + +NTSTATUS +STDCALL +NtDuplicateObject( + IN HANDLE SourceProcessHandle, + IN HANDLE SourceHandle, + IN HANDLE TargetProcessHandle, + OUT PHANDLE TargetHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN InheritHandle, + IN ULONG Options + ); + +NTSTATUS +STDCALL +ZwDuplicateObject( + IN HANDLE SourceProcessHandle, + IN PHANDLE SourceHandle, + IN HANDLE TargetProcessHandle, + OUT PHANDLE TargetHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN InheritHandle, + IN ULONG Options + ); + +/* + * FUNCTION: Checks a clients access rights to a object and issues a audit a alarm. ( it logs the access ) + * ARGUMENTS: + * SubsystemName = Specifies the name of the subsystem, can be "WIN32" or "DEBUG" + * ObjectHandle = + * ObjectAttributes = + * DesiredAcces = + * GenericMapping = + * ObjectCreation = + * GrantedAccess = + * AccessStatus = + * GenerateOnClose = + * REMARKS: The arguments map to the win32 AccessCheck + * RETURNS: Status + */ + +NTSTATUS +STDCALL +NtAccessCheckAndAuditAlarm( + IN PUNICODE_STRING SubsystemName, + IN PHANDLE ObjectHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN PGENERIC_MAPPING GenericMapping, + IN BOOLEAN ObjectCreation, + OUT PULONG GrantedAccess, + OUT PBOOLEAN AccessStatus, + OUT PBOOLEAN GenerateOnClose + ); + +NTSTATUS +STDCALL +ZwAccessCheckAndAuditAlarm( + IN PUNICODE_STRING SubsystemName, + IN PHANDLE ObjectHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN PGENERIC_MAPPING GenericMapping, + IN BOOLEAN ObjectCreation, + OUT PULONG GrantedAccess, + OUT PBOOLEAN AccessStatus, + OUT PBOOLEAN GenerateOnClose + ); + +/* + * FUNCTION: Adds an atom to the global atom table + * ARGUMENTS: + * AtomString = The string to add to the atom table. + * Atom (OUT) = Caller supplies storage for the resulting atom. + * REMARKS: The arguments map to the win32 add GlobalAddAtom. + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtAddAtom( + IN PWSTR AtomName, + IN OUT PRTL_ATOM Atom + ); + + +NTSTATUS +STDCALL +ZwAddAtom( + IN PWSTR AtomName, + IN OUT PRTL_ATOM Atom + ); + +NTSTATUS +STDCALL +NtAllocateUuids( + PULARGE_INTEGER Time, + PULONG Range, + PULONG Sequence + ); + +NTSTATUS +STDCALL +ZwAllocateUuids( + PULARGE_INTEGER Time, + PULONG Range, + PULONG Sequence + ); + +/* + * FUNCTION: Cancels a timer + * ARGUMENTS: + * TimerHandle = Handle to the timer + * CurrentState = Specifies the state of the timer when cancelled. + * REMARKS: + * The arguments to this function map to the function CancelWaitableTimer. + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtCancelTimer( + IN HANDLE TimerHandle, + OUT PBOOLEAN CurrentState OPTIONAL + ); + +NTSTATUS +STDCALL +ZwCancelTimer( + IN HANDLE TimerHandle, + OUT ULONG ElapsedTime + ); + +/* + * FUNCTION: Creates a paging file. + * ARGUMENTS: + * FileName = Name of the pagefile + * InitialSize = Specifies the initial size in bytes + * MaximumSize = Specifies the maximum size in bytes + * Reserved = Reserved for future use + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtCreatePagingFile( + IN PUNICODE_STRING FileName, + IN PLARGE_INTEGER InitialSize, + IN PLARGE_INTEGER MaxiumSize, + IN ULONG Reserved + ); + +NTSTATUS +STDCALL +ZwCreatePagingFile( + IN PUNICODE_STRING FileName, + IN PLARGE_INTEGER InitialSize, + IN PLARGE_INTEGER MaxiumSize, + IN ULONG Reserved + ); + +/* + * FUNCTION: Creates a user mode thread + * ARGUMENTS: + * ThreadHandle (OUT) = Caller supplied storage for the resulting handle + * DesiredAccess = Specifies the allowed or desired access to the thread. + * ObjectAttributes = Initialized attributes for the object. + * ProcessHandle = Handle to the threads parent process. + * ClientId (OUT) = Caller supplies storage for returned process id and thread id. + * ThreadContext = Initial processor context for the thread. + * InitialTeb = Initial user mode stack context for the thread. + * CreateSuspended = Specifies if the thread is ready for scheduling + * REMARKS: + * This function maps to the win32 function CreateThread. + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtCreateThread( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ProcessHandle, + OUT PCLIENT_ID ClientId, + IN PCONTEXT ThreadContext, + IN PINITIAL_TEB InitialTeb, + IN BOOLEAN CreateSuspended + ); + +NTSTATUS +STDCALL +ZwCreateThread( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ProcessHandle, + OUT PCLIENT_ID ClientId, + IN PCONTEXT ThreadContext, + IN PINITIAL_TEB InitialTeb, + IN BOOLEAN CreateSuspended + ); + +NTSTATUS +STDCALL +NtDuplicateToken( + IN HANDLE ExistingToken, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN TOKEN_TYPE TokenType, + OUT PHANDLE NewToken + ); + +NTSTATUS +STDCALL +ZwDuplicateToken( + IN HANDLE ExistingToken, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN TOKEN_TYPE TokenType, + OUT PHANDLE NewToken + ); + +/* + * FUNCTION: Finds a atom + * ARGUMENTS: + * AtomName = Name to search for. + * Atom = Caller supplies storage for the resulting atom + * RETURNS: Status + * REMARKS: + * This funciton maps to the win32 GlobalFindAtom + */ +NTSTATUS +STDCALL +NtFindAtom( + IN PWSTR AtomName, + OUT PRTL_ATOM Atom OPTIONAL + ); + +NTSTATUS +STDCALL +ZwFindAtom( + IN PWSTR AtomName, + OUT PRTL_ATOM Atom OPTIONAL + ); + +/* + * FUNCTION: Flushes a the processors instruction cache + * ARGUMENTS: + * ProcessHandle = Points to the process owning the cache + * BaseAddress = // might this be a image address ???? + * NumberOfBytesToFlush = + * RETURNS: Status + * REMARKS: + * This funciton is used by debuggers + */ +NTSTATUS +STDCALL +NtFlushInstructionCache( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN UINT NumberOfBytesToFlush + ); + +NTSTATUS +STDCALL +ZwFlushInstructionCache( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN UINT NumberOfBytesToFlush + ); + +/* + * FUNCTION: Flushes virtual memory to file + * ARGUMENTS: + * ProcessHandle = Points to the process that allocated the virtual memory + * BaseAddress = Points to the memory address + * NumberOfBytesToFlush = Limits the range to flush, + * NumberOfBytesFlushed = Actual number of bytes flushed + * RETURNS: Status + * REMARKS: + * Check return status on STATUS_NOT_MAPPED_DATA + */ +NTSTATUS +STDCALL +NtFlushVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToFlush, + OUT PULONG NumberOfBytesFlushed OPTIONAL + ); + +NTSTATUS +STDCALL +ZwFlushVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToFlush, + OUT PULONG NumberOfBytesFlushed OPTIONAL + ); + +/* + * FUNCTION: Retrieves the uptime of the system + * ARGUMENTS: + * UpTime = Number of clock ticks since boot. + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtGetTickCount( + PULONG UpTime + ); + +NTSTATUS +STDCALL +ZwGetTickCount( + PULONG UpTime + ); + +/* + * FUNCTION: Loads a registry key. + * ARGUMENTS: + * KeyHandle = Handle to the registry key + * ObjectAttributes = ??? + * REMARK: + * This procedure maps to the win32 procedure RegLoadKey + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtLoadKey( + PHANDLE KeyHandle, + POBJECT_ATTRIBUTES ObjectAttributes + ); + +NTSTATUS +STDCALL +ZwLoadKey( + PHANDLE KeyHandle, + POBJECT_ATTRIBUTES ObjectAttributes + ); + +/* + * FUNCTION: Locks a range of virtual memory. + * ARGUMENTS: + * ProcessHandle = Handle to the process + * BaseAddress = Lower boundary of the range of bytes to lock. + * NumberOfBytesLock = Offset to the upper boundary. + * NumberOfBytesLocked (OUT) = Number of bytes actually locked. + * REMARK: + This procedure maps to the win32 procedure VirtualLock + * RETURNS: Status [STATUS_SUCCESS | STATUS_WAS_LOCKED ] + */ +NTSTATUS +STDCALL +NtLockVirtualMemory( + HANDLE ProcessHandle, + PVOID BaseAddress, + ULONG NumberOfBytesToLock, + PULONG NumberOfBytesLocked + ); + +NTSTATUS +STDCALL +ZwLockVirtualMemory( + HANDLE ProcessHandle, + PVOID BaseAddress, + ULONG NumberOfBytesToLock, + PULONG NumberOfBytesLocked + ); + +NTSTATUS +STDCALL +NtOpenObjectAuditAlarm( + IN PUNICODE_STRING SubsystemName, + IN PVOID HandleId, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE ClientToken, + IN ULONG DesiredAccess, + IN ULONG GrantedAccess, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN ObjectCreation, + IN BOOLEAN AccessGranted, + OUT PBOOLEAN GenerateOnClose + ); + +NTSTATUS +STDCALL +ZwOpenObjectAuditAlarm( + IN PUNICODE_STRING SubsystemName, + IN PVOID HandleId, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE ClientToken, + IN ULONG DesiredAccess, + IN ULONG GrantedAccess, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN ObjectCreation, + IN BOOLEAN AccessGranted, + OUT PBOOLEAN GenerateOnClose + ); + +/* + * FUNCTION: Set the access protection of a range of virtual memory + * ARGUMENTS: + * ProcessHandle = Handle to process owning the virtual address space + * BaseAddress = Start address + * NumberOfBytesToProtect = Delimits the range of virtual memory + * for which the new access protection holds + * NewAccessProtection = The new access proctection for the pages + * OldAccessProtection = Caller should supply storage for the old + * access protection + * + * REMARKS: + * The function maps to the win32 VirtualProtectEx + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG OldAccessProtection + ); + +NTSTATUS +STDCALL +ZwProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG OldAccessProtection + ); + +NTSTATUS +STDCALL +NtQueryInformationAtom( + IN RTL_ATOM Atom, + IN ATOM_INFORMATION_CLASS AtomInformationClass, + OUT PVOID AtomInformation, + IN ULONG AtomInformationLength, + OUT PULONG ReturnLength OPTIONAL + ); + +NTSTATUS +STDCALL +ZwQueryInformationAtom( + IN RTL_ATOM Atom, + IN ATOM_INFORMATION_CLASS AtomInformationClass, + OUT PVOID AtomInformation, + IN ULONG AtomInformationLength, + OUT PULONG ReturnLength OPTIONAL + ); + +/* + * FUNCTION: Query information about the content of a directory object + * ARGUMENTS: + DirObjInformation = Buffer must be large enough to hold the name strings too + GetNextIndex = If TRUE :return the index of the next object in this directory in ObjectIndex + If FALSE: return the number of objects in this directory in ObjectIndex + IgnoreInputIndex= If TRUE: ignore input value of ObjectIndex always start at index 0 + If FALSE use input value of ObjectIndex + ObjectIndex = zero based index of object in the directory depends on GetNextIndex and IgnoreInputIndex + DataWritten = Actual size of the ObjectIndex ??? + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtQueryDirectoryObject( + IN HANDLE DirObjHandle, + OUT POBJDIR_INFORMATION DirObjInformation, + IN ULONG BufferLength, + IN BOOLEAN GetNextIndex, + IN BOOLEAN IgnoreInputIndex, + IN OUT PULONG ObjectIndex, + OUT PULONG DataWritten OPTIONAL + ); + +NTSTATUS +STDCALL +ZwQueryDirectoryObject( + IN HANDLE DirObjHandle, + OUT POBJDIR_INFORMATION DirObjInformation, + IN ULONG BufferLength, + IN BOOLEAN GetNextIndex, + IN BOOLEAN IgnoreInputIndex, + IN OUT PULONG ObjectIndex, + OUT PULONG DataWritten OPTIONAL + ); + +/* + * FUNCTION: Queries the information of a process object. + * ARGUMENTS: + * ProcessHandle = Handle to the process object + * ProcessInformation = Index to a certain information structure + + ProcessBasicInformation PROCESS_BASIC_INFORMATION + ProcessQuotaLimits QUOTA_LIMITS + ProcessIoCounters IO_COUNTERS + ProcessVmCounters VM_COUNTERS + ProcessTimes KERNEL_USER_TIMES + ProcessBasePriority KPRIORITY + ProcessRaisePriority KPRIORITY + ProcessDebugPort HANDLE + ProcessExceptionPort HANDLE + ProcessAccessToken PROCESS_ACCESS_TOKEN + ProcessLdtInformation LDT_ENTRY ?? + ProcessLdtSize ULONG + ProcessDefaultHardErrorMode ULONG + ProcessIoPortHandlers // kernel mode only + ProcessPooledUsageAndLimits POOLED_USAGE_AND_LIMITS + ProcessWorkingSetWatch PROCESS_WS_WATCH_INFORMATION + ProcessUserModeIOPL (I/O Privilege Level) + ProcessEnableAlignmentFaultFixup BOOLEAN + ProcessPriorityClass ULONG + ProcessWx86Information ULONG + ProcessHandleCount ULONG + ProcessAffinityMask ULONG + ProcessPooledQuotaLimits QUOTA_LIMITS + MaxProcessInfoClass + + * ProcessInformation = Caller supplies storage for the process information structure + * ProcessInformationLength = Size of the process information structure + * ReturnLength = Actual number of bytes written + + * REMARK: + * This procedure maps to the win32 GetProcessTimes, GetProcessVersion, + GetProcessWorkingSetSize, GetProcessPriorityBoost, GetProcessAffinityMask, GetPriorityClass, + GetProcessShutdownParameters functions. + * RETURNS: Status +*/ + +NTSTATUS +STDCALL +NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN CINT ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength + ); + +NTSTATUS +STDCALL +ZwQueryInformationProcess( + IN HANDLE ProcessHandle, + IN CINT ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength + ); + +/* + * FUNCTION: Query the interval and the clocksource for profiling + * ARGUMENTS: + Interval = + ClockSource = + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtQueryIntervalProfile( + OUT PULONG Interval, + OUT KPROFILE_SOURCE ClockSource + ); + +NTSTATUS +STDCALL +ZwQueryIntervalProfile( + OUT PULONG Interval, + OUT KPROFILE_SOURCE ClockSource + ); + +/* + * FUNCTION: Queries the information of a object. + * ARGUMENTS: + ObjectHandle = Handle to a object + ObjectInformationClass = Index to a certain information structure + + ObjectBasicInformation + ObjectTypeInformation OBJECT_TYPE_INFORMATION + ObjectNameInformation OBJECT_NAME_INFORMATION + ObjectDataInformation OBJECT_DATA_INFORMATION + + ObjectInformation = Caller supplies storage for resulting information + Length = Size of the supplied storage + ResultLength = Bytes written + */ + +NTSTATUS +STDCALL +NtQueryObject( + IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +NTSTATUS +STDCALL +ZwQueryObject( + IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +NTSTATUS +STDCALL +NtQuerySecurityObject( + IN HANDLE Object, + IN CINT SecurityObjectInformationClass, + OUT PVOID SecurityObjectInformation, + IN ULONG Length, + OUT PULONG ReturnLength + ); + +NTSTATUS +STDCALL +ZwQuerySecurityObject( + IN HANDLE Object, + IN CINT SecurityObjectInformationClass, + OUT PVOID SecurityObjectInformation, + IN ULONG Length, + OUT PULONG ReturnLength + ); + +/* + * FUNCTION: Queries the virtual memory information. + * ARGUMENTS: + ProcessHandle = Process owning the virtual address space + BaseAddress = Points to the page where the information is queried for. + * VirtualMemoryInformationClass = Index to a certain information structure + + MemoryBasicInformation MEMORY_BASIC_INFORMATION + + * VirtualMemoryInformation = caller supplies storage for the information structure + * Length = size of the structure + ResultLength = Data written + * RETURNS: Status + * +*/ + +NTSTATUS +STDCALL +NtQueryVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID Address, + IN IN CINT VirtualMemoryInformationClass, + OUT PVOID VirtualMemoryInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +NTSTATUS +STDCALL +ZwQueryVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID Address, + IN IN CINT VirtualMemoryInformationClass, + OUT PVOID VirtualMemoryInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +/* + * FUNCTION: Raises a hard error (stops the system) + * ARGUMENTS: + * Status = Status code of the hard error + * Unknown2 = ?? + * Unknown3 = ?? + * Unknown4 = ?? + * Unknown5 = ?? + * Unknown6 = ?? + * RETURNS: Status + * + */ + +NTSTATUS +STDCALL +NtRaiseHardError( + IN NTSTATUS Status, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5, + ULONG Unknown6 + ); + +NTSTATUS +STDCALL +ZwRaiseHardError( + IN NTSTATUS Status, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5, + ULONG Unknown6 + ); + +/* + * FUNCTION: Sets the information of a registry key. + * ARGUMENTS: + * KeyHandle = Handle to the registry key + * KeyInformationClass = Index to the a certain information structure. + Can be one of the following values: + + * KeyWriteTimeInformation KEY_WRITE_TIME_INFORMATION + + KeyInformation = Storage for the new information + * KeyInformationLength = Size of the information strucure + * RETURNS: Status + */ + +NTSTATUS +STDCALL +NtSetInformationKey( + IN HANDLE KeyHandle, + IN CINT KeyInformationClass, + IN PVOID KeyInformation, + IN ULONG KeyInformationLength + ); + +NTSTATUS +STDCALL +ZwSetInformationKey( + IN HANDLE KeyHandle, + IN CINT KeyInformationClass, + IN PVOID KeyInformation, + IN ULONG KeyInformationLength + ); + +/* + * FUNCTION: Changes a set of object specific parameters + * ARGUMENTS: + * ObjectHandle = + * ObjectInformationClass = Index to the set of parameters to change. + + + ObjectBasicInformation + ObjectTypeInformation OBJECT_TYPE_INFORMATION + ObjectAllInformation + ObjectDataInformation OBJECT_DATA_INFORMATION + ObjectNameInformation OBJECT_NAME_INFORMATION + + + * ObjectInformation = Caller supplies storage for parameters to set. + * Length = Size of the storage supplied + * RETURNS: Status +*/ +NTSTATUS +STDCALL +NtSetInformationObject( + IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length + ); + +NTSTATUS +STDCALL +ZwSetInformationObject( + IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length + ); + +/* + * FUNCTION: Changes a set of process specific parameters + * ARGUMENTS: + * ProcessHandle = Handle to the process + * ProcessInformationClass = Index to a information structure. + * + * ProcessBasicInformation PROCESS_BASIC_INFORMATION + * ProcessQuotaLimits QUOTA_LIMITS + * ProcessBasePriority KPRIORITY + * ProcessRaisePriority KPRIORITY + * ProcessDebugPort HANDLE + * ProcessExceptionPort HANDLE + * ProcessAccessToken PROCESS_ACCESS_TOKEN + * ProcessDefaultHardErrorMode ULONG + * ProcessPriorityClass ULONG + * ProcessAffinityMask KAFFINITY //?? + * + * ProcessInformation = Caller supplies storage for information to set. + * ProcessInformationLength = Size of the information structure + * RETURNS: Status +*/ +NTSTATUS +STDCALL +NtSetInformationProcess( + IN HANDLE ProcessHandle, + IN CINT ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationLength + ); + +NTSTATUS +STDCALL +ZwSetInformationProcess( + IN HANDLE ProcessHandle, + IN CINT ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationLength + ); + +/* + * FUNCTION: Sets the characteristics of a timer + * ARGUMENTS: + * TimerHandle = Handle to the timer + * DueTime = Time before the timer becomes signalled for the first time. + * TimerApcRoutine = Completion routine can be called on time completion + * TimerContext = Argument to the completion routine + * Resume = Specifies if the timer should repeated after completing one cycle + * Period = Cycle of the timer + * REMARKS: This routine maps to the win32 SetWaitableTimer. + * RETURNS: Status +*/ +NTSTATUS +STDCALL +NtSetTimer( + IN HANDLE TimerHandle, + IN PLARGE_INTEGER DueTime, + IN PTIMERAPCROUTINE TimerApcRoutine, + IN PVOID TimerContext, + IN BOOL WakeTimer, + IN ULONG Period OPTIONAL, + OUT PBOOLEAN PreviousState OPTIONAL + ); + +NTSTATUS +STDCALL +ZwSetTimer( + IN HANDLE TimerHandle, + IN PLARGE_INTEGER DueTime, + IN PTIMERAPCROUTINE TimerApcRoutine, + IN PVOID TimerContext, + IN BOOL WakeTimer, + IN ULONG Period OPTIONAL, + OUT PBOOLEAN PreviousState OPTIONAL + ); + +/* + * FUNCTION: Unloads a registry key. + * ARGUMENTS: + * KeyHandle = Handle to the registry key + * REMARK: + * This procedure maps to the win32 procedure RegUnloadKey + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtUnloadKey( + HANDLE KeyHandle + ); + +NTSTATUS +STDCALL +ZwUnloadKey( + HANDLE KeyHandle + ); + +/* + * FUNCTION: Unlocks a range of virtual memory. + * ARGUMENTS: + * ProcessHandle = Handle to the process + * BaseAddress = Lower boundary of the range of bytes to unlock. + * NumberOfBytesToUnlock = Offset to the upper boundary to unlock. + * NumberOfBytesUnlocked (OUT) = Number of bytes actually unlocked. + * REMARK: + This procedure maps to the win32 procedure VirtualUnlock + * RETURNS: Status [ STATUS_SUCCESS | STATUS_PAGE_WAS_ULOCKED ] + */ +NTSTATUS +STDCALL +NtUnlockVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToUnlock, + OUT PULONG NumberOfBytesUnlocked OPTIONAL + ); + +NTSTATUS +STDCALL +ZwUnlockVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToUnlock, + OUT PULONG NumberOfBytesUnlocked OPTIONAL + ); + +/* + * FUNCTION: Waits for multiple objects to become signalled. + * ARGUMENTS: + * Count = The number of objects + * Object = The array of object handles + * WaitType = Can be one of the values UserMode or KernelMode + * Alertable = If true the wait is alertable. + * Time = The maximum wait time. + * REMARKS: + * This function maps to the win32 WaitForMultipleObjectEx. + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtWaitForMultipleObjects ( + IN ULONG Count, + IN HANDLE Object[], + IN CINT WaitType, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Time + ); + +NTSTATUS +STDCALL +ZwWaitForMultipleObjects ( + IN ULONG Count, + IN HANDLE Object[], + IN CINT WaitType, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Time + ); + +/* + * FUNCTION: Creates a profile + * ARGUMENTS: + * ProfileHandle (OUT) = Caller supplied storage for the resulting handle + * ObjectAttribute = Initialized attributes for the object + * ImageBase = Start address of executable image + * ImageSize = Size of the image + * Granularity = Bucket size + * Buffer = Caller supplies buffer for profiling info + * ProfilingSize = Buffer size + * ClockSource = Specify 0 / FALSE ?? + * ProcessorMask = A value of -1 indicates disables per processor profiling, + otherwise bit set for the processor to profile. + * REMARKS: + * This function maps to the win32 CreateProcess. + * RETURNS: Status + */ + +NTSTATUS +STDCALL +NtCreateProfile(OUT PHANDLE ProfileHandle, + IN HANDLE ProcessHandle, + IN PVOID ImageBase, + IN ULONG ImageSize, + IN ULONG Granularity, + OUT PULONG Buffer, + IN ULONG ProfilingSize, + IN KPROFILE_SOURCE Source, + IN ULONG ProcessorMask); + +NTSTATUS +STDCALL +ZwCreateProfile( + OUT PHANDLE ProfileHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG ImageBase, + IN ULONG ImageSize, + IN ULONG Granularity, + OUT PVOID Buffer, + IN ULONG ProfilingSize, + IN ULONG ClockSource, + IN ULONG ProcessorMask + ); + +/* + * FUNCTION: Delays the execution of the calling thread. + * ARGUMENTS: + * Alertable = If TRUE the thread is alertable during is wait period + * Interval = Specifies the interval to wait. + * RETURNS: Status + */ + +NTSTATUS +STDCALL +NtDelayExecution( + IN ULONG Alertable, + IN TIME *Interval + ); + +NTSTATUS +STDCALL +ZwDelayExecution( + IN BOOLEAN Alertable, + IN TIME *Interval + ); + +/* + * FUNCTION: Extends a section + * ARGUMENTS: + * SectionHandle = Handle to the section + * NewMaximumSize = Adjusted size + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtExtendSection( + IN HANDLE SectionHandle, + IN ULONG NewMaximumSize + ); + +NTSTATUS +STDCALL +ZwExtendSection( + IN HANDLE SectionHandle, + IN ULONG NewMaximumSize + ); + +/* + * FUNCTION: Queries the information of a section object. + * ARGUMENTS: + * SectionHandle = Handle to the section link object + * SectionInformationClass = Index to a certain information structure + * SectionInformation (OUT)= Caller supplies storage for resulting information + * Length = Size of the supplied storage + * ResultLength = Data written + * RETURNS: Status + * +*/ +NTSTATUS +STDCALL +NtQuerySection( + IN HANDLE SectionHandle, + IN CINT SectionInformationClass, + OUT PVOID SectionInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +NTSTATUS +STDCALL +ZwQuerySection( + IN HANDLE SectionHandle, + IN CINT SectionInformationClass, + OUT PVOID SectionInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +typedef struct _SECTION_IMAGE_INFORMATION +{ + PVOID EntryPoint; + ULONG Unknown1; + ULONG StackReserve; + ULONG StackCommit; + ULONG Subsystem; + USHORT MinorSubsystemVersion; + USHORT MajorSubsystemVersion; + ULONG Unknown2; + ULONG Characteristics; + USHORT ImageNumber; + BOOLEAN Executable; + UCHAR Unknown3; + ULONG Unknown4[3]; +} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; + +#endif /* !__USE_W32API */ + #endif /* __DDK_ZW_H */ diff --git a/include/ddk/zwtypes.h b/include/ntos/zwtypes.h old mode 100644 new mode 100755 similarity index 97% rename from include/ddk/zwtypes.h rename to include/ntos/zwtypes.h index 1095c91..cc1fe02 --- a/include/ddk/zwtypes.h +++ b/include/ntos/zwtypes.h @@ -1,6 +1,8 @@ #ifndef __INCLUDE_DDK_ZWTYPES_H #define __INCLUDE_DDK_ZWTYPES_H +#ifndef __USE_W32API + typedef enum _DEBUG_CONTROL_CODE { DebugGetTraceInformation = 1, @@ -17,25 +19,8 @@ typedef enum _KPROFILE_SOURCE ProfileTime } KPROFILE_SOURCE; -#define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF ) -#define NtCurrentThread() ( (HANDLE) 0xFFFFFFFE ) - -#ifdef __NTOSKRNL__ -extern ULONG EXPORTED NtBuildNumber; -#else -extern ULONG IMPORTED NtBuildNumber; -#endif - - -// event access mask - -#define EVENT_READ_ACCESS 1 -#define EVENT_WRITE_ACCESS 2 - - // file disposition values - #define FILE_SUPERSEDE 0x0000 #define FILE_OPEN 0x0001 #define FILE_CREATE 0x0002 @@ -58,137 +43,6 @@ typedef enum _JOBOBJECTINFOCLASS { // Q S JobObjectExtendedLimitInformation, // Y Y } JOBOBJECTINFOCLASS; -//process query / set information class - -#define ProcessBasicInformation 0 -#define ProcessQuotaLimits 1 -#define ProcessIoCounters 2 -#define ProcessVmCounters 3 -#define ProcessTimes 4 -#define ProcessBasePriority 5 -#define ProcessRaisePriority 6 -#define ProcessDebugPort 7 -#define ProcessExceptionPort 8 -#define ProcessAccessToken 9 -#define ProcessLdtInformation 10 -#define ProcessLdtSize 11 -#define ProcessDefaultHardErrorMode 12 -#define ProcessIoPortHandlers 13 -#define ProcessPooledUsageAndLimits 14 -#define ProcessWorkingSetWatch 15 -#define ProcessUserModeIOPL 16 -#define ProcessEnableAlignmentFaultFixup 17 -#define ProcessPriorityClass 18 -#define ProcessWx86Information 19 -#define ProcessHandleCount 20 -#define ProcessAffinityMask 21 -#define ProcessPriorityBoost 22 -#define ProcessDeviceMap 23 -#define ProcessSessionInformation 24 -#define ProcessForegroundInformation 25 -#define ProcessWow64Information 26 -/* ReactOS private. */ -#define ProcessImageFileName 27 -#define ProcessDesktop 28 -#define MaxProcessInfoClass 29 - -/* - * thread query / set information class - */ -#define ThreadBasicInformation 0 -#define ThreadTimes 1 -#define ThreadPriority 2 -#define ThreadBasePriority 3 -#define ThreadAffinityMask 4 -#define ThreadImpersonationToken 5 -#define ThreadDescriptorTableEntry 6 -#define ThreadEnableAlignmentFaultFixup 7 -#define ThreadEventPair 8 -#define ThreadQuerySetWin32StartAddress 9 -#define ThreadZeroTlsCell 10 -#define ThreadPerformanceCount 11 -#define ThreadAmILastThread 12 -#define ThreadIdealProcessor 13 -#define ThreadPriorityBoost 14 -#define ThreadSetTlsArrayAddress 15 -#define ThreadIsIoPending 16 -#define ThreadHideFromDebugger 17 -#define MaxThreadInfoClass 17 - -// object handle information - -#define ObjectBasicInformation 0 -#define ObjectNameInformation 1 -#define ObjectTypeInformation 2 -#define ObjectAllInformation 3 -#define ObjectDataInformation 4 - -// atom information - -typedef enum _ATOM_INFORMATION_CLASS -{ - AtomBasicInformation = 0, - AtomTableInformation = 1, -} ATOM_INFORMATION_CLASS; - -typedef struct _ATOM_BASIC_INFORMATION -{ - USHORT UsageCount; - USHORT Flags; - USHORT NameLength; - WCHAR Name[1]; -} ATOM_BASIC_INFORMATION, *PATOM_BASIC_INFORMATION; - -typedef struct _ATOM_TABLE_INFORMATION -{ - ULONG NumberOfAtoms; - RTL_ATOM Atoms[1]; -} ATOM_TABLE_INFORMATION, *PATOM_TABLE_INFORMATION; - - -// mutant information - -typedef enum _MUTANT_INFORMATION_CLASS -{ - MutantBasicInformation = 0 -} MUTANT_INFORMATION_CLASS; - -typedef struct _MUTANT_BASIC_INFORMATION -{ - LONG Count; - BOOLEAN Owned; - BOOLEAN Abandoned; -} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION; - - -// semaphore information - -typedef enum _SEMAPHORE_INFORMATION_CLASS -{ - SemaphoreBasicInformation = 0 -} SEMAPHORE_INFORMATION_CLASS; - -typedef struct _SEMAPHORE_BASIC_INFORMATION -{ - LONG CurrentCount; - LONG MaximumCount; -} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION; - - -// event information - -typedef enum _EVENT_INFORMATION_CLASS -{ - EventBasicInformation = 0 -} EVENT_INFORMATION_CLASS; - -typedef struct _EVENT_BASIC_INFORMATION -{ - EVENT_TYPE EventType; - LONG EventState; -} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION; - - // system information // {Nt|Zw}{Query|Set}SystemInformation // (GN means Gary Nebbet in "NT/W2K Native API Reference") @@ -445,529 +299,234 @@ struct _SYSTEM_PERFORMANCE_INFORMATION } SYSTEM_PERFORMANCE_INFO, *PSYSTEM_PERFORMANCE_INFO; -// SystemTimeOfDayInformation (3) +// SystemModuleInformation (11) typedef -struct _SYSTEM_TIMEOFDAY_INFORMATION +struct _SYSTEM_MODULE_ENTRY { - LARGE_INTEGER BootTime; - LARGE_INTEGER CurrentTime; - LARGE_INTEGER TimeZoneBias; - ULONG TimeZoneId; - ULONG Reserved; -} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION; + ULONG Unknown1; + ULONG Unknown2; + PVOID BaseAddress; + ULONG Size; + ULONG Flags; + ULONG EntryIndex; + USHORT NameLength; /* Length of module name not including the path, this field contains valid value only for NTOSKRNL module*/ + USHORT PathLength; /* Length of 'directory path' part of modulename*/ + CHAR Name [256]; +} SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY; -// SystemPathInformation (4) -// IT DOES NOT WORK typedef -struct _SYSTEM_PATH_INFORMATION +struct _SYSTEM_MODULE_INFORMATION { - PVOID Dummy; + ULONG Count; + SYSTEM_MODULE_ENTRY Module [1]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; -} SYSTEM_PATH_INFORMATION, * PSYSTEM_PATH_INFORMATION; +// SystemHandleInformation (16) +// (see ontypes.h) +typedef +struct _SYSTEM_HANDLE_ENTRY +{ + ULONG OwnerPid; + BYTE ObjectType; + BYTE HandleFlags; + USHORT HandleValue; + PVOID ObjectPointer; + ULONG AccessMask; + +} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY; -// SystemProcessInformation (5) typedef -struct _SYSTEM_THREAD_INFORMATION +struct _SYSTEM_HANDLE_INFORMATION { - TIME KernelTime; - TIME UserTime; - TIME CreateTime; - ULONG TickCount; - ULONG StartEIP; - CLIENT_ID ClientId; - ULONG DynamicPriority; - ULONG BasePriority; - ULONG nSwitches; - DWORD State; - KWAIT_REASON WaitReason; + ULONG Count; + SYSTEM_HANDLE_ENTRY Handle [1]; -} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; +// SystemObjectInformation (17) typedef -struct SYSTEM_PROCESS_INFORMATION +struct _SYSTEM_OBJECT_TYPE_INFORMATION { - ULONG RelativeOffset; - ULONG ThreadCount; - ULONG Unused1 [6]; - TIME CreateTime; - TIME UserTime; - TIME KernelTime; - UNICODE_STRING Name; - ULONG BasePriority; - ULONG ProcessId; - ULONG ParentProcessId; - ULONG HandleCount; - ULONG Unused2[2]; - ULONG PeakVirtualSizeBytes; - ULONG TotalVirtualSizeBytes; - ULONG PageFaultCount; - ULONG PeakWorkingSetSizeBytes; - ULONG TotalWorkingSetSizeBytes; - ULONG PeakPagedPoolUsagePages; - ULONG TotalPagedPoolUsagePages; - ULONG PeakNonPagedPoolUsagePages; - ULONG TotalNonPagedPoolUsagePages; - ULONG TotalPageFileUsageBytes; - ULONG PeakPageFileUsageBytes; - ULONG TotalPrivateBytes; - SYSTEM_THREAD_INFORMATION ThreadSysInfo [1]; + ULONG NextEntryOffset; + ULONG ObjectCount; + ULONG HandleCount; + ULONG TypeNumber; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ACCESS_MASK ValidAccessMask; + POOL_TYPE PoolType; + UCHAR Unknown; + UNICODE_STRING Name; -} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; +} SYSTEM_OBJECT_TYPE_INFORMATION, *PSYSTEM_OBJECT_TYPE_INFORMATION; -// SystemCallCountInformation (6) typedef -struct _SYSTEM_SDT_INFORMATION +struct _SYSTEM_OBJECT_INFORMATION { - ULONG BufferLength; - ULONG NumberOfSystemServiceTables; - ULONG NumberOfServices [1]; - ULONG ServiceCounters [1]; + ULONG NextEntryOffset; + PVOID Object; + ULONG CreatorProcessId; + USHORT Unknown; + USHORT Flags; + ULONG PointerCount; + ULONG HandleCount; + ULONG PagedPoolUsage; + ULONG NonPagedPoolUsage; + ULONG ExclusiveProcessId; + PSECURITY_DESCRIPTOR SecurityDescriptor; + UNICODE_STRING Name; -} SYSTEM_SDT_INFORMATION, *PSYSTEM_SDT_INFORMATION; +} SYSTEM_OBJECT_INFORMATION, *PSYSTEM_OBJECT_INFORMATION; -// SystemDeviceInformation (7) +// SystemPageFileInformation (18) typedef -struct _SYSTEM_DEVICE_INFORMATION +struct _SYSTEM_PAGEFILE_INFORMATION { - ULONG NumberOfDisks; - ULONG NumberOfFloppies; - ULONG NumberOfCdRoms; - ULONG NumberOfTapes; - ULONG NumberOfSerialPorts; - ULONG NumberOfParallelPorts; -} SYSTEM_DEVICE_INFORMATION, *PSYSTEM_DEVICE_INFORMATION; + ULONG RelativeOffset; + ULONG CurrentSizePages; + ULONG TotalUsedPages; + ULONG PeakUsedPages; + UNICODE_STRING PagefileFileName; + +} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION; -// SystemProcessorPerformanceInformation (8) -// (one per processor in the system) +// SystemCacheInformation (21) typedef -struct _SYSTEM_PROCESSORTIME_INFO +struct _SYSTEM_CACHE_INFORMATION { - TIME TotalProcessorRunTime; - TIME TotalProcessorTime; - TIME TotalProcessorUserTime; - TIME TotalDPCTime; - TIME TotalInterruptTime; - ULONG TotalInterrupts; - ULONG Unused; + ULONG CurrentSize; + ULONG PeakSize; + ULONG PageFaultCount; + ULONG MinimumWorkingSet; + ULONG MaximumWorkingSet; + ULONG Unused[4]; -} SYSTEM_PROCESSORTIME_INFO, *PSYSTEM_PROCESSORTIME_INFO; +} SYSTEM_CACHE_INFORMATION; -// SystemFlagsInformation (9) +// SystemDpcInformation (24) typedef -struct _SYSTEM_FLAGS_INFORMATION +struct _SYSTEM_DPC_INFORMATION { - ULONG Flags; - -} SYSTEM_FLAGS_INFORMATION, * PSYSTEM_FLAGS_INFORMATION; - -#define FLG_STOP_ON_EXCEPTION 0x00000001 -#define FLG_SHOW_LDR_SNAPS 0x00000002 -#define FLG_DEBUG_INITIAL_COMMAND 0x00000004 -#define FLG_STOP_ON_HANG_GUI 0x00000008 -#define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010 -#define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020 -#define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040 -#define FLG_HEAP_VALIDATE_ALL 0x00000080 -#define FLG_POOL_ENABLE_TAIL_CHECK 0x00000100 -#define FLG_POOL_ENABLE_FREE_CHECK 0x00000200 -#define FLG_POOL_ENABLE_TAGGING 0x00000400 -#define FLG_HEAP_ENABLE_TAGGING 0x00000800 -#define FLG_USER_STACK_TRACE_DB 0x00001000 -#define FLG_KERNEL_STACK_TRACE_DB 0x00002000 -#define FLG_MAINTAIN_OBJECT_TYPELIST 0x00004000 -#define FLG_HEAP_ENABLE_TAG_BY_DLL 0x00008000 -#define FLG_IGNORE_DEBUG_PRIV 0x00010000 -#define FLG_ENABLE_CSRDEBUG 0x00020000 -#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 -#define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 -#define FLG_HEAP_ENABLE_CALL_TRACING 0x00100000 -#define FLG_HEAP_DISABLE_COALESCING 0x00200000 -#define FLG_ENABLE_CLOSE_EXCEPTION 0x00400000 -#define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 -#define FLG_UNKNOWN_01000000 0x01000000 -#define FLG_UNKNOWN_02000000 0x02000000 -#define FLG_UNKNOWN_04000000 0x04000000 -#define FLG_ENABLE_DBGPRINT_BUFFERING 0x08000000 -#define FLG_UNKNOWN_10000000 0x10000000 -#define FLG_UNKNOWN_20000000 0x20000000 -#define FLG_UNKNOWN_40000000 0x40000000 -#define FLG_UNKNOWN_80000000 0x80000000 + ULONG Unused; + ULONG KiMaximumDpcQueueDepth; + ULONG KiMinimumDpcRate; + ULONG KiAdjustDpcThreshold; + ULONG KiIdealDpcRate; -// SystemCallTimeInformation (10) -// UNKNOWN +} SYSTEM_DPC_INFORMATION, *PSYSTEM_DPC_INFORMATION; -// SystemModuleInformation (11) -typedef -struct _SYSTEM_MODULE_ENTRY +// SystemLoadImage (26) +typedef struct _SYSTEM_LOAD_IMAGE { - ULONG Unknown1; - ULONG Unknown2; - PVOID BaseAddress; - ULONG Size; - ULONG Flags; - ULONG EntryIndex; - USHORT NameLength; /* Length of module name not including the path, this field contains valid value only for NTOSKRNL module*/ - USHORT PathLength; /* Length of 'directory path' part of modulename*/ - CHAR Name [256]; -} SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY; + UNICODE_STRING ModuleName; + PVOID ModuleBase; + PVOID SectionPointer; + PVOID EntryPoint; + PVOID ExportDirectory; +} SYSTEM_LOAD_IMAGE, *PSYSTEM_LOAD_IMAGE; -typedef -struct _SYSTEM_MODULE_INFORMATION +// SystemUnloadImage (27) +typedef struct _SYSTEM_UNLOAD_IMAGE { - ULONG Count; - SYSTEM_MODULE_ENTRY Module [1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + PVOID ModuleBase; +} SYSTEM_UNLOAD_IMAGE, *PSYSTEM_UNLOAD_IMAGE; -// SystemLocksInformation (12) +// SystemTimeAdjustmentInformation (28) typedef -struct _SYSTEM_RESOURCE_LOCK_ENTRY +struct _SYSTEM_QUERY_TIME_ADJUSTMENT { - ULONG ResourceAddress; - ULONG Always1; - ULONG Unknown; - ULONG ActiveCount; - ULONG ContentionCount; - ULONG Unused[2]; - ULONG NumberOfSharedWaiters; - ULONG NumberOfExclusiveWaiters; - -} SYSTEM_RESOURCE_LOCK_ENTRY, *PSYSTEM_RESOURCE_LOCK_ENTRY; + ULONG TimeAdjustment; + ULONG MaximumIncrement; + BOOLEAN TimeSynchronization; + +} SYSTEM_QUERY_TIME_ADJUSTMENT, *PSYSTEM_QUERY_TIME_ADJUSTMENT; typedef -struct _SYSTEM_RESOURCE_LOCK_INFO +struct _SYSTEM_SET_TIME_ADJUSTMENT { - ULONG Count; - SYSTEM_RESOURCE_LOCK_ENTRY Lock [1]; + ULONG TimeAdjustment; + BOOLEAN TimeSynchronization; -} SYSTEM_RESOURCE_LOCK_INFO, *PSYSTEM_RESOURCE_LOCK_INFO; +} SYSTEM_TIME_ADJUSTMENT_INFO, *PSYSTEM_TIME_ADJUSTMENT_INFO; -// SystemInformation13 (13) -// UNKNOWN +// atom information -// SystemInformation14 (14) -// UNKNOWN +typedef enum _ATOM_INFORMATION_CLASS +{ + AtomBasicInformation = 0, + AtomTableInformation = 1, +} ATOM_INFORMATION_CLASS; -// SystemInformation15 (15) -// UNKNOWN +typedef struct _ATOM_BASIC_INFORMATION +{ + USHORT UsageCount; + USHORT Flags; + USHORT NameLength; + WCHAR Name[1]; +} ATOM_BASIC_INFORMATION, *PATOM_BASIC_INFORMATION; -// SystemHandleInformation (16) -// (see ontypes.h) -typedef -struct _SYSTEM_HANDLE_ENTRY +// SystemLoadAndCallImage(38) +typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE { - ULONG OwnerPid; - BYTE ObjectType; - BYTE HandleFlags; - USHORT HandleValue; - PVOID ObjectPointer; - ULONG AccessMask; - -} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY; + UNICODE_STRING ModuleName; +} SYSTEM_LOAD_AND_CALL_IMAGE, *PSYSTEM_LOAD_AND_CALL_IMAGE; +// SystemTimeZoneInformation (44) typedef -struct _SYSTEM_HANDLE_INFORMATION +struct _SYSTEM_TIME_ZONE_INFORMATION { - ULONG Count; - SYSTEM_HANDLE_ENTRY Handle [1]; - -} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; + LONG Bias; + WCHAR StandardName [32]; + TIME StandardDate; + LONG StandardBias; + WCHAR DaylightName [32]; + TIME DaylightDate; + LONG DaylightBias; -// SystemObjectInformation (17) +} SYSTEM_TIME_ZONE_INFORMATION, * PSYSTEM_TIME_ZONE_INFORMATION; + +// SystemLookasideInformation (45) typedef -struct _SYSTEM_OBJECT_TYPE_INFORMATION +struct _SYSTEM_LOOKASIDE_INFORMATION { - ULONG NextEntryOffset; - ULONG ObjectCount; - ULONG HandleCount; - ULONG TypeNumber; - ULONG InvalidAttributes; - GENERIC_MAPPING GenericMapping; - ACCESS_MASK ValidAccessMask; - POOL_TYPE PoolType; - UCHAR Unknown; - UNICODE_STRING Name; + USHORT Depth; + USHORT MaximumDepth; + ULONG TotalAllocates; + ULONG AllocatesMisses; + ULONG TotalFrees; + ULONG FreeMisses; + POOL_TYPE Type; + ULONG Tag; + ULONG Size; -} SYSTEM_OBJECT_TYPE_INFORMATION, *PSYSTEM_OBJECT_TYPE_INFORMATION; +} SYSTEM_LOOKASIDE_INFORMATION, * PSYSTEM_LOOKASIDE_INFORMATION; +// SystemSetTimeSlipEvent (46) typedef -struct _SYSTEM_OBJECT_INFORMATION +struct _SYSTEM_SET_TIME_SLIP_EVENT { - ULONG NextEntryOffset; - PVOID Object; - ULONG CreatorProcessId; - USHORT Unknown; - USHORT Flags; - ULONG PointerCount; - ULONG HandleCount; - ULONG PagedPoolUsage; - ULONG NonPagedPoolUsage; - ULONG ExclusiveProcessId; - PSECURITY_DESCRIPTOR SecurityDescriptor; - UNICODE_STRING Name; + HANDLE TimeSlipEvent; /* IN */ -} SYSTEM_OBJECT_INFORMATION, *PSYSTEM_OBJECT_INFORMATION; +} SYSTEM_SET_TIME_SLIP_EVENT, * PSYSTEM_SET_TIME_SLIP_EVENT; -// SystemPageFileInformation (18) +// SystemCreateSession (47) +// (available only on TSE/NT5+) typedef -struct _SYSTEM_PAGEFILE_INFORMATION +struct _SYSTEM_CREATE_SESSION { - ULONG RelativeOffset; - ULONG CurrentSizePages; - ULONG TotalUsedPages; - ULONG PeakUsedPages; - UNICODE_STRING PagefileFileName; - -} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION; + ULONG SessionId; /* OUT */ -// SystemInstructionEmulationInfo (19) +} SYSTEM_CREATE_SESSION, * PSYSTEM_CREATE_SESSION; + +// SystemDeleteSession (48) +// (available only on TSE/NT5+) typedef -struct _SYSTEM_VDM_INFORMATION -{ - ULONG VdmSegmentNotPresentCount; - ULONG VdmINSWCount; - ULONG VdmESPREFIXCount; - ULONG VdmCSPREFIXCount; - ULONG VdmSSPREFIXCount; - ULONG VdmDSPREFIXCount; - ULONG VdmFSPREFIXCount; - ULONG VdmGSPREFIXCount; - ULONG VdmOPER32PREFIXCount; - ULONG VdmADDR32PREFIXCount; - ULONG VdmINSBCount; - ULONG VdmINSWV86Count; - ULONG VdmOUTSBCount; - ULONG VdmOUTSWCount; - ULONG VdmPUSHFCount; - ULONG VdmPOPFCount; - ULONG VdmINTNNCount; - ULONG VdmINTOCount; - ULONG VdmIRETCount; - ULONG VdmINBIMMCount; - ULONG VdmINWIMMCount; - ULONG VdmOUTBIMMCount; - ULONG VdmOUTWIMMCount; - ULONG VdmINBCount; - ULONG VdmINWCount; - ULONG VdmOUTBCount; - ULONG VdmOUTWCount; - ULONG VdmLOCKPREFIXCount; - ULONG VdmREPNEPREFIXCount; - ULONG VdmREPPREFIXCount; - ULONG VdmHLTCount; - ULONG VdmCLICount; - ULONG VdmSTICount; - ULONG VdmBopCount; - -} SYSTEM_VDM_INFORMATION, *PSYSTEM_VDM_INFORMATION; - -// SystemInformation20 (20) -// UNKNOWN - -// SystemCacheInformation (21) -typedef -struct _SYSTEM_CACHE_INFORMATION -{ - ULONG CurrentSize; - ULONG PeakSize; - ULONG PageFaultCount; - ULONG MinimumWorkingSet; - ULONG MaximumWorkingSet; - ULONG Unused[4]; - -} SYSTEM_CACHE_INFORMATION; - -// SystemPoolTagInformation (22) -// found by Klaus P. Gerlicher -// (implemented only in checked builds) -typedef -struct _POOL_TAG_STATS -{ - ULONG AllocationCount; - ULONG FreeCount; - ULONG SizeBytes; - -} POOL_TAG_STATS; - -typedef -struct _SYSTEM_POOL_TAG_ENTRY -{ - ULONG Tag; - POOL_TAG_STATS Paged; - POOL_TAG_STATS NonPaged; - -} SYSTEM_POOL_TAG_ENTRY, * PSYSTEM_POOL_TAG_ENTRY; - -typedef -struct _SYSTEM_POOL_TAG_INFO -{ - ULONG Count; - SYSTEM_POOL_TAG_ENTRY PoolEntry [1]; - -} SYSTEM_POOL_TAG_INFO, *PSYSTEM_POOL_TAG_INFO; - -// SystemProcessorScheduleInfo (23) -typedef -struct _SYSTEM_PROCESSOR_SCHEDULE_INFO -{ - ULONG nContextSwitches; - ULONG nDPCQueued; - ULONG nDPCRate; - ULONG TimerResolution; - ULONG nDPCBypasses; - ULONG nAPCBypasses; - -} SYSTEM_PROCESSOR_SCHEDULE_INFO, *PSYSTEM_PROCESSOR_SCHEDULE_INFO; - -// SystemDpcInformation (24) -typedef -struct _SYSTEM_DPC_INFORMATION -{ - ULONG Unused; - ULONG KiMaximumDpcQueueDepth; - ULONG KiMinimumDpcRate; - ULONG KiAdjustDpcThreshold; - ULONG KiIdealDpcRate; - -} SYSTEM_DPC_INFORMATION, *PSYSTEM_DPC_INFORMATION; - -// SystemInformation25 (25) -// UNKNOWN - -// SystemLoadImage (26) -typedef struct _SYSTEM_LOAD_IMAGE -{ - UNICODE_STRING ModuleName; - PVOID ModuleBase; - PVOID SectionPointer; - PVOID EntryPoint; - PVOID ExportDirectory; -} SYSTEM_LOAD_IMAGE, *PSYSTEM_LOAD_IMAGE; - -// SystemUnloadImage (27) -typedef struct _SYSTEM_UNLOAD_IMAGE -{ - PVOID ModuleBase; -} SYSTEM_UNLOAD_IMAGE, *PSYSTEM_UNLOAD_IMAGE; - -// SystemTimeAdjustmentInformation (28) -typedef -struct _SYSTEM_QUERY_TIME_ADJUSTMENT -{ - ULONG TimeAdjustment; - ULONG MaximumIncrement; - BOOLEAN TimeSynchronization; - -} SYSTEM_QUERY_TIME_ADJUSTMENT, *PSYSTEM_QUERY_TIME_ADJUSTMENT; - -typedef -struct _SYSTEM_SET_TIME_ADJUSTMENT -{ - ULONG TimeAdjustment; - BOOLEAN TimeSynchronization; - -} SYSTEM_TIME_ADJUSTMENT_INFO, *PSYSTEM_TIME_ADJUSTMENT_INFO; - -// SystemProcessorFaultCountInfo (33) -typedef -struct _SYSTEM_PROCESSOR_FAULT_INFO -{ - ULONG nAlignmentFixup; - ULONG nExceptionDispatches; - ULONG nFloatingEmulation; - ULONG Unknown; - -} SYSTEM_PROCESSOR_FAULT_INFO, *PSYSTEM_PROCESSOR_FAULT_INFO; - -// SystemCrashDumpStateInfo (34) -// - -// SystemDebuggerInformation (35) -typedef -struct _SYSTEM_DEBUGGER_INFO -{ - BOOLEAN KdDebuggerEnabled; - BOOLEAN KdDebuggerPresent; - -} SYSTEM_DEBUGGER_INFO, *PSYSTEM_DEBUGGER_INFO; - -// SystemInformation36 (36) -// UNKNOWN - -// SystemQuotaInformation (37) -typedef -struct _SYSTEM_QUOTA_INFORMATION -{ - ULONG CmpGlobalQuota; - ULONG CmpGlobalQuotaUsed; - ULONG MmSizeofPagedPoolInBytes; - -} SYSTEM_QUOTA_INFORMATION, *PSYSTEM_QUOTA_INFORMATION; - -// SystemLoadAndCallImage(38) -typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE -{ - UNICODE_STRING ModuleName; -} SYSTEM_LOAD_AND_CALL_IMAGE, *PSYSTEM_LOAD_AND_CALL_IMAGE; - -// SystemTimeZoneInformation (44) -typedef -struct _SYSTEM_TIME_ZONE_INFORMATION -{ - LONG Bias; - WCHAR StandardName [32]; - TIME StandardDate; - LONG StandardBias; - WCHAR DaylightName [32]; - TIME DaylightDate; - LONG DaylightBias; - -} SYSTEM_TIME_ZONE_INFORMATION, * PSYSTEM_TIME_ZONE_INFORMATION; - -// SystemLookasideInformation (45) -typedef -struct _SYSTEM_LOOKASIDE_INFORMATION -{ - USHORT Depth; - USHORT MaximumDepth; - ULONG TotalAllocates; - ULONG AllocatesMisses; - ULONG TotalFrees; - ULONG FreeMisses; - POOL_TYPE Type; - ULONG Tag; - ULONG Size; - -} SYSTEM_LOOKASIDE_INFORMATION, * PSYSTEM_LOOKASIDE_INFORMATION; - -// SystemSetTimeSlipEvent (46) -typedef -struct _SYSTEM_SET_TIME_SLIP_EVENT -{ - HANDLE TimeSlipEvent; /* IN */ - -} SYSTEM_SET_TIME_SLIP_EVENT, * PSYSTEM_SET_TIME_SLIP_EVENT; - -// SystemCreateSession (47) -// (available only on TSE/NT5+) -typedef -struct _SYSTEM_CREATE_SESSION -{ - ULONG SessionId; /* OUT */ - -} SYSTEM_CREATE_SESSION, * PSYSTEM_CREATE_SESSION; - -// SystemDeleteSession (48) -// (available only on TSE/NT5+) -typedef -struct _SYSTEM_DELETE_SESSION +struct _SYSTEM_DELETE_SESSION { ULONG SessionId; /* IN */ } SYSTEM_DELETE_SESSION, * PSYSTEM_DELETE_SESSION; -// (49) -// UNKNOWN - // SystemRangeStartInformation (50) typedef struct _SYSTEM_RANGE_START_INFORMATION @@ -976,12 +535,6 @@ struct _SYSTEM_RANGE_START_INFORMATION } SYSTEM_RANGE_START_INFORMATION, * PSYSTEM_RANGE_START_INFORMATION; -// SystemVerifierInformation (51) -// UNKNOWN - -// SystemAddVerifier (52) -// UNKNOWN - // SystemSessionProcessesInformation (53) // (available only on TSE/NT5+) typedef @@ -1030,58 +583,16 @@ typedef struct _MEMORY_WORKING_SET_LIST { // Information Class 1 typedef struct _MEMORY_SECTION_NAME_STATIC(ANYSIZE_ARRAY) MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME; -// shutdown action - -typedef enum SHUTDOWN_ACTION_TAG { - ShutdownNoReboot, - ShutdownReboot, - ShutdownPowerOff -} SHUTDOWN_ACTION; - -// wait type - -#define WaitAll 0 -#define WaitAny 1 - -// number of wait objects - -#define THREAD_WAIT_OBJECTS 3 -//#define MAXIMUM_WAIT_OBJECTS 64 - -// key restore flags - -#define REG_WHOLE_HIVE_VOLATILE 1 -#define REG_REFRESH_HIVE 2 - -// object type access rights - -#define OBJECT_TYPE_CREATE 0x0001 -#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) - -// directory access rights - -#define DIRECTORY_QUERY 0x0001 -#define DIRECTORY_TRAVERSE 0x0002 -#define DIRECTORY_CREATE_OBJECT 0x0004 -#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 - -#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) - -// symbolic link access rights - -#define SYMBOLIC_LINK_QUERY 0x0001 -#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) - -// Information class 0 -typedef struct _PROCESS_BASIC_INFORMATION -{ - NTSTATUS ExitStatus; - PPEB PebBaseAddress; - KAFFINITY AffinityMask; - KPRIORITY BasePriority; - ULONG UniqueProcessId; - ULONG InheritedFromUniqueProcessId; -} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; +// Information class 0 +typedef struct _PROCESS_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PPEB PebBaseAddress; + KAFFINITY AffinityMask; + KPRIORITY BasePriority; + ULONG UniqueProcessId; + ULONG InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; // Information class 1 typedef struct _QUOTA_LIMITS @@ -1206,23 +717,6 @@ typedef struct _OBJECT_NAME_INFORMATION UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; - - -typedef struct _OBJECT_DATA_INFORMATION -{ - BOOLEAN bInheritHandle; - BOOLEAN bProtectFromClose; -} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION; - - -typedef struct _OBJECT_TYPE_INFORMATION -{ - UNICODE_STRING Name; - UNICODE_STRING Type; - ULONG TotalHandles; - ULONG ReferenceCount; -} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; - // file information typedef struct _FILE_BASIC_INFORMATION @@ -1338,121 +832,720 @@ typedef struct _FILE_ACCESS_INFORMATION { } FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; -typedef struct _FILE_MODE_INFORMATION { - ULONG Mode; -} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; +typedef struct _FILE_MODE_INFORMATION { + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + + +typedef struct _FILE_PIPE_INFORMATION { + ULONG ReadMode; + ULONG CompletionMode; +} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION; + +typedef struct _FILE_PIPE_LOCAL_INFORMATION { + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +typedef struct _FILE_PIPE_REMOTE_INFORMATION { + LARGE_INTEGER CollectDataTime; + ULONG MaximumCollectionCount; +} FILE_PIPE_REMOTE_INFORMATION, *PFILE_PIPE_REMOTE_INFORMATION; + +typedef struct _FILE_MAILSLOT_QUERY_INFORMATION { + ULONG MaxMessageSize; + ULONG Unknown; /* ?? */ + ULONG NextSize; + ULONG MessageCount; + LARGE_INTEGER Timeout; +} FILE_MAILSLOT_QUERY_INFORMATION, *PFILE_MAILSLOT_QUERY_INFORMATION; + +typedef struct _FILE_MAILSLOT_SET_INFORMATION { + LARGE_INTEGER Timeout; +} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION; + +typedef struct _FILE_COMPRESSION_INFORMATION { + LARGE_INTEGER CompressedFileSize; + USHORT CompressionFormat; + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved[3]; +} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; + +typedef struct _FILE_ALL_INFORMATION { + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; + + +// file system information structures + +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; + + +typedef struct _FILE_FS_VOLUME_INFORMATION { + TIME VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[0]; +} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; + +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { + ULONG FileSystemAttributes; + LONG MaximumComponentNameLength; + ULONG FileSystemNameLength; + WCHAR FileSystemName[0]; +} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; + +/* + FileSystemAttributes is one of the following values: + + FILE_CASE_SENSITIVE_SEARCH 0x00000001 + FILE_CASE_PRESERVED_NAMES 0x00000002 + FILE_UNICODE_ON_DISK 0x00000004 + FILE_PERSISTENT_ACLS 0x00000008 + FILE_FILE_COMPRESSION 0x00000010 + FILE_VOLUME_QUOTAS 0x00000020 + FILE_VOLUME_IS_COMPRESSED 0x00008000 +*/ +typedef struct _FILE_FS_LABEL_INFORMATION { + ULONG VolumeLabelLength; + WCHAR VolumeLabel[0]; +} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; + +// read file scatter / write file scatter +//FIXME I am a win32 struct aswell + +typedef union _FILE_SEGMENT_ELEMENT { + PVOID Buffer; + ULONG Alignment; +}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; + +typedef struct _FILE_DIRECTORY_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + TIME CreationTime; + TIME LastAccessTime; + TIME LastWriteTime; + TIME ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[0]; +} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; + +typedef struct _FILE_FULL_DIRECTORY_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + TIME CreationTime; + TIME LastAccessTime; + TIME LastWriteTime; + TIME ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + WCHAR FileName[0]; // variable size +} FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION, + FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION; + + +typedef struct _FILE_BOTH_DIRECTORY_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + TIME CreationTime; + TIME LastAccessTime; + TIME LastWriteTime; + TIME ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CHAR ShortNameLength; + WCHAR ShortName[12]; // 8.3 name + WCHAR FileName[0]; +} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION, + FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; + +/* + NotifyFilter / CompletionFilter: + + FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 + FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 + FILE_NOTIFY_CHANGE_NAME 0x00000003 + FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 + FILE_NOTIFY_CHANGE_SIZE 0x00000008 + FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 + FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020 + FILE_NOTIFY_CHANGE_CREATION 0x00000040 + FILE_NOTIFY_CHANGE_EA 0x00000080 + FILE_NOTIFY_CHANGE_SECURITY 0x00000100 + FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 + FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 + FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 +*/ + +typedef struct _FILE_NOTIFY_INFORMATION { + ULONG Action; + ULONG FileNameLength; + WCHAR FileName[0]; +} FILE_NOTIFY_INFORMATION; + +#define FSCTL_GET_VOLUME_BITMAP 0x9006F +#define FSCTL_GET_RETRIEVAL_POINTERS 0x90073 +#define FSCTL_MOVE_FILE 0x90074 + +typedef struct _MAPPING_PAIR +{ + ULONGLONG Vcn; + ULONGLONG Lcn; +} MAPPING_PAIR, *PMAPPING_PAIR; + +typedef struct _GET_RETRIEVAL_DESCRIPTOR +{ + ULONG NumberOfPairs; + ULONGLONG StartVcn; + MAPPING_PAIR Pair[0]; // variable size +} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR; + +typedef struct _MOVEFILE_DESCRIPTOR +{ + HANDLE FileHandle; + ULONG Reserved; + LARGE_INTEGER StartVcn; + LARGE_INTEGER TargetLcn; + ULONG NumVcns; + ULONG Reserved1; +} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR; + +typedef struct _SECTION_BASIC_INFORMATION +{ + PVOID BaseAddress; + ULONG Attributes; + LARGE_INTEGER Size; +} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; + +typedef enum _SECTION_INFORMATION_CLASS +{ + SectionBasicInformation, + SectionImageInformation, +} SECTION_INFORMATION_CLASS; + +// shutdown action + +typedef enum SHUTDOWN_ACTION_TAG { + ShutdownNoReboot, + ShutdownReboot, + ShutdownPowerOff +} SHUTDOWN_ACTION; + +#else /* __USE_W32API */ + +#define DebugDbgLoadSymbols ((DEBUG_CONTROL_CODE)0xffffffff) + +#endif /* __USE_W32API */ + +#define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF ) +#define NtCurrentThread() ( (HANDLE) 0xFFFFFFFE ) +#if 1 +extern ULONG NtBuildNumber; +#else +#ifdef __NTOSKRNL__ +extern ULONG NtBuildNumber; +#else +extern ULONG NtBuildNumber; +#endif +#endif + +// event access mask + +#define EVENT_READ_ACCESS 1 +#define EVENT_WRITE_ACCESS 2 + +//process query / set information class + +#define ProcessBasicInformation 0 +#define ProcessQuotaLimits 1 +#define ProcessIoCounters 2 +#define ProcessVmCounters 3 +#define ProcessTimes 4 +#define ProcessBasePriority 5 +#define ProcessRaisePriority 6 +#define ProcessDebugPort 7 +#define ProcessExceptionPort 8 +#define ProcessAccessToken 9 +#define ProcessLdtInformation 10 +#define ProcessLdtSize 11 +#define ProcessDefaultHardErrorMode 12 +#define ProcessIoPortHandlers 13 +#define ProcessPooledUsageAndLimits 14 +#define ProcessWorkingSetWatch 15 +#define ProcessUserModeIOPL 16 +#define ProcessEnableAlignmentFaultFixup 17 +#define ProcessPriorityClass 18 +#define ProcessWx86Information 19 +#define ProcessHandleCount 20 +#define ProcessAffinityMask 21 +#define ProcessPriorityBoost 22 +#define ProcessDeviceMap 23 +#define ProcessSessionInformation 24 +#define ProcessForegroundInformation 25 +#define ProcessWow64Information 26 +/* ReactOS private. */ +#define ProcessImageFileName 27 +#define ProcessDesktop 28 +#define MaxProcessInfoClass 29 + +/* + * thread query / set information class + */ +#define ThreadBasicInformation 0 +#define ThreadTimes 1 +#define ThreadPriority 2 +#define ThreadBasePriority 3 +#define ThreadAffinityMask 4 +#define ThreadImpersonationToken 5 +#define ThreadDescriptorTableEntry 6 +#define ThreadEnableAlignmentFaultFixup 7 +#define ThreadEventPair 8 +#define ThreadQuerySetWin32StartAddress 9 +#define ThreadZeroTlsCell 10 +#define ThreadPerformanceCount 11 +#define ThreadAmILastThread 12 +#define ThreadIdealProcessor 13 +#define ThreadPriorityBoost 14 +#define ThreadSetTlsArrayAddress 15 +#define ThreadIsIoPending 16 +#define ThreadHideFromDebugger 17 +#define MaxThreadInfoClass 17 + +// object handle information + +#define ObjectBasicInformation 0 +#define ObjectNameInformation 1 +#define ObjectTypeInformation 2 +#define ObjectAllInformation 3 +#define ObjectDataInformation 4 + +typedef struct _ATOM_TABLE_INFORMATION +{ + ULONG NumberOfAtoms; + RTL_ATOM Atoms[1]; +} ATOM_TABLE_INFORMATION, *PATOM_TABLE_INFORMATION; + + +// mutant information + +typedef enum _MUTANT_INFORMATION_CLASS +{ + MutantBasicInformation = 0 +} MUTANT_INFORMATION_CLASS; + +typedef struct _MUTANT_BASIC_INFORMATION +{ + LONG Count; + BOOLEAN Owned; + BOOLEAN Abandoned; +} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION; + + +// SystemTimeOfDayInformation (3) +typedef +struct _SYSTEM_TIMEOFDAY_INFORMATION +{ + LARGE_INTEGER BootTime; + LARGE_INTEGER CurrentTime; + LARGE_INTEGER TimeZoneBias; + ULONG TimeZoneId; + ULONG Reserved; +} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION; + +// SystemPathInformation (4) +// IT DOES NOT WORK +typedef +struct _SYSTEM_PATH_INFORMATION +{ + PVOID Dummy; + +} SYSTEM_PATH_INFORMATION, * PSYSTEM_PATH_INFORMATION; + +// SystemProcessInformation (5) +typedef +struct _SYSTEM_THREAD_INFORMATION +{ + TIME KernelTime; + TIME UserTime; + TIME CreateTime; + ULONG TickCount; + ULONG StartEIP; + CLIENT_ID ClientId; + ULONG DynamicPriority; + ULONG BasePriority; + ULONG nSwitches; + DWORD State; + KWAIT_REASON WaitReason; + +} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; + +typedef +struct SYSTEM_PROCESS_INFORMATION +{ + ULONG RelativeOffset; + ULONG ThreadCount; + ULONG Unused1 [6]; + TIME CreateTime; + TIME UserTime; + TIME KernelTime; + UNICODE_STRING Name; + ULONG BasePriority; + ULONG ProcessId; + ULONG ParentProcessId; + ULONG HandleCount; + ULONG Unused2[2]; + ULONG PeakVirtualSizeBytes; + ULONG TotalVirtualSizeBytes; + ULONG PageFaultCount; + ULONG PeakWorkingSetSizeBytes; + ULONG TotalWorkingSetSizeBytes; + ULONG PeakPagedPoolUsagePages; + ULONG TotalPagedPoolUsagePages; + ULONG PeakNonPagedPoolUsagePages; + ULONG TotalNonPagedPoolUsagePages; + ULONG TotalPageFileUsageBytes; + ULONG PeakPageFileUsageBytes; + ULONG TotalPrivateBytes; + SYSTEM_THREAD_INFORMATION ThreadSysInfo [1]; + +} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; + +// SystemCallCountInformation (6) +typedef +struct _SYSTEM_SDT_INFORMATION +{ + ULONG BufferLength; + ULONG NumberOfSystemServiceTables; + ULONG NumberOfServices [1]; + ULONG ServiceCounters [1]; + +} SYSTEM_SDT_INFORMATION, *PSYSTEM_SDT_INFORMATION; + +// SystemDeviceInformation (7) +typedef +struct _SYSTEM_DEVICE_INFORMATION +{ + ULONG NumberOfDisks; + ULONG NumberOfFloppies; + ULONG NumberOfCdRoms; + ULONG NumberOfTapes; + ULONG NumberOfSerialPorts; + ULONG NumberOfParallelPorts; +} SYSTEM_DEVICE_INFORMATION, *PSYSTEM_DEVICE_INFORMATION; + +// SystemProcessorPerformanceInformation (8) +// (one per processor in the system) +typedef +struct _SYSTEM_PROCESSORTIME_INFO +{ + TIME TotalProcessorRunTime; + TIME TotalProcessorTime; + TIME TotalProcessorUserTime; + TIME TotalDPCTime; + TIME TotalInterruptTime; + ULONG TotalInterrupts; + ULONG Unused; + +} SYSTEM_PROCESSORTIME_INFO, *PSYSTEM_PROCESSORTIME_INFO; + +// SystemFlagsInformation (9) +typedef +struct _SYSTEM_FLAGS_INFORMATION +{ + ULONG Flags; + +} SYSTEM_FLAGS_INFORMATION, * PSYSTEM_FLAGS_INFORMATION; + +#define FLG_STOP_ON_EXCEPTION 0x00000001 +#define FLG_SHOW_LDR_SNAPS 0x00000002 +#define FLG_DEBUG_INITIAL_COMMAND 0x00000004 +#define FLG_STOP_ON_HANG_GUI 0x00000008 +#define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010 +#define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020 +#define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040 +#define FLG_HEAP_VALIDATE_ALL 0x00000080 +#define FLG_POOL_ENABLE_TAIL_CHECK 0x00000100 +#define FLG_POOL_ENABLE_FREE_CHECK 0x00000200 +#define FLG_POOL_ENABLE_TAGGING 0x00000400 +#define FLG_HEAP_ENABLE_TAGGING 0x00000800 +#define FLG_USER_STACK_TRACE_DB 0x00001000 +#define FLG_KERNEL_STACK_TRACE_DB 0x00002000 +#define FLG_MAINTAIN_OBJECT_TYPELIST 0x00004000 +#define FLG_HEAP_ENABLE_TAG_BY_DLL 0x00008000 +#define FLG_IGNORE_DEBUG_PRIV 0x00010000 +#define FLG_ENABLE_CSRDEBUG 0x00020000 +#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 +#define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 +#define FLG_HEAP_ENABLE_CALL_TRACING 0x00100000 +#define FLG_HEAP_DISABLE_COALESCING 0x00200000 +#define FLG_ENABLE_CLOSE_EXCEPTION 0x00400000 +#define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 +#define FLG_UNKNOWN_01000000 0x01000000 +#define FLG_UNKNOWN_02000000 0x02000000 +#define FLG_UNKNOWN_04000000 0x04000000 +#define FLG_ENABLE_DBGPRINT_BUFFERING 0x08000000 +#define FLG_UNKNOWN_10000000 0x10000000 +#define FLG_UNKNOWN_20000000 0x20000000 +#define FLG_UNKNOWN_40000000 0x40000000 +#define FLG_UNKNOWN_80000000 0x80000000 + +// SystemCallTimeInformation (10) +// UNKNOWN + +// SystemLocksInformation (12) +typedef +struct _SYSTEM_RESOURCE_LOCK_ENTRY +{ + ULONG ResourceAddress; + ULONG Always1; + ULONG Unknown; + ULONG ActiveCount; + ULONG ContentionCount; + ULONG Unused[2]; + ULONG NumberOfSharedWaiters; + ULONG NumberOfExclusiveWaiters; + +} SYSTEM_RESOURCE_LOCK_ENTRY, *PSYSTEM_RESOURCE_LOCK_ENTRY; + +typedef +struct _SYSTEM_RESOURCE_LOCK_INFO +{ + ULONG Count; + SYSTEM_RESOURCE_LOCK_ENTRY Lock [1]; + +} SYSTEM_RESOURCE_LOCK_INFO, *PSYSTEM_RESOURCE_LOCK_INFO; + +// SystemInformation13 (13) +// UNKNOWN + +// SystemInformation14 (14) +// UNKNOWN + +// SystemInformation15 (15) +// UNKNOWN + +// SystemInstructionEmulationInfo (19) +typedef +struct _SYSTEM_VDM_INFORMATION +{ + ULONG VdmSegmentNotPresentCount; + ULONG VdmINSWCount; + ULONG VdmESPREFIXCount; + ULONG VdmCSPREFIXCount; + ULONG VdmSSPREFIXCount; + ULONG VdmDSPREFIXCount; + ULONG VdmFSPREFIXCount; + ULONG VdmGSPREFIXCount; + ULONG VdmOPER32PREFIXCount; + ULONG VdmADDR32PREFIXCount; + ULONG VdmINSBCount; + ULONG VdmINSWV86Count; + ULONG VdmOUTSBCount; + ULONG VdmOUTSWCount; + ULONG VdmPUSHFCount; + ULONG VdmPOPFCount; + ULONG VdmINTNNCount; + ULONG VdmINTOCount; + ULONG VdmIRETCount; + ULONG VdmINBIMMCount; + ULONG VdmINWIMMCount; + ULONG VdmOUTBIMMCount; + ULONG VdmOUTWIMMCount; + ULONG VdmINBCount; + ULONG VdmINWCount; + ULONG VdmOUTBCount; + ULONG VdmOUTWCount; + ULONG VdmLOCKPREFIXCount; + ULONG VdmREPNEPREFIXCount; + ULONG VdmREPPREFIXCount; + ULONG VdmHLTCount; + ULONG VdmCLICount; + ULONG VdmSTICount; + ULONG VdmBopCount; + +} SYSTEM_VDM_INFORMATION, *PSYSTEM_VDM_INFORMATION; + +// SystemInformation20 (20) +// UNKNOWN + +// SystemPoolTagInformation (22) +// found by Klaus P. Gerlicher +// (implemented only in checked builds) +typedef +struct _POOL_TAG_STATS +{ + ULONG AllocationCount; + ULONG FreeCount; + ULONG SizeBytes; + +} POOL_TAG_STATS; + +typedef +struct _SYSTEM_POOL_TAG_ENTRY +{ + ULONG Tag; + POOL_TAG_STATS Paged; + POOL_TAG_STATS NonPaged; + +} SYSTEM_POOL_TAG_ENTRY, * PSYSTEM_POOL_TAG_ENTRY; + +typedef +struct _SYSTEM_POOL_TAG_INFO +{ + ULONG Count; + SYSTEM_POOL_TAG_ENTRY PoolEntry [1]; + +} SYSTEM_POOL_TAG_INFO, *PSYSTEM_POOL_TAG_INFO; + +// SystemProcessorScheduleInfo (23) +typedef +struct _SYSTEM_PROCESSOR_SCHEDULE_INFO +{ + ULONG nContextSwitches; + ULONG nDPCQueued; + ULONG nDPCRate; + ULONG TimerResolution; + ULONG nDPCBypasses; + ULONG nAPCBypasses; + +} SYSTEM_PROCESSOR_SCHEDULE_INFO, *PSYSTEM_PROCESSOR_SCHEDULE_INFO; + +// SystemInformation25 (25) +// UNKNOWN + +// SystemProcessorFaultCountInfo (33) +typedef +struct _SYSTEM_PROCESSOR_FAULT_INFO +{ + ULONG nAlignmentFixup; + ULONG nExceptionDispatches; + ULONG nFloatingEmulation; + ULONG Unknown; + +} SYSTEM_PROCESSOR_FAULT_INFO, *PSYSTEM_PROCESSOR_FAULT_INFO; + +// SystemCrashDumpStateInfo (34) +// + +// SystemDebuggerInformation (35) +typedef +struct _SYSTEM_DEBUGGER_INFO +{ + BOOLEAN KdDebuggerEnabled; + BOOLEAN KdDebuggerPresent; + +} SYSTEM_DEBUGGER_INFO, *PSYSTEM_DEBUGGER_INFO; + +// SystemInformation36 (36) +// UNKNOWN + +// SystemQuotaInformation (37) +typedef +struct _SYSTEM_QUOTA_INFORMATION +{ + ULONG CmpGlobalQuota; + ULONG CmpGlobalQuotaUsed; + ULONG MmSizeofPagedPoolInBytes; + +} SYSTEM_QUOTA_INFORMATION, *PSYSTEM_QUOTA_INFORMATION; + +// (49) +// UNKNOWN + +// SystemVerifierInformation (51) +// UNKNOWN +// SystemAddVerifier (52) +// UNKNOWN -typedef struct _FILE_PIPE_INFORMATION { - ULONG ReadMode; - ULONG CompletionMode; -} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION; +// wait type -typedef struct _FILE_PIPE_LOCAL_INFORMATION { - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; - ULONG CurrentInstances; - ULONG InboundQuota; - ULONG ReadDataAvailable; - ULONG OutboundQuota; - ULONG WriteQuotaAvailable; - ULONG NamedPipeState; - ULONG NamedPipeEnd; -} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; +#define WaitAll 0 +#define WaitAny 1 -typedef struct _FILE_PIPE_REMOTE_INFORMATION { - LARGE_INTEGER CollectDataTime; - ULONG MaximumCollectionCount; -} FILE_PIPE_REMOTE_INFORMATION, *PFILE_PIPE_REMOTE_INFORMATION; +// number of wait objects -typedef struct _FILE_MAILSLOT_QUERY_INFORMATION { - ULONG MaxMessageSize; - ULONG Unknown; /* ?? */ - ULONG NextSize; - ULONG MessageCount; - LARGE_INTEGER Timeout; -} FILE_MAILSLOT_QUERY_INFORMATION, *PFILE_MAILSLOT_QUERY_INFORMATION; +#define THREAD_WAIT_OBJECTS 3 +//#define MAXIMUM_WAIT_OBJECTS 64 -typedef struct _FILE_MAILSLOT_SET_INFORMATION { - LARGE_INTEGER Timeout; -} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION; +// key restore flags -typedef struct _FILE_COMPRESSION_INFORMATION { - LARGE_INTEGER CompressedFileSize; - USHORT CompressionFormat; - UCHAR CompressionUnitShift; - UCHAR ChunkShift; - UCHAR ClusterShift; - UCHAR Reserved[3]; -} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; +#define REG_WHOLE_HIVE_VOLATILE 1 +#define REG_REFRESH_HIVE 2 -typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; - FILE_INTERNAL_INFORMATION InternalInformation; - FILE_EA_INFORMATION EaInformation; - FILE_ACCESS_INFORMATION AccessInformation; - FILE_POSITION_INFORMATION PositionInformation; - FILE_MODE_INFORMATION ModeInformation; - FILE_ALIGNMENT_INFORMATION AlignmentInformation; - FILE_NAME_INFORMATION NameInformation; -} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; +// object type access rights +#define OBJECT_TYPE_CREATE 0x0001 +#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) -// file system information structures +// directory access rights -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; +#define DIRECTORY_QUERY 0x0001 +#define DIRECTORY_TRAVERSE 0x0002 +#define DIRECTORY_CREATE_OBJECT 0x0004 +#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 +#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) -typedef struct _FILE_FS_VOLUME_INFORMATION { - TIME VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[0]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; +// symbolic link access rights -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; +#define SYMBOLIC_LINK_QUERY 0x0001 +#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) -typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { - ULONG FileSystemAttributes; - LONG MaximumComponentNameLength; - ULONG FileSystemNameLength; - WCHAR FileSystemName[0]; -} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; -/* - FileSystemAttributes is one of the following values: +typedef struct _OBJECT_DATA_INFORMATION +{ + BOOLEAN bInheritHandle; + BOOLEAN bProtectFromClose; +} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION; - FILE_CASE_SENSITIVE_SEARCH 0x00000001 - FILE_CASE_PRESERVED_NAMES 0x00000002 - FILE_UNICODE_ON_DISK 0x00000004 - FILE_PERSISTENT_ACLS 0x00000008 - FILE_FILE_COMPRESSION 0x00000010 - FILE_VOLUME_QUOTAS 0x00000020 - FILE_VOLUME_IS_COMPRESSED 0x00008000 -*/ -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[0]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; -// read file scatter / write file scatter -//FIXME I am a win32 struct aswell +typedef struct _OBJECT_TYPE_INFORMATION +{ + UNICODE_STRING Name; + UNICODE_STRING Type; + ULONG TotalHandles; + ULONG ReferenceCount; +} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; -typedef union _FILE_SEGMENT_ELEMENT { - PVOID Buffer; - ULONG Alignment; -}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT; // directory information @@ -1463,81 +1556,6 @@ typedef struct _OBJDIR_INFORMATION { } OBJDIR_INFORMATION, *POBJDIR_INFORMATION; -typedef struct _FILE_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - TIME CreationTime; - TIME LastAccessTime; - TIME LastWriteTime; - TIME ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[0]; -} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; - -typedef struct _FILE_FULL_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - TIME CreationTime; - TIME LastAccessTime; - TIME LastWriteTime; - TIME ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - WCHAR FileName[0]; // variable size -} FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION, - FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION; - - -typedef struct _FILE_BOTH_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - TIME CreationTime; - TIME LastAccessTime; - TIME LastWriteTime; - TIME ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - CHAR ShortNameLength; - WCHAR ShortName[12]; // 8.3 name - WCHAR FileName[0]; -} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION, - FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; - - -/* - NotifyFilter / CompletionFilter: - - FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 - FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 - FILE_NOTIFY_CHANGE_NAME 0x00000003 - FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 - FILE_NOTIFY_CHANGE_SIZE 0x00000008 - FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 - FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020 - FILE_NOTIFY_CHANGE_CREATION 0x00000040 - FILE_NOTIFY_CHANGE_EA 0x00000080 - FILE_NOTIFY_CHANGE_SECURITY 0x00000100 - FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 - FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 - FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 -*/ - -typedef struct _FILE_NOTIFY_INFORMATION { - ULONG Action; - ULONG FileNameLength; - WCHAR FileName[0]; -} FILE_NOTIFY_INFORMATION; - - /* Action is one of the following values: @@ -1556,22 +1574,6 @@ typedef struct _FILE_NOTIFY_INFORMATION { // File System Control commands ( related to defragging ) #define FSCTL_READ_MFT_RECORD 0x90068 // NTFS only -#define FSCTL_GET_VOLUME_BITMAP 0x9006F -#define FSCTL_GET_RETRIEVAL_POINTERS 0x90073 -#define FSCTL_MOVE_FILE 0x90074 - -typedef struct _MAPPING_PAIR -{ - ULONGLONG Vcn; - ULONGLONG Lcn; -} MAPPING_PAIR, *PMAPPING_PAIR; - -typedef struct _GET_RETRIEVAL_DESCRIPTOR -{ - ULONG NumberOfPairs; - ULONGLONG StartVcn; - MAPPING_PAIR Pair[0]; // variable size -} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR; typedef struct _BITMAP_DESCRIPTOR { @@ -1580,17 +1582,6 @@ typedef struct _BITMAP_DESCRIPTOR BYTE Map[0]; // variable size } BITMAP_DESCRIPTOR, *PBITMAP_DESCRIPTOR; -typedef struct _MOVEFILE_DESCRIPTOR -{ - HANDLE FileHandle; - ULONG Reserved; - LARGE_INTEGER StartVcn; - LARGE_INTEGER TargetLcn; - ULONG NumVcns; - ULONG Reserved1; -} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR; - - //typedef enum _TIMER_TYPE //{ @@ -1629,34 +1620,4 @@ struct _LPC_PORT_BASIC_INFORMATION } LPC_PORT_BASIC_INFORMATION, * PLPC_PORT_BASIC_INFORMATION; -typedef struct _SECTION_BASIC_INFORMATION -{ - PVOID BaseAddress; - ULONG Attributes; - LARGE_INTEGER Size; -} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; - -typedef struct _SECTION_IMAGE_INFORMATION -{ - PVOID EntryPoint; - ULONG Unknown1; - ULONG StackReserve; - ULONG StackCommit; - ULONG Subsystem; - USHORT MinorSubsystemVersion; - USHORT MajorSubsystemVersion; - ULONG Unknown2; - ULONG Characteristics; - USHORT ImageNumber; - BOOLEAN Executable; - UCHAR Unknown3; - ULONG Unknown4[3]; -} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; - -typedef enum _SECTION_INFORMATION_CLASS -{ - SectionBasicInformation, - SectionImageInformation, -} SECTION_INFORMATION_CLASS; - #endif diff --git a/include/pe.h b/include/pe.h index 0905542..b618758 100644 --- a/include/pe.h +++ b/include/pe.h @@ -1,35 +1,40 @@ #ifndef __INCLUDE_PE_H #define __INCLUDE_PE_H +//#define _ANONYMOUS_UNION __extension__ +//#define _ANONYMOUS_STRUCT __extension__ + +#ifdef __GNUC__ +#ifndef NONAMELESSUNION +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) #define _ANONYMOUS_UNION __extension__ #define _ANONYMOUS_STRUCT __extension__ -#define NTAPI +#else +#if defined(__cplusplus) +#define _ANONYMOUS_UNION __extension__ +#endif +#endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */ +#endif /* NONAMELESSUNION */ +#else +#define _ANONYMOUS_UNION +#define _ANONYMOUS_STRUCT +#endif /* __GNUC__ */ -#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) -#define IMAGE_SECTION_CHAR_CODE 0x00000020 -#define IMAGE_SECTION_CHAR_DATA 0x00000040 -#define IMAGE_SECTION_CHAR_BSS 0x00000080 -#define IMAGE_SECTION_CHAR_NON_CACHABLE 0x04000000 -#define IMAGE_SECTION_CHAR_NON_PAGEABLE 0x08000000 -#define IMAGE_SECTION_CHAR_SHARED 0x10000000 -#define IMAGE_SECTION_CHAR_EXECUTABLE 0x20000000 -#define IMAGE_SECTION_CHAR_READABLE 0x40000000 -#define IMAGE_SECTION_CHAR_WRITABLE 0x80000000 -#define IMAGE_SECTION_NOLOAD 0x00000002 +#ifndef NTAPI +#define NTAPI STDCALL +#endif -#define IMAGE_DOS_MAGIC 0x5a4d -#define IMAGE_PE_MAGIC 0x00004550 +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +#define IMAGE_SIZEOF_SHORT_NAME 8 +#define IMAGE_SIZEOF_SYMBOL 18 + +#ifndef __USE_W32API #define IMAGE_DOS_SIGNATURE 0x5a4d #define IMAGE_OS2_SIGNATURE 0x454e - #define IMAGE_OS2_SIGNATURE_LE 0x454c #define IMAGE_VXD_SIGNATURE 0x454c -#define IMAGE_NT_SIGNATURE 0x00004550 - - -#define IMAGE_SIZEOF_FILE_HEADER 20 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). @@ -53,250 +58,6 @@ #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - - -#define IMAGE_SUBSYSTEM_UNKNOWN 0 -#define IMAGE_SUBSYSTEM_NATIVE 1 -#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 -#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 -#define IMAGE_SUBSYSTEM_OS2_GUI 4 -#define IMAGE_SUBSYSTEM_OS2_CUI 5 -#define IMAGE_SUBSYSTEM_POSIX_GUI 6 -#define IMAGE_SUBSYSTEM_POSIX_CUI 7 -#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 - - - -// Directory Entries - -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory -#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory -#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table -#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory -#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) -#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers -#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address -// -// Section header format. -// -#define IMAGE_SIZEOF_FILE_HEADER 20 -#define IMAGE_FILE_MACHINE_UNKNOWN 0 -#define IMAGE_NT_SIGNATURE 0x00004550 -#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b -#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 -#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 -#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 -#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 -#define IMAGE_SIZEOF_SHORT_NAME 8 -#define IMAGE_SIZEOF_SECTION_HEADER 40 -#define IMAGE_SIZEOF_SYMBOL 18 -#define IMAGE_SIZEOF_AUX_SYMBOL 18 -#define IMAGE_SIZEOF_RELOCATION 10 -#define IMAGE_SIZEOF_BASE_RELOCATION 8 -#define IMAGE_SIZEOF_LINENUMBER 6 -#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 -#define SIZEOF_RFPO_DATA 16 -#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader)) -#define IMAGE_SCN_TYPE_NO_PAD 8 -#define IMAGE_SCN_CNT_CODE 32 -#define IMAGE_SCN_CNT_INITIALIZED_DATA 64 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128 -#define IMAGE_SCN_LNK_OTHER 256 -#define IMAGE_SCN_LNK_INFO 512 -#define IMAGE_SCN_LNK_REMOVE 2048 -#define IMAGE_SCN_LNK_COMDAT 4096 -#define IMAGE_SCN_MEM_FARDATA 0x8000 -#define IMAGE_SCN_MEM_PURGEABLE 0x20000 -#define IMAGE_SCN_MEM_16BIT 0x20000 -#define IMAGE_SCN_MEM_LOCKED 0x40000 -#define IMAGE_SCN_MEM_PRELOAD 0x80000 -#define IMAGE_SCN_ALIGN_1BYTES 0x100000 -#define IMAGE_SCN_ALIGN_2BYTES 0x200000 -#define IMAGE_SCN_ALIGN_4BYTES 0x300000 -#define IMAGE_SCN_ALIGN_8BYTES 0x400000 -#define IMAGE_SCN_ALIGN_16BYTES 0x500000 -#define IMAGE_SCN_ALIGN_32BYTES 0x600000 -#define IMAGE_SCN_ALIGN_64BYTES 0x700000 -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x1000000 -#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 -#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000 -#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000 -#define IMAGE_SCN_MEM_SHARED 0x10000000 -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define IMAGE_SCN_MEM_READ 0x40000000 -#define IMAGE_SCN_MEM_WRITE 0x80000000 -#define IMAGE_SYM_UNDEFINED 0 -#define IMAGE_SYM_ABSOLUTE (-1) -#define IMAGE_SYM_DEBUG (-2) -#define IMAGE_SYM_TYPE_NULL 0 -#define IMAGE_SYM_TYPE_VOID 1 -#define IMAGE_SYM_TYPE_CHAR 2 -#define IMAGE_SYM_TYPE_SHORT 3 -#define IMAGE_SYM_TYPE_INT 4 -#define IMAGE_SYM_TYPE_LONG 5 -#define IMAGE_SYM_TYPE_FLOAT 6 -#define IMAGE_SYM_TYPE_DOUBLE 7 -#define IMAGE_SYM_TYPE_STRUCT 8 -#define IMAGE_SYM_TYPE_UNION 9 -#define IMAGE_SYM_TYPE_ENUM 10 -#define IMAGE_SYM_TYPE_MOE 11 -#define IMAGE_SYM_TYPE_BYTE 12 -#define IMAGE_SYM_TYPE_WORD 13 -#define IMAGE_SYM_TYPE_UINT 14 -#define IMAGE_SYM_TYPE_DWORD 15 -#define IMAGE_SYM_TYPE_PCODE 32768 -#define IMAGE_SYM_DTYPE_NULL 0 -#define IMAGE_SYM_DTYPE_POINTER 1 -#define IMAGE_SYM_DTYPE_FUNCTION 2 -#define IMAGE_SYM_DTYPE_ARRAY 3 -#define IMAGE_SYM_CLASS_END_OF_FUNCTION (-1) -#define IMAGE_SYM_CLASS_NULL 0 -#define IMAGE_SYM_CLASS_AUTOMATIC 1 -#define IMAGE_SYM_CLASS_EXTERNAL 2 -#define IMAGE_SYM_CLASS_STATIC 3 -#define IMAGE_SYM_CLASS_REGISTER 4 -#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 -#define IMAGE_SYM_CLASS_LABEL 6 -#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 -#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 -#define IMAGE_SYM_CLASS_ARGUMENT 9 -#define IMAGE_SYM_CLASS_STRUCT_TAG 10 -#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 -#define IMAGE_SYM_CLASS_UNION_TAG 12 -#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 -#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 -#define IMAGE_SYM_CLASS_ENUM_TAG 15 -#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 -#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 -#define IMAGE_SYM_CLASS_BIT_FIELD 18 -#define IMAGE_SYM_CLASS_FAR_EXTERNAL 68 -#define IMAGE_SYM_CLASS_BLOCK 100 -#define IMAGE_SYM_CLASS_FUNCTION 101 -#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 -#define IMAGE_SYM_CLASS_FILE 103 -#define IMAGE_SYM_CLASS_SECTION 104 -#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 -#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 -#define IMAGE_COMDAT_SELECT_ANY 2 -#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 -#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 -#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 -#define IMAGE_COMDAT_SELECT_LARGEST 6 -#define IMAGE_COMDAT_SELECT_NEWEST 7 -#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 -#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 -#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 -#define IMAGE_REL_I386_ABSOLUTE 0 -#define IMAGE_REL_I386_DIR16 1 -#define IMAGE_REL_I386_REL16 2 -#define IMAGE_REL_I386_DIR32 6 -#define IMAGE_REL_I386_DIR32NB 7 -#define IMAGE_REL_I386_SEG12 9 -#define IMAGE_REL_I386_SECTION 10 -#define IMAGE_REL_I386_SECREL 11 -#define IMAGE_REL_I386_REL32 20 -#define IMAGE_REL_MIPS_ABSOLUTE 0 -#define IMAGE_REL_MIPS_REFHALF 1 -#define IMAGE_REL_MIPS_REFWORD 2 -#define IMAGE_REL_MIPS_JMPADDR 3 -#define IMAGE_REL_MIPS_REFHI 4 -#define IMAGE_REL_MIPS_REFLO 5 -#define IMAGE_REL_MIPS_GPREL 6 -#define IMAGE_REL_MIPS_LITERAL 7 -#define IMAGE_REL_MIPS_SECTION 10 -#define IMAGE_REL_MIPS_SECREL 11 -#define IMAGE_REL_MIPS_SECRELLO 12 -#define IMAGE_REL_MIPS_SECRELHI 13 -#define IMAGE_REL_MIPS_REFWORDNB 34 -#define IMAGE_REL_MIPS_PAIR 35 -#define IMAGE_REL_ALPHA_ABSOLUTE 0 -#define IMAGE_REL_ALPHA_REFLONG 1 -#define IMAGE_REL_ALPHA_REFQUAD 2 -#define IMAGE_REL_ALPHA_GPREL32 3 -#define IMAGE_REL_ALPHA_LITERAL 4 -#define IMAGE_REL_ALPHA_LITUSE 5 -#define IMAGE_REL_ALPHA_GPDISP 6 -#define IMAGE_REL_ALPHA_BRADDR 7 -#define IMAGE_REL_ALPHA_HINT 8 -#define IMAGE_REL_ALPHA_INLINE_REFLONG 9 -#define IMAGE_REL_ALPHA_REFHI 10 -#define IMAGE_REL_ALPHA_REFLO 11 -#define IMAGE_REL_ALPHA_PAIR 12 -#define IMAGE_REL_ALPHA_MATCH 13 -#define IMAGE_REL_ALPHA_SECTION 14 -#define IMAGE_REL_ALPHA_SECREL 15 -#define IMAGE_REL_ALPHA_REFLONGNB 16 -#define IMAGE_REL_ALPHA_SECRELLO 17 -#define IMAGE_REL_ALPHA_SECRELHI 18 -#define IMAGE_REL_PPC_ABSOLUTE 0 -#define IMAGE_REL_PPC_ADDR64 1 -#define IMAGE_REL_PPC_ADDR32 2 -#define IMAGE_REL_PPC_ADDR24 3 -#define IMAGE_REL_PPC_ADDR16 4 -#define IMAGE_REL_PPC_ADDR14 5 -#define IMAGE_REL_PPC_REL24 6 -#define IMAGE_REL_PPC_REL14 7 -#define IMAGE_REL_PPC_TOCREL16 8 -#define IMAGE_REL_PPC_TOCREL14 9 -#define IMAGE_REL_PPC_ADDR32NB 10 -#define IMAGE_REL_PPC_SECREL 11 -#define IMAGE_REL_PPC_SECTION 12 -#define IMAGE_REL_PPC_IFGLUE 13 -#define IMAGE_REL_PPC_IMGLUE 14 -#define IMAGE_REL_PPC_SECREL16 15 -#define IMAGE_REL_PPC_REFHI 16 -#define IMAGE_REL_PPC_REFLO 17 -#define IMAGE_REL_PPC_PAIR 18 -#define IMAGE_REL_PPC_TYPEMASK 255 -#define IMAGE_REL_PPC_NEG 256 -#define IMAGE_REL_PPC_BRTAKEN 512 -#define IMAGE_REL_PPC_BRNTAKEN 1024 -#define IMAGE_REL_PPC_TOCDEFN 2048 -#define IMAGE_REL_BASED_ABSOLUTE 0 -#define IMAGE_REL_BASED_HIGH 1 -#define IMAGE_REL_BASED_LOW 2 -#define IMAGE_REL_BASED_HIGHLOW 3 -#define IMAGE_REL_BASED_HIGHADJ 4 -#define IMAGE_REL_BASED_MIPS_JMPADDR 5 -#define IMAGE_ARCHIVE_START_SIZE 8 -#define IMAGE_ARCHIVE_START "!\n" -#define IMAGE_ARCHIVE_END "`\n" -#define IMAGE_ARCHIVE_PAD "\n" -#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " -#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " -#define IMAGE_ORDINAL_FLAG 0x80000000 -#define IMAGE_SNAP_BY_ORDINAL(o) ((o&IMAGE_ORDINAL_FLAG)!=0) -#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 -#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 -#define IMAGE_DEBUG_TYPE_UNKNOWN 0 -#define IMAGE_DEBUG_TYPE_COFF 1 -#define IMAGE_DEBUG_TYPE_CODEVIEW 2 -#define IMAGE_DEBUG_TYPE_FPO 3 -#define IMAGE_DEBUG_TYPE_MISC 4 -#define IMAGE_DEBUG_TYPE_EXCEPTION 5 -#define IMAGE_DEBUG_TYPE_FIXUP 6 -#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 -#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 - - -#define IMAGE_SIZEOF_SHORT_NAME 8 - -#define IMAGE_SIZEOF_SECTION_HEADER 40 - -#define IMAGE_SECTION_CODE (0x20) -#define IMAGE_SECTION_INITIALIZED_DATA (0x40) -#define IMAGE_SECTION_UNINITIALIZED_DATA (0x80) - #pragma pack(push,4) typedef struct _IMAGE_FILE_HEADER { WORD Machine; @@ -701,12 +462,305 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { } IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER; #pragma pack(pop) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +// +// Each directory contains the 32-bit Name of the entry and an offset, +// relative to the beginning of the resource directory of the data associated +// with this directory entry. If the name of the entry is an actual text +// string instead of an integer Id, then the high order bit of the name field +// is set to one and the low order 31-bits are an offset, relative to the +// beginning of the resource directory of the string, which is of type +// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the +// low-order 16-bits are the integer Id that identify this resource directory +// entry. If the directory entry is yet another resource directory (i.e. a +// subdirectory), then the high order bit of the offset field will be +// set to indicate this. Otherwise the high bit is clear and the offset +// field points to a resource data entry. +// +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + DWORD Name; + DWORD OffsetToData; +} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; +/* +typedef struct _IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; + IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[0]; +} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; +*/ + +#endif /* !__USE_W32API */ + +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) + +#define IMAGE_SECTION_CHAR_CODE 0x00000020 +#define IMAGE_SECTION_CHAR_DATA 0x00000040 +#define IMAGE_SECTION_CHAR_BSS 0x00000080 +#define IMAGE_SECTION_CHAR_NON_CACHABLE 0x04000000 +#define IMAGE_SECTION_CHAR_NON_PAGEABLE 0x08000000 +#define IMAGE_SECTION_CHAR_SHARED 0x10000000 +#define IMAGE_SECTION_CHAR_EXECUTABLE 0x20000000 +#define IMAGE_SECTION_CHAR_READABLE 0x40000000 +#define IMAGE_SECTION_CHAR_WRITABLE 0x80000000 +#define IMAGE_SECTION_NOLOAD 0x00000002 + +#define IMAGE_DOS_MAGIC 0x5a4d +#define IMAGE_PE_MAGIC 0x00004550 + +#define IMAGE_NT_SIGNATURE 0x00004550 + + +#define IMAGE_SIZEOF_FILE_HEADER 20 + + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define IMAGE_SUBSYSTEM_OS2_GUI 4 +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_GUI 6 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 + + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers +#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address +// +// Section header format. +// +#define IMAGE_SIZEOF_FILE_HEADER 20 +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_NT_SIGNATURE 0x00004550 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 +#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_SIZEOF_SECTION_HEADER 40 +#define IMAGE_SIZEOF_AUX_SYMBOL 18 +#define IMAGE_SIZEOF_RELOCATION 10 +#define IMAGE_SIZEOF_BASE_RELOCATION 8 +#define IMAGE_SIZEOF_LINENUMBER 6 +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 +#define SIZEOF_RFPO_DATA 16 +#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader)) +#define IMAGE_SCN_TYPE_NO_PAD 8 +#define IMAGE_SCN_CNT_CODE 32 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 64 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128 +#define IMAGE_SCN_LNK_OTHER 256 +#define IMAGE_SCN_LNK_INFO 512 +#define IMAGE_SCN_LNK_REMOVE 2048 +#define IMAGE_SCN_LNK_COMDAT 4096 +#define IMAGE_SCN_MEM_FARDATA 0x8000 +#define IMAGE_SCN_MEM_PURGEABLE 0x20000 +#define IMAGE_SCN_MEM_16BIT 0x20000 +#define IMAGE_SCN_MEM_LOCKED 0x40000 +#define IMAGE_SCN_MEM_PRELOAD 0x80000 +#define IMAGE_SCN_ALIGN_1BYTES 0x100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x500000 +#define IMAGE_SCN_ALIGN_32BYTES 0x600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x700000 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x1000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 +#define IMAGE_SYM_UNDEFINED 0 +#define IMAGE_SYM_ABSOLUTE (-1) +#define IMAGE_SYM_DEBUG (-2) +#define IMAGE_SYM_TYPE_NULL 0 +#define IMAGE_SYM_TYPE_VOID 1 +#define IMAGE_SYM_TYPE_CHAR 2 +#define IMAGE_SYM_TYPE_SHORT 3 +#define IMAGE_SYM_TYPE_INT 4 +#define IMAGE_SYM_TYPE_LONG 5 +#define IMAGE_SYM_TYPE_FLOAT 6 +#define IMAGE_SYM_TYPE_DOUBLE 7 +#define IMAGE_SYM_TYPE_STRUCT 8 +#define IMAGE_SYM_TYPE_UNION 9 +#define IMAGE_SYM_TYPE_ENUM 10 +#define IMAGE_SYM_TYPE_MOE 11 +#define IMAGE_SYM_TYPE_BYTE 12 +#define IMAGE_SYM_TYPE_WORD 13 +#define IMAGE_SYM_TYPE_UINT 14 +#define IMAGE_SYM_TYPE_DWORD 15 +#define IMAGE_SYM_TYPE_PCODE 32768 +#define IMAGE_SYM_DTYPE_NULL 0 +#define IMAGE_SYM_DTYPE_POINTER 1 +#define IMAGE_SYM_DTYPE_FUNCTION 2 +#define IMAGE_SYM_DTYPE_ARRAY 3 +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (-1) +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 68 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 +#define IMAGE_COMDAT_SELECT_LARGEST 6 +#define IMAGE_COMDAT_SELECT_NEWEST 7 +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 +#define IMAGE_REL_I386_ABSOLUTE 0 +#define IMAGE_REL_I386_DIR16 1 +#define IMAGE_REL_I386_REL16 2 +#define IMAGE_REL_I386_DIR32 6 +#define IMAGE_REL_I386_DIR32NB 7 +#define IMAGE_REL_I386_SEG12 9 +#define IMAGE_REL_I386_SECTION 10 +#define IMAGE_REL_I386_SECREL 11 +#define IMAGE_REL_I386_REL32 20 +#define IMAGE_REL_MIPS_ABSOLUTE 0 +#define IMAGE_REL_MIPS_REFHALF 1 +#define IMAGE_REL_MIPS_REFWORD 2 +#define IMAGE_REL_MIPS_JMPADDR 3 +#define IMAGE_REL_MIPS_REFHI 4 +#define IMAGE_REL_MIPS_REFLO 5 +#define IMAGE_REL_MIPS_GPREL 6 +#define IMAGE_REL_MIPS_LITERAL 7 +#define IMAGE_REL_MIPS_SECTION 10 +#define IMAGE_REL_MIPS_SECREL 11 +#define IMAGE_REL_MIPS_SECRELLO 12 +#define IMAGE_REL_MIPS_SECRELHI 13 +#define IMAGE_REL_MIPS_REFWORDNB 34 +#define IMAGE_REL_MIPS_PAIR 35 +#define IMAGE_REL_ALPHA_ABSOLUTE 0 +#define IMAGE_REL_ALPHA_REFLONG 1 +#define IMAGE_REL_ALPHA_REFQUAD 2 +#define IMAGE_REL_ALPHA_GPREL32 3 +#define IMAGE_REL_ALPHA_LITERAL 4 +#define IMAGE_REL_ALPHA_LITUSE 5 +#define IMAGE_REL_ALPHA_GPDISP 6 +#define IMAGE_REL_ALPHA_BRADDR 7 +#define IMAGE_REL_ALPHA_HINT 8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 9 +#define IMAGE_REL_ALPHA_REFHI 10 +#define IMAGE_REL_ALPHA_REFLO 11 +#define IMAGE_REL_ALPHA_PAIR 12 +#define IMAGE_REL_ALPHA_MATCH 13 +#define IMAGE_REL_ALPHA_SECTION 14 +#define IMAGE_REL_ALPHA_SECREL 15 +#define IMAGE_REL_ALPHA_REFLONGNB 16 +#define IMAGE_REL_ALPHA_SECRELLO 17 +#define IMAGE_REL_ALPHA_SECRELHI 18 +#define IMAGE_REL_PPC_ABSOLUTE 0 +#define IMAGE_REL_PPC_ADDR64 1 +#define IMAGE_REL_PPC_ADDR32 2 +#define IMAGE_REL_PPC_ADDR24 3 +#define IMAGE_REL_PPC_ADDR16 4 +#define IMAGE_REL_PPC_ADDR14 5 +#define IMAGE_REL_PPC_REL24 6 +#define IMAGE_REL_PPC_REL14 7 +#define IMAGE_REL_PPC_TOCREL16 8 +#define IMAGE_REL_PPC_TOCREL14 9 +#define IMAGE_REL_PPC_ADDR32NB 10 +#define IMAGE_REL_PPC_SECREL 11 +#define IMAGE_REL_PPC_SECTION 12 +#define IMAGE_REL_PPC_IFGLUE 13 +#define IMAGE_REL_PPC_IMGLUE 14 +#define IMAGE_REL_PPC_SECREL16 15 +#define IMAGE_REL_PPC_REFHI 16 +#define IMAGE_REL_PPC_REFLO 17 +#define IMAGE_REL_PPC_PAIR 18 +#define IMAGE_REL_PPC_TYPEMASK 255 +#define IMAGE_REL_PPC_NEG 256 +#define IMAGE_REL_PPC_BRTAKEN 512 +#define IMAGE_REL_PPC_BRNTAKEN 1024 +#define IMAGE_REL_PPC_TOCDEFN 2048 +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(o) ((o&IMAGE_ORDINAL_FLAG)!=0) +#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 +#define IMAGE_DEBUG_TYPE_UNKNOWN 0 +#define IMAGE_DEBUG_TYPE_COFF 1 +#define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#define IMAGE_DEBUG_TYPE_FPO 3 +#define IMAGE_DEBUG_TYPE_MISC 4 +#define IMAGE_DEBUG_TYPE_EXCEPTION 5 +#define IMAGE_DEBUG_TYPE_FIXUP 6 +#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 +#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 + + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SECTION_CODE (0x20) +#define IMAGE_SECTION_INITIALIZED_DATA (0x40) +#define IMAGE_SECTION_UNINITIALIZED_DATA (0x80) + // // Import Format // #define IMAGE_ORDINAL_FLAG 0x80000000 -#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) // Predefined resource types ... there may be some more, but I don't have @@ -738,35 +792,6 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { // -// -// Each directory contains the 32-bit Name of the entry and an offset, -// relative to the beginning of the resource directory of the data associated -// with this directory entry. If the name of the entry is an actual text -// string instead of an integer Id, then the high order bit of the name field -// is set to one and the low order 31-bits are an offset, relative to the -// beginning of the resource directory of the string, which is of type -// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the -// low-order 16-bits are the integer Id that identify this resource directory -// entry. If the directory entry is yet another resource directory (i.e. a -// subdirectory), then the high order bit of the offset field will be -// set to indicate this. Otherwise the high bit is clear and the offset -// field points to a resource data entry. -// -typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { - DWORD Name; - DWORD OffsetToData; -} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; -/* -typedef struct _IMAGE_RESOURCE_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - WORD NumberOfNamedEntries; - WORD NumberOfIdEntries; - IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[0]; -} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; -*/ #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 diff --git a/include/reactos/.cvsignore b/include/reactos/.cvsignore index 173ec6d..6f0d7c2 100644 --- a/include/reactos/.cvsignore +++ b/include/reactos/.cvsignore @@ -1,2 +1,3 @@ buildno.h -bugcodes.h \ No newline at end of file +bugcodes.h +errcodes.h diff --git a/include/reactos/resource.h b/include/reactos/resource.h index 57f09de..a9ab8ce 100644 --- a/include/reactos/resource.h +++ b/include/reactos/resource.h @@ -22,7 +22,7 @@ /* Common version strings for rc scripts */ #define RES_STR_COMPANY_NAME "ReactOS Development Team\0" -#define RES_STR_LEGAL_COPYRIGHT "Copyright (c) 1998-2002 ReactOS Team\0" +#define RES_STR_LEGAL_COPYRIGHT "Copyright (c) 1998-2003 ReactOS Team\0" #define RES_STR_PRODUCT_NAME "ReactOS Operating System\0" #define RES_STR_PRODUCT_VERSION KERNEL_VERSION_RC diff --git a/include/reactos/version.h b/include/reactos/version.h index 246d033..2580f07 100644 --- a/include/reactos/version.h +++ b/include/reactos/version.h @@ -18,10 +18,10 @@ #define __VERSION_H #define KERNEL_VERSION_MAJOR 0 -#define KERNEL_VERSION_MINOR 0 -#define KERNEL_VERSION_PATCH_LEVEL 21 +#define KERNEL_VERSION_MINOR 1 +#define KERNEL_VERSION_PATCH_LEVEL 0 /* Edit each time a new release is out: format is YYYYMMDD (UTC) */ -#define KERNEL_RELEASE_DATE 20021031L +#define KERNEL_RELEASE_DATE 20030201L #endif diff --git a/include/structs.h b/include/structs.h index 56e0947..5cae0a4 100644 --- a/include/structs.h +++ b/include/structs.h @@ -503,7 +503,7 @@ typedef struct tagLOGFONTW { BYTE lfClipPrecision; BYTE lfQuality; BYTE lfPitchAndFamily; - LPWSTR lfFaceName; + WCHAR lfFaceName[LF_FACESIZE]; } LOGFONTW, *LPLOGFONTW, *PLOGFONTW; typedef struct { @@ -2434,6 +2434,8 @@ typedef struct tagMETAFILEPICT { LONG xExt; LONG yExt; HMETAFILE hMF; +#else + LONG mm; // robd #endif } METAFILEPICT, *PMETAFILEPICT, *LPMETAFILEPICT; @@ -2896,14 +2898,81 @@ typedef struct _OFNOTIFY { LPTSTR pszFile; } OFNOTIFY, *LPOFNOTIFY; -typedef struct _OSVERSIONINFO { +typedef struct _OSVERSIONINFOA { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[ 128 ]; +} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; + +typedef struct _OSVERSIONINFOW { DWORD dwOSVersionInfoSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformId; - TCHAR szCSDVersion[ 128 ]; -} OSVERSIONINFO, *POSVERSIONINFO, *LPOSVERSIONINFO; + WCHAR szCSDVersion[ 128 ]; +} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW; + +#ifdef UNICODE +typedef OSVERSIONINFOA OSVERSIONINFO; +#else +typedef OSVERSIONINFOW OSVERSIONINFO; +#endif + +typedef struct _OSVERSIONINFOEXA +#if defined(__cplusplus) +: public OSVERSIONINFOA +{ +#elif 0 +{ + OSVERSIONINFOA; +#else +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[ 128 ]; +#endif + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; + +typedef struct _OSVERSIONINFOEXW +#if defined(__cplusplus) +: public OSVERSIONINFOW +{ +#elif 0 +{ + OSVERSIONINFOW; +#else +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[ 128 ]; +#endif + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW; + +#ifdef UNICODE +typedef OSVERSIONINFOEXA OSVERSIONINFOEX; +#else +typedef OSVERSIONINFOEXW OSVERSIONINFOEX; +#endif typedef struct tagTEXTMETRIC { LONG tmHeight; diff --git a/include/tchar.h b/include/tchar.h index 9dc3ab4..922f7f5 100644 --- a/include/tchar.h +++ b/include/tchar.h @@ -26,7 +26,7 @@ * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of + * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Revision$ @@ -51,7 +51,13 @@ */ #ifndef _TCHAR_DEFINED #ifndef RC_INVOKED -typedef wchar_t TCHAR; +typedef wchar_t _TCHAR; +typedef signed wchar_t _TSCHAR; +typedef unsigned wchar_t _TUCHAR; +typedef wchar_t _TXCHAR; +/* #if !__STDC__ */ +typedef wchar_t TCHAR; +/* #endif */ #endif /* Not RC_INVOKED */ #define _TCHAR_DEFINED #endif @@ -61,13 +67,19 @@ typedef wchar_t TCHAR; * Enclose constant strings and literal characters in the _TEXT and _T macro to make * them unicode constant strings when _UNICODE is defined. */ +#ifndef _TEXT #define _TEXT(x) L ## x +#endif +#ifndef _T #define _T(x) L ## x +#endif /* * Unicode functions */ +#define _tmain _wmain + #define _tprintf wprintf #define _ftprintf fwprintf #define _stprintf swprintf @@ -142,7 +154,15 @@ typedef wchar_t TCHAR; */ #ifndef _TCHAR_DEFINED #ifndef RC_INVOKED -typedef char TCHAR; +typedef char _TCHAR; +typedef signed char _TSCHAR; +typedef unsigned char _TUCHAR; +typedef char _TXCHAR; + +/*#if !__STDC__*/ +typedef char TCHAR; +/*#endif*/ + #endif #define _TCHAR_DEFINED #endif @@ -150,14 +170,20 @@ typedef char TCHAR; /* * Enclose constant strings and characters in the _TEXT and _T macro. */ +#ifndef _TEXT #define _TEXT(x) x +#endif +#ifndef _T #define _T(x) x +#endif /* * Non-unicode (standard) functions */ +#define _tmain main + #define _tprintf printf #define _ftprintf fprintf #define _stprintf sprintf diff --git a/include/unicode.h b/include/unicode.h index 2c92941..dcf22bb 100644 --- a/include/unicode.h +++ b/include/unicode.h @@ -641,6 +641,17 @@ CopyFileW( WINBOOL STDCALL +CopyFileExW( + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + LPBOOL pbCancel, + DWORD dwCopyFlags + ); + +WINBOOL +STDCALL MoveFileW( LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName @@ -654,6 +665,16 @@ MoveFileExW( DWORD dwFlags ); +WINBOOL +STDCALL +MoveFileWithProgressW( + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + DWORD dwFlags + ); + HANDLE STDCALL CreateNamedPipeW( @@ -2131,7 +2152,7 @@ FindNextFileW( WINBOOL STDCALL GetVersionExW( - LPOSVERSIONINFO lpVersionInformation + LPOSVERSIONINFOW lpVersionInformation ); #define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y,\ @@ -2251,7 +2272,7 @@ InitiateSystemShutdownW( WINBOOL STDCALL AbortSystemShutdownW( - LPWSTR lpMachineName + LPCWSTR lpMachineName ); LONG diff --git a/include/win32k/gdiobj.h b/include/win32k/gdiobj.h index 1b5fbbd..89475a2 100644 --- a/include/win32k/gdiobj.h +++ b/include/win32k/gdiobj.h @@ -9,7 +9,12 @@ #include - /* GDI objects magic numbers */ +/*! \defgroup GDI Magic + * + * GDI object magic numbers + * + */ +//@{ #define GO_PEN_MAGIC 0x4f47 #define GO_BRUSH_MAGIC 0x4f48 #define GO_FONT_MAGIC 0x4f49 @@ -25,12 +30,13 @@ #define GO_ENHMETAFILE_DC_MAGIC 0x4f53 #define GO_DCE_MAGIC 0x4f54 #define GO_MAGIC_DONTCARE 0xffff - +//@} /* (RJJ) swiped stock handles from wine */ /* First handle possible for stock objects (must be >= GDI_HEAP_SIZE) */ #define FIRST_STOCK_HANDLE 0xffffff00 - /* Stock objects handles */ +/*! Stock object handles */ +//@{ #define NB_STOCK_OBJECTS (DEFAULT_GUI_FONT + 1) #define STOCK_WHITE_BRUSH ((HBRUSH)(FIRST_STOCK_HANDLE+WHITE_BRUSH)) #define STOCK_LTGRAY_BRUSH ((HBRUSH)(FIRST_STOCK_HANDLE+LTGRAY_BRUSH)) @@ -53,11 +59,15 @@ #define FIRST_STOCK_FONT STOCK_OEM_FIXED_FONT #define LAST_STOCK_FONT STOCK_DEFAULT_GUI_FONT #define LAST_STOCK_HANDLE ((DWORD)STOCK_DEFAULT_GUI_FONT) +//@} +/*! + * GDI object header. This is a part of any GDI object +*/ typedef struct _GDIOBJHDR { WORD wTableIndex; - DWORD dwCount; //reference count. + DWORD dwCount; /// reference count for the object } GDIOBJHDR, *PGDIOBJHDR; typedef PVOID PGDIOBJ; @@ -75,10 +85,19 @@ typedef struct _GDI_HANDLE_TABLE GDI_HANDLE_ENTRY Handles [1]; } GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE; +typedef struct _GDIMULTILOCK +{ + HGDIOBJ hObj; + PGDIOBJ pObj; + WORD Magic; +} GDIMULTILOCK, *PGDIMULTILOCK; + HGDIOBJ GDIOBJ_AllocObj(WORD Size, WORD Magic); BOOL GDIOBJ_FreeObj (HGDIOBJ Obj, WORD Magic, DWORD Flag); PGDIOBJ GDIOBJ_LockObj (HGDIOBJ Obj, WORD Magic); +BOOL GDIOBJ_LockMultipleObj( PGDIMULTILOCK pList, INT nObj ); BOOL GDIOBJ_UnlockObj (HGDIOBJ Obj, WORD Magic); +BOOL GDIOBJ_UnlockMultipleObj( PGDIMULTILOCK pList, INT nObj ); WORD GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle); VOID STDCALL W32kDumpGdiObjects( INT Process ); BOOL STDCALL W32kCleanupForProcess( INT Process ); diff --git a/include/win32k/math.h b/include/win32k/math.h index fcb0e32..81a7f66 100644 --- a/include/win32k/math.h +++ b/include/win32k/math.h @@ -42,7 +42,7 @@ extern "C" { * * NOTE: The CRTDLL version uses _HUGE_dll instead. */ -#if __MSVCRT__ +#ifdef __MSVCRT__ extern double* __imp__HUGE; #define HUGE_VAL (*__imp__HUGE) #else diff --git a/include/win32k/ntuser.h b/include/win32k/ntuser.h index b38fdae..c515fb7 100644 --- a/include/win32k/ntuser.h +++ b/include/win32k/ntuser.h @@ -772,10 +772,7 @@ NtUserGetProcessWindowStation(VOID); DWORD STDCALL -NtUserGetScrollBarInfo( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2); +NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi); DWORD STDCALL @@ -1515,10 +1512,7 @@ NtUserShowCaret( DWORD STDCALL -NtUserShowScrollBar( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2); +NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow); BOOL STDCALL diff --git a/include/windows.h b/include/windows.h index 8e62678..6404819 100644 --- a/include/windows.h +++ b/include/windows.h @@ -119,6 +119,9 @@ #endif #endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */ #endif /* NONAMELESSUNION */ +#else +#define _ANONYMOUS_UNION +#define _ANONYMOUS_STRUCT #endif /* __GNUC__ */ #ifndef _ANONYMOUS_UNION diff --git a/include/wine/commctrl.h b/include/wine/commctrl.h new file mode 100644 index 0000000..cfaa14e --- /dev/null +++ b/include/wine/commctrl.h @@ -0,0 +1,4492 @@ +/* + * Common controls definitions + * + * Copyright (C) the Wine project + * + * 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_COMMCTRL_H +#define __WINE_COMMCTRL_H + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" +#include "prsht.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GetWindowWord GetWindowLongA + +/* Macros to map Winelib names to the correct implementation name */ +/* depending on __WINE__ and UNICODE macros. */ +/* Note that Winelib is purely Win32. */ + +#ifdef __WINE__ +# define WINELIB_NAME_AW(func) \ + func##_must_be_suffixed_with_W_or_A_in_this_context \ + func##_must_be_suffixed_with_W_or_A_in_this_context +#else /* __WINE__ */ +# ifdef UNICODE +# define WINELIB_NAME_AW(func) func##W +# else +# define WINELIB_NAME_AW(func) func##A +# endif /* UNICODE */ +#endif /* __WINE__ */ + +#ifdef __WINE__ +# define DECL_WINELIB_TYPE_AW(type) /* nothing */ +#else /* __WINE__ */ +# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; +#endif /* __WINE__ */ + + + +BOOL WINAPI ShowHideMenuCtl (HWND, UINT, LPINT); +VOID WINAPI GetEffectiveClientRect (HWND, LPRECT, LPINT); +VOID WINAPI InitCommonControls (VOID); + +typedef struct tagINITCOMMONCONTROLSEX { + DWORD dwSize; + DWORD dwICC; +} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX; + +BOOL WINAPI InitCommonControlsEx (LPINITCOMMONCONTROLSEX); + +LANGID WINAPI GetMUILanguage (VOID); +VOID WINAPI InitMUILanguage (LANGID uiLang); + + +#define COMCTL32_VERSION 5 /* dll version */ + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0400 +#endif + +#define ICC_LISTVIEW_CLASSES 0x00000001 /* listview, header */ +#define ICC_TREEVIEW_CLASSES 0x00000002 /* treeview, tooltips */ +#define ICC_BAR_CLASSES 0x00000004 /* toolbar, statusbar, trackbar, tooltips */ +#define ICC_TAB_CLASSES 0x00000008 /* tab, tooltips */ +#define ICC_UPDOWN_CLASS 0x00000010 /* updown */ +#define ICC_PROGRESS_CLASS 0x00000020 /* progress */ +#define ICC_HOTKEY_CLASS 0x00000040 /* hotkey */ +#define ICC_ANIMATE_CLASS 0x00000080 /* animate */ +#define ICC_WIN95_CLASSES 0x000000FF +#define ICC_DATE_CLASSES 0x00000100 /* month picker, date picker, time picker, updown */ +#define ICC_USEREX_CLASSES 0x00000200 /* comboex */ +#define ICC_COOL_CLASSES 0x00000400 /* rebar (coolbar) */ +#define ICC_INTERNET_CLASSES 0x00000800 /* IP address, ... */ +#define ICC_PAGESCROLLER_CLASS 0x00001000 /* page scroller */ +#define ICC_NATIVEFNTCTL_CLASS 0x00002000 /* native font control ???*/ + + +/* common control styles */ +#define CCS_TOP 0x00000001L +#define CCS_NOMOVEY 0x00000002L +#define CCS_BOTTOM 0x00000003L +#define CCS_NORESIZE 0x00000004L +#define CCS_NOPARENTALIGN 0x00000008L +#define CCS_ADJUSTABLE 0x00000020L +#define CCS_NODIVIDER 0x00000040L +#define CCS_VERT 0x00000080L +#define CCS_LEFT (CCS_VERT|CCS_TOP) +#define CCS_RIGHT (CCS_VERT|CCS_BOTTOM) +#define CCS_NOMOVEX (CCS_VERT|CCS_NOMOVEY) + + +/* common control shared messages */ +#define CCM_FIRST 0x2000 + +#define CCM_SETBKCOLOR (CCM_FIRST+1) /* lParam = bkColor */ +#define CCM_SETCOLORSCHEME (CCM_FIRST+2) /* lParam = COLORSCHEME struct ptr */ +#define CCM_GETCOLORSCHEME (CCM_FIRST+3) /* lParam = COLORSCHEME struct ptr */ +#define CCM_GETDROPTARGET (CCM_FIRST+4) +#define CCM_SETUNICODEFORMAT (CCM_FIRST+5) +#define CCM_GETUNICODEFORMAT (CCM_FIRST+6) +#define CCM_SETVERSION (CCM_FIRST+7) +#define CCM_GETVERSION (CCM_FIRST+8) +#define CCM_SETNOTIFYWINDOW (CCM_FIRST+9) /* wParam = hwndParent */ + + +/* common notification codes (WM_NOTIFY)*/ +#define NM_FIRST (0U- 0U) +#define NM_LAST (0U- 99U) +#define NM_OUTOFMEMORY (NM_FIRST-1) +#define NM_CLICK (NM_FIRST-2) +#define NM_DBLCLK (NM_FIRST-3) +#define NM_RETURN (NM_FIRST-4) +#define NM_RCLICK (NM_FIRST-5) +#define NM_RDBLCLK (NM_FIRST-6) +#define NM_SETFOCUS (NM_FIRST-7) +#define NM_KILLFOCUS (NM_FIRST-8) +#define NM_CUSTOMDRAW (NM_FIRST-12) +#define NM_HOVER (NM_FIRST-13) +#define NM_NCHITTEST (NM_FIRST-14) +#define NM_KEYDOWN (NM_FIRST-15) +#define NM_RELEASEDCAPTURE (NM_FIRST-16) +#define NM_SETCURSOR (NM_FIRST-17) +#define NM_CHAR (NM_FIRST-18) +#define NM_TOOLTIPSCREATED (NM_FIRST-19) + +#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \ + (fn)((hwnd), (int)(wParam), (NMHDR*)(lParam)) +#define FORWARD_WM_NOTIFY(hwnd, idFrom, pnmhdr, fn) \ + (LRESULT)(fn)((hwnd), WM_NOTIFY, (WPARAM)(int)(idFrom), (LPARAM)(NMHDR*)(pnmhdr)) + + +/* callback constants */ +#define LPSTR_TEXTCALLBACKA ((LPSTR)-1L) +#define LPSTR_TEXTCALLBACKW ((LPWSTR)-1L) +#define LPSTR_TEXTCALLBACK WINELIB_NAME_AW(LPSTR_TEXTCALLBACK) + +#define I_IMAGECALLBACK (-1) +#define I_IMAGENONE (-2) +#define I_INDENTCALLBACK (-1) +#define I_CHILDRENCALLBACK (-1) + +/* owner drawn types */ +#define ODT_HEADER 100 +#define ODT_TAB 101 +#define ODT_LISTVIEW 102 + +/* common notification structures */ +typedef struct tagNMTOOLTIPSCREATED +{ + NMHDR hdr; + HWND hwndToolTips; +} NMTOOLTIPSCREATED, *LPNMTOOLTIPSCREATED; + +typedef struct tagNMMOUSE +{ + NMHDR hdr; + DWORD dwItemSpec; + DWORD dwItemData; + POINT pt; + DWORD dwHitInfo; /* info where on item or control the mouse is */ +} NMMOUSE, *LPNMMOUSE; + +typedef struct tagNMOBJECTNOTIFY +{ + NMHDR hdr; + int iItem; +#ifdef __IID_DEFINED__ + const IID *piid; +#else + const void *piid; +#endif + void *pObject; + HRESULT hResult; + DWORD dwFlags; +} NMOBJECTNOTIFY, *LPNMOBJECTNOTIFY; + +typedef struct tagNMKEY +{ + NMHDR hdr; + UINT nVKey; + UINT uFlags; +} NMKEY, *LPNMKEY; + +typedef struct tagNMCHAR +{ + NMHDR hdr; + UINT ch; + DWORD dwItemPrev; /* Item previously selected */ + DWORD dwItemNext; /* Item to be selected */ +} NMCHAR, *LPNMCHAR; + +#ifndef CCSIZEOF_STRUCT +#define CCSIZEOF_STRUCT(name, member) \ + (((INT)((LPBYTE)(&((name*)0)->member)-((LPBYTE)((name*)0))))+ \ + sizeof(((name*)0)->member)) +#endif + + +/* This is only for Winelib applications. DON't use it wine itself!!! */ +#ifndef SNDMSG +#ifdef __cplusplus +#define SNDMSG ::SendMessage +#else /* __cplusplus */ +#define SNDMSG SendMessage +#endif /* __cplusplus */ +#endif /* SNDMSG */ + + +#ifdef __cplusplus +#define SNDMSGA ::SendMessageA +#define SNDMSGW ::SendMessageW +#else +#define SNDMSGA SendMessageA +#define SNDMSGW SendMessageW +#endif + +/* Custom Draw messages */ + +#define CDRF_DODEFAULT 0x0 +#define CDRF_NEWFONT 0x00000002 +#define CDRF_SKIPDEFAULT 0x00000004 +#define CDRF_NOTIFYPOSTPAINT 0x00000010 +#define CDRF_NOTIFYITEMDRAW 0x00000020 +#define CDRF_NOTIFYSUBITEMDRAW 0x00000020 +#define CDRF_NOTIFYPOSTERASE 0x00000040 +#define CDRF_NOTIFYITEMERASE 0x00000080 /* obsolete ??? */ + + +/* drawstage flags */ + +#define CDDS_PREPAINT 1 +#define CDDS_POSTPAINT 2 +#define CDDS_PREERASE 3 +#define CDDS_POSTERASE 4 + +#define CDDS_ITEM 0x00010000 +#define CDDS_ITEMPREPAINT (CDDS_ITEM | CDDS_PREPAINT) +#define CDDS_ITEMPOSTPAINT (CDDS_ITEM | CDDS_POSTPAINT) +#define CDDS_ITEMPREERASE (CDDS_ITEM | CDDS_PREERASE) +#define CDDS_ITEMPOSTERASE (CDDS_ITEM | CDDS_POSTERASE) +#define CDDS_SUBITEM 0x00020000 + +/* itemState flags */ + +#define CDIS_SELECTED 0x0001 +#define CDIS_GRAYED 0x0002 +#define CDIS_DISABLED 0x0004 +#define CDIS_CHECKED 0x0008 +#define CDIS_FOCUS 0x0010 +#define CDIS_DEFAULT 0x0020 +#define CDIS_HOT 0x0040 +#define CDIS_MARKED 0x0080 +#define CDIS_INDETERMINATE 0x0100 + + +typedef struct tagNMCUSTOMDRAWINFO +{ + NMHDR hdr; + DWORD dwDrawStage; + HDC hdc; + RECT rc; + DWORD dwItemSpec; + UINT uItemState; + LPARAM lItemlParam; +} NMCUSTOMDRAW, *LPNMCUSTOMDRAW; + +typedef struct tagNMTTCUSTOMDRAW +{ + NMCUSTOMDRAW nmcd; + UINT uDrawFlags; +} NMTTCUSTOMDRAW, *LPNMTTCUSTOMDRAW; + + + + +/* StatusWindow */ + +#define STATUSCLASSNAME16 "msctls_statusbar" +#define STATUSCLASSNAMEA "msctls_statusbar32" +#if defined(__GNUC__) +# define STATUSCLASSNAMEW (const WCHAR []){ 'm','s','c','t','l','s','_', \ + 's','t','a','t','u','s','b','a','r','3','2',0 } +#elif defined(_MSC_VER) +# define STATUSCLASSNAMEW L"msctls_statusbar32" +#else +static const WCHAR STATUSCLASSNAMEW[] = { 'm','s','c','t','l','s','_', + 's','t','a','t','u','s','b','a','r','3','2',0 }; +#endif +#define STATUSCLASSNAME WINELIB_NAME_AW(STATUSCLASSNAME) + +#define SBT_NOBORDERS 0x0100 +#define SBT_POPOUT 0x0200 +#define SBT_RTLREADING 0x0400 /* not supported */ +#define SBT_TOOLTIPS 0x0800 +#define SBT_OWNERDRAW 0x1000 + +#define SBARS_SIZEGRIP 0x0100 + +#define SB_SETTEXTA (WM_USER+1) +#define SB_SETTEXTW (WM_USER+11) +#define SB_SETTEXT WINELIB_NAME_AW(SB_SETTEXT) +#define SB_GETTEXTA (WM_USER+2) +#define SB_GETTEXTW (WM_USER+13) +#define SB_GETTEXT WINELIB_NAME_AW(SB_GETTEXT) +#define SB_GETTEXTLENGTHA (WM_USER+3) +#define SB_GETTEXTLENGTHW (WM_USER+12) +#define SB_GETTEXTLENGTH WINELIB_NAME_AW(SB_GETTEXTLENGTH) +#define SB_SETPARTS (WM_USER+4) +#define SB_SETBORDERS (WM_USER+5) +#define SB_GETPARTS (WM_USER+6) +#define SB_GETBORDERS (WM_USER+7) +#define SB_SETMINHEIGHT (WM_USER+8) +#define SB_SIMPLE (WM_USER+9) +#define SB_GETRECT (WM_USER+10) +#define SB_ISSIMPLE (WM_USER+14) +#define SB_SETICON (WM_USER+15) +#define SB_SETTIPTEXTA (WM_USER+16) +#define SB_SETTIPTEXTW (WM_USER+17) +#define SB_SETTIPTEXT WINELIB_NAME_AW(SB_SETTIPTEXT) +#define SB_GETTIPTEXTA (WM_USER+18) +#define SB_GETTIPTEXTW (WM_USER+19) +#define SB_GETTIPTEXT WINELIB_NAME_AW(SB_GETTIPTEXT) +#define SB_GETICON (WM_USER+20) +#define SB_SETBKCOLOR CCM_SETBKCOLOR /* lParam = bkColor */ +#define SB_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define SB_SETUNICODEFORMAT CCM_SETUNICODEFORMAT + +#define SBN_FIRST (0U-880U) +#define SBN_LAST (0U-899U) +#define SBN_SIMPLEMODECHANGE (SBN_FIRST-0) + +HWND WINAPI CreateStatusWindowA (INT, LPCSTR, HWND, UINT); +HWND WINAPI CreateStatusWindowW (INT, LPCWSTR, HWND, UINT); +#define CreateStatusWindow WINELIB_NAME_AW(CreateStatusWindow) +VOID WINAPI DrawStatusTextA (HDC, LPRECT, LPCSTR, UINT); +VOID WINAPI DrawStatusTextW (HDC, LPRECT, LPCWSTR, UINT); +#define DrawStatusText WINELIB_NAME_AW(DrawStatusText) +VOID WINAPI MenuHelp (UINT, WPARAM, LPARAM, HMENU, + HINSTANCE, HWND, UINT*); + +typedef struct tagCOLORSCHEME +{ + DWORD dwSize; + COLORREF clrBtnHighlight; /* highlight color */ + COLORREF clrBtnShadow; /* shadow color */ +} COLORSCHEME, *LPCOLORSCHEME; + +/************************************************************************** + * Drag List control + */ + +typedef struct tagDRAGLISTINFO +{ + UINT uNotification; + HWND hWnd; + POINT ptCursor; +} DRAGLISTINFO, *LPDRAGLISTINFO; + +#define DL_BEGINDRAG (WM_USER+133) +#define DL_DRAGGING (WM_USER+134) +#define DL_DROPPED (WM_USER+135) +#define DL_CANCELDRAG (WM_USER+136) + +#define DL_CURSORSET 0 +#define DL_STOPCURSOR 1 +#define DL_COPYCURSOR 2 +#define DL_MOVECURSOR 3 + +#define DRAGLISTMSGSTRING TEXT("commctrl_DragListMsg") + +BOOL WINAPI MakeDragList (HWND); +VOID WINAPI DrawInsert (HWND, HWND, INT); +INT WINAPI LBItemFromPt (HWND, POINT, BOOL); + + +/* UpDown */ + +#define UPDOWN_CLASS16 "msctls_updown" +#define UPDOWN_CLASSA "msctls_updown32" +#if defined(__GNUC__) +# define UPDOWN_CLASSW (const WCHAR []){ 'm','s','c','t','l','s','_', \ + 'u','p','d','o','w','n','3','2',0 } +#elif defined(_MSC_VER) +# define UPDOWN_CLASSW L"msctls_updown32" +#else +static const WCHAR UPDOWN_CLASSW[] = { 'm','s','c','t','l','s','_', + 'u','p','d','o','w','n','3','2',0 }; +#endif +#define UPDOWN_CLASS WINELIB_NAME_AW(UPDOWN_CLASS) + +typedef struct tagUDACCEL +{ + UINT nSec; + UINT nInc; +} UDACCEL, *LPUDACCEL; + +#define UD_MAXVAL 0x7fff +#define UD_MINVAL 0x8001 + +#define UDS_WRAP 0x0001 +#define UDS_SETBUDDYINT 0x0002 +#define UDS_ALIGNRIGHT 0x0004 +#define UDS_ALIGNLEFT 0x0008 +#define UDS_AUTOBUDDY 0x0010 +#define UDS_ARROWKEYS 0x0020 +#define UDS_HORZ 0x0040 +#define UDS_NOTHOUSANDS 0x0080 +#define UDS_HOTTRACK 0x0100 + +#define UDN_FIRST (0U-721) +#define UDN_LAST (0U-740) +#define UDN_DELTAPOS (UDN_FIRST-1) + +#define UDM_SETRANGE (WM_USER+101) +#define UDM_GETRANGE (WM_USER+102) +#define UDM_SETPOS (WM_USER+103) +#define UDM_GETPOS (WM_USER+104) +#define UDM_SETBUDDY (WM_USER+105) +#define UDM_GETBUDDY (WM_USER+106) +#define UDM_SETACCEL (WM_USER+107) +#define UDM_GETACCEL (WM_USER+108) +#define UDM_SETBASE (WM_USER+109) +#define UDM_GETBASE (WM_USER+110) +#define UDM_SETRANGE32 (WM_USER+111) +#define UDM_GETRANGE32 (WM_USER+112) +#define UDM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define UDM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define UDM_SETPOS32 (WM_USER+113) +#define UDM_GETPOS32 (WM_USER+114) + + +#define NMUPDOWN NM_UPDOWN +#define LPNMUPDOWN LPNM_UPDOWN + +typedef struct tagNM_UPDOWN +{ + NMHDR hdr; + int iPos; + int iDelta; +} NM_UPDOWN, *LPNM_UPDOWN; + +HWND WINAPI CreateUpDownControl (DWORD, INT, INT, INT, INT, + HWND, INT, HINSTANCE, HWND, + INT, INT, INT); + +/* Progress Bar */ + +#define PROGRESS_CLASS16 "msctls_progress" +#define PROGRESS_CLASSA "msctls_progress32" +#if defined(__GNUC__) +# define PROGRESS_CLASSW (const WCHAR []){ 'm','s','c','t','l','s','_', \ + 'p','r','o','g','r','e','s','s','3','2',0 } +#elif defined(_MSC_VER) +# define PROGRESS_CLASSW L"msctls_progress32" +#else +static const WCHAR PROGRESS_CLASSW[] = { 'm','s','c','t','l','s','_', + 'p','r','o','g','r','e','s','s','3','2',0 }; +#endif +#define PROGRESS_CLASS WINELIB_NAME_AW(PROGRESS_CLASS) + +#define PBM_SETRANGE (WM_USER+1) +#define PBM_SETPOS (WM_USER+2) +#define PBM_DELTAPOS (WM_USER+3) +#define PBM_SETSTEP (WM_USER+4) +#define PBM_STEPIT (WM_USER+5) +#define PBM_SETRANGE32 (WM_USER+6) +#define PBM_GETRANGE (WM_USER+7) +#define PBM_GETPOS (WM_USER+8) +#define PBM_SETBARCOLOR (WM_USER+9) +#define PBM_SETBKCOLOR CCM_SETBKCOLOR + +#define PBS_SMOOTH 0x01 +#define PBS_VERTICAL 0x04 + +typedef struct +{ + INT iLow; + INT iHigh; +} PBRANGE, *PPBRANGE; + + +/* ImageList */ + +struct _IMAGELIST; +typedef struct _IMAGELIST *HIMAGELIST; + +#ifndef CLR_NONE +#define CLR_NONE 0xFFFFFFFF +#endif + +#ifndef CLR_DEFAULT +#define CLR_DEFAULT 0xFF000000 +#endif + +#define CLR_HILIGHT CLR_DEFAULT + +#define ILC_MASK 0x0001 +#define ILC_COLOR 0x0000 +#define ILC_COLORDDB 0x00FE +#define ILC_COLOR4 0x0004 +#define ILC_COLOR8 0x0008 +#define ILC_COLOR16 0x0010 +#define ILC_COLOR24 0x0018 +#define ILC_COLOR32 0x0020 +#define ILC_PALETTE 0x0800 /* no longer supported by M$ */ + +#define ILD_NORMAL 0x0000 +#define ILD_TRANSPARENT 0x0001 +#define ILD_BLEND25 0x0002 +#define ILD_BLEND50 0x0004 +#define ILD_MASK 0x0010 +#define ILD_IMAGE 0x0020 +#define ILD_ROP 0x0040 +#define ILD_OVERLAYMASK 0x0F00 +#define ILD_PRESERVEALPHA 0x1000 +#define ILD_SCALE 0x2000 +#define ILD_DPISCALE 0x4000 + +#define ILD_SELECTED ILD_BLEND50 +#define ILD_FOCUS ILD_BLEND25 +#define ILD_BLEND ILD_BLEND50 + +#define INDEXTOOVERLAYMASK(i) ((i)<<8) +#define INDEXTOSTATEIMAGEMASK(i) ((i)<<12) + +#define ILCF_MOVE (0x00000000) +#define ILCF_SWAP (0x00000001) + +#define ILS_NORMAL 0x0000 +#define ILS_GLOW 0x0001 +#define ILS_SHADOW 0x0002 +#define ILS_SATURATE 0x0004 +#define ILS_ALPHA 0x0008 + +typedef struct _IMAGEINFO +{ + HBITMAP hbmImage; + HBITMAP hbmMask; + INT Unused1; + INT Unused2; + RECT rcImage; +} IMAGEINFO, *LPIMAGEINFO; + + +typedef struct _IMAGELISTDRAWPARAMS +{ + DWORD cbSize; + HIMAGELIST himl; + INT i; + HDC hdcDst; + INT x; + INT y; + INT cx; + INT cy; + INT xBitmap; /* x offest from the upperleft of bitmap */ + INT yBitmap; /* y offset from the upperleft of bitmap */ + COLORREF rgbBk; + COLORREF rgbFg; + UINT fStyle; + DWORD dwRop; + DWORD fState; + DWORD Frame; + DWORD crEffect; +} IMAGELISTDRAWPARAMS, *LPIMAGELISTDRAWPARAMS; + + +INT WINAPI ImageList_Add(HIMAGELIST,HBITMAP,HBITMAP); +INT WINAPI ImageList_AddIcon (HIMAGELIST, HICON); +INT WINAPI ImageList_AddMasked(HIMAGELIST,HBITMAP,COLORREF); +BOOL WINAPI ImageList_BeginDrag(HIMAGELIST,INT,INT,INT); +BOOL WINAPI ImageList_Copy(HIMAGELIST,INT,HIMAGELIST,INT,INT); +HIMAGELIST WINAPI ImageList_Create(INT,INT,UINT,INT,INT); +BOOL WINAPI ImageList_Destroy(HIMAGELIST); +BOOL WINAPI ImageList_DragEnter(HWND,INT,INT); +BOOL WINAPI ImageList_DragLeave(HWND); +BOOL WINAPI ImageList_DragMove(INT,INT); +BOOL WINAPI ImageList_DragShowNolock (BOOL); +BOOL WINAPI ImageList_Draw(HIMAGELIST,INT,HDC,INT,INT,UINT); +BOOL WINAPI ImageList_DrawEx(HIMAGELIST,INT,HDC,INT,INT,INT, + INT,COLORREF,COLORREF,UINT); +BOOL WINAPI ImageList_DrawIndirect(IMAGELISTDRAWPARAMS*); +HIMAGELIST WINAPI ImageList_Duplicate(HIMAGELIST); +BOOL WINAPI ImageList_EndDrag(VOID); +COLORREF WINAPI ImageList_GetBkColor(HIMAGELIST); +HIMAGELIST WINAPI ImageList_GetDragImage(POINT*,POINT*); +HICON WINAPI ImageList_GetIcon(HIMAGELIST,INT,UINT); +BOOL WINAPI ImageList_GetIconSize(HIMAGELIST,INT*,INT*); +INT WINAPI ImageList_GetImageCount(HIMAGELIST); +BOOL WINAPI ImageList_GetImageInfo(HIMAGELIST,INT,IMAGEINFO*); +BOOL WINAPI ImageList_GetImageRect(HIMAGELIST,INT,LPRECT); +HIMAGELIST WINAPI ImageList_LoadImageA(HINSTANCE,LPCSTR,INT,INT, + COLORREF,UINT,UINT); +HIMAGELIST WINAPI ImageList_LoadImageW(HINSTANCE,LPCWSTR,INT,INT, + COLORREF,UINT,UINT); +#define ImageList_LoadImage WINELIB_NAME_AW(ImageList_LoadImage) +HIMAGELIST WINAPI ImageList_Merge(HIMAGELIST,INT,HIMAGELIST,INT,INT,INT); +#ifdef IStream_IMETHODS +HIMAGELIST WINAPI ImageList_Read(LPSTREAM); +#endif +BOOL WINAPI ImageList_Remove(HIMAGELIST,INT); +BOOL WINAPI ImageList_Replace(HIMAGELIST,INT,HBITMAP,HBITMAP); +INT WINAPI ImageList_ReplaceIcon(HIMAGELIST,INT,HICON); +COLORREF WINAPI ImageList_SetBkColor(HIMAGELIST,COLORREF); +BOOL WINAPI ImageList_SetDragCursorImage(HIMAGELIST,INT,INT,INT); + +BOOL WINAPI ImageList_SetIconSize(HIMAGELIST,INT,INT); +BOOL WINAPI ImageList_SetImageCount(HIMAGELIST,INT); +BOOL WINAPI ImageList_SetOverlayImage(HIMAGELIST,INT,INT); +#ifdef IStream_IMETHODS +BOOL WINAPI ImageList_Write(HIMAGELIST, LPSTREAM); +#endif + +#ifndef __WINE__ +#define ImageList_AddIcon(himl,hicon) ImageList_ReplaceIcon(himl,-1,hicon) +#endif +#define ImageList_ExtractIcon(hi,himl,i) ImageList_GetIcon(himl,i,0) +#define ImageList_LoadBitmap(hi,lpbmp,cx,cGrow,crMask) \ + ImageList_LoadImage(hi,lpbmp,cx,cGrow,crMask,IMAGE_BITMAP,0) +#define ImageList_RemoveAll(himl) ImageList_Remove(himl,-1) + + +#ifndef WM_MOUSEHOVER +#define WM_MOUSEHOVER 0x02A1 +#define WM_MOUSELEAVE 0x02A3 +#endif + +#ifndef TME_HOVER + +#define TME_HOVER 0x00000001 +#define TME_LEAVE 0x00000002 +#define TME_QUERY 0x40000000 +#define TME_CANCEL 0x80000000 + + +#define HOVER_DEFAULT 0xFFFFFFFF + +typedef struct tagTRACKMOUSEEVENT { + DWORD cbSize; + DWORD dwFlags; + HWND hwndTrack; + DWORD dwHoverTime; +} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT; + +#endif + +BOOL +WINAPI +_TrackMouseEvent( + LPTRACKMOUSEEVENT lpEventTrack); + +/* Flat Scrollbar control */ + +#define FLATSB_CLASS16 "flatsb_class" +#define FLATSB_CLASSA "flatsb_class32" +#if defined(__GNUC__) +# define FLATSB_CLASSW (const WCHAR []){ 'f','l','a','t','s','b','_', \ + 'c','l','a','s','s','3','2',0 } +#elif defined(_MSC_VER) +# define FLATSB_CLASSW L"flatsb_class32" +#else +static const WCHAR FLATSB_CLASSW[] = { 'f','l','a','t','s','b','_', + 'c','l','a','s','s','3','2',0 }; +#endif +#define FLATSB_CLASS WINELIB_NAME_AW(FLATSB_CLASS) + +#define WSB_PROP_CYVSCROLL 0x00000001L +#define WSB_PROP_CXHSCROLL 0x00000002L +#define WSB_PROP_CYHSCROLL 0x00000004L +#define WSB_PROP_CXVSCROLL 0x00000008L +#define WSB_PROP_CXHTHUMB 0x00000010L +#define WSB_PROP_CYVTHUMB 0x00000020L +#define WSB_PROP_VBKGCOLOR 0x00000040L +#define WSB_PROP_HBKGCOLOR 0x00000080L +#define WSB_PROP_VSTYLE 0x00000100L +#define WSB_PROP_HSTYLE 0x00000200L +#define WSB_PROP_WINSTYLE 0x00000400L +#define WSB_PROP_PALETTE 0x00000800L +#define WSB_PROP_MASK 0x00000FFFL + +#define FSB_REGULAR_MODE 0 +#define FSB_ENCARTA_MODE 1 +#define FSB_FLAT_MODE 2 + + +BOOL WINAPI FlatSB_EnableScrollBar(HWND, INT, UINT); +BOOL WINAPI FlatSB_ShowScrollBar(HWND, INT, BOOL); +BOOL WINAPI FlatSB_GetScrollRange(HWND, INT, LPINT, LPINT); +BOOL WINAPI FlatSB_GetScrollInfo(HWND, INT, LPSCROLLINFO); +INT WINAPI FlatSB_GetScrollPos(HWND, INT); +BOOL WINAPI FlatSB_GetScrollProp(HWND, INT, LPINT); +INT WINAPI FlatSB_SetScrollPos(HWND, INT, INT, BOOL); +INT WINAPI FlatSB_SetScrollInfo(HWND, INT, LPSCROLLINFO, BOOL); +INT WINAPI FlatSB_SetScrollRange(HWND, INT, INT, INT, BOOL); +BOOL WINAPI FlatSB_SetScrollProp(HWND, UINT, INT, BOOL); +BOOL WINAPI InitializeFlatSB(HWND); +HRESULT WINAPI UninitializeFlatSB(HWND); + +/* Subclassing stuff */ +typedef LRESULT (CALLBACK *SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR); +BOOL WINAPI SetWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR); +BOOL WINAPI GetWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR*); +BOOL WINAPI RemoveWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR); +LRESULT WINAPI DefSubclassProc(HWND, UINT, WPARAM, LPARAM); + +/* Header control */ + +#define WC_HEADER16 "SysHeader" +#define WC_HEADERA "SysHeader32" +#if defined(__GNUC__) +# define WC_HEADERW (const WCHAR []){ 'S','y','s','H','e','a','d','e','r','3','2',0 } +#elif defined(_MSC_VER) +# define WC_HEADERW L"SysHeader32" +#else +static const WCHAR WC_HEADERW[] = { 'S','y','s','H','e','a','d','e','r','3','2',0 }; +#endif +#define WC_HEADER WINELIB_NAME_AW(WC_HEADER) + +#define HDS_HORZ 0x0000 +#define HDS_BUTTONS 0x0002 +#define HDS_HOTTRACK 0x0004 +#define HDS_HIDDEN 0x0008 +#define HDS_DRAGDROP 0x0040 +#define HDS_FULLDRAG 0x0080 + +#define HDI_WIDTH 0x0001 +#define HDI_HEIGHT HDI_WIDTH +#define HDI_TEXT 0x0002 +#define HDI_FORMAT 0x0004 +#define HDI_LPARAM 0x0008 +#define HDI_BITMAP 0x0010 +#define HDI_IMAGE 0x0020 +#define HDI_DI_SETITEM 0x0040 +#define HDI_ORDER 0x0080 + +#define HDF_LEFT 0x0000 +#define HDF_RIGHT 0x0001 +#define HDF_CENTER 0x0002 +#define HDF_JUSTIFYMASK 0x0003 +#define HDF_RTLREADING 0x0004 + +#define HDF_IMAGE 0x0800 +#define HDF_BITMAP_ON_RIGHT 0x1000 +#define HDF_BITMAP 0x2000 +#define HDF_STRING 0x4000 +#define HDF_OWNERDRAW 0x8000 + +#define HHT_NOWHERE 0x0001 +#define HHT_ONHEADER 0x0002 +#define HHT_ONDIVIDER 0x0004 +#define HHT_ONDIVOPEN 0x0008 +#define HHT_ABOVE 0x0100 +#define HHT_BELOW 0x0200 +#define HHT_TORIGHT 0x0400 +#define HHT_TOLEFT 0x0800 + +#define HDM_FIRST 0x1200 +#define HDM_GETITEMCOUNT (HDM_FIRST+0) +#define HDM_INSERTITEMA (HDM_FIRST+1) +#define HDM_INSERTITEMW (HDM_FIRST+10) +#define HDM_INSERTITEM WINELIB_NAME_AW(HDM_INSERTITEM) +#define HDM_DELETEITEM (HDM_FIRST+2) +#define HDM_GETITEMA (HDM_FIRST+3) +#define HDM_GETITEMW (HDM_FIRST+11) +#define HDM_GETITEM WINELIB_NAME_AW(HDM_GETITEM) +#define HDM_SETITEMA (HDM_FIRST+4) +#define HDM_SETITEMW (HDM_FIRST+12) +#define HDM_SETITEM WINELIB_NAME_AW(HDM_SETITEM) +#define HDM_LAYOUT (HDM_FIRST+5) +#define HDM_HITTEST (HDM_FIRST+6) +#define HDM_GETITEMRECT (HDM_FIRST+7) +#define HDM_SETIMAGELIST (HDM_FIRST+8) +#define HDM_GETIMAGELIST (HDM_FIRST+9) + +#define HDM_ORDERTOINDEX (HDM_FIRST+15) +#define HDM_CREATEDRAGIMAGE (HDM_FIRST+16) +#define HDM_GETORDERARRAY (HDM_FIRST+17) +#define HDM_SETORDERARRAY (HDM_FIRST+18) +#define HDM_SETHOTDIVIDER (HDM_FIRST+19) +#define HDM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define HDM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT + +#define HDN_FIRST (0U-300U) +#define HDN_LAST (0U-399U) +#define HDN_ITEMCHANGINGA (HDN_FIRST-0) +#define HDN_ITEMCHANGINGW (HDN_FIRST-20) +#define HDN_ITEMCHANGING WINELIB_NAME_AW(HDN_ITEMCHANGING) +#define HDN_ITEMCHANGEDA (HDN_FIRST-1) +#define HDN_ITEMCHANGEDW (HDN_FIRST-21) +#define HDN_ITEMCHANGED WINELIB_NAME_AW(HDN_ITEMCHANGED) +#define HDN_ITEMCLICKA (HDN_FIRST-2) +#define HDN_ITEMCLICKW (HDN_FIRST-22) +#define HDN_ITEMCLICK WINELIB_NAME_AW(HDN_ITEMCLICK) +#define HDN_ITEMDBLCLICKA (HDN_FIRST-3) +#define HDN_ITEMDBLCLICKW (HDN_FIRST-23) +#define HDN_ITEMDBLCLICK WINELIB_NAME_AW(HDN_ITEMDBLCLICK) +#define HDN_DIVIDERDBLCLICKA (HDN_FIRST-5) +#define HDN_DIVIDERDBLCLICKW (HDN_FIRST-25) +#define HDN_DIVIDERDBLCLICK WINELIB_NAME_AW(HDN_DIVIDERDBLCLICK) +#define HDN_BEGINTRACKA (HDN_FIRST-6) +#define HDN_BEGINTRACKW (HDN_FIRST-26) +#define HDN_BEGINTRACK WINELIB_NAME_AW(HDN_BEGINTRACK) +#define HDN_ENDTRACKA (HDN_FIRST-7) +#define HDN_ENDTRACKW (HDN_FIRST-27) +#define HDN_ENDTRACK WINELIB_NAME_AW(HDN_ENDTRACK) +#define HDN_TRACKA (HDN_FIRST-8) +#define HDN_TRACKW (HDN_FIRST-28) +#define HDN_TRACK WINELIB_NAME_AW(HDN_TRACK) +#define HDN_GETDISPINFOA (HDN_FIRST-9) +#define HDN_GETDISPINFOW (HDN_FIRST-29) +#define HDN_GETDISPINFO WINELIB_NAME_AW(HDN_GETDISPINFO) +#define HDN_BEGINDRAG (HDN_FIRST-10) +#define HDN_ENDDRAG (HDN_FIRST-11) + +typedef struct _HD_LAYOUT +{ + RECT *prc; + WINDOWPOS *pwpos; +} HDLAYOUT, *LPHDLAYOUT; + +#define HD_LAYOUT HDLAYOUT + +typedef struct _HD_ITEMA +{ + UINT mask; + INT cxy; + LPSTR pszText; + HBITMAP hbm; + INT cchTextMax; + INT fmt; + LPARAM lParam; + INT iImage; + INT iOrder; + UINT type; + LPVOID pvFilter; +} HDITEMA, *LPHDITEMA; + +typedef struct _HD_ITEMW +{ + UINT mask; + INT cxy; + LPWSTR pszText; + HBITMAP hbm; + INT cchTextMax; + INT fmt; + LPARAM lParam; + INT iImage; + INT iOrder; + UINT type; + LPVOID pvFilter; +} HDITEMW, *LPHDITEMW; + +#define HDITEM WINELIB_NAME_AW(HDITEM) +#define LPHDITEM WINELIB_NAME_AW(LPHDITEM) +#define HD_ITEM HDITEM + +#define HDITEM_V1_SIZEA CCSIZEOF_STRUCT(HDITEMA, lParam) +#define HDITEM_V1_SIZEW CCSIZEOF_STRUCT(HDITEMW, lParam) +#define HDITEM_V1_SIZE WINELIB_NAME_AW(HDITEM_V1_SIZE) + +typedef struct _HD_HITTESTINFO +{ + POINT pt; + UINT flags; + INT iItem; +} HDHITTESTINFO, *LPHDHITTESTINFO; + +#define HD_HITTESTINFO HDHITTESTINFO + +typedef struct tagNMHEADERA +{ + NMHDR hdr; + INT iItem; + INT iButton; + HDITEMA *pitem; +} NMHEADERA, *LPNMHEADERA; + +typedef struct tagNMHEADERW +{ + NMHDR hdr; + INT iItem; + INT iButton; + HDITEMW *pitem; +} NMHEADERW, *LPNMHEADERW; + +#define NMHEADER WINELIB_NAME_AW(NMHEADER) +#define LPNMHEADER WINELIB_NAME_AW(LPNMHEADER) +#define HD_NOTIFY NMHEADER + +typedef struct tagNMHDDISPINFOA +{ + NMHDR hdr; + INT iItem; + UINT mask; + LPSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; +} NMHDDISPINFOA, *LPNMHDDISPINFOA; + +typedef struct tagNMHDDISPINFOW +{ + NMHDR hdr; + INT iItem; + UINT mask; + LPWSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; +} NMHDDISPINFOW, *LPNMHDDISPINFOW; + +#define NMHDDISPINFO WINELIB_NAME_AW(NMHDDISPINFO) +#define LPNMHDDISPINFO WINELIB_NAME_AW(LPNMHDDISPINFO) + +#define Header_GetItemCount(hwndHD) \ + (INT)SNDMSGA((hwndHD),HDM_GETITEMCOUNT,0,0L) +#define Header_InsertItemA(hwndHD,i,phdi) \ + (INT)SNDMSGA((hwndHD),HDM_INSERTITEMA,(WPARAM)(INT)(i),(LPARAM)(const HDITEMA*)(phdi)) +#define Header_InsertItemW(hwndHD,i,phdi) \ + (INT)SNDMSGW((hwndHD),HDM_INSERTITEMW,(WPARAM)(INT)(i),(LPARAM)(const HDITEMW*)(phdi)) +#define Header_InsertItem WINELIB_NAME_AW(Header_InsertItem) +#define Header_DeleteItem(hwndHD,i) \ + (BOOL)SNDMSGA((hwndHD),HDM_DELETEITEM,(WPARAM)(INT)(i),0L) +#define Header_GetItemA(hwndHD,i,phdi) \ + (BOOL)SNDMSGA((hwndHD),HDM_GETITEMA,(WPARAM)(INT)(i),(LPARAM)(HDITEMA*)(phdi)) +#define Header_GetItemW(hwndHD,i,phdi) \ + (BOOL)SNDMSGW((hwndHD),HDM_GETITEMW,(WPARAM)(INT)(i),(LPARAM)(HDITEMW*)(phdi)) +#define Header_GetItem WINELIB_NAME_AW(Header_GetItem) +#define Header_SetItemA(hwndHD,i,phdi) \ + (BOOL)SNDMSGA((hwndHD),HDM_SETITEMA,(WPARAM)(INT)(i),(LPARAM)(const HDITEMA*)(phdi)) +#define Header_SetItemW(hwndHD,i,phdi) \ + (BOOL)SNDMSGW((hwndHD),HDM_SETITEMW,(WPARAM)(INT)(i),(LPARAM)(const HDITEMW*)(phdi)) +#define Header_SetItem WINELIB_NAME_AW(Header_SetItem) +#define Header_Layout(hwndHD,playout) \ + (BOOL)SNDMSGA((hwndHD),HDM_LAYOUT,0,(LPARAM)(LPHDLAYOUT)(playout)) +#define Header_GetItemRect(hwnd,iItem,lprc) \ + (BOOL)SNDMSGA((hwnd),HDM_GETITEMRECT,(WPARAM)iItem,(LPARAM)lprc) +#define Header_SetImageList(hwnd,himl) \ + (HIMAGELIST)SNDMSGA((hwnd),HDM_SETIMAGELIST,0,(LPARAM)himl) +#define Header_GetImageList(hwnd) \ + (HIMAGELIST)SNDMSGA((hwnd),HDM_GETIMAGELIST,0,0) +#define Header_OrderToIndex(hwnd,i) \ + (INT)SNDMSGA((hwnd),HDM_ORDERTOINDEX,(WPARAM)i,0) +#define Header_CreateDragImage(hwnd,i) \ + (HIMAGELIST)SNDMSGA((hwnd),HDM_CREATEDRAGIMAGE,(WPARAM)i,0) +#define Header_GetOrderArray(hwnd,iCount,lpi) \ + (BOOL)SNDMSGA((hwnd),HDM_GETORDERARRAY,(WPARAM)iCount,(LPARAM)lpi) +#define Header_SetOrderArray(hwnd,iCount,lpi) \ + (BOOL)SNDMSGA((hwnd),HDM_SETORDERARRAY,(WPARAM)iCount,(LPARAM)lpi) +#define Header_SetHotDivider(hwnd,fPos,dw) \ + (INT)SNDMSGA((hwnd),HDM_SETHOTDIVIDER,(WPARAM)fPos,(LPARAM)dw) +#define Header_SetUnicodeFormat(hwnd,fUnicode) \ + (BOOL)SNDMSGA((hwnd),HDM_SETUNICODEFORMAT,(WPARAM)(fUnicode),0) +#define Header_GetUnicodeFormat(hwnd) \ + (BOOL)SNDMSGA((hwnd),HDM_GETUNICODEFORMAT,0,0) + + +/* Toolbar */ + +#define TOOLBARCLASSNAME16 "ToolbarWindow" +#define TOOLBARCLASSNAMEA "ToolbarWindow32" +#if defined(__GNUC__) +# define TOOLBARCLASSNAMEW (const WCHAR []){ 'T','o','o','l','b','a','r', \ + 'W','i','n','d','o','w','3','2',0 } +#elif defined(_MSC_VER) +# define TOOLBARCLASSNAMEW L"ToolbarWindow32" +#else +static const WCHAR TOOLBARCLASSNAMEW[] = { 'T','o','o','l','b','a','r', + 'W','i','n','d','o','w','3','2',0 }; +#endif +#define TOOLBARCLASSNAME WINELIB_NAME_AW(TOOLBARCLASSNAME) + +#define CMB_MASKED 0x02 + +#define TBSTATE_CHECKED 0x01 +#define TBSTATE_PRESSED 0x02 +#define TBSTATE_ENABLED 0x04 +#define TBSTATE_HIDDEN 0x08 +#define TBSTATE_INDETERMINATE 0x10 +#define TBSTATE_WRAP 0x20 +#define TBSTATE_ELLIPSES 0x40 +#define TBSTATE_MARKED 0x80 + + +/* as of _WIN32_IE >= 0x0500 the following symbols are obsolete, + * "everyone" should use the BTNS_... stuff below + */ +#define TBSTYLE_BUTTON 0x00 +#define TBSTYLE_SEP 0x01 +#define TBSTYLE_CHECK 0x02 +#define TBSTYLE_GROUP 0x04 +#define TBSTYLE_CHECKGROUP (TBSTYLE_GROUP | TBSTYLE_CHECK) +#define TBSTYLE_DROPDOWN 0x08 +#define TBSTYLE_AUTOSIZE 0x10 +#define TBSTYLE_NOPREFIX 0x20 +#define BTNS_BUTTON TBSTYLE_BUTTON +#define BTNS_SEP TBSTYLE_SEP +#define BTNS_CHECK TBSTYLE_CHECK +#define BTNS_GROUP TBSTYLE_GROUP +#define BTNS_CHECKGROUP TBSTYLE_CHECKGROUP +#define BTNS_DROPDOWN TBSTYLE_DROPDOWN +#define BTNS_AUTOSIZE TBSTYLE_AUTOSIZE +#define BTNS_NOPREFIX TBSTYLE_NOPREFIX +#define BTNS_SHOWTEXT 0x40 /* ignored unless TBSTYLE_EX_MIXEDB set */ +#define BTNS_WHOLEDROPDOWN 0x80 /* draw dropdown arrow, but without split arrow section */ + +#define TBSTYLE_TOOLTIPS 0x0100 +#define TBSTYLE_WRAPABLE 0x0200 +#define TBSTYLE_ALTDRAG 0x0400 +#define TBSTYLE_FLAT 0x0800 +#define TBSTYLE_LIST 0x1000 +#define TBSTYLE_CUSTOMERASE 0x2000 +#define TBSTYLE_REGISTERDROP 0x4000 +#define TBSTYLE_TRANSPARENT 0x8000 +#define TBSTYLE_EX_DRAWDDARROWS 0x00000001 +#define TBSTYLE_EX_UNDOC1 0x00000004 /* similar to TBSTYLE_WRAPABLE */ +#define TBSTYLE_EX_MIXEDBUTTONS 0x00000008 +#define TBSTYLE_EX_HIDECLIPPEDBUTTONS 0x00000010 /* don't show partially obscured buttons */ +#define TBSTYLE_EX_DOUBLEBUFFER 0x00000080 /* Double Buffer the toolbar ??? */ + +#define TBIF_IMAGE 0x00000001 +#define TBIF_TEXT 0x00000002 +#define TBIF_STATE 0x00000004 +#define TBIF_STYLE 0x00000008 +#define TBIF_LPARAM 0x00000010 +#define TBIF_COMMAND 0x00000020 +#define TBIF_SIZE 0x00000040 + +#define TBBF_LARGE 0x0001 + +#define TB_ENABLEBUTTON (WM_USER+1) +#define TB_CHECKBUTTON (WM_USER+2) +#define TB_PRESSBUTTON (WM_USER+3) +#define TB_HIDEBUTTON (WM_USER+4) +#define TB_INDETERMINATE (WM_USER+5) +#define TB_MARKBUTTON (WM_USER+6) +#define TB_ISBUTTONENABLED (WM_USER+9) +#define TB_ISBUTTONCHECKED (WM_USER+10) +#define TB_ISBUTTONPRESSED (WM_USER+11) +#define TB_ISBUTTONHIDDEN (WM_USER+12) +#define TB_ISBUTTONINDETERMINATE (WM_USER+13) +#define TB_ISBUTTONHIGHLIGHTED (WM_USER+14) +#define TB_SETSTATE (WM_USER+17) +#define TB_GETSTATE (WM_USER+18) +#define TB_ADDBITMAP (WM_USER+19) +#define TB_ADDBUTTONSA (WM_USER+20) +#define TB_ADDBUTTONSW (WM_USER+68) +#define TB_ADDBUTTONS WINELIB_NAME_AW(TB_ADDBUTTONS) +#define TB_HITTEST (WM_USER+69) +#define TB_INSERTBUTTONA (WM_USER+21) +#define TB_INSERTBUTTONW (WM_USER+67) +#define TB_INSERTBUTTON WINELIB_NAME_AW(TB_INSERTBUTTON) +#define TB_DELETEBUTTON (WM_USER+22) +#define TB_GETBUTTON (WM_USER+23) +#define TB_BUTTONCOUNT (WM_USER+24) +#define TB_COMMANDTOINDEX (WM_USER+25) +#define TB_SAVERESTOREA (WM_USER+26) +#define TB_SAVERESTOREW (WM_USER+76) +#define TB_SAVERESTORE WINELIB_NAME_AW(TB_SAVERESTORE) +#define TB_CUSTOMIZE (WM_USER+27) +#define TB_ADDSTRINGA (WM_USER+28) +#define TB_ADDSTRINGW (WM_USER+77) +#define TB_ADDSTRING WINELIB_NAME_AW(TB_ADDSTRING) +#define TB_GETITEMRECT (WM_USER+29) +#define TB_BUTTONSTRUCTSIZE (WM_USER+30) +#define TB_SETBUTTONSIZE (WM_USER+31) +#define TB_SETBITMAPSIZE (WM_USER+32) +#define TB_AUTOSIZE (WM_USER+33) +#define TB_GETTOOLTIPS (WM_USER+35) +#define TB_SETTOOLTIPS (WM_USER+36) +#define TB_SETPARENT (WM_USER+37) +#define TB_SETROWS (WM_USER+39) +#define TB_GETROWS (WM_USER+40) +#define TB_GETBITMAPFLAGS (WM_USER+41) +#define TB_SETCMDID (WM_USER+42) +#define TB_CHANGEBITMAP (WM_USER+43) +#define TB_GETBITMAP (WM_USER+44) +#define TB_GETBUTTONTEXTA (WM_USER+45) +#define TB_GETBUTTONTEXTW (WM_USER+75) +#define TB_GETBUTTONTEXT WINELIB_NAME_AW(TB_GETBUTTONTEXT) +#define TB_REPLACEBITMAP (WM_USER+46) +#define TB_SETINDENT (WM_USER+47) +#define TB_SETIMAGELIST (WM_USER+48) +#define TB_GETIMAGELIST (WM_USER+49) +#define TB_LOADIMAGES (WM_USER+50) +#define TB_GETRECT (WM_USER+51) /* wParam is the Cmd instead of index */ +#define TB_SETHOTIMAGELIST (WM_USER+52) +#define TB_GETHOTIMAGELIST (WM_USER+53) +#define TB_SETDISABLEDIMAGELIST (WM_USER+54) +#define TB_GETDISABLEDIMAGELIST (WM_USER+55) +#define TB_SETSTYLE (WM_USER+56) +#define TB_GETSTYLE (WM_USER+57) +#define TB_GETBUTTONSIZE (WM_USER+58) +#define TB_SETBUTTONWIDTH (WM_USER+59) +#define TB_SETMAXTEXTROWS (WM_USER+60) +#define TB_GETTEXTROWS (WM_USER+61) +#define TB_GETOBJECT (WM_USER+62) +#define TB_GETBUTTONINFOW (WM_USER+63) +#define TB_GETBUTTONINFOA (WM_USER+65) +#define TB_GETBUTTONINFO WINELIB_NAME_AW(TB_GETBUTTONINFO) +#define TB_SETBUTTONINFOW (WM_USER+64) +#define TB_SETBUTTONINFOA (WM_USER+66) +#define TB_SETBUTTONINFO WINELIB_NAME_AW(TB_SETBUTTONINFO) +#define TB_SETDRAWTEXTFLAGS (WM_USER+70) +#define TB_GETHOTITEM (WM_USER+71) +#define TB_SETHOTITEM (WM_USER+72) +#define TB_SETANCHORHIGHLIGHT (WM_USER+73) +#define TB_GETANCHORHIGHLIGHT (WM_USER+74) +#define TB_MAPACCELERATORA (WM_USER+78) +#define TB_MAPACCELERATORW (WM_USER+90) +#define TB_MAPACCELERATOR WINELIB_NAME_AW(TB_MAPACCELERATOR) +#define TB_GETINSERTMARK (WM_USER+79) +#define TB_SETINSERTMARK (WM_USER+80) +#define TB_INSERTMARKHITTEST (WM_USER+81) +#define TB_MOVEBUTTON (WM_USER+82) +#define TB_GETMAXSIZE (WM_USER+83) +#define TB_SETEXTENDEDSTYLE (WM_USER+84) +#define TB_GETEXTENDEDSTYLE (WM_USER+85) +#define TB_GETPADDING (WM_USER+86) +#define TB_SETPADDING (WM_USER+87) +#define TB_SETINSERTMARKCOLOR (WM_USER+88) +#define TB_GETINSERTMARKCOLOR (WM_USER+89) +#define TB_SETCOLORSCHEME CCM_SETCOLORSCHEME +#define TB_GETCOLORSCHEME CCM_GETCOLORSCHEME +#define TB_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define TB_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define TB_GETSTRINGW (WM_USER+91) +#define TB_GETSTRINGA (WM_USER+92) +#define TB_GETSTRING WINELIB_NAME_AW(TB_GETSTRING) + +/* undocumented messages in Toolbar */ +#define TB_UNKWN45D (WM_USER+93) +#define TB_UNKWN45E (WM_USER+94) +#define TB_UNKWN460 (WM_USER+96) +#define TB_UNKWN463 (WM_USER+99) +#define TB_UNKWN464 (WM_USER+100) + + +#define TBN_FIRST (0U-700U) +#define TBN_LAST (0U-720U) +#define TBN_GETBUTTONINFOA (TBN_FIRST-0) +#define TBN_GETBUTTONINFOW (TBN_FIRST-20) +#define TBN_GETBUTTONINFO WINELIB_NAME_AW(TBN_GETBUTTONINFO) +#define TBN_BEGINDRAG (TBN_FIRST-1) +#define TBN_ENDDRAG (TBN_FIRST-2) +#define TBN_BEGINADJUST (TBN_FIRST-3) +#define TBN_ENDADJUST (TBN_FIRST-4) +#define TBN_RESET (TBN_FIRST-5) +#define TBN_QUERYINSERT (TBN_FIRST-6) +#define TBN_QUERYDELETE (TBN_FIRST-7) +#define TBN_TOOLBARCHANGE (TBN_FIRST-8) +#define TBN_CUSTHELP (TBN_FIRST-9) +#define TBN_DROPDOWN (TBN_FIRST-10) +#define TBN_GETOBJECT (TBN_FIRST-12) +#define TBN_HOTITEMCHANGE (TBN_FIRST-13) +#define TBN_DRAGOUT (TBN_FIRST-14) +#define TBN_DELETINGBUTTON (TBN_FIRST-15) +#define TBN_GETDISPINFOA (TBN_FIRST-16) +#define TBN_GETDISPINFOW (TBN_FIRST-17) +#define TBN_GETDISPINFO WINELIB_NAME_AW(TBN_GETDISPINFO) +#define TBN_GETINFOTIPA (TBN_FIRST-18) +#define TBN_GETINFOTIPW (TBN_FIRST-19) +#define TBN_GETINFOTIP WINELIB_NAME_AW(TBN_GETINFOTIP) +#define TBN_INITCUSTOMIZE (TBN_FIRST-23) +#define TBNRF_HIDEHELP 0x00000001 + + +/* Return values from TBN_DROPDOWN */ +#define TBDDRET_DEFAULT 0 +#define TBDDRET_NODEFAULT 1 +#define TBDDRET_TREATPRESSED 2 + +typedef struct _NMTBCUSTOMDRAW +{ + NMCUSTOMDRAW nmcd; + HBRUSH hbrMonoDither; + HBRUSH hbrLines; + HPEN hpenLines; + COLORREF clrText; + COLORREF clrMark; + COLORREF clrTextHighlight; + COLORREF clrBtnFace; + COLORREF clrBtnHighlight; + COLORREF clrHighlightHotTrack; + RECT rcText; + int nStringBkMode; + int nHLStringBkMode; +} NMTBCUSTOMDRAW, *LPNMTBCUSTOMDRAW; + +/* return flags for Toolbar NM_CUSTOMDRAW notifications */ +#define TBCDRF_NOEDGES 0x00010000 /* Don't draw button edges */ +#define TBCDRF_HILITEHOTTRACK 0x00020000 /* Use color of the button bkgnd */ + /* when hottracked */ +#define TBCDRF_NOOFFSET 0x00040000 /* No offset button if pressed */ +#define TBCDRF_NOMARK 0x00080000 /* Don't draw default highlight */ + /* for TBSTATE_MARKED */ +#define TBCDRF_NOETCHEDEFFECT 0x00100000 /* No etched effect for */ + /* disabled items */ +#define TBCDRF_BLENDICON 0x00200000 /* ILD_BLEND50 on the icon image */ +#define TBCDRF_NOBACKGROUND 0x00400000 /* ILD_BLEND50 on the icon image */ + + +/* This is just for old CreateToolbar. */ +/* Don't use it in new programs. */ +typedef struct _OLDTBBUTTON { + INT iBitmap; + INT idCommand; + BYTE fsState; + BYTE fsStyle; + BYTE bReserved[2]; + DWORD dwData; +} OLDTBBUTTON, *POLDTBBUTTON, *LPOLDTBBUTTON; +typedef const OLDTBBUTTON *LPCOLDTBBUTTON; + + +typedef struct _TBBUTTON { + INT iBitmap; + INT idCommand; + BYTE fsState; + BYTE fsStyle; + BYTE bReserved[2]; + DWORD dwData; + INT iString; +} TBBUTTON, *PTBBUTTON, *LPTBBUTTON; +typedef const TBBUTTON *LPCTBBUTTON; + + +typedef struct _COLORMAP { + COLORREF from; + COLORREF to; +} COLORMAP, *LPCOLORMAP; + + +typedef struct tagTBADDBITMAP { + HINSTANCE hInst; + UINT nID; +} TBADDBITMAP, *LPTBADDBITMAP; + +#define HINST_COMMCTRL ((HINSTANCE)-1) +#define IDB_STD_SMALL_COLOR 0 +#define IDB_STD_LARGE_COLOR 1 +#define IDB_VIEW_SMALL_COLOR 4 +#define IDB_VIEW_LARGE_COLOR 5 +#define IDB_HIST_SMALL_COLOR 8 +#define IDB_HIST_LARGE_COLOR 9 + +#define STD_CUT 0 +#define STD_COPY 1 +#define STD_PASTE 2 +#define STD_UNDO 3 +#define STD_REDOW 4 +#define STD_DELETE 5 +#define STD_FILENEW 6 +#define STD_FILEOPEN 7 +#define STD_FILESAVE 8 +#define STD_PRINTPRE 9 +#define STD_PROPERTIES 10 +#define STD_HELP 11 +#define STD_FIND 12 +#define STD_REPLACE 13 +#define STD_PRINT 14 + +#define VIEW_LARGEICONS 0 +#define VIEW_SMALLICONS 1 +#define VIEW_LIST 2 +#define VIEW_DETAILS 3 +#define VIEW_SORTNAME 4 +#define VIEW_SORTSIZE 5 +#define VIEW_SORTDATE 6 +#define VIEW_SORTTYPE 7 +#define VIEW_PARENTFOLDER 8 +#define VIEW_NETCONNECT 9 +#define VIEW_NETDISCONNECT 10 +#define VIEW_NEWFOLDER 11 +#define VIEW_VIEWMENU 12 + +#define HIST_BACK 0 +#define HIST_FORWARD 1 +#define HIST_FAVORITES 2 +#define HIST_ADDTOFAVORITES 3 +#define HIST_VIEWTREE 4 + +typedef struct tagTBSAVEPARAMSA { + HKEY hkr; + LPCSTR pszSubKey; + LPCSTR pszValueName; +} TBSAVEPARAMSA, *LPTBSAVEPARAMSA; + +typedef struct tagTBSAVEPARAMSW { + HKEY hkr; + LPCWSTR pszSubKey; + LPCWSTR pszValueName; +} TBSAVEPARAMSW, *LPTBSAVEPARAMSW; + +#define TBSAVEPARAMS WINELIB_NAME_AW(TBSAVEPARAMS) +#define LPTBSAVEPARAMS WINELIB_NAME_AW(LPTBSAVEPARAMS) + +typedef struct +{ + UINT cbSize; + DWORD dwMask; + INT idCommand; + INT iImage; + BYTE fsState; + BYTE fsStyle; + WORD cx; + DWORD lParam; + LPSTR pszText; + INT cchText; +} TBBUTTONINFOA, *LPTBBUTTONINFOA; + +typedef struct +{ + UINT cbSize; + DWORD dwMask; + INT idCommand; + INT iImage; + BYTE fsState; + BYTE fsStyle; + WORD cx; + DWORD lParam; + LPWSTR pszText; + INT cchText; +} TBBUTTONINFOW, *LPTBBUTTONINFOW; + +#define TBBUTTONINFO WINELIB_NAME_AW(TBBUTTONINFO) +#define LPTBBUTTONINFO WINELIB_NAME_AW(LPTBBUTTONINFO) + +typedef struct tagNMTBHOTITEM +{ + NMHDR hdr; + int idOld; + int idNew; + DWORD dwFlags; +} NMTBHOTITEM, *LPNMTBHOTITEM; + +typedef struct tagNMTBGETINFOTIPA +{ + NMHDR hdr; + LPSTR pszText; + INT cchTextMax; + INT iItem; + LPARAM lParam; +} NMTBGETINFOTIPA, *LPNMTBGETINFOTIPA; + +typedef struct tagNMTBGETINFOTIPW +{ + NMHDR hdr; + LPWSTR pszText; + INT cchTextMax; + INT iItem; + LPARAM lParam; +} NMTBGETINFOTIPW, *LPNMTBGETINFOTIPW; + +#define NMTBGETINFOTIP WINELIB_NAME_AW(NMTBGETINFOFTIP) +#define LPNMTBGETINFOTIP WINELIB_NAME_AW(LPNMTBGETINFOTIP) + +typedef struct +{ + NMHDR hdr; + DWORD dwMask; + int idCommand; + DWORD lParam; + int iImage; + LPSTR pszText; + int cchText; +} NMTBDISPINFOA, *LPNMTBDISPINFOA; + +typedef struct +{ + NMHDR hdr; + DWORD dwMask; + int idCommand; + DWORD lParam; + int iImage; + LPWSTR pszText; + int cchText; +} NMTBDISPINFOW, *LPNMTBDISPINFOW; + +#define NMTBDISPINFO WINELIB_NAME_AW(NMTBDISPINFO) +#define LPNMTBDISPINFO WINELIB_NAME_AW(LPNMTBDISPINFO) + +/* contents of dwMask in the NMTBDISPINFO structure */ +#define TBNF_IMAGE 0x00000001 +#define TBNF_TEXT 0x00000002 +#define TBNF_DI_SETITEM 0x10000000 + + +typedef struct tagNMTOOLBARA +{ + NMHDR hdr; + INT iItem; + TBBUTTON tbButton; + INT cchText; + LPSTR pszText; + RECT rcButton; /* Version 5.80 */ +} NMTOOLBARA, *LPNMTOOLBARA, TBNOTIFYA, *LPTBNOTIFYA; + +typedef struct tagNMTOOLBARW +{ + NMHDR hdr; + INT iItem; + TBBUTTON tbButton; + INT cchText; + LPWSTR pszText; + RECT rcButton; /* Version 5.80 */ +} NMTOOLBARW, *LPNMTOOLBARW, TBNOTIFYW, *LPTBNOTIFYW; + +#define NMTOOLBAR WINELIB_NAME_AW(NMTOOLBAR) +#define LPNMTOOLBAR WINELIB_NAME_AW(LPNMTOOLBAR) +#define TBNOTIFY WINELIB_NAME_AW(TBNOTIFY) +#define LPTBNOTIFY WINELIB_NAME_AW(LPTBNOTIFY) + +typedef struct +{ + HINSTANCE hInstOld; + UINT nIDOld; + HINSTANCE hInstNew; + UINT nIDNew; + INT nButtons; +} TBREPLACEBITMAP, *LPTBREPLACEBITMAP; + +#define HICF_OTHER 0x00000000 +#define HICF_MOUSE 0x00000001 /* Triggered by mouse */ +#define HICF_ARROWKEYS 0x00000002 /* Triggered by arrow keys */ +#define HICF_ACCELERATOR 0x00000004 /* Triggered by accelerator */ +#define HICF_DUPACCEL 0x00000008 /* This accelerator is not unique */ +#define HICF_ENTERING 0x00000010 /* idOld is invalid */ +#define HICF_LEAVING 0x00000020 /* idNew is invalid */ +#define HICF_RESELECT 0x00000040 /* hot item reselected */ +#define HICF_LMOUSE 0x00000080 /* left mouse button selected */ +#define HICF_TOGGLEDROPDOWN 0x00000100 /* Toggle button's dropdown state */ + +typedef struct +{ + int iButton; + DWORD dwFlags; +} TBINSERTMARK, *LPTBINSERTMARK; +#define TBIMHT_AFTER 0x00000001 /* TRUE = insert After iButton, otherwise before */ +#define TBIMHT_BACKGROUND 0x00000002 /* TRUE if and only if missed buttons completely */ + +HWND WINAPI +CreateToolbar(HWND, DWORD, UINT, INT, HINSTANCE, + UINT, LPCOLDTBBUTTON, INT); + +HWND WINAPI +CreateToolbarEx(HWND, DWORD, UINT, INT, + HINSTANCE, UINT, LPCTBBUTTON, + INT, INT, INT, INT, INT, UINT); + +HBITMAP WINAPI +CreateMappedBitmap (HINSTANCE, INT, UINT, LPCOLORMAP, INT); + + +/* Tool tips */ + +#define TOOLTIPS_CLASS16 "tooltips_class" +#define TOOLTIPS_CLASSA "tooltips_class32" +#if defined(__GNUC__) +# define TOOLTIPS_CLASSW (const WCHAR []){ 't','o','o','l','t','i','p','s','_', \ + 'c','l','a','s','s','3','2',0 } +#elif defined(_MSC_VER) +# define TOOLTIPS_CLASSW L"tooltips_class32" +#else +static const WCHAR TOOLTIPS_CLASSW[] = { 't','o','o','l','t','i','p','s','_', + 'c','l','a','s','s','3','2',0 }; +#endif +#define TOOLTIPS_CLASS WINELIB_NAME_AW(TOOLTIPS_CLASS) + +#define INFOTIPSIZE 1024 + +#define TTS_ALWAYSTIP 0x01 +#define TTS_NOPREFIX 0x02 + +#define TTF_IDISHWND 0x0001 +#define TTF_CENTERTIP 0x0002 +#define TTF_RTLREADING 0x0004 +#define TTF_SUBCLASS 0x0010 +#define TTF_TRACK 0x0020 +#define TTF_ABSOLUTE 0x0080 +#define TTF_TRANSPARENT 0x0100 +#define TTF_DI_SETITEM 0x8000 /* valid only on the TTN_NEEDTEXT callback */ + + +#define TTDT_AUTOMATIC 0 +#define TTDT_RESHOW 1 +#define TTDT_AUTOPOP 2 +#define TTDT_INITIAL 3 + + +#define TTM_ACTIVATE (WM_USER+1) +#define TTM_SETDELAYTIME (WM_USER+3) +#define TTM_ADDTOOLA (WM_USER+4) +#define TTM_ADDTOOLW (WM_USER+50) +#define TTM_ADDTOOL WINELIB_NAME_AW(TTM_ADDTOOL) +#define TTM_DELTOOLA (WM_USER+5) +#define TTM_DELTOOLW (WM_USER+51) +#define TTM_DELTOOL WINELIB_NAME_AW(TTM_DELTOOL) +#define TTM_NEWTOOLRECTA (WM_USER+6) +#define TTM_NEWTOOLRECTW (WM_USER+52) +#define TTM_NEWTOOLRECT WINELIB_NAME_AW(TTM_NEWTOOLRECT) +#define TTM_RELAYEVENT (WM_USER+7) +#define TTM_GETTOOLINFOA (WM_USER+8) +#define TTM_GETTOOLINFOW (WM_USER+53) +#define TTM_GETTOOLINFO WINELIB_NAME_AW(TTM_GETTOOLINFO) +#define TTM_SETTOOLINFOA (WM_USER+9) +#define TTM_SETTOOLINFOW (WM_USER+54) +#define TTM_SETTOOLINFO WINELIB_NAME_AW(TTM_SETTOOLINFO) +#define TTM_HITTESTA (WM_USER+10) +#define TTM_HITTESTW (WM_USER+55) +#define TTM_HITTEST WINELIB_NAME_AW(TTM_HITTEST) +#define TTM_GETTEXTA (WM_USER+11) +#define TTM_GETTEXTW (WM_USER+56) +#define TTM_GETTEXT WINELIB_NAME_AW(TTM_GETTEXT) +#define TTM_UPDATETIPTEXTA (WM_USER+12) +#define TTM_UPDATETIPTEXTW (WM_USER+57) +#define TTM_UPDATETIPTEXT WINELIB_NAME_AW(TTM_UPDATETIPTEXT) +#define TTM_GETTOOLCOUNT (WM_USER+13) +#define TTM_ENUMTOOLSA (WM_USER+14) +#define TTM_ENUMTOOLSW (WM_USER+58) +#define TTM_ENUMTOOLS WINELIB_NAME_AW(TTM_ENUMTOOLS) +#define TTM_GETCURRENTTOOLA (WM_USER+15) +#define TTM_GETCURRENTTOOLW (WM_USER+59) +#define TTM_GETCURRENTTOOL WINELIB_NAME_AW(TTM_GETCURRENTTOOL) +#define TTM_WINDOWFROMPOINT (WM_USER+16) +#define TTM_TRACKACTIVATE (WM_USER+17) +#define TTM_TRACKPOSITION (WM_USER+18) +#define TTM_SETTIPBKCOLOR (WM_USER+19) +#define TTM_SETTIPTEXTCOLOR (WM_USER+20) +#define TTM_GETDELAYTIME (WM_USER+21) +#define TTM_GETTIPBKCOLOR (WM_USER+22) +#define TTM_GETTIPTEXTCOLOR (WM_USER+23) +#define TTM_SETMAXTIPWIDTH (WM_USER+24) +#define TTM_GETMAXTIPWIDTH (WM_USER+25) +#define TTM_SETMARGIN (WM_USER+26) +#define TTM_GETMARGIN (WM_USER+27) +#define TTM_POP (WM_USER+28) +#define TTM_UPDATE (WM_USER+29) +#define TTM_GETBUBBLESIZE (WM_USER+30) + + +#define TTN_FIRST (0U-520U) +#define TTN_LAST (0U-549U) +#define TTN_GETDISPINFOA (TTN_FIRST-0) +#define TTN_GETDISPINFOW (TTN_FIRST-10) +#define TTN_GETDISPINFO WINELIB_NAME_AW(TTN_GETDISPINFO) +#define TTN_SHOW (TTN_FIRST-1) +#define TTN_POP (TTN_FIRST-2) + +#define TTN_NEEDTEXT TTN_GETDISPINFO +#define TTN_NEEDTEXTA TTN_GETDISPINFOA +#define TTN_NEEDTEXTW TTN_GETDISPINFOW + +typedef struct tagTOOLINFOA { + UINT cbSize; + UINT uFlags; + HWND hwnd; + UINT uId; + RECT rect; + HINSTANCE hinst; + LPSTR lpszText; + LPARAM lParam; +} TTTOOLINFOA, *LPTOOLINFOA, *PTOOLINFOA, *LPTTTOOLINFOA; + +typedef struct tagTOOLINFOW { + UINT cbSize; + UINT uFlags; + HWND hwnd; + UINT uId; + RECT rect; + HINSTANCE hinst; + LPWSTR lpszText; + LPARAM lParam; +} TTTOOLINFOW, *LPTOOLINFOW, *PTOOLINFOW, *LPTTTOOLINFOW; + +#define TTTOOLINFO WINELIB_NAME_AW(TTTOOLINFO) +#define TOOLINFO WINELIB_NAME_AW(TTTOOLINFO) +#define PTOOLINFO WINELIB_NAME_AW(PTOOLINFO) +#define LPTTTOOLINFO WINELIB_NAME_AW(LPTTTOOLINFO) +#define LPTOOLINFO WINELIB_NAME_AW(LPTOOLINFO) + +#define TTTOOLINFO_V1_SIZEA CCSIZEOF_STRUCT(TTTOOLINFOA, lpszText) +#define TTTOOLINFO_V1_SIZEW CCSIZEOF_STRUCT(TTTOOLINFOW, lpszText) +#define TTTOOLINFO_V1_SIZE WINELIB_NAME_AW(TTTOOLINFO_V1_SIZE) + +typedef struct _TT_HITTESTINFOA +{ + HWND hwnd; + POINT pt; + TTTOOLINFOA ti; +} TTHITTESTINFOA, *LPTTHITTESTINFOA; +#define LPHITTESTINFOA LPTTHITTESTINFOA + +typedef struct _TT_HITTESTINFOW +{ + HWND hwnd; + POINT pt; + TTTOOLINFOW ti; +} TTHITTESTINFOW, *LPTTHITTESTINFOW; +#define LPHITTESTINFOW LPTTHITTESTINFOW + +#define TTHITTESTINFO WINELIB_NAME_AW(TTHITTESTINFO) +#define LPTTHITTESTINFO WINELIB_NAME_AW(LPTTHITTESTINFO) +#define LPHITTESTINFO WINELIB_NAME_AW(LPHITTESTINFO) + +typedef struct tagNMTTDISPINFOA +{ + NMHDR hdr; + LPSTR lpszText; + CHAR szText[80]; + HINSTANCE hinst; + UINT uFlags; + LPARAM lParam; +} NMTTDISPINFOA, *LPNMTTDISPINFOA; + +typedef struct tagNMTTDISPINFOW +{ + NMHDR hdr; + LPWSTR lpszText; + WCHAR szText[80]; + HINSTANCE hinst; + UINT uFlags; + LPARAM lParam; +} NMTTDISPINFOW, *LPNMTTDISPINFOW; + +#define NMTTDISPINFO WINELIB_NAME_AW(NMTTDISPINFO) +#define LPNMTTDISPINFO WINELIB_NAME_AW(LPNMTTDISPINFO) + +#define NMTTDISPINFO_V1_SIZEA CCSIZEOF_STRUCT(NMTTDISPINFOA, uFlags) +#define NMTTDISPINFO_V1_SIZEW CCSIZEOF_STRUCT(NMTTDISPINFOW, uFlags) +#define NMTTDISPINFO_V1_SIZE WINELIB_NAME_AW(NMTTDISPINFO_V1_SIZE) + +#define TOOLTIPTEXTW NMTTDISPINFOW +#define TOOLTIPTEXTA NMTTDISPINFOA +#define TOOLTIPTEXT NMTTDISPINFO +#define LPTOOLTIPTEXTW LPNMTTDISPINFOW +#define LPTOOLTIPTEXTA LPNMTTDISPINFOA +#define LPTOOLTIPTEXT LPNMTTDISPINFO + + +/* Rebar control */ + +#define REBARCLASSNAME16 "ReBarWindow" +#define REBARCLASSNAMEA "ReBarWindow32" +#if defined(__GNUC__) +# define REBARCLASSNAMEW (const WCHAR []){ 'R','e','B','a','r', \ + 'W','i','n','d','o','w','3','2',0 } +#elif defined(_MSC_VER) +# define REBARCLASSNAMEW L"ReBarWindow32" +#else +static const WCHAR REBARCLASSNAMEW[] = { 'R','e','B','a','r', + 'W','i','n','d','o','w','3','2',0 }; +#endif +#define REBARCLASSNAME WINELIB_NAME_AW(REBARCLASSNAME) + +#define RBS_TOOLTIPS 0x0100 +#define RBS_VARHEIGHT 0x0200 +#define RBS_BANDBORDERS 0x0400 +#define RBS_FIXEDORDER 0x0800 +#define RBS_REGISTERDROP 0x1000 +#define RBS_AUTOSIZE 0x2000 +#define RBS_VERTICALGRIPPER 0x4000 +#define RBS_DBLCLKTOGGLE 0x8000 + +#define RBIM_IMAGELIST 0x00000001 + +#define RBBIM_STYLE 0x00000001 +#define RBBIM_COLORS 0x00000002 +#define RBBIM_TEXT 0x00000004 +#define RBBIM_IMAGE 0x00000008 +#define RBBIM_CHILD 0x00000010 +#define RBBIM_CHILDSIZE 0x00000020 +#define RBBIM_SIZE 0x00000040 +#define RBBIM_BACKGROUND 0x00000080 +#define RBBIM_ID 0x00000100 +#define RBBIM_IDEALSIZE 0x00000200 +#define RBBIM_LPARAM 0x00000400 +#define RBBIM_HEADERSIZE 0x00000800 + +#define RBBS_BREAK 0x00000001 +#define RBBS_FIXEDSIZE 0x00000002 +#define RBBS_CHILDEDGE 0x00000004 +#define RBBS_HIDDEN 0x00000008 +#define RBBS_NOVERT 0x00000010 +#define RBBS_FIXEDBMP 0x00000020 +#define RBBS_VARIABLEHEIGHT 0x00000040 +#define RBBS_GRIPPERALWAYS 0x00000080 +#define RBBS_NOGRIPPER 0x00000100 + +#define RBNM_ID 0x00000001 +#define RBNM_STYLE 0x00000002 +#define RBNM_LPARAM 0x00000004 + +#define RBHT_NOWHERE 0x0001 +#define RBHT_CAPTION 0x0002 +#define RBHT_CLIENT 0x0003 +#define RBHT_GRABBER 0x0004 + +#define RB_INSERTBANDA (WM_USER+1) +#define RB_INSERTBANDW (WM_USER+10) +#define RB_INSERTBAND WINELIB_NAME_AW(RB_INSERTBAND) +#define RB_DELETEBAND (WM_USER+2) +#define RB_GETBARINFO (WM_USER+3) +#define RB_SETBARINFO (WM_USER+4) +#define RB_GETBANDINFO (WM_USER+5) /* just for compatibility */ +#define RB_SETBANDINFOA (WM_USER+6) +#define RB_SETBANDINFOW (WM_USER+11) +#define RB_SETBANDINFO WINELIB_NAME_AW(RB_SETBANDINFO) +#define RB_SETPARENT (WM_USER+7) +#define RB_HITTEST (WM_USER+8) +#define RB_GETRECT (WM_USER+9) +#define RB_GETBANDCOUNT (WM_USER+12) +#define RB_GETROWCOUNT (WM_USER+13) +#define RB_GETROWHEIGHT (WM_USER+14) +#define RB_IDTOINDEX (WM_USER+16) +#define RB_GETTOOLTIPS (WM_USER+17) +#define RB_SETTOOLTIPS (WM_USER+18) +#define RB_SETBKCOLOR (WM_USER+19) +#define RB_GETBKCOLOR (WM_USER+20) +#define RB_SETTEXTCOLOR (WM_USER+21) +#define RB_GETTEXTCOLOR (WM_USER+22) +#define RB_SIZETORECT (WM_USER+23) +#define RB_BEGINDRAG (WM_USER+24) +#define RB_ENDDRAG (WM_USER+25) +#define RB_DRAGMOVE (WM_USER+26) +#define RB_GETBARHEIGHT (WM_USER+27) +#define RB_GETBANDINFOW (WM_USER+28) +#define RB_GETBANDINFOA (WM_USER+29) +#define RB_GETBANDINFO16 WINELIB_NAME_AW(RB_GETBANDINFO16) +#define RB_MINIMIZEBAND (WM_USER+30) +#define RB_MAXIMIZEBAND (WM_USER+31) +#define RB_GETBANDBORDERS (WM_USER+34) +#define RB_SHOWBAND (WM_USER+35) +#define RB_SETPALETTE (WM_USER+37) +#define RB_GETPALETTE (WM_USER+38) +#define RB_MOVEBAND (WM_USER+39) +#define RB_GETDROPTARGET CCM_GETDROPTARGET +#define RB_SETCOLORSCHEME CCM_SETCOLORSCHEME +#define RB_GETCOLORSCHEME CCM_GETCOLORSCHEME +#define RB_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define RB_GETUNICODEFORMAT CCM_GETUNICODEFORMAT + +#define RBN_FIRST (0U-831U) +#define RBN_LAST (0U-859U) +#define RBN_HEIGHTCHANGE (RBN_FIRST-0) +#define RBN_GETOBJECT (RBN_FIRST-1) +#define RBN_LAYOUTCHANGED (RBN_FIRST-2) +#define RBN_AUTOSIZE (RBN_FIRST-3) +#define RBN_BEGINDRAG (RBN_FIRST-4) +#define RBN_ENDDRAG (RBN_FIRST-5) +#define RBN_DELETINGBAND (RBN_FIRST-6) +#define RBN_DELETEDBAND (RBN_FIRST-7) +#define RBN_CHILDSIZE (RBN_FIRST-8) + +typedef struct tagREBARINFO +{ + UINT cbSize; + UINT fMask; + HIMAGELIST himl; +} REBARINFO, *LPREBARINFO; + +typedef struct tagREBARBANDINFOA +{ + UINT cbSize; + UINT fMask; + UINT fStyle; + COLORREF clrFore; + COLORREF clrBack; + LPSTR lpText; + UINT cch; + INT iImage; + HWND hwndChild; + UINT cxMinChild; + UINT cyMinChild; + UINT cx; + HBITMAP hbmBack; + UINT wID; + UINT cyChild; + UINT cyMaxChild; + UINT cyIntegral; + UINT cxIdeal; + LPARAM lParam; + UINT cxHeader; +} REBARBANDINFOA, *LPREBARBANDINFOA; + +typedef REBARBANDINFOA const *LPCREBARBANDINFOA; + +typedef struct tagREBARBANDINFOW +{ + UINT cbSize; + UINT fMask; + UINT fStyle; + COLORREF clrFore; + COLORREF clrBack; + LPWSTR lpText; + UINT cch; + INT iImage; + HWND hwndChild; + UINT cxMinChild; + UINT cyMinChild; + UINT cx; + HBITMAP hbmBack; + UINT wID; + UINT cyChild; + UINT cyMaxChild; + UINT cyIntegral; + UINT cxIdeal; + LPARAM lParam; + UINT cxHeader; +} REBARBANDINFOW, *LPREBARBANDINFOW; + +typedef REBARBANDINFOW const *LPCREBARBANDINFOW; + +#define REBARBANDINFO WINELIB_NAME_AW(REBARBANDINFO) +#define LPREBARBANDINFO WINELIB_NAME_AW(LPREBARBANDINFO) +#define LPCREBARBANDINFO WINELIB_NAME_AW(LPCREBARBANDINFO) + +#define REBARBANDINFO_V3_SIZEA CCSIZEOF_STRUCT(REBARBANDINFOA, wID) +#define REBARBANDINFO_V3_SIZEW CCSIZEOF_STRUCT(REBARBANDINFOW, wID) +#define REBARBANDINFO_V3_SIZE WINELIB_NAME_AW(REBARBANDINFO_V3_SIZE) + +typedef struct tagNMREBARCHILDSIZE +{ + NMHDR hdr; + UINT uBand; + UINT wID; + RECT rcChild; + RECT rcBand; +} NMREBARCHILDSIZE, *LPNMREBARCHILDSIZE; + +typedef struct tagNMREBAR +{ + NMHDR hdr; + DWORD dwMask; + UINT uBand; + UINT fStyle; + UINT wID; + LPARAM lParam; +} NMREBAR, *LPNMREBAR; + +typedef struct tagNMRBAUTOSIZE +{ + NMHDR hdr; + BOOL fChanged; + RECT rcTarget; + RECT rcActual; +} NMRBAUTOSIZE, *LPNMRBAUTOSIZE; + +typedef struct _RB_HITTESTINFO +{ + POINT pt; + UINT flags; + INT iBand; +} RBHITTESTINFO, *LPRBHITTESTINFO; + + +/* Trackbar control */ + +#define TRACKBAR_CLASS16 "msctls_trackbar" +#define TRACKBAR_CLASSA "msctls_trackbar32" +#if defined(__GNUC__) +# define TRACKBAR_CLASSW (const WCHAR []){ 'm','s','c','t','l','s','_', \ + 't','r','a','c','k','b','a','r','3','2',0 } +#elif defined(_MSC_VER) +# define TRACKBAR_CLASSW L"msctls_trackbar32" +#else +static const WCHAR TRACKBAR_CLASSW[] = { 'm','s','c','t','l','s','_', + 't','r','a','c','k','b','a','r','3','2',0 }; +#endif +#define TRACKBAR_CLASS WINELIB_NAME_AW(TRACKBAR_CLASS) + +#define TBS_AUTOTICKS 0x0001 +#define TBS_VERT 0x0002 +#define TBS_HORZ 0x0000 +#define TBS_TOP 0x0004 +#define TBS_BOTTOM 0x0000 +#define TBS_LEFT 0x0004 +#define TBS_RIGHT 0x0000 +#define TBS_BOTH 0x0008 +#define TBS_NOTICKS 0x0010 +#define TBS_ENABLESELRANGE 0x0020 +#define TBS_FIXEDLENGTH 0x0040 +#define TBS_NOTHUMB 0x0080 +#define TBS_TOOLTIPS 0x0100 +#define TBS_REVERSED 0x0200 +#define TBS_DOWNISLEFT 0x0400 + +#define TBTS_TOP 0 +#define TBTS_LEFT 1 +#define TBTS_BOTTOM 2 +#define TBTS_RIGHT 3 + +#define TB_LINEUP 0 +#define TB_LINEDOWN 1 +#define TB_PAGEUP 2 +#define TB_PAGEDOWN 3 +#define TB_THUMBPOSITION 4 +#define TB_THUMBTRACK 5 +#define TB_TOP 6 +#define TB_BOTTOM 7 +#define TB_ENDTRACK 8 + +#define TBCD_TICS 0x0001 +#define TBCD_THUMB 0x0002 +#define TBCD_CHANNEL 0x0003 + +#define TBM_GETPOS (WM_USER) +#define TBM_GETRANGEMIN (WM_USER+1) +#define TBM_GETRANGEMAX (WM_USER+2) +#define TBM_GETTIC (WM_USER+3) +#define TBM_SETTIC (WM_USER+4) +#define TBM_SETPOS (WM_USER+5) +#define TBM_SETRANGE (WM_USER+6) +#define TBM_SETRANGEMIN (WM_USER+7) +#define TBM_SETRANGEMAX (WM_USER+8) +#define TBM_CLEARTICS (WM_USER+9) +#define TBM_SETSEL (WM_USER+10) +#define TBM_SETSELSTART (WM_USER+11) +#define TBM_SETSELEND (WM_USER+12) +#define TBM_GETPTICS (WM_USER+14) +#define TBM_GETTICPOS (WM_USER+15) +#define TBM_GETNUMTICS (WM_USER+16) +#define TBM_GETSELSTART (WM_USER+17) +#define TBM_GETSELEND (WM_USER+18) +#define TBM_CLEARSEL (WM_USER+19) +#define TBM_SETTICFREQ (WM_USER+20) +#define TBM_SETPAGESIZE (WM_USER+21) +#define TBM_GETPAGESIZE (WM_USER+22) +#define TBM_SETLINESIZE (WM_USER+23) +#define TBM_GETLINESIZE (WM_USER+24) +#define TBM_GETTHUMBRECT (WM_USER+25) +#define TBM_GETCHANNELRECT (WM_USER+26) +#define TBM_SETTHUMBLENGTH (WM_USER+27) +#define TBM_GETTHUMBLENGTH (WM_USER+28) +#define TBM_SETTOOLTIPS (WM_USER+29) +#define TBM_GETTOOLTIPS (WM_USER+30) +#define TBM_SETTIPSIDE (WM_USER+31) +#define TBM_SETBUDDY (WM_USER+32) +#define TBM_GETBUDDY (WM_USER+33) +#define TBM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define TBM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT + + +/* Pager control */ + +#define WC_PAGESCROLLERA "SysPager" +#if defined(__GNUC__) +# define WC_PAGESCROLLERW (const WCHAR []){ 'S','y','s','P','a','g','e','r',0 } +#elif defined(_MSC_VER) +# define WC_PAGESCROLLERW L"SysPager" +#else +static const WCHAR WC_PAGESCROLLERW[] = { 'S','y','s','P','a','g','e','r',0 }; +#endif +#define WC_PAGESCROLLER WINELIB_NAME_AW(WC_PAGESCROLLER) + +#define PGS_VERT 0x00000000 +#define PGS_HORZ 0x00000001 +#define PGS_AUTOSCROLL 0x00000002 +#define PGS_DRAGNDROP 0x00000004 + +#define PGF_INVISIBLE 0 +#define PGF_NORMAL 1 +#define PGF_GRAYED 2 +#define PGF_DEPRESSED 4 +#define PGF_HOT 8 + +#define PGB_TOPORLEFT 0 +#define PGB_BOTTOMORRIGHT 1 + +/* only used with PGN_SCROLL */ +#define PGF_SCROLLUP 1 +#define PGF_SCROLLDOWN 2 +#define PGF_SCROLLLEFT 4 +#define PGF_SCROLLRIGHT 8 + +#define PGK_SHIFT 1 +#define PGK_CONTROL 2 +#define PGK_MENU 4 + +/* only used with PGN_CALCSIZE */ +#define PGF_CALCWIDTH 1 +#define PGF_CALCHEIGHT 2 + +#define PGM_FIRST 0x1400 +#define PGM_SETCHILD (PGM_FIRST+1) +#define PGM_RECALCSIZE (PGM_FIRST+2) +#define PGM_FORWARDMOUSE (PGM_FIRST+3) +#define PGM_SETBKCOLOR (PGM_FIRST+4) +#define PGM_GETBKCOLOR (PGM_FIRST+5) +#define PGM_SETBORDER (PGM_FIRST+6) +#define PGM_GETBORDER (PGM_FIRST+7) +#define PGM_SETPOS (PGM_FIRST+8) +#define PGM_GETPOS (PGM_FIRST+9) +#define PGM_SETBUTTONSIZE (PGM_FIRST+10) +#define PGM_GETBUTTONSIZE (PGM_FIRST+11) +#define PGM_GETBUTTONSTATE (PGM_FIRST+12) +#define PGM_GETDROPTARGET CCM_GETDROPTARGET + +#define PGN_FIRST (0U-900U) +#define PGN_LAST (0U-950U) +#define PGN_SCROLL (PGN_FIRST-1) +#define PGN_CALCSIZE (PGN_FIRST-2) + +#include "pshpack1.h" + +typedef struct +{ + NMHDR hdr; + WORD fwKeys; + RECT rcParent; + INT iDir; + INT iXpos; + INT iYpos; + INT iScroll; +} NMPGSCROLL, *LPNMPGSCROLL; + +#include "poppack.h" + +typedef struct +{ + NMHDR hdr; + DWORD dwFlag; + INT iWidth; + INT iHeight; +} NMPGCALCSIZE, *LPNMPGCALCSIZE; + + +/* Treeview control */ + +#define WC_TREEVIEWA "SysTreeView32" +#if defined(__GNUC__) +# define WC_TREEVIEWW (const WCHAR []){ 'S','y','s', \ + 'T','r','e','e','V','i','e','w','3','2',0 } +#elif defined(_MSC_VER) +# define WC_TREEVIEWW L"SysTreeView32" +#else +static const WCHAR WC_TREEVIEWW[] = { 'S','y','s', + 'T','r','e','e','V','i','e','w','3','2',0 }; +#endif +#define WC_TREEVIEW WINELIB_NAME_AW(WC_TREEVIEW) + +#define TVSIL_NORMAL 0 +#define TVSIL_STATE 2 + +#define TV_FIRST 0x1100 +#define TVM_INSERTITEMA (TV_FIRST+0) +#define TVM_INSERTITEMW (TV_FIRST+50) +#define TVM_INSERTITEM WINELIB_NAME_AW(TVM_INSERTITEM) +#define TVM_DELETEITEM (TV_FIRST+1) +#define TVM_EXPAND (TV_FIRST+2) +#define TVM_GETITEMRECT (TV_FIRST+4) +#define TVM_GETCOUNT (TV_FIRST+5) +#define TVM_GETINDENT (TV_FIRST+6) +#define TVM_SETINDENT (TV_FIRST+7) +#define TVM_GETIMAGELIST (TV_FIRST+8) +#define TVM_SETIMAGELIST (TV_FIRST+9) +#define TVM_GETNEXTITEM (TV_FIRST+10) +#define TVM_SELECTITEM (TV_FIRST+11) +#define TVM_GETITEMA (TV_FIRST+12) +#define TVM_GETITEMW (TV_FIRST+62) +#define TVM_GETITEM WINELIB_NAME_AW(TVM_GETITEM) +#define TVM_SETITEMA (TV_FIRST+13) +#define TVM_SETITEMW (TV_FIRST+63) +#define TVM_SETITEM WINELIB_NAME_AW(TVM_SETITEM) +#define TVM_EDITLABELA (TV_FIRST+14) +#define TVM_EDITLABELW (TV_FIRST+65) +#define TVM_EDITLABEL WINELIB_NAME_AW(TVM_EDITLABEL) +#define TVM_GETEDITCONTROL (TV_FIRST+15) +#define TVM_GETVISIBLECOUNT (TV_FIRST+16) +#define TVM_HITTEST (TV_FIRST+17) +#define TVM_CREATEDRAGIMAGE (TV_FIRST+18) +#define TVM_SORTCHILDREN (TV_FIRST+19) +#define TVM_ENSUREVISIBLE (TV_FIRST+20) +#define TVM_SORTCHILDRENCB (TV_FIRST+21) +#define TVM_ENDEDITLABELNOW (TV_FIRST+22) +#define TVM_GETISEARCHSTRINGA (TV_FIRST+23) +#define TVM_GETISEARCHSTRINGW (TV_FIRST+64) +#define TVM_GETISEARCHSTRING WINELIB_NAME_AW(TVM_GETISEARCHSTRING) +#define TVM_SETTOOLTIPS (TV_FIRST+24) +#define TVM_GETTOOLTIPS (TV_FIRST+25) +#define TVM_SETINSERTMARK (TV_FIRST+26) +#define TVM_SETITEMHEIGHT (TV_FIRST+27) +#define TVM_GETITEMHEIGHT (TV_FIRST+28) +#define TVM_SETBKCOLOR (TV_FIRST+29) +#define TVM_SETTEXTCOLOR (TV_FIRST+30) +#define TVM_GETBKCOLOR (TV_FIRST+31) +#define TVM_GETTEXTCOLOR (TV_FIRST+32) +#define TVM_SETSCROLLTIME (TV_FIRST+33) +#define TVM_GETSCROLLTIME (TV_FIRST+34) +#define TVM_UNKNOWN35 (TV_FIRST+35) +#define TVM_UNKNOWN36 (TV_FIRST+36) +#define TVM_SETINSERTMARKCOLOR (TV_FIRST+37) +#define TVM_GETINSERTMARKCOLOR (TV_FIRST+38) +#define TVM_GETITEMSTATE (TV_FIRST+39) +#define TVM_SETLINECOLOR (TV_FIRST+40) +#define TVM_GETLINECOLOR (TV_FIRST+41) +#define TVM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define TVM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT + + + +#define TVN_FIRST (0U-400U) +#define TVN_LAST (0U-499U) + +#define TVN_SELCHANGINGA (TVN_FIRST-1) +#define TVN_SELCHANGINGW (TVN_FIRST-50) +#define TVN_SELCHANGING WINELIB_NAME_AW(TVN_SELCHANGING) + +#define TVN_SELCHANGEDA (TVN_FIRST-2) +#define TVN_SELCHANGEDW (TVN_FIRST-51) +#define TVN_SELCHANGED WINELIB_NAME_AW(TVN_SELCHANGED) + +#define TVN_GETDISPINFOA (TVN_FIRST-3) +#define TVN_GETDISPINFOW (TVN_FIRST-52) +#define TVN_GETDISPINFO WINELIB_NAME_AW(TVN_GETDISPINFO) + +#define TVN_SETDISPINFOA (TVN_FIRST-4) +#define TVN_SETDISPINFOW (TVN_FIRST-53) +#define TVN_SETDISPINFO WINELIB_NAME_AW(TVN_SETDISPINFO) + +#define TVN_ITEMEXPANDINGA (TVN_FIRST-5) +#define TVN_ITEMEXPANDINGW (TVN_FIRST-54) +#define TVN_ITEMEXPANDING WINELIB_NAME_AW(TVN_ITEMEXPANDING) + +#define TVN_ITEMEXPANDEDA (TVN_FIRST-6) +#define TVN_ITEMEXPANDEDW (TVN_FIRST-55) +#define TVN_ITEMEXPANDED WINELIB_NAME_AW(TVN_ITEMEXPANDED) + +#define TVN_BEGINDRAGA (TVN_FIRST-7) +#define TVN_BEGINDRAGW (TVN_FIRST-56) +#define TVN_BEGINDRAG WINELIB_NAME_AW(TVN_BEGINDRAG) + +#define TVN_BEGINRDRAGA (TVN_FIRST-8) +#define TVN_BEGINRDRAGW (TVN_FIRST-57) +#define TVN_BEGINRDRAG WINELIB_NAME_AW(TVN_BEGINRDRAG) + +#define TVN_DELETEITEMA (TVN_FIRST-9) +#define TVN_DELETEITEMW (TVN_FIRST-58) +#define TVN_DELETEITEM WINELIB_NAME_AW(TVN_DELETEITEM) + +#define TVN_BEGINLABELEDITA (TVN_FIRST-10) +#define TVN_BEGINLABELEDITW (TVN_FIRST-59) +#define TVN_BEGINLABELEDIT WINELIB_NAME_AW(TVN_BEGINLABELEDIT) + +#define TVN_ENDLABELEDITA (TVN_FIRST-11) +#define TVN_ENDLABELEDITW (TVN_FIRST-60) +#define TVN_ENDLABELEDIT WINELIB_NAME_AW(TVN_ENDLABELEDIT) + +#define TVN_KEYDOWN (TVN_FIRST-12) + +#define TVN_GETINFOTIPA (TVN_FIRST-13) +#define TVN_GETINFOTIPW (TVN_FIRST-14) +#define TVN_GETINFOTIP WINELIB_NAME_AW(TVN_GETINFOTIP) + +#define TVN_SINGLEEXPAND (TVN_FIRST-15) + + + + + +#define TVIF_TEXT 0x0001 +#define TVIF_IMAGE 0x0002 +#define TVIF_PARAM 0x0004 +#define TVIF_STATE 0x0008 +#define TVIF_HANDLE 0x0010 +#define TVIF_SELECTEDIMAGE 0x0020 +#define TVIF_CHILDREN 0x0040 +#define TVIF_INTEGRAL 0x0080 +#define TVIF_DI_SETITEM 0x1000 + +#define TVI_ROOT ((HTREEITEM)0xffff0000) /* -65536 */ +#define TVI_FIRST ((HTREEITEM)0xffff0001) /* -65535 */ +#define TVI_LAST ((HTREEITEM)0xffff0002) /* -65534 */ +#define TVI_SORT ((HTREEITEM)0xffff0003) /* -65533 */ + +#define TVIS_FOCUSED 0x0001 +#define TVIS_SELECTED 0x0002 +#define TVIS_CUT 0x0004 +#define TVIS_DROPHILITED 0x0008 +#define TVIS_BOLD 0x0010 +#define TVIS_EXPANDED 0x0020 +#define TVIS_EXPANDEDONCE 0x0040 +#define TVIS_EXPANDPARTIAL 0x0080 +#define TVIS_OVERLAYMASK 0x0f00 +#define TVIS_STATEIMAGEMASK 0xf000 +#define TVIS_USERMASK 0xf000 + +#define TVHT_NOWHERE 0x0001 +#define TVHT_ONITEMICON 0x0002 +#define TVHT_ONITEMLABEL 0x0004 +#define TVHT_ONITEMINDENT 0x0008 +#define TVHT_ONITEMBUTTON 0x0010 +#define TVHT_ONITEMRIGHT 0x0020 +#define TVHT_ONITEMSTATEICON 0x0040 +#define TVHT_ONITEM 0x0046 +#define TVHT_ABOVE 0x0100 +#define TVHT_BELOW 0x0200 +#define TVHT_TORIGHT 0x0400 +#define TVHT_TOLEFT 0x0800 + +#define TVS_HASBUTTONS 0x0001 +#define TVS_HASLINES 0x0002 +#define TVS_LINESATROOT 0x0004 +#define TVS_EDITLABELS 0x0008 +#define TVS_DISABLEDRAGDROP 0x0010 +#define TVS_SHOWSELALWAYS 0x0020 +#define TVS_RTLREADING 0x0040 +#define TVS_NOTOOLTIPS 0x0080 +#define TVS_CHECKBOXES 0x0100 +#define TVS_TRACKSELECT 0x0200 +#define TVS_SINGLEEXPAND 0x0400 +#define TVS_INFOTIP 0x0800 +#define TVS_FULLROWSELECT 0x1000 +#define TVS_NOSCROLL 0x2000 +#define TVS_NONEVENHEIGHT 0x4000 +#define TVS_NOHSCROLL 0x8000 + +#define TVS_SHAREDIMAGELISTS 0x0000 +#define TVS_PRIVATEIMAGELISTS 0x0400 + + +#define TVE_COLLAPSE 0x0001 +#define TVE_EXPAND 0x0002 +#define TVE_TOGGLE 0x0003 +#define TVE_EXPANDPARTIAL 0x4000 +#define TVE_COLLAPSERESET 0x8000 + +#define TVGN_ROOT 0 +#define TVGN_NEXT 1 +#define TVGN_PREVIOUS 2 +#define TVGN_PARENT 3 +#define TVGN_CHILD 4 +#define TVGN_FIRSTVISIBLE 5 +#define TVGN_NEXTVISIBLE 6 +#define TVGN_PREVIOUSVISIBLE 7 +#define TVGN_DROPHILITE 8 +#define TVGN_CARET 9 +#define TVGN_LASTVISIBLE 10 + +#define TVC_UNKNOWN 0x00 +#define TVC_BYMOUSE 0x01 +#define TVC_BYKEYBOARD 0x02 + + +typedef struct _TREEITEM *HTREEITEM; + +typedef struct { + UINT mask; + HTREEITEM hItem; + UINT state; + UINT stateMask; + LPSTR pszText; + INT cchTextMax; + INT iImage; + INT iSelectedImage; + INT cChildren; + LPARAM lParam; +} TVITEMA, *LPTVITEMA; + +typedef struct { + UINT mask; + HTREEITEM hItem; + UINT state; + UINT stateMask; + LPWSTR pszText; + INT cchTextMax; + INT iImage; + INT iSelectedImage; + INT cChildren; + LPARAM lParam; +} TVITEMW, *LPTVITEMW; + +#define TV_ITEMA TVITEMA +#define TV_ITEMW TVITEMW +#define LPTV_ITEMA LPTVITEMA +#define LPTV_ITEMW LPTVITEMW + +#define TVITEM WINELIB_NAME_AW(TVITEM) +#define LPTVITEM WINELIB_NAME_AW(LPTVITEM) +#define TV_ITEM WINELIB_NAME_AW(TV_ITEM) +#define LPTV_ITEM WINELIB_NAME_AW(LPTV_ITEM) + +typedef struct { + UINT mask; + HTREEITEM hItem; + UINT state; + UINT stateMask; + LPSTR pszText; + INT cchTextMax; + INT iImage; + INT iSelectedImage; + INT cChildren; + LPARAM lParam; + INT iIntegral; +} TVITEMEXA, *LPTVITEMEXA; + +typedef struct { + UINT mask; + HTREEITEM hItem; + UINT state; + UINT stateMask; + LPWSTR pszText; + INT cchTextMax; + INT iImage; + INT iSelectedImage; + INT cChildren; + LPARAM lParam; + INT iIntegral; +} TVITEMEXW, *LPTVITEMEXW; + +#define TVITEMEX WINELIB_NAME_AW(TVITEMEX) +#define LPTVITEMEX WINELIB_NAME_AW(LPTVITEMEX) + +typedef struct tagTVINSERTSTRUCTA { + HTREEITEM hParent; + HTREEITEM hInsertAfter; + union { + TVITEMEXA itemex; + TVITEMA item; + } DUMMYUNIONNAME; +} TVINSERTSTRUCTA, *LPTVINSERTSTRUCTA; + +typedef struct tagTVINSERTSTRUCTW { + HTREEITEM hParent; + HTREEITEM hInsertAfter; + union { + TVITEMEXW itemex; + TVITEMW item; + } DUMMYUNIONNAME; +} TVINSERTSTRUCTW, *LPTVINSERTSTRUCTW; + +#define TVINSERTSTRUCT WINELIB_NAME_AW(TVINSERTSTRUCT) +#define LPTVINSERTSTRUCT WINELIB_NAME_AW(LPTVINSERTSTRUCT) + +#define TVINSERTSTRUCT_V1_SIZEA CCSIZEOF_STRUCT(TVINSERTSTRUCTA, item) +#define TVINSERTSTRUCT_V1_SIZEW CCSIZEOF_STRUCT(TVINSERTSTRUCTW, item) +#define TVINSERTSTRUCT_V1_SIZE WINELIB_NAME_AW(TVINSERTSTRUCT_V1_SIZE) + +#define TV_INSERTSTRUCT TVINSERTSTRUCT +#define TV_INSERTSTRUCTA TVINSERTSTRUCTA +#define TV_INSERTSTRUCTW TVINSERTSTRUCTW +#define LPTV_INSERTSTRUCT LPTVINSERTSTRUCT +#define LPTV_INSERTSTRUCTA LPTVINSERTSTRUCTA +#define LPTV_INSERTSTRUCTW LPTVINSERTSTRUCTW + + + +typedef struct tagNMTREEVIEWA { + NMHDR hdr; + UINT action; + TVITEMA itemOld; + TVITEMA itemNew; + POINT ptDrag; +} NMTREEVIEWA, *LPNMTREEVIEWA; + +typedef struct tagNMTREEVIEWW { + NMHDR hdr; + UINT action; + TVITEMW itemOld; + TVITEMW itemNew; + POINT ptDrag; +} NMTREEVIEWW, *LPNMTREEVIEWW; + +#define NMTREEVIEW WINELIB_NAME_AW(NMTREEVIEW) +#define NM_TREEVIEW WINELIB_NAME_AW(NMTREEVIEW) +#define LPNMTREEVIEW WINELIB_NAME_AW(LPNMTREEVIEW) + +#define LPNM_TREEVIEW LPNMTREEVIEW + +typedef struct tagTVDISPINFOA { + NMHDR hdr; + TVITEMA item; +} NMTVDISPINFOA, *LPNMTVDISPINFOA; + +typedef struct tagTVDISPINFOW { + NMHDR hdr; + TVITEMW item; +} NMTVDISPINFOW, *LPNMTVDISPINFOW; + +#define NMTVDISPINFO WINELIB_NAME_AW(NMTVDISPINFO) +#define LPNMTVDISPINFO WINELIB_NAME_AW(LPNMTVDISPINFO) +#define TV_DISPINFO NMTVDISPINFO + +typedef INT (CALLBACK *PFNTVCOMPARE)(LPARAM, LPARAM, LPARAM); + +typedef struct tagTVSORTCB +{ + HTREEITEM hParent; + PFNTVCOMPARE lpfnCompare; + LPARAM lParam; +} TVSORTCB, *LPTVSORTCB; + +#define TV_SORTCB TVSORTCB +#define LPTV_SORTCB LPTVSORTCB + +typedef struct tagTVHITTESTINFO { + POINT pt; + UINT flags; + HTREEITEM hItem; +} TVHITTESTINFO, *LPTVHITTESTINFO; + +#define TV_HITTESTINFO TVHITTESTINFO + + +/* Custom Draw Treeview */ + +#define NMTVCUSTOMDRAW_V3_SIZE CCSIZEOF_STRUCT(NMTVCUSTOMDRAW, clrTextBk) + +#define TVCDRF_NOIMAGES 0x00010000 + +typedef struct tagNMTVCUSTOMDRAW +{ + NMCUSTOMDRAW nmcd; + COLORREF clrText; + COLORREF clrTextBk; + INT iLevel; /* IE>0x0400 */ +} NMTVCUSTOMDRAW, *LPNMTVCUSTOMDRAW; + +/* Treeview tooltips */ + +typedef struct tagNMTVGETINFOTIPA +{ + NMHDR hdr; + LPSTR pszText; + INT cchTextMax; + HTREEITEM hItem; + LPARAM lParam; +} NMTVGETINFOTIPA, *LPNMTVGETINFOTIPA; + +typedef struct tagNMTVGETINFOTIPW +{ + NMHDR hdr; + LPWSTR pszText; + INT cchTextMax; + HTREEITEM hItem; + LPARAM lParam; +} NMTVGETINFOTIPW, *LPNMTVGETINFOTIPW; + +#define NMTVGETINFOTIP WINELIB_NAME_AW(NMTVGETINFOTIP) +#define LPNMTVGETINFOTIP WINELIB_NAME_AW(LPNMTVGETINFOTIP) + +#include "pshpack1.h" +typedef struct tagTVKEYDOWN +{ + NMHDR hdr; + WORD wVKey; + UINT flags; +} NMTVKEYDOWN, *LPNMTVKEYDOWN; +#include "poppack.h" + +#define TV_KEYDOWN NMTVKEYDOWN + +#define TreeView_InsertItemA(hwnd, phdi) \ + (HTREEITEM)SNDMSGA((hwnd), TVM_INSERTITEMA, 0, \ + (LPARAM)(LPTVINSERTSTRUCTA)(phdi)) +#define TreeView_InsertItemW(hwnd,phdi) \ + (HTREEITEM)SNDMSGW((hwnd), TVM_INSERTITEMW, 0, \ + (LPARAM)(LPTVINSERTSTRUCTW)(phdi)) +#define TreeView_InsertItem WINELIB_NAME_AW(TreeView_InsertItem) + +#define TreeView_DeleteItem(hwnd, hItem) \ + (BOOL)SNDMSGA((hwnd), TVM_DELETEITEM, 0, (LPARAM)(HTREEITEM)(hItem)) +#define TreeView_DeleteAllItems(hwnd) \ + (BOOL)SNDMSGA((hwnd), TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT) +#define TreeView_Expand(hwnd, hitem, code) \ + (BOOL)SNDMSGA((hwnd), TVM_EXPAND, (WPARAM)code, \ + (LPARAM)(HTREEITEM)(hitem)) + +#define TreeView_GetItemRect(hwnd, hitem, prc, code) \ + (*(HTREEITEM *)prc = (hitem), (BOOL)SNDMSGA((hwnd), \ + TVM_GETITEMRECT, (WPARAM)(code), (LPARAM)(RECT *)(prc))) + +#define TreeView_GetCount(hwnd) \ + (UINT)SNDMSGA((hwnd), TVM_GETCOUNT, 0, 0) +#define TreeView_GetIndent(hwnd) \ + (UINT)SNDMSGA((hwnd), TVM_GETINDENT, 0, 0) +#define TreeView_SetIndent(hwnd, indent) \ + (BOOL)SNDMSGA((hwnd), TVM_SETINDENT, (WPARAM)indent, 0) + +#define TreeView_GetImageList(hwnd, iImage) \ + (HIMAGELIST)SNDMSGA((hwnd), TVM_GETIMAGELIST, iImage, 0) + +#define TreeView_SetImageList(hwnd, himl, iImage) \ + (HIMAGELIST)SNDMSGA((hwnd), TVM_SETIMAGELIST, iImage, \ + (LPARAM)(UINT)(HIMAGELIST)(himl)) + +#define TreeView_GetNextItem(hwnd, hitem, code) \ + (HTREEITEM)SNDMSGA((hwnd), TVM_GETNEXTITEM, (WPARAM)code,\ +(LPARAM)(HTREEITEM) (hitem)) + +#define TreeView_GetChild(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_CHILD) +#define TreeView_GetNextSibling(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_NEXT) +#define TreeView_GetPrevSibling(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_PREVIOUS) +#define TreeView_GetParent(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_PARENT) +#define TreeView_GetFirstVisible(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_FIRSTVISIBLE) +#define TreeView_GetLastVisible(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_LASTVISIBLE) +#define TreeView_GetNextVisible(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_NEXTVISIBLE) +#define TreeView_GetPrevVisible(hwnd, hitem) \ + TreeView_GetNextItem(hwnd, hitem , TVGN_PREVIOUSVISIBLE) +#define TreeView_GetSelection(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_CARET) +#define TreeView_GetDropHilight(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_DROPHILITE) +#define TreeView_GetRoot(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_ROOT) +#define TreeView_GetLastVisible(hwnd) \ + TreeView_GetNextItem(hwnd, NULL, TVGN_LASTVISIBLE) + + +#define TreeView_Select(hwnd, hitem, code) \ + (UINT)SNDMSGA((hwnd), TVM_SELECTITEM, (WPARAM)code, \ +(LPARAM)(UINT)(hitem)) + + +#define TreeView_SelectItem(hwnd, hitem) \ + TreeView_Select(hwnd, hitem, TVGN_CARET) +#define TreeView_SelectDropTarget(hwnd, hitem) \ + TreeView_Select(hwnd, hitem, TVGN_DROPHILITE) +#define TreeView_SelectSetFirstVisible(hwnd, hitem) \ + TreeView_Select(hwnd, hitem, TVGN_FIRSTVISIBLE) + + +#define TreeView_GetItemA(hwnd, pitem) \ + (BOOL)SNDMSGA((hwnd), TVM_GETITEMA, 0, (LPARAM) (TVITEMA *)(pitem)) +#define TreeView_GetItemW(hwnd, pitem) \ + (BOOL)SNDMSGW((hwnd), TVM_GETITEMA, 0, (LPARAM) (TVITEMA *)(pitem)) +#define TreeView_GetItem WINELIB_NAME_AW(TreeView_GetItem) + +#define TreeView_SetItemA(hwnd, pitem) \ + (BOOL)SNDMSGA((hwnd), TVM_SETITEMA, 0, (LPARAM)(const TVITEMA *)(pitem)) +#define TreeView_SetItemW(hwnd, pitem) \ + (BOOL)SNDMSGW((hwnd), TVM_SETITEMA, 0, (LPARAM)(const TVITEMA *)(pitem)) +#define TreeView_SetItem WINELIB_NAME_AW(TreeView_SetItem) + +#define TreeView_EditLabel(hwnd, hitem) \ + (HWND)SNDMSGA((hwnd), TVM_EDITLABEL, 0, (LPARAM)(HTREEITEM)(hitem)) + +#define TreeView_GetEditControl(hwnd) \ + (HWND)SNDMSGA((hwnd), TVM_GETEDITCONTROL, 0, 0) + +#define TreeView_GetVisibleCount(hwnd) \ + (UINT)SNDMSGA((hwnd), TVM_GETVISIBLECOUNT, 0, 0) + +#define TreeView_HitTest(hwnd, lpht) \ + (HTREEITEM)SNDMSGA((hwnd), TVM_HITTEST, 0,\ +(LPARAM)(LPTVHITTESTINFO)(lpht)) + +#define TreeView_CreateDragImage(hwnd, hitem) \ + (HIMAGELIST)SNDMSGA((hwnd), TVM_CREATEDRAGIMAGE, 0,\ +(LPARAM)(HTREEITEM)(hitem)) + +#define TreeView_SortChildren(hwnd, hitem, recurse) \ + (BOOL)SNDMSGA((hwnd), TVM_SORTCHILDREN, (WPARAM)recurse,\ +(LPARAM)(HTREEITEM)(hitem)) + +#define TreeView_EnsureVisible(hwnd, hitem) \ + (BOOL)SNDMSGA((hwnd), TVM_ENSUREVISIBLE, 0, (LPARAM)(UINT)(hitem)) + +#define TreeView_SortChildrenCB(hwnd, psort, recurse) \ + (BOOL)SNDMSGA((hwnd), TVM_SORTCHILDRENCB, (WPARAM)recurse, \ + (LPARAM)(LPTV_SORTCB)(psort)) + +#define TreeView_EndEditLabelNow(hwnd, fCancel) \ + (BOOL)SNDMSGA((hwnd), TVM_ENDEDITLABELNOW, (WPARAM)fCancel, 0) + +#define TreeView_GetISearchString(hwnd, lpsz) \ + (BOOL)SNDMSGA((hwnd), TVM_GETISEARCHSTRING, 0, \ + (LPARAM)(LPTSTR)lpsz) + +#define TreeView_SetToolTips(hwnd, hwndTT) \ + (HWND)SNDMSGA((hwnd), TVM_SETTOOLTIPS, (WPARAM)(hwndTT), 0) + +#define TreeView_GetToolTips(hwnd) \ + (HWND)SNDMSGA((hwnd), TVM_GETTOOLTIPS, 0, 0) + +#define TreeView_SetItemHeight(hwnd, iHeight) \ + (INT)SNDMSGA((hwnd), TVM_SETITEMHEIGHT, (WPARAM)iHeight, 0) + +#define TreeView_GetItemHeight(hwnd) \ + (INT)SNDMSGA((hwnd), TVM_GETITEMHEIGHT, 0, 0) + +#define TreeView_SetBkColor(hwnd, clr) \ + (COLORREF)SNDMSGA((hwnd), TVM_SETBKCOLOR, 0, (LPARAM)clr) + +#define TreeView_SetTextColor(hwnd, clr) \ + (COLORREF)SNDMSGA((hwnd), TVM_SETTEXTCOLOR, 0, (LPARAM)clr) + +#define TreeView_GetBkColor(hwnd) \ + (COLORREF)SNDMSGA((hwnd), TVM_GETBKCOLOR, 0, 0) + +#define TreeView_GetTextColor(hwnd) \ + (COLORREF)SNDMSGA((hwnd), TVM_GETTEXTCOLOR, 0, 0) + +#define TreeView_SetScrollTime(hwnd, uTime) \ + (UINT)SNDMSGA((hwnd), TVM_SETSCROLLTIME, uTime, 0) + +#define TreeView_GetScrollTime(hwnd) \ + (UINT)SNDMSGA((hwnd), TVM_GETSCROLLTIME, 0, 0) + +#define TreeView_SetInsertMark(hwnd, hItem, fAfter) \ + (BOOL)SNDMSGA((hwnd), TVM_SETINSERTMARK, (WPARAM)(fAfter), \ + (LPARAM) (hItem)) + +#define TreeView_SetInsertMarkColor(hwnd, clr) \ + (COLORREF)SNDMSGA((hwnd), TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr) + +#define TreeView_GetInsertMarkColor(hwnd) \ + (COLORREF)SNDMSGA((hwnd), TVM_GETINSERTMARKCOLOR, 0, 0) + +#define TreeView_GetItemState(hwndTV, hti, mask) \ + (UINT)SNDMSGA((hwndTV), TVM_GETITEMSTATE, (WPARAM)(hti), (LPARAM)(mask)) +#define TreeView_GetCheckState(hwndTV, hti) \ + ((((UINT)(SNDMSGA((hwndTV), TVM_GETITEMSTATE, (WPARAM)(hti), \ + TVIS_STATEIMAGEMASK))) >> 12) -1) + +#define TreeView_SetLineColor(hwnd, clr) \ + (COLORREF)SNDMSGA((hwnd), TVM_SETLINECOLOR, 0, (LPARAM)(clr)) + +#define TreeView_GetLineColor(hwnd) \ + (COLORREF)SNDMSGA((hwnd), TVM_GETLINECOLOR, 0, 0) + +#define TreeView_SetItemState(hwndTV, hti, data, _mask) \ +{ TVITEM _TVi; \ + _TVi.mask = TVIF_STATE; \ + _TVi.hItem = hti; \ + _TVi.stateMask = _mask; \ + _TVi.state = data; \ + SNDMSGA((hwndTV), TVM_SETITEM, 0, (LPARAM)(TV_ITEM *)&_TVi); \ +} + + +/* Listview control */ + +#define WC_LISTVIEWA "SysListView32" +#if defined(__GNUC__) +# define WC_LISTVIEWW (const WCHAR []){ 'S','y','s', \ + 'L','i','s','t','V','i','e','w','3','2',0 } +#elif defined(_MSC_VER) +# define WC_LISTVIEWW L"SysListView32" +#else +static const WCHAR WC_LISTVIEWW[] = { 'S','y','s', + 'L','i','s','t','V','i','e','w','3','2',0 }; +#endif +#define WC_LISTVIEW WINELIB_NAME_AW(WC_LISTVIEW) + +#define LVSCW_AUTOSIZE -1 +#define LVSCW_AUTOSIZE_USEHEADER -2 + +#define LVS_ICON 0x0000 +#define LVS_REPORT 0x0001 +#define LVS_SMALLICON 0x0002 +#define LVS_LIST 0x0003 +#define LVS_TYPEMASK 0x0003 +#define LVS_SINGLESEL 0x0004 +#define LVS_SHOWSELALWAYS 0x0008 +#define LVS_SORTASCENDING 0x0010 +#define LVS_SORTDESCENDING 0x0020 +#define LVS_SHAREIMAGELISTS 0x0040 +#define LVS_NOLABELWRAP 0x0080 +#define LVS_AUTOARRANGE 0x0100 +#define LVS_EDITLABELS 0x0200 +#define LVS_OWNERDATA 0x1000 +#define LVS_NOSCROLL 0x2000 +#define LVS_TYPESTYLEMASK 0xfc00 +#define LVS_ALIGNTOP 0x0000 +#define LVS_ALIGNLEFT 0x0800 +#define LVS_ALIGNMASK 0x0c00 +#define LVS_OWNERDRAWFIXED 0x0400 +#define LVS_NOCOLUMNHEADER 0x4000 +#define LVS_NOSORTHEADER 0x8000 + +#define LVS_EX_GRIDLINES 0x0001 +#define LVS_EX_SUBITEMIMAGES 0x0002 +#define LVS_EX_CHECKBOXES 0x0004 +#define LVS_EX_TRACKSELECT 0x0008 +#define LVS_EX_HEADERDRAGDROP 0x0010 +#define LVS_EX_FULLROWSELECT 0x0020 +#define LVS_EX_ONECLICKACTIVATE 0x0040 +#define LVS_EX_TWOCLICKACTIVATE 0x0080 +#define LVS_EX_FLATSB 0x0100 +#define LVS_EX_REGIONAL 0x0200 +#define LVS_EX_INFOTIP 0x0400 +#define LVS_EX_UNDERLINEHOT 0x0800 +#define LVS_EX_UNDERLINECOLD 0x1000 +#define LVS_EX_MULTIWORKAREAS 0x2000 + +#define LVCF_FMT 0x0001 +#define LVCF_WIDTH 0x0002 +#define LVCF_TEXT 0x0004 +#define LVCF_SUBITEM 0x0008 +#define LVCF_IMAGE 0x0010 +#define LVCF_ORDER 0x0020 + +#define LVCFMT_LEFT 0x0000 +#define LVCFMT_RIGHT 0x0001 +#define LVCFMT_CENTER 0x0002 +#define LVCFMT_JUSTIFYMASK 0x0003 +#define LVCFMT_IMAGE 0x0800 +#define LVCFMT_BITMAP_ON_RIGHT 0x1000 +#define LVCFMT_COL_HAS_IMAGES 0x8000 + +#define LVSIL_NORMAL 0 +#define LVSIL_SMALL 1 +#define LVSIL_STATE 2 + +/* following 2 flags only for LVS_OWNERDATA listviews */ +/* and only in report or list mode */ +#define LVSICF_NOINVALIDATEALL 0x0001 +#define LVSICF_NOSCROLL 0x0002 + + +#define LVFI_PARAM 0X0001 +#define LVFI_STRING 0X0002 +#define LVFI_PARTIAL 0X0008 +#define LVFI_WRAP 0X0020 +#define LVFI_NEARESTXY 0X0040 + +#define LVIF_TEXT 0x0001 +#define LVIF_IMAGE 0x0002 +#define LVIF_PARAM 0x0004 +#define LVIF_STATE 0x0008 +#define LVIF_INDENT 0x0010 +#define LVIF_NORECOMPUTE 0x0800 +#define LVIF_DI_SETITEM 0x1000 + +#define LVIR_BOUNDS 0x0000 +#define LVIR_LABEL 0x0002 +#define LVIR_ICON 0x0001 +#define LVIR_SELECTBOUNDS 0x0003 + +#define LVIS_FOCUSED 0x0001 +#define LVIS_SELECTED 0x0002 +#define LVIS_CUT 0x0004 +#define LVIS_DROPHILITED 0x0008 +#define LVIS_ACTIVATING 0x0020 + +#define LVIS_OVERLAYMASK 0x0F00 +#define LVIS_STATEIMAGEMASK 0xF000 + +#define LVNI_ALL 0x0000 +#define LVNI_FOCUSED 0x0001 +#define LVNI_SELECTED 0x0002 +#define LVNI_CUT 0x0004 +#define LVNI_DROPHILITED 0x0008 + +#define LVNI_ABOVE 0x0100 +#define LVNI_BELOW 0x0200 +#define LVNI_TOLEFT 0x0400 +#define LVNI_TORIGHT 0x0800 + +#define LVHT_NOWHERE 0x0001 +#define LVHT_ONITEMICON 0x0002 +#define LVHT_ONITEMLABEL 0x0004 +#define LVHT_ONITEMSTATEICON 0x0008 +#define LVHT_ONITEM (LVHT_ONITEMICON|LVHT_ONITEMLABEL|LVHT_ONITEMSTATEICON) + +#define LVHT_ABOVE 0x0008 +#define LVHT_BELOW 0x0010 +#define LVHT_TORIGHT 0x0020 +#define LVHT_TOLEFT 0x0040 + +#define LVM_FIRST 0x1000 +#define LVM_GETBKCOLOR (LVM_FIRST+0) +#define LVM_SETBKCOLOR (LVM_FIRST+1) +#define LVM_GETIMAGELIST (LVM_FIRST+2) +#define LVM_SETIMAGELIST (LVM_FIRST+3) +#define LVM_GETITEMCOUNT (LVM_FIRST+4) +#define LVM_GETITEMA (LVM_FIRST+5) +#define LVM_GETITEMW (LVM_FIRST+75) +#define LVM_GETITEM WINELIB_NAME_AW(LVM_GETITEM) +#define LVM_SETITEMA (LVM_FIRST+6) +#define LVM_SETITEMW (LVM_FIRST+76) +#define LVM_SETITEM WINELIB_NAME_AW(LVM_SETITEM) +#define LVM_INSERTITEMA (LVM_FIRST+7) +#define LVM_INSERTITEMW (LVM_FIRST+77) +#define LVM_INSERTITEM WINELIB_NAME_AW(LVM_INSERTITEM) +#define LVM_DELETEITEM (LVM_FIRST+8) +#define LVM_DELETEALLITEMS (LVM_FIRST+9) +#define LVM_GETCALLBACKMASK (LVM_FIRST+10) +#define LVM_SETCALLBACKMASK (LVM_FIRST+11) +#define LVM_GETNEXTITEM (LVM_FIRST+12) +#define LVM_FINDITEMA (LVM_FIRST+13) +#define LVM_FINDITEMW (LVM_FIRST+83) +#define LVM_FINDITEM WINELIB_NAME_AW(LVM_FINDITEM) +#define LVM_GETITEMRECT (LVM_FIRST+14) +#define LVM_SETITEMPOSITION (LVM_FIRST+15) +#define LVM_GETITEMPOSITION (LVM_FIRST+16) +#define LVM_GETSTRINGWIDTHA (LVM_FIRST+17) +#define LVM_GETSTRINGWIDTHW (LVM_FIRST+87) +#define LVM_GETSTRINGWIDTH WINELIB_NAME_AW(LVM_GETSTRINGWIDTH) +#define LVM_HITTEST (LVM_FIRST+18) +#define LVM_ENSUREVISIBLE (LVM_FIRST+19) +#define LVM_SCROLL (LVM_FIRST+20) +#define LVM_REDRAWITEMS (LVM_FIRST+21) +#define LVM_ARRANGE (LVM_FIRST+22) +#define LVM_EDITLABELA (LVM_FIRST+23) +#define LVM_EDITLABELW (LVM_FIRST+118) +#define LVM_EDITLABEL WINELIB_NAME_AW(LVM_EDITLABEL) +#define LVM_GETEDITCONTROL (LVM_FIRST+24) +#define LVM_GETCOLUMNA (LVM_FIRST+25) +#define LVM_GETCOLUMNW (LVM_FIRST+95) +#define LVM_GETCOLUMN WINELIB_NAME_AW(LVM_GETCOLUMN) +#define LVM_SETCOLUMNA (LVM_FIRST+26) +#define LVM_SETCOLUMNW (LVM_FIRST+96) +#define LVM_SETCOLUMN WINELIB_NAME_AW(LVM_SETCOLUMN) +#define LVM_INSERTCOLUMNA (LVM_FIRST+27) +#define LVM_INSERTCOLUMNW (LVM_FIRST+97) +#define LVM_INSERTCOLUMN WINELIB_NAME_AW(LVM_INSERTCOLUMN) +#define LVM_DELETECOLUMN (LVM_FIRST+28) +#define LVM_GETCOLUMNWIDTH (LVM_FIRST+29) +#define LVM_SETCOLUMNWIDTH (LVM_FIRST+30) +#define LVM_GETHEADER (LVM_FIRST+31) + +#define LVM_CREATEDRAGIMAGE (LVM_FIRST+33) +#define LVM_GETVIEWRECT (LVM_FIRST+34) +#define LVM_GETTEXTCOLOR (LVM_FIRST+35) +#define LVM_SETTEXTCOLOR (LVM_FIRST+36) +#define LVM_GETTEXTBKCOLOR (LVM_FIRST+37) +#define LVM_SETTEXTBKCOLOR (LVM_FIRST+38) +#define LVM_GETTOPINDEX (LVM_FIRST+39) +#define LVM_GETCOUNTPERPAGE (LVM_FIRST+40) +#define LVM_GETORIGIN (LVM_FIRST+41) +#define LVM_UPDATE (LVM_FIRST+42) +#define LVM_SETITEMSTATE (LVM_FIRST+43) +#define LVM_GETITEMSTATE (LVM_FIRST+44) +#define LVM_GETITEMTEXTA (LVM_FIRST+45) +#define LVM_GETITEMTEXTW (LVM_FIRST+115) +#define LVM_GETITEMTEXT WINELIB_NAME_AW(LVM_GETITEMTEXT) +#define LVM_SETITEMTEXTA (LVM_FIRST+46) +#define LVM_SETITEMTEXTW (LVM_FIRST+116) +#define LVM_SETITEMTEXT WINELIB_NAME_AW(LVM_SETITEMTEXT) +#define LVM_SETITEMCOUNT (LVM_FIRST+47) +#define LVM_SORTITEMS (LVM_FIRST+48) +#define LVM_SETITEMPOSITION32 (LVM_FIRST+49) +#define LVM_GETSELECTEDCOUNT (LVM_FIRST+50) +#define LVM_GETITEMSPACING (LVM_FIRST+51) +#define LVM_GETISEARCHSTRINGA (LVM_FIRST+52) +#define LVM_GETISEARCHSTRINGW (LVM_FIRST+117) +#define LVM_GETISEARCHSTRING WINELIB_NAME_AW(LVM_GETISEARCHSTRING) +#define LVM_SETICONSPACING (LVM_FIRST+53) +#define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST+54) +#define LVM_GETEXTENDEDLISTVIEWSTYLE (LVM_FIRST+55) +#define LVM_GETSUBITEMRECT (LVM_FIRST+56) +#define LVM_SUBITEMHITTEST (LVM_FIRST+57) +#define LVM_SETCOLUMNORDERARRAY (LVM_FIRST+58) +#define LVM_GETCOLUMNORDERARRAY (LVM_FIRST+59) +#define LVM_SETHOTITEM (LVM_FIRST+60) +#define LVM_GETHOTITEM (LVM_FIRST+61) +#define LVM_SETHOTCURSOR (LVM_FIRST+62) +#define LVM_GETHOTCURSOR (LVM_FIRST+63) +#define LVM_APPROXIMATEVIEWRECT (LVM_FIRST+64) +#define LVM_SETWORKAREAS (LVM_FIRST+65) +#define LVM_GETSELECTIONMARK (LVM_FIRST+66) +#define LVM_SETSELECTIONMARK (LVM_FIRST+67) +#define LVM_SETBKIMAGEA (LVM_FIRST+68) +#define LVM_SETBKIMAGEW (LVM_FIRST+138) +#define LVM_SETBKIMAGE WINELIB_NAME_AW(LVM_SETBKIMAGE) +#define LVM_GETBKIMAGEA (LVM_FIRST+69) +#define LVM_GETBKIMAGEW (LVM_FIRST+139) +#define LVM_GETBKIMAGE WINELIB_NAME_AW(LVM_GETBKIMAGE) +#define LVM_GETWORKAREAS (LVM_FIRST+70) +#define LVM_SETHOVERTIME (LVM_FIRST+71) +#define LVM_GETHOVERTIME (LVM_FIRST+72) +#define LVM_GETNUMBEROFWORKAREAS (LVM_FIRST+73) +#define LVM_SETTOOLTIPS (LVM_FIRST+74) +#define LVM_GETTOOLTIPS (LVM_FIRST+78) +#define LVM_GETUNICODEFORMAT (CCM_GETUNICODEFORMAT) +#define LVM_SETUNICODEFORMAT (CCM_SETUNICODEFORMAT) + +#define LVN_FIRST (0U-100U) +#define LVN_LAST (0U-199U) +#define LVN_ITEMCHANGING (LVN_FIRST-0) +#define LVN_ITEMCHANGED (LVN_FIRST-1) +#define LVN_INSERTITEM (LVN_FIRST-2) +#define LVN_DELETEITEM (LVN_FIRST-3) +#define LVN_DELETEALLITEMS (LVN_FIRST-4) +#define LVN_BEGINLABELEDITA (LVN_FIRST-5) +#define LVN_BEGINLABELEDITW (LVN_FIRST-75) +#define LVN_BEGINLABELEDIT WINELIB_NAME_AW(LVN_BEGINLABELEDIT) +#define LVN_ENDLABELEDITA (LVN_FIRST-6) +#define LVN_ENDLABELEDITW (LVN_FIRST-76) +#define LVN_ENDLABELEDIT WINELIB_NAME_AW(LVN_ENDLABELEDIT) +#define LVN_COLUMNCLICK (LVN_FIRST-8) +#define LVN_BEGINDRAG (LVN_FIRST-9) +#define LVN_BEGINRDRAG (LVN_FIRST-11) +#define LVN_ODCACHEHINT (LVN_FIRST-13) +#define LVN_ITEMACTIVATE (LVN_FIRST-14) +#define LVN_ODSTATECHANGED (LVN_FIRST-15) +#define LVN_HOTTRACK (LVN_FIRST-21) +#define LVN_ODFINDITEMA (LVN_FIRST-52) +#define LVN_ODFINDITEMW (LVN_FIRST-79) +#define LVN_ODFINDITEM WINELIB_NAME_AW(LVN_ODFINDITEM) +#define LVN_GETDISPINFOA (LVN_FIRST-50) +#define LVN_GETDISPINFOW (LVN_FIRST-77) +#define LVN_GETDISPINFO WINELIB_NAME_AW(LVN_GETDISPINFO) +#define LVN_SETDISPINFOA (LVN_FIRST-51) +#define LVN_SETDISPINFOW (LVN_FIRST-78) +#define LVN_SETDISPINFO WINELIB_NAME_AW(LVN_SETDISPINFO) +#define LVN_KEYDOWN (LVN_FIRST-55) +#define LVN_MARQUEEBEGIN (LVN_FIRST-56) +#define LVN_GETINFOTIPA (LVN_FIRST-57) +#define LVN_GETINFOTIPW (LVN_FIRST-58) +#define LVN_GETINFOTIP WINELIB_NAME_AW(LVN_GETINFOTIP) + +#define LVA_ALIGNLEFT 0x0000 +#define LVA_DEFAULT 0x0001 +#define LVA_ALIGNTOP 0x0002 +#define LVA_SNAPTOGRID 0x0005 + +typedef struct tagLVITEMA +{ + UINT mask; + INT iItem; + INT iSubItem; + UINT state; + UINT stateMask; + LPSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; + INT iIndent; /* (_WIN32_IE >= 0x0300) */ + int iGroupId; /* (_WIN32_IE >= 0x560) */ + UINT cColumns; /* (_WIN32_IE >= 0x560) */ + PUINT puColumns; /* (_WIN32_IE >= 0x560) */ +} LVITEMA, *LPLVITEMA; + +typedef struct tagLVITEMW +{ + UINT mask; + INT iItem; + INT iSubItem; + UINT state; + UINT stateMask; + LPWSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; + INT iIndent; /* (_WIN32_IE >= 0x0300) */ + int iGroupId; /* (_WIN32_IE >= 0x560) */ + UINT cColumns; /* (_WIN32_IE >= 0x560) */ + PUINT puColumns; /* (_WIN32_IE >= 0x560) */ +} LVITEMW, *LPLVITEMW; + +#define LVITEM WINELIB_NAME_AW(LVITEM) +#define LPLVITEM WINELIB_NAME_AW(LPLVITEM) + +#define LVITEM_V1_SIZEA CCSIZEOF_STRUCT(LVITEMA, lParam) +#define LVITEM_V1_SIZEW CCSIZEOF_STRUCT(LVITEMW, lParam) +#define LVITEM_V1_SIZE WINELIB_NAME_AW(LVITEM_V1_SIZE) + +#define LV_ITEM LVITEM + +typedef struct LVSETINFOTIPA +{ + UINT cbSize; + DWORD dwFlags; + LPSTR pszText; + int iItem; + int iSubItem; +} LVSETINFOTIPA, *PLVSETINFOTIPA; + +typedef struct LVSETINFOTIPW +{ + UINT cbSize; + DWORD dwFlags; + LPWSTR pszText; + int iItem; + int iSubItem; +} LVSETINFOTIPW, *PLVSETINFOTIPW; + +#define LVSETINFOTIP WINELIB_NAME_AW(LVSETINFOTIP) +#define PLVSETINFOTIP WINELIB_NAME_AW(PLVSETINFOTIP) + +/* ListView background image structs and constants + For _WIN32_IE version 0x400 and later. */ + +typedef struct tagLVBKIMAGEA +{ + ULONG ulFlags; + HBITMAP hbm; + LPSTR pszImage; + UINT cchImageMax; + int xOffsetPercent; + int yOffsetPercent; +} LVBKIMAGEA, *LPLVBKIMAGEA; + +typedef struct tagLVBKIMAGEW +{ + ULONG ulFlags; + HBITMAP hbm; + LPWSTR pszImage; + UINT cchImageMax; + int xOffsetPercent; + int yOffsetPercent; +} LVBKIMAGEW, *LPLVBKIMAGEW; + +#define LVBKIMAGE WINELIB_NAME_AW(LVBKIMAGE) +#define LPLVBKIMAGE WINELIB_NAME_AW(LPLVBKIMAGE) + +#define LVBKIF_SOURCE_NONE 0x00000000 +#define LVBKIF_SOURCE_HBITMAP 0x00000001 +#define LVBKIF_SOURCE_URL 0x00000002 +#define LVBKIF_SOURCE_MASK 0x00000003 +#define LVBKIF_STYLE_NORMAL 0x00000000 +#define LVBKIF_STYLE_TILE 0x00000010 +#define LVBKIF_STYLE_MASK 0x00000010 + +#define ListView_SetBkImage(hwnd, plvbki) \ + (BOOL)SNDMSG((hwnd), LVM_SETBKIMAGE, 0, (LPARAM)plvbki) + +#define ListView_GetBkImage(hwnd, plvbki) \ + (BOOL)SNDMSG((hwnd), LVM_GETBKIMAGE, 0, (LPARAM)plvbki) + +typedef struct tagLVCOLUMNA +{ + UINT mask; + INT fmt; + INT cx; + LPSTR pszText; + INT cchTextMax; + INT iSubItem; + INT iImage; /* (_WIN32_IE >= 0x0300) */ + INT iOrder; /* (_WIN32_IE >= 0x0300) */ +} LVCOLUMNA, *LPLVCOLUMNA; + +typedef struct tagLVCOLUMNW +{ + UINT mask; + INT fmt; + INT cx; + LPWSTR pszText; + INT cchTextMax; + INT iSubItem; + INT iImage; /* (_WIN32_IE >= 0x0300) */ + INT iOrder; /* (_WIN32_IE >= 0x0300) */ +} LVCOLUMNW, *LPLVCOLUMNW; + +#define LVCOLUMN WINELIB_NAME_AW(LVCOLUMN) +#define LPLVCOLUMN WINELIB_NAME_AW(LPLVCOLUMN) + +#define LVCOLUMN_V1_SIZEA CCSIZEOF_STRUCT(LVCOLUMNA, iSubItem) +#define LVCOLUMN_V1_SIZEW CCSIZEOF_STRUCT(LVCOLUMNW, iSubItem) +#define LVCOLUMN_V1_SIZE WINELIB_NAME_AW(LVCOLUMN_V1_SIZE) + +#define LV_COLUMN LVCOLUMN + + +typedef struct tagNMLISTVIEW +{ + NMHDR hdr; + INT iItem; + INT iSubItem; + UINT uNewState; + UINT uOldState; + UINT uChanged; + POINT ptAction; + LPARAM lParam; +} NMLISTVIEW, *LPNMLISTVIEW; + +#define NM_LISTVIEW NMLISTVIEW +#define LPNM_LISTVIEW LPNMLISTVIEW + +typedef struct tagNMITEMACTIVATE +{ + NMHDR hdr; + int iItem; + int iSubItem; + UINT uNewState; + UINT uOldState; + UINT uChanged; + POINT ptAction; + LPARAM lParam; + UINT uKeyFlags; +} NMITEMACTIVATE, *LPNMITEMACTIVATE; + +typedef struct tagLVDISPINFOA +{ + NMHDR hdr; + LVITEMA item; +} NMLVDISPINFOA, *LPNMLVDISPINFOA; + +typedef struct tagLVDISPINFOW +{ + NMHDR hdr; + LVITEMW item; +} NMLVDISPINFOW, *LPNMLVDISPINFOW; + +#define NMLVDISPINFO WINELIB_NAME_AW(NMLVDISPINFO) +#define LPNMLVDISPINFO WINELIB_NAME_AW(LPNMLVDISPINFO) + +#define LV_DISPINFO NMLVDISPINFO + +#include "pshpack1.h" +typedef struct tagLVKEYDOWN +{ + NMHDR hdr; + WORD wVKey; + UINT flags; +} NMLVKEYDOWN, *LPNMLVKEYDOWN; +#include "poppack.h" + +#define LV_KEYDOWN NMLVKEYDOWN + +typedef struct tagNMLVGETINFOTIPA +{ + NMHDR hdr; + DWORD dwFlags; + LPSTR pszText; + int cchTextMax; + int iItem; + int iSubItem; + LPARAM lParam; +} NMLVGETINFOTIPA, *LPNMLVGETINFOTIPA; + +typedef struct tagNMLVGETINFOTIPW +{ + NMHDR hdr; + DWORD dwFlags; + LPWSTR pszText; + int cchTextMax; + int iItem; + int iSubItem; + LPARAM lParam; +} NMLVGETINFOTIPW, *LPNMLVGETINFOTIPW; + +#define NMLVGETINFOTIP WINELIB_NAME_AW(NMLVGETINFOTIP) +#define LPNMLVGETINFOTIP WINELIB_NAME_AW(LPNMLVGETINFOTIP) + +typedef struct tagLVHITTESTINFO +{ + POINT pt; + UINT flags; + INT iItem; + INT iSubItem; +} LVHITTESTINFO, *LPLVHITTESTINFO; + +#define LV_HITTESTINFO LVHITTESTINFO +#define _LV_HITTESTINFO tagLVHITTESTINFO +#define LVHITTESTINFO_V1_SIZE CCSIZEOF_STRUCT(LVHITTESTINFO,iItem) + +typedef struct tagLVFINDINFOA +{ + UINT flags; + LPCSTR psz; + LPARAM lParam; + POINT pt; + UINT vkDirection; +} LVFINDINFOA, *LPLVFINDINFOA; + +typedef struct tagLVFINDINFOW +{ + UINT flags; + LPCWSTR psz; + LPARAM lParam; + POINT pt; + UINT vkDirection; +} LVFINDINFOW, *LPLVFINDINFOW; + +#define LVFINDINFO WINELIB_NAME_AW(LVFINDINFO) +#define LPLVFINDINFO WINELIB_NAME_AW(LPLVFINDINFO) + +/* Groups relates structures */ + +typedef struct LVGROUPA +{ + UINT cbSize; + UINT mask; + LPSTR pszHeader; + int cchHeader; + int iGroupId; + UINT stateMask; + UINT state; + UINT uAlign; +} LVGROUPA, *PLVGROUPA; + +typedef struct LVGROUPW +{ + UINT cbSize; + UINT mask; + LPWSTR pszHeader; + int cchHeader; + int iGroupId; + UINT stateMask; + UINT state; + UINT uAlign; +} LVGROUPW, *PLVGROUPW; + +#define LVGROUP WINELIB_NAME_AW(LVGROUP) +#define PLVGROUP WINELIB_NAME_AW(PLVGROUP) + +typedef struct LVGROUPMETRICS +{ + UINT cbSize; + UINT mask; + UINT Left; + UINT Top; + UINT Right; + UINT Bottom; + COLORREF crLeft; + COLORREF crTop; + COLORREF crRight; + COLORREF crBottom; + COLORREF crRightHeader; + COLORREF crFooter; +} LVGROUPMETRICS, *PLVGROUPMETRICS; + +typedef INT (*PFNLVGROUPCOMPARE)(INT, INT, VOID*); + +typedef struct LVINSERTGROUPSORTEDA +{ + PFNLVGROUPCOMPARE pfnGroupCompare; + LPVOID *pvData; + LVGROUPA lvGroup; +} LVINSERTGROUPSORTEDA, *PLVINSERTGROUPSORTEDA; + +typedef struct LVINSERTGROUPSORTEDW +{ + PFNLVGROUPCOMPARE pfnGroupCompare; + LPVOID *pvData; + LVGROUPW lvGroup; +} LVINSERTGROUPSORTEDW, *PLVINSERTGROUPSORTEDW; + +#define LVINSERTGROUPSORTED WINELIB_NAME_AW(LVINSERTGROUPSORTED) +#define PLVINSERTGROUPSORTED WINELIB_NAME_AW(PLVINSERTGROUPSORTED) + +/* Tile related structures */ + +typedef struct LVTILEINFO +{ + UINT cbSize; + int iItem; + UINT cColumns; + PUINT puColumns; +} LVTILEINFO, *PLVTILEINFO; + +typedef struct LVTILEVIEWINFO +{ + UINT cbSize; + DWORD dwMask; + DWORD dwFlags; + SIZE sizeTile; + int cLines; + RECT rcLabelMargin; +} LVTILEVIEWINFO, *PLVTILEVIEWINFO; + +typedef struct LVINSERTMARK +{ + UINT cbSize; + DWORD dwFlags; + int iItem; + DWORD dwReserved; +} LVINSERTMARK, *PLVINSERTMARK; + +typedef struct tagTCHITTESTINFO +{ + POINT pt; + UINT flags; +} TCHITTESTINFO, *LPTCHITTESTINFO; + +#define TC_HITTESTINFO TCHITTESTINFO + +typedef INT (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); + +#define NMLVCUSTOMDRAW_V3_SIZE CCSIZEOF_STRUCT(NMLCUSTOMDRW, clrTextBk) + +typedef struct tagNMLVCUSTOMDRAW +{ + NMCUSTOMDRAW nmcd; + COLORREF clrText; + COLORREF clrTextBk; + int iSubItem; /* (_WIN32_IE >= 0x0400) */ + DWORD dwItemType; /* (_WIN32_IE >= 0x560) */ + COLORREF clrFace; /* (_WIN32_IE >= 0x560) */ + int iIconEffect; /* (_WIN32_IE >= 0x560) */ + int iIconPhase; /* (_WIN32_IE >= 0x560) */ + int iPartId; /* (_WIN32_IE >= 0x560) */ + int iStateId; /* (_WIN32_IE >= 0x560) */ + RECT rcText; /* (_WIN32_IE >= 0x560) */ + UINT uAlign; /* (_WIN32_IE >= 0x560) */ +} NMLVCUSTOMDRAW, *LPNMLVCUSTOMDRAW; + +typedef struct tagNMLVCACHEHINT +{ + NMHDR hdr; + INT iFrom; + INT iTo; +} NMLVCACHEHINT, *LPNMLVCACHEHINT; + +#define LPNM_CACHEHINT LPNMLVCACHEHINT +#define PNM_CACHEHINT LPNMLVCACHEHINT +#define NM_CACHEHINT NMLVCACHEHINT + +typedef struct tagNMLVFINDITEMA +{ + NMHDR hdr; + int iStart; + LVFINDINFOA lvfi; +} NMLVFINDITEMA, *LPNMLVFINDITEMA; + +typedef struct tagNMLVFINDITEMW +{ + NMHDR hdr; + int iStart; + LVFINDINFOW lvfi; +} NMLVFINDITEMW, *LPNMLVFINDITEMW; + +#define NMLVFINDITEM WINELIB_NAME_AW(NMLVFINDITEM) +#define LPNMLVFINDITEM WINELIB_NAME_AW(LPNMLVFINDITEM) +#define NM_FINDITEM NMLVFINDITEM +#define LPNM_FINDITEM LPNMLVFINDITEM +#define PNM_FINDITEM LPNMLVFINDITEM + +typedef struct tagNMLVODSTATECHANGE +{ + NMHDR hdr; + int iFrom; + int iTo; + UINT uNewState; + UINT uOldState; +} NMLVODSTATECHANGE, *LPNMLVODSTATECHANGE; + +#define PNM_ODSTATECHANGE LPNMLVODSTATECHANGE +#define LPNM_ODSTATECHANGE LPNMLVODSTATECHANGE +#define NM_ODSTATECHANGE NMLVODSTATECHANGE + +typedef struct NMLVSCROLL +{ + NMHDR hdr; + int dx; + int dy; +} NMLVSCROLL, *LPNMLVSCROLL; + +#define ListView_SetTextBkColor(hwnd,clrBk) \ + (BOOL)SNDMSGA((hwnd),LVM_SETTEXTBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) +#define ListView_SetTextColor(hwnd,clrBk) \ + (BOOL)SNDMSGA((hwnd),LVM_SETTEXTCOLOR,0,(LPARAM)(COLORREF)(clrBk)) +#define ListView_DeleteColumn(hwnd,col)\ + (LRESULT)SNDMSGA((hwnd),LVM_DELETECOLUMN,0,(LPARAM)(INT)(col)) +#define ListView_GetColumnA(hwnd,x,col)\ + (LRESULT)SNDMSGA((hwnd),LVM_GETCOLUMNA,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNA)(col)) +#define ListView_GetColumnW(hwnd,x,col)\ + (LRESULT)SNDMSGW((hwnd),LVM_GETCOLUMNW,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNW)(col)) +#define ListView_GetColumn WINELIB_NAME_AW(ListView_GetColumn) +#define ListView_SetColumnA(hwnd,x,col)\ + (LRESULT)SNDMSGA((hwnd),LVM_SETCOLUMNA,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNA)(col)) +#define ListView_SetColumnW(hwnd,x,col)\ + (LRESULT)SNDMSGW((hwnd),LVM_SETCOLUMNW,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNW)(col)) +#define ListView_SetColumn WINELIB_NAME_AW(ListView_SetColumn) + + +#define ListView_GetNextItem(hwnd,nItem,flags) \ + (INT)SNDMSGA((hwnd),LVM_GETNEXTITEM,(WPARAM)(INT)(nItem),(LPARAM)(MAKELPARAM(flags,0))) +#define ListView_FindItemA(hwnd,nItem,plvfi) \ + (INT)SNDMSGA((hwnd),LVM_FINDITEMA,(WPARAM)(INT)(nItem),(LPARAM)(LVFINDINFOA*)(plvfi)) +#define ListView_FindItemW(hwnd,nItem,plvfi) \ + (INT)SNDMSGW((hwnd),LVM_FINDITEMW,(WPARAM)(INT)(nItem),(LPARAM)(LVFINDINFOW*)(plvfi)) +#define ListView_FindItem WINELIB_NAME_AW(ListView_FindItem) + +#define ListView_Arrange(hwnd,code) \ + (INT)SNDMSGA((hwnd),LVM_ARRANGE,(WPARAM)(INT)(code),0L) +#define ListView_GetItemPosition(hwnd,i,ppt) \ + (INT)SNDMSGA((hwnd),LVM_GETITEMPOSITION,(WPARAM)(INT)(i),(LPARAM)(LPPOINT)(ppt)) +#define ListView_GetItemRect(hwnd,i,prc,code) \ + (BOOL)SNDMSGA((hwnd), LVM_GETITEMRECT, (WPARAM)(int)(i), \ + ((prc) ? (((RECT*)(prc))->left = (code),(LPARAM)(RECT \ + *)(prc)) : (LPARAM)(RECT*)NULL)) +#define ListView_SetItemA(hwnd,pitem) \ + (INT)SNDMSGA((hwnd),LVM_SETITEMA,0,(LPARAM)(const LVITEMA *)(pitem)) +#define ListView_SetItemW(hwnd,pitem) \ + (INT)SNDMSGW((hwnd),LVM_SETITEMW,0,(LPARAM)(const LVITEMW *)(pitem)) +#define ListView_SetItem WINELIB_NAME_AW(ListView_SetItem) +#define ListView_SetItemState(hwnd,i,pitem) \ + (BOOL)SNDMSGA((hwnd),LVM_SETITEMSTATE,(WPARAM)(UINT)(i),(LPARAM)(LPLVITEMA)(pitem)) +#define ListView_GetItemState(hwnd,i,mask) \ + (BOOL)SNDMSGA((hwnd),LVM_GETITEMSTATE,(WPARAM)(UINT)(i),(LPARAM)(UINT)(mask)) +#define ListView_GetCountPerPage(hwnd) \ + (BOOL)SNDMSGW((hwnd),LVM_GETCOUNTPERPAGE,0,0L) +#define ListView_GetImageList(hwnd,iImageList) \ + (HIMAGELIST)SNDMSGA((hwnd),LVM_GETIMAGELIST,(WPARAM)(INT)(iImageList),0L) +#define ListView_GetStringWidthA(hwnd,pstr) \ + (INT)SNDMSGA((hwnd),LVM_GETSTRINGWIDTHA,0,(LPARAM)(LPCSTR)(pstr)) +#define ListView_GetStringWidthW(hwnd,pstr) \ + (INT)SNDMSGW((hwnd),LVM_GETSTRINGWIDTHW,0,(LPARAM)(LPCWSTR)(pstr)) +#define ListView_GetStringWidth WINELIB_NAME_AW(ListView_GetStringWidth) +#define ListView_GetTopIndex(hwnd) \ + (BOOL)SNDMSGA((hwnd),LVM_GETTOPINDEX,0,0L) +#define ListView_Scroll(hwnd,dx,dy) \ + (BOOL)SNDMSGA((hwnd),LVM_SCROLL,(WPARAM)(INT)(dx),(LPARAM)(INT)(dy)) +#define ListView_EnsureVisible(hwnd,i,fPartialOk) \ + (BOOL)SNDMSGA((hwnd),LVM_ENSUREVISIBLE,(WPARAM)(INT)i,(LPARAM)(BOOL)fPartialOk) +#define ListView_SetBkColor(hwnd,clrBk) \ + (BOOL)SNDMSGA((hwnd),LVM_SETBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) +#define ListView_SetImageList(hwnd,himl,iImageList) \ + (HIMAGELIST)(UINT)SNDMSGA((hwnd),LVM_SETIMAGELIST,(WPARAM)(iImageList),(LPARAM)(UINT)(HIMAGELIST)(himl)) +#define ListView_GetItemCount(hwnd) \ + (INT)SNDMSGA((hwnd),LVM_GETITEMCOUNT,0,0L) + +#define ListView_GetItemA(hwnd,pitem) \ + (BOOL)SNDMSGA((hwnd),LVM_GETITEMA,0,(LPARAM)(LVITEMA *)(pitem)) +#define ListView_GetItemW(hwnd,pitem) \ + (BOOL)SNDMSGW((hwnd),LVM_GETITEMW,0,(LPARAM)(LVITEMW *)(pitem)) +#define ListView_GetItem WINELIB_NAME_AW(ListView_GetItem) + +#define ListView_HitTest(hwnd,pinfo) \ + (INT)SNDMSGA((hwnd),LVM_HITTEST,0,(LPARAM)(LPLVHITTESTINFO)(pinfo)) + +#define ListView_InsertItemA(hwnd,pitem) \ + (INT)SNDMSGA((hwnd),LVM_INSERTITEMA,0,(LPARAM)(const LVITEMA *)(pitem)) +#define ListView_InsertItemW(hwnd,pitem) \ + (INT)SNDMSGW((hwnd),LVM_INSERTITEMW,0,(LPARAM)(const LVITEMW *)(pitem)) +#define ListView_InsertItem WINELIB_NAME_AW(ListView_InsertItem) + +#define ListView_DeleteAllItems(hwnd) \ + (BOOL)SNDMSGA((hwnd),LVM_DELETEALLITEMS,0,0L) + +#define ListView_InsertColumnA(hwnd,iCol,pcol) \ + (INT)SNDMSGA((hwnd),LVM_INSERTCOLUMNA,(WPARAM)(INT)(iCol),(LPARAM)(const LVCOLUMNA *)(pcol)) +#define ListView_InsertColumnW(hwnd,iCol,pcol) \ + (INT)SNDMSGW((hwnd),LVM_INSERTCOLUMNW,(WPARAM)(INT)(iCol),(LPARAM)(const LVCOLUMNW *)(pcol)) +#define ListView_InsertColumn WINELIB_NAME_AW(ListView_InsertColumn) + +#define ListView_SortItems(hwndLV,_pfnCompare,_lPrm) \ + (BOOL)SNDMSGA((hwndLV),LVM_SORTITEMS,(WPARAM)(LPARAM)_lPrm,(LPARAM)(PFNLVCOMPARE)_pfnCompare) +#define ListView_SetItemPosition(hwndLV, i, x, y) \ + (BOOL)SNDMSGA((hwndLV),LVM_SETITEMPOSITION,(WPARAM)(INT)(i),MAKELPARAM((x),(y))) +#define ListView_GetSelectedCount(hwndLV) \ + (UINT)SNDMSGA((hwndLV),LVM_GETSELECTEDCOUNT,0,0L) + +#define ListView_EditLabelA(hwndLV, i) \ + (HWND)SNDMSGA((hwndLV),LVM_EDITLABELA,(WPARAM)(int)(i), 0L) +#define ListView_EditLabelW(hwndLV, i) \ + (HWND)SNDMSGW((hwndLV),LVM_EDITLABELW,(WPARAM)(int)(i), 0L) +#define ListView_EditLabel WINELIB_NAME_AW(ListView_EditLabel) + +#define ListView_SetItemTextA(hwndLV, i, _iSubItem, _pszText) \ +{ LVITEMA _LVi; _LVi.iSubItem = _iSubItem; _LVi.pszText = _pszText;\ + SNDMSGA(hwndLV, LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM) (LVITEMA*)&_LVi);} +#define ListView_SetItemTextW(hwndLV, i, _iSubItem, _pszText) \ +{ LVITEMW _LVi; _LVi.iSubItem = _iSubItem; _LVi.pszText = _pszText;\ + SNDMSGW(hwndLV, LVM_SETITEMTEXTW, (WPARAM)i, (LPARAM) (LVITEMW*)& _LVi);} +#define ListView_SetItemText WINELIB_NAME_AW(ListView_SetItemText) + +#define ListView_DeleteItem(hwndLV, i) \ + (BOOL)SNDMSGA(hwndLV, LVM_DELETEITEM, (WPARAM)(int)(i), 0L) +#define ListView_Update(hwndLV, i) \ + (BOOL)SNDMSGA((hwndLV), LVM_UPDATE, (WPARAM)(i), 0L) +#define ListView_GetColumnOrderArray(hwndLV, iCount, pi) \ + (BOOL)SNDMSGA((hwndLV), LVM_GETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) +#define ListView_GetExtendedListViewStyle(hwndLV) \ + (DWORD)SNDMSGA((hwndLV), LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L) +#define ListView_GetHotCursor(hwndLV) \ + (HCURSOR)SNDMSGA((hwndLV), LVM_GETHOTCURSOR, 0, 0L) +#define ListView_GetHotItem(hwndLV) \ + (int)SNDMSGA((hwndLV), LVM_GETHOTITEM, 0, 0L) +#define ListView_GetItemSpacing(hwndLV, fSmall) \ + (DWORD)SNDMSGA((hwndLV), LVM_GETITEMSPACING, (WPARAM)fSmall, 0L) +#define ListView_GetSubItemRect(hwndLV, iItem, iSubItem, code, prc) \ + (BOOL)SNDMSGA((hwndLV), LVM_GETSUBITEMRECT, (WPARAM)(int)(iItem), \ + ((prc) ? (((LPRECT)(prc))->top = iSubItem), (((LPRECT)(prc))->left = code):0), (LPARAM)prc) +#define ListView_GetToolTips(hwndLV) \ + (HWND)SNDMSGA((hwndLV), LVM_GETTOOLTIPS, 0, 0L) +#define ListView_SetColumnOrderArray(hwndLV, iCount, pi) \ + (BOOL)SNDMSGA((hwndLV), LVM_SETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) +#define ListView_SetExtendedListViewStyle(hwndLV, dw) \ + (DWORD)SNDMSGA((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)dw) +#define ListView_SetExtendedListViewStyleEx(hwndLV, dwMask, dw) \ + (DWORD)SNDMSGA((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, (WPARAM)dwMask, (LPARAM)dw) +#define ListView_SetHotCursor(hwndLV, hcur) \ + (HCURSOR)SNDMSGA((hwndLV), LVM_SETHOTCURSOR, 0, (LPARAM)hcur) +#define ListView_SetHotItem(hwndLV, i) \ + (int)SNDMSGA((hwndLV), LVM_SETHOTITEM, (WPARAM)i, 0L) +#define ListView_SetIconSpacing(hwndLV, cx, cy) \ + (DWORD)SNDMSGA((hwndLV), LVM_SETICONSPACING, 0, MAKELONG(cx,cy)) +#define ListView_SetToolTips(hwndLV, hwndNewHwnd) \ + (HWND)SNDMSGA((hwndLV), LVM_SETTOOLTIPS, (WPARAM)hwndNewHwnd, 0L) +#define ListView_SubItemHitTest(hwndLV, plvhti) \ + (int)SNDMSGA((hwndLV), LVM_SUBITEMHITTEST, 0, (LPARAM)(LPLVHITTESTINFO)(plvhti)) + + +/* Tab Control */ + +#define WC_TABCONTROL16 "SysTabControl" +#define WC_TABCONTROLA "SysTabControl32" +#if defined(__GNUC__) +# define WC_TABCONTROLW (const WCHAR []){ 'S','y','s', \ + 'T','a','b','C','o','n','t','r','o','l','3','2',0 } +#elif defined(_MSC_VER) +# define WC_TABCONTROLW L"SysTabControl32" +#else +static const WCHAR WC_TABCONTROLW[] = { 'S','y','s', + 'T','a','b','C','o','n','t','r','o','l','3','2',0 }; +#endif +#define WC_TABCONTROL WINELIB_NAME_AW(WC_TABCONTROL) + +/* tab control styles */ +#define TCS_SCROLLOPPOSITE 0x0001 /* assumes multiline tab */ +#define TCS_BOTTOM 0x0002 +#define TCS_RIGHT 0x0002 +#define TCS_MULTISELECT 0x0004 /* allow multi-select in button mode */ +#define TCS_FLATBUTTONS 0x0008 +#define TCS_FORCEICONLEFT 0x0010 +#define TCS_FORCELABELLEFT 0x0020 +#define TCS_HOTTRACK 0x0040 +#define TCS_VERTICAL 0x0080 +#define TCS_TABS 0x0000 +#define TCS_BUTTONS 0x0100 +#define TCS_SINGLELINE 0x0000 +#define TCS_MULTILINE 0x0200 +#define TCS_RIGHTJUSTIFY 0x0000 +#define TCS_FIXEDWIDTH 0x0400 +#define TCS_RAGGEDRIGHT 0x0800 +#define TCS_FOCUSONBUTTONDOWN 0x1000 +#define TCS_OWNERDRAWFIXED 0x2000 +#define TCS_TOOLTIPS 0x4000 +#define TCS_FOCUSNEVER 0x8000 +#define TCS_EX_FLATSEPARATORS 0x00000001 /* to be used with */ +#define TCS_EX_REGISTERDROP 0x00000002 /* TCM_SETEXTENDEDSTYLE */ + + +#define TCM_FIRST 0x1300 + +#define TCM_GETIMAGELIST (TCM_FIRST + 2) +#define TCM_SETIMAGELIST (TCM_FIRST + 3) +#define TCM_GETITEMCOUNT (TCM_FIRST + 4) +#define TCM_GETITEM WINELIB_NAME_AW(TCM_GETITEM) +#define TCM_GETITEMA (TCM_FIRST + 5) +#define TCM_GETITEMW (TCM_FIRST + 60) +#define TCM_SETITEMA (TCM_FIRST + 6) +#define TCM_SETITEMW (TCM_FIRST + 61) +#define TCM_SETITEM WINELIB_NAME_AW(TCM_SETITEM) +#define TCM_INSERTITEMA (TCM_FIRST + 7) +#define TCM_INSERTITEMW (TCM_FIRST + 62) +#define TCM_INSERTITEM WINELIB_NAME_AW(TCM_INSERTITEM) +#define TCM_DELETEITEM (TCM_FIRST + 8) +#define TCM_DELETEALLITEMS (TCM_FIRST + 9) +#define TCM_GETITEMRECT (TCM_FIRST + 10) +#define TCM_GETCURSEL (TCM_FIRST + 11) +#define TCM_SETCURSEL (TCM_FIRST + 12) +#define TCM_HITTEST (TCM_FIRST + 13) +#define TCM_SETITEMEXTRA (TCM_FIRST + 14) +#define TCM_ADJUSTRECT (TCM_FIRST + 40) +#define TCM_SETITEMSIZE (TCM_FIRST + 41) +#define TCM_REMOVEIMAGE (TCM_FIRST + 42) +#define TCM_SETPADDING (TCM_FIRST + 43) +#define TCM_GETROWCOUNT (TCM_FIRST + 44) +#define TCM_GETTOOLTIPS (TCM_FIRST + 45) +#define TCM_SETTOOLTIPS (TCM_FIRST + 46) +#define TCM_GETCURFOCUS (TCM_FIRST + 47) +#define TCM_SETCURFOCUS (TCM_FIRST + 48) +#define TCM_SETMINTABWIDTH (TCM_FIRST + 49) +#define TCM_DESELECTALL (TCM_FIRST + 50) +#define TCM_HIGHLIGHTITEM (TCM_FIRST + 51) +#define TCM_SETEXTENDEDSTYLE (TCM_FIRST + 52) +#define TCM_GETEXTENDEDSTYLE (TCM_FIRST + 53) +#define TCM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define TCM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT + + +#define TCIF_TEXT 0x0001 +#define TCIF_IMAGE 0x0002 +#define TCIF_RTLREADING 0x0004 +#define TCIF_PARAM 0x0008 +#define TCIF_STATE 0x0010 + +#define TCIS_BUTTONPRESSED 0x0001 +#define TCIS_HIGHLIGHTED 0x0002 + +/* TabCtrl Macros */ +#define TabCtrl_GetImageList(hwnd) \ + (HIMAGELIST)SNDMSGA((hwnd), TCM_GETIMAGELIST, 0, 0L) +#define TabCtrl_SetImageList(hwnd, himl) \ + (HIMAGELIST)SNDMSGA((hwnd), TCM_SETIMAGELIST, 0, (LPARAM)(UINT)(HIMAGELIST)(himl)) +#define TabCtrl_GetItemCount(hwnd) \ + (int)SNDMSGA((hwnd), TCM_GETITEMCOUNT, 0, 0L) +#define TabCtrl_GetItemA(hwnd, iItem, pitem) \ + (BOOL)SNDMSGA((hwnd), TCM_GETITEM, (WPARAM)(int)iItem, (LPARAM)(TC_ITEM *)(pitem)) +#define TabCtrl_GetItemW(hwnd, iItem, pitem) \ + (BOOL)SNDMSGW((hwnd), TCM_GETITEM, (WPARAM)(int)iItem, (LPARAM)(TC_ITEM *)(pitem)) +#define TabCtrl_GetItem WINELIB_NAME_AW(TabCtrl_GetItem) +#define TabCtrl_SetItemA(hwnd, iItem, pitem) \ + (BOOL)SNDMSGA((hwnd), TCM_SETITEM, (WPARAM)(int)iItem, (LPARAM)(TC_ITEM *)(pitem)) +#define TabCtrl_SetItemW(hwnd, iItem, pitem) \ + (BOOL)SNDMSGW((hwnd), TCM_SETITEM, (WPARAM)(int)iItem, (LPARAM)(TC_ITEM *)(pitem)) +#define TabCtrl_SetItem WINELIB_NAME_AW(TabCtrl_GetItem) +#define TabCtrl_InsertItemA(hwnd, iItem, pitem) \ + (int)SNDMSGA((hwnd), TCM_INSERTITEM, (WPARAM)(int)iItem, (LPARAM)(const TC_ITEM *)(pitem)) +#define TabCtrl_InsertItemW(hwnd, iItem, pitem) \ + (int)SNDMSGW((hwnd), TCM_INSERTITEM, (WPARAM)(int)iItem, (LPARAM)(const TC_ITEM *)(pitem)) +#define TabCtrl_InsertItem WINELIB_NAME_AW(TabCtrl_InsertItem) +#define TabCtrl_DeleteItem(hwnd, i) \ + (BOOL)SNDMSGA((hwnd), TCM_DELETEITEM, (WPARAM)(int)(i), 0L) +#define TabCtrl_DeleteAllItems(hwnd) \ + (BOOL)SNDMSGA((hwnd), TCM_DELETEALLITEMS, 0, 0L) +#define TabCtrl_GetItemRect(hwnd, i, prc) \ + (BOOL)SNDMSGA((hwnd), TCM_GETITEMRECT, (WPARAM)(int)(i), (LPARAM)(RECT *)(prc)) +#define TabCtrl_GetCurSel(hwnd) \ + (int)SNDMSGA((hwnd), TCM_GETCURSEL, 0, 0) +#define TabCtrl_SetCurSel(hwnd, i) \ + (int)SNDMSGA((hwnd), TCM_SETCURSEL, (WPARAM)i, 0) +#define TabCtrl_HitTest(hwndTC, pinfo) \ + (int)SNDMSGA((hwndTC), TCM_HITTEST, 0, (LPARAM)(TC_HITTESTINFO *)(pinfo)) +#define TabCtrl_SetItemExtra(hwndTC, cb) \ + (BOOL)SNDMSGA((hwndTC), TCM_SETITEMEXTRA, (WPARAM)(cb), 0L) +#define TabCtrl_AdjustRect(hwnd, bLarger, prc) \ + (int)SNDMSGA(hwnd, TCM_ADJUSTRECT, (WPARAM)(BOOL)bLarger, (LPARAM)(RECT *)prc) +#define TabCtrl_SetItemSize(hwnd, x, y) \ + (DWORD)SNDMSGA((hwnd), TCM_SETITEMSIZE, 0, MAKELPARAM(x,y)) +#define TabCtrl_RemoveImage(hwnd, i) \ + (void)SNDMSGA((hwnd), TCM_REMOVEIMAGE, i, 0L) +#define TabCtrl_SetPadding(hwnd, cx, cy) \ + (void)SNDMSGA((hwnd), TCM_SETPADDING, 0, MAKELPARAM(cx, cy)) +#define TabCtrl_GetRowCount(hwnd) \ + (int)SNDMSGA((hwnd), TCM_GETROWCOUNT, 0, 0L) +#define TabCtrl_GetToolTips(hwnd) \ + (HWND)SNDMSGA((hwnd), TCM_GETTOOLTIPS, 0, 0L) +#define TabCtrl_SetToolTips(hwnd, hwndTT) \ + (void)SNDMSGA((hwnd), TCM_SETTOOLTIPS, (WPARAM)hwndTT, 0L) +#define TabCtrl_GetCurFocus(hwnd) \ + (int)SNDMSGA((hwnd), TCM_GETCURFOCUS, 0, 0) +#define TabCtrl_SetCurFocus(hwnd, i) \ + SNDMSGA((hwnd),TCM_SETCURFOCUS, i, 0) +#define TabCtrl_SetMinTabWidth(hwnd, x) \ + (int)SNDMSGA((hwnd), TCM_SETMINTABWIDTH, 0, x) +#define TabCtrl_DeselectAll(hwnd, fExcludeFocus)\ + (void)SNDMSGA((hwnd), TCM_DESELECTALL, fExcludeFocus, 0) + + +/* constants for TCHITTESTINFO */ + +#define TCHT_NOWHERE 0x01 +#define TCHT_ONITEMICON 0x02 +#define TCHT_ONITEMLABEL 0x04 +#define TCHT_ONITEM (TCHT_ONITEMICON | TCHT_ONITEMLABEL) + + +typedef struct tagTCITEMA { + UINT mask; + UINT dwState; + UINT dwStateMask; + LPSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; +} TCITEMA, *LPTCITEMA; + +typedef struct tagTCITEMW +{ + UINT mask; + DWORD dwState; + DWORD dwStateMask; + LPWSTR pszText; + INT cchTextMax; + INT iImage; + LPARAM lParam; +} TCITEMW, *LPTCITEMW; + +#define TCITEM WINELIB_NAME_AW(TCITEM) +#define LPTCITEM WINELIB_NAME_AW(LPTCITEM) +#define TC_ITEM TCITEM + +#define TCN_FIRST (0U-550U) +#define TCN_LAST (0U-580U) +#define TCN_KEYDOWN (TCN_FIRST - 0) +#define TCN_SELCHANGE (TCN_FIRST - 1) +#define TCN_SELCHANGING (TCN_FIRST - 2) +#define TCN_GETOBJECT (TCN_FIRST - 3) + +#include "pshpack1.h" +typedef struct tagTCKEYDOWN +{ + NMHDR hdr; + WORD wVKey; + UINT flags; +} NMTCKEYDOWN; +#include "poppack.h" + +#define TC_KEYDOWN NMTCKEYDOWN + +/* ComboBoxEx control */ + +#define WC_COMBOBOXEXA "ComboBoxEx32" +#if defined(__GNUC__) +# define WC_COMBOBOXEXW (const WCHAR []){ 'C','o','m','b','o', \ + 'B','o','x','E','x','3','2',0 } +#elif defined(_MSC_VER) +# define WC_COMBOBOXEXW L"ComboBoxEx32" +#else +static const WCHAR WC_COMBOBOXEXW[] = { 'C','o','m','b','o', + 'B','o','x','E','x','3','2',0 }; +#endif +#define WC_COMBOBOXEX WINELIB_NAME_AW(WC_COMBOBOXEX) + +#define CBEIF_TEXT 0x00000001 +#define CBEIF_IMAGE 0x00000002 +#define CBEIF_SELECTEDIMAGE 0x00000004 +#define CBEIF_OVERLAY 0x00000008 +#define CBEIF_INDENT 0x00000010 +#define CBEIF_LPARAM 0x00000020 +#define CBEIF_DI_SETITEM 0x10000000 + +#define CBEM_INSERTITEMA (WM_USER+1) +#define CBEM_INSERTITEMW (WM_USER+11) +#define CBEM_INSERTITEM WINELIB_NAME_AW(CBEM_INSERTITEM) +#define CBEM_SETIMAGELIST (WM_USER+2) +#define CBEM_GETIMAGELIST (WM_USER+3) +#define CBEM_GETITEMA (WM_USER+4) +#define CBEM_GETITEMW (WM_USER+13) +#define CBEM_GETITEM WINELIB_NAME_AW(CBEM_GETITEM) +#define CBEM_SETITEMA (WM_USER+5) +#define CBEM_SETITEMW (WM_USER+12) +#define CBEM_SETITEM WINELIB_NAME_AW(CBEM_SETITEM) +#define CBEM_DELETEITEM CB_DELETESTRING +#define CBEM_GETCOMBOCONTROL (WM_USER+6) +#define CBEM_GETEDITCONTROL (WM_USER+7) +#define CBEM_SETEXSTYLE (WM_USER+8) +#define CBEM_GETEXSTYLE (WM_USER+9) +#define CBEM_GETEXTENDEDSTYLE (WM_USER+9) +#define CBEM_SETEXTENDEDSTYLE (WM_USER+14) +#define CBEM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT +#define CBEM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define CBEM_HASEDITCHANGED (WM_USER+10) + +#define CBEIF_TEXT 0x00000001 +#define CBEIF_IMAGE 0x00000002 +#define CBEIF_SELECTEDIMAGE 0x00000004 +#define CBEIF_OVERLAY 0x00000008 +#define CBEIF_INDENT 0x00000010 +#define CBEIF_LPARAM 0x00000020 +#define CBEIF_DI_SETITEM 0x10000000 + +#define CBEN_FIRST (0U-800U) +#define CBEN_LAST (0U-830U) + +#define CBEN_GETDISPINFOA (CBEN_FIRST - 0) +#define CBEN_GETDISPINFOW (CBEN_FIRST - 7) +#define CBEN_GETDISPINFO WINELIB_NAME_AW(CBEN_GETDISPINFO) +#define CBEN_INSERTITEM (CBEN_FIRST - 1) +#define CBEN_DELETEITEM (CBEN_FIRST - 2) +#define CBEN_BEGINEDIT (CBEN_FIRST - 4) +#define CBEN_ENDEDITA (CBEN_FIRST - 5) +#define CBEN_ENDEDITW (CBEN_FIRST - 6) +#define CBEN_ENDEDIT WINELIB_NAME_AW(CBEN_ENDEDIT) +#define CBEN_DRAGBEGINA (CBEN_FIRST - 8) +#define CBEN_DRAGBEGINW (CBEN_FIRST - 9) +#define CBEN_DRAGBEGIN WINELIB_NAME_AW(CBEN_DRAGBEGIN) + +#define CBES_EX_NOEDITIMAGE 0x00000001 +#define CBES_EX_NOEDITIMAGEINDENT 0x00000002 +#define CBES_EX_PATHWORDBREAKPROC 0x00000004 +#define CBES_EX_NOSIZELIMIT 0x00000008 +#define CBES_EX_CASESENSITIVE 0x00000010 + + +typedef struct tagCOMBOBOXEXITEMA +{ + UINT mask; + int iItem; + LPSTR pszText; + int cchTextMax; + int iImage; + int iSelectedImage; + int iOverlay; + int iIndent; + LPARAM lParam; +} COMBOBOXEXITEMA, *PCOMBOBOXEXITEMA; +typedef COMBOBOXEXITEMA const *PCCOMBOEXITEMA; /* Yes, there's a BOX missing */ + +typedef struct tagCOMBOBOXEXITEMW +{ + UINT mask; + int iItem; + LPWSTR pszText; + int cchTextMax; + int iImage; + int iSelectedImage; + int iOverlay; + int iIndent; + LPARAM lParam; +} COMBOBOXEXITEMW, *PCOMBOBOXEXITEMW; +typedef COMBOBOXEXITEMW const *PCCOMBOEXITEMW; /* Yes, there's a BOX missing */ + +#define COMBOBOXEXITEM WINELIB_NAME_AW(COMBOBOXEXITEM) +#define PCOMBOBOXEXITEM WINELIB_NAME_AW(PCOMBOBOXEXITEM) +#define PCCOMBOBOXEXITEM WINELIB_NAME_AW(PCCOMBOEXITEM) /* Yes, there's a BOX missing */ + +#define CBENF_KILLFOCUS 1 +#define CBENF_RETURN 2 +#define CBENF_ESCAPE 3 +#define CBENF_DROPDOWN 4 + +#define CBEMAXSTRLEN 260 + +typedef struct tagNMCBEENDEDITW +{ + NMHDR hdr; + BOOL fChanged; + int iNewSelection; + WCHAR szText[CBEMAXSTRLEN]; + int iWhy; +} NMCBEENDEDITW, *LPNMCBEENDEDITW, *PNMCBEENDEDITW; + +typedef struct tagNMCBEENDEDITA +{ + NMHDR hdr; + BOOL fChanged; + int iNewSelection; + char szText[CBEMAXSTRLEN]; + int iWhy; +} NMCBEENDEDITA, *LPNMCBEENDEDITA, *PNMCBEENDEDITA; + +#define NMCBEENDEDIT WINELIB_NAME_AW(NMCBEENDEDIT) +#define LPNMCBEENDEDIT WINELIB_NAME_AW(LPNMCBEENDEDIT) +#define PNMCBEENDEDIT WINELIB_NAME_AW(PNMCBEENDEDIT) + +typedef struct +{ + NMHDR hdr; + COMBOBOXEXITEMA ceItem; +} NMCOMBOBOXEXA, *PNMCOMBOBOXEXA; + +typedef struct +{ + NMHDR hdr; + COMBOBOXEXITEMW ceItem; +} NMCOMBOBOXEXW, *PNMCOMBOBOXEXW; + +#define NMCOMBOBOXEX WINELIB_NAME_AW(NMCOMBOBOXEX) +#define PNMCOMBOBOXEX WINELIB_NAME_AW(PNMCOMBOBOXEX) + +typedef struct +{ + NMHDR hdr; + int iItemid; + char szText[CBEMAXSTRLEN]; +} NMCBEDRAGBEGINA, *PNMCBEDRAGBEGINA, *LPNMCBEDRAGBEGINA; + +typedef struct +{ + NMHDR hdr; + int iItemid; + WCHAR szText[CBEMAXSTRLEN]; +} NMCBEDRAGBEGINW, *PNMCBEDRAGBEGINW, *LPNMCBEDRAGBEGINW; + +#define NMCBEDRAGBEGIN WINELIB_NAME_AW(NMCBEDRAGBEGIN) +#define PNMCBEDRAGBEGIN WINELIB_NAME_AW(PNMCBEDRAGBEGIN) +#define LPNMCBEDRAGBEGIN WINELIB_NAME_AW(LPNMCBEDRAGBEGIN) + + +/* Hotkey control */ + +#define HOTKEY_CLASS16 "msctls_hotkey" +#define HOTKEY_CLASSA "msctls_hotkey32" +#if defined(__GNUC__) +# define HOTKEY_CLASSW (const WCHAR []){ 'm','s','c','t','l','s','_', \ + 'h','o','t','k','e','y','3','2',0 } +#elif defined(_MSC_VER) +# define HOTKEY_CLASSW L"msctls_hotkey32" +#else +static const WCHAR HOTKEY_CLASSW[] = { 'm','s','c','t','l','s','_', + 'h','o','t','k','e','y','3','2',0 }; +#endif +#define HOTKEY_CLASS WINELIB_NAME_AW(HOTKEY_CLASS) + +#define HOTKEYF_SHIFT 0x01 +#define HOTKEYF_CONTROL 0x02 +#define HOTKEYF_ALT 0x04 +#define HOTKEYF_EXT 0x08 + +#define HKCOMB_NONE 0x0001 +#define HKCOMB_S 0x0002 +#define HKCOMB_C 0x0004 +#define HKCOMB_A 0x0008 +#define HKCOMB_SC 0x0010 +#define HKCOMB_SA 0x0020 +#define HKCOMB_CA 0x0040 +#define HKCOMB_SCA 0x0080 + +#define HKM_SETHOTKEY (WM_USER+1) +#define HKM_GETHOTKEY (WM_USER+2) +#define HKM_SETRULES (WM_USER+3) + + +/* animate control */ + +#define ANIMATE_CLASSA "SysAnimate32" +#if defined(__GNUC__) +# define ANIMATE_CLASSW (const WCHAR []){ 'S','y','s', \ + 'A','n','i','m','a','t','e','3','2',0 } +#elif defined(_MSC_VER) +# define ANIMATE_CLASSW L"SysAnimate32" +#else +static const WCHAR ANIMATE_CLASSW[] = { 'S','y','s', + 'A','n','i','m','a','t','e','3','2',0 }; +#endif +#define ANIMATE_CLASS WINELIB_NAME_AW(ANIMATE_CLASS) + +#define ACS_CENTER 0x0001 +#define ACS_TRANSPARENT 0x0002 +#define ACS_AUTOPLAY 0x0004 +#define ACS_TIMER 0x0008 /* no threads, just timers */ + +#define ACM_OPENA (WM_USER+100) +#define ACM_OPENW (WM_USER+103) +#define ACM_OPEN WINELIB_NAME_AW(ACM_OPEN) +#define ACM_PLAY (WM_USER+101) +#define ACM_STOP (WM_USER+102) + +#define ACN_START 1 +#define ACN_STOP 2 + +#define Animate_CreateA(hwndP,id,dwStyle,hInstance) \ + CreateWindowA(ANIMATE_CLASSA,NULL,dwStyle,0,0,0,0,hwndP,(HMENU)(id),hInstance,NULL) +#define Animate_CreateW(hwndP,id,dwStyle,hInstance) \ + CreateWindowW(ANIMATE_CLASSW,NULL,dwStyle,0,0,0,0,hwndP,(HMENU)(id),hInstance,NULL) +#define Animate_Create WINELIB_NAME_AW(Animate_Create) +#define Animate_OpenA(hwnd,szName) \ + (BOOL)SNDMSGA(hwnd,ACM_OPENA,0,(LPARAM)(LPSTR)(szName)) +#define Animate_OpenW(hwnd,szName) \ + (BOOL)SNDMSGW(hwnd,ACM_OPENW,0,(LPARAM)(LPWSTR)(szName)) +#define Animate_Open WINELIB_NAME_AW(Animate_Open) +#define Animate_OpenExA(hwnd,hInst,szName) \ + (BOOL)SNDMSGA(hwnd,ACM_OPENA,(WPARAM)hInst,(LPARAM)(LPSTR)(szName)) +#define Animate_OpenExW(hwnd,hInst,szName) \ + (BOOL)SNDMSGW(hwnd,ACM_OPENW,(WPARAM)hInst,(LPARAM)(LPWSTR)(szName)) +#define Animate_OpenEx WINELIB_NAME_AW(Animate_OpenEx) +#define Animate_Play(hwnd,from,to,rep) \ + (BOOL)SNDMSGA(hwnd,ACM_PLAY,(WPARAM)(UINT)(rep),(LPARAM)MAKELONG(from,to)) +#define Animate_Stop(hwnd) \ + (BOOL)SNDMSGA(hwnd,ACM_STOP,0,0) +#define Animate_Close(hwnd) \ + (BOOL)SNDMSGA(hwnd,ACM_OPENA,0,0) +#define Animate_Seek(hwnd,frame) \ + (BOOL)SNDMSGA(hwnd,ACM_PLAY,1,(LPARAM)MAKELONG(frame,frame)) + + +/************************************************************************** + * IP Address control + */ + +#define WC_IPADDRESSA "SysIPAddress32" +#if defined(__GNUC__) +# define WC_IPADDRESSW (const WCHAR []){ 'S','y','s', \ + 'I','P','A','d','d','r','e','s','s','3','2',0 } +#elif defined(_MSC_VER) +# define WC_IPADDRESSW L"SysIPAddress32" +#else +static const WCHAR WC_IPADDRESSW[] = { 'S','y','s', + 'I','P','A','d','d','r','e','s','s','3','2',0 }; +#endif +#define WC_IPADDRESS WINELIB_NAME_AW(WC_IPADDRESS) + +#define IPM_CLEARADDRESS (WM_USER+100) +#define IPM_SETADDRESS (WM_USER+101) +#define IPM_GETADDRESS (WM_USER+102) +#define IPM_SETRANGE (WM_USER+103) +#define IPM_SETFOCUS (WM_USER+104) +#define IPM_ISBLANK (WM_USER+105) + +#define IPN_FIRST (0U-860U) +#define IPN_LAST (0U-879U) +#define IPN_FIELDCHANGED (IPN_FIRST-0) + +typedef struct tagNMIPADDRESS +{ + NMHDR hdr; + INT iField; + INT iValue; +} NMIPADDRESS, *LPNMIPADDRESS; + +#define MAKEIPRANGE(low,high) \ + ((LPARAM)(WORD)(((BYTE)(high)<<8)+(BYTE)(low))) +#define MAKEIPADDRESS(b1,b2,b3,b4) \ + ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))) + +#define FIRST_IPADDRESS(x) (((x)>>24)&0xff) +#define SECOND_IPADDRESS(x) (((x)>>16)&0xff) +#define THIRD_IPADDRESS(x) (((x)>>8)&0xff) +#define FOURTH_IPADDRESS(x) ((x)&0xff) + + +/************************************************************************** + * Native Font control + */ + +#define WC_NATIVEFONTCTLA "NativeFontCtl" +#if defined(__GNUC__) +# define WC_NATIVEFONTCTLW (const WCHAR []){ 'N','a','t','i','v','e', \ + 'F','o','n','t','C','t','l',0 } +#elif defined(_MSC_VER) +# define WC_NATIVEFONTCTLW L"NativeFontCtl" +#else +static const WCHAR WC_NATIVEFONTCTLW[] = { 'N','a','t','i','v','e', + 'F','o','n','t','C','t','l',0 }; +#endif +#define WC_NATIVEFONTCTL WINELIB_NAME_AW(WC_NATIVEFONTCTL) + +#define NFS_EDIT 0x0001 +#define NFS_STATIC 0x0002 +#define NFS_LISTCOMBO 0x0004 +#define NFS_BUTTON 0x0008 +#define NFS_ALL 0x0010 + + +/************************************************************************** + * Month calendar control + * + */ + +#define MONTHCAL_CLASSA "SysMonthCal32" +#if defined(__GNUC__) +# define MONTHCAL_CLASSW (const WCHAR []){ 'S','y','s', \ + 'M','o','n','t','h','C','a','l','3','2',0 } +#elif defined(_MSC_VER) +# define MONTHCAL_CLASSW L"SysMonthCal32" +#else +static const WCHAR MONTHCAL_CLASSW[] = { 'S','y','s', + 'M','o','n','t','h','C','a','l','3','2',0 }; +#endif +#define MONTHCAL_CLASS WINELIB_NAME_AW(MONTHCAL_CLASS) + +#define MCM_FIRST 0x1000 +#define MCN_FIRST (0U-750U) +#define MCN_LAST (0U-759U) + + +#define MCM_GETCURSEL (MCM_FIRST + 1) +#define MCM_SETCURSEL (MCM_FIRST + 2) +#define MCM_GETMAXSELCOUNT (MCM_FIRST + 3) +#define MCM_SETMAXSELCOUNT (MCM_FIRST + 4) +#define MCM_GETSELRANGE (MCM_FIRST + 5) +#define MCM_SETSELRANGE (MCM_FIRST + 6) +#define MCM_GETMONTHRANGE (MCM_FIRST + 7) +#define MCM_SETDAYSTATE (MCM_FIRST + 8) +#define MCM_GETMINREQRECT (MCM_FIRST + 9) +#define MCM_SETCOLOR (MCM_FIRST + 10) +#define MCM_GETCOLOR (MCM_FIRST + 11) +#define MCM_SETTODAY (MCM_FIRST + 12) +#define MCM_GETTODAY (MCM_FIRST + 13) +#define MCM_HITTEST (MCM_FIRST + 14) +#define MCM_SETFIRSTDAYOFWEEK (MCM_FIRST + 15) +#define MCM_GETFIRSTDAYOFWEEK (MCM_FIRST + 16) +#define MCM_GETRANGE (MCM_FIRST + 17) +#define MCM_SETRANGE (MCM_FIRST + 18) +#define MCM_GETMONTHDELTA (MCM_FIRST + 19) +#define MCM_SETMONTHDELTA (MCM_FIRST + 20) +#define MCM_GETMAXTODAYWIDTH (MCM_FIRST + 21) +#define MCM_GETUNICODEFORMAT CCM_GETUNICODEFORMAT +#define MCM_SETUNICODEFORMAT CCM_SETUNICODEFORMAT + + +/* Notifications */ + +#define MCN_SELCHANGE (MCN_FIRST + 1) +#define MCN_GETDAYSTATE (MCN_FIRST + 3) +#define MCN_SELECT (MCN_FIRST + 4) + +#define MCSC_BACKGROUND 0 +#define MCSC_TEXT 1 +#define MCSC_TITLEBK 2 +#define MCSC_TITLETEXT 3 +#define MCSC_MONTHBK 4 +#define MCSC_TRAILINGTEXT 5 + +#define MCS_DAYSTATE 0x0001 +#define MCS_MULTISELECT 0x0002 +#define MCS_WEEKNUMBERS 0x0004 +#define MCS_NOTODAY 0x0010 +#define MCS_NOTODAYCIRCLE 0x0008 + +#define MCHT_TITLE 0x00010000 +#define MCHT_CALENDAR 0x00020000 +#define MCHT_TODAYLINK 0x00030000 + +#define MCHT_NEXT 0x01000000 +#define MCHT_PREV 0x02000000 +#define MCHT_NOWHERE 0x00000000 +#define MCHT_TITLEBK (MCHT_TITLE) +#define MCHT_TITLEMONTH (MCHT_TITLE | 0x0001) +#define MCHT_TITLEYEAR (MCHT_TITLE | 0x0002) +#define MCHT_TITLEBTNNEXT (MCHT_TITLE | MCHT_NEXT | 0x0003) +#define MCHT_TITLEBTNPREV (MCHT_TITLE | MCHT_PREV | 0x0003) + +#define MCHT_CALENDARBK (MCHT_CALENDAR) +#define MCHT_CALENDARDATE (MCHT_CALENDAR | 0x0001) +#define MCHT_CALENDARDATENEXT (MCHT_CALENDARDATE | MCHT_NEXT) +#define MCHT_CALENDARDATEPREV (MCHT_CALENDARDATE | MCHT_PREV) +#define MCHT_CALENDARDAY (MCHT_CALENDAR | 0x0002) +#define MCHT_CALENDARWEEKNUM (MCHT_CALENDAR | 0x0003) + + + +#define GMR_VISIBLE 0 +#define GMR_DAYSTATE 1 + + +/* Month calendar's structures */ + + +typedef struct { + UINT cbSize; + POINT pt; + UINT uHit; + SYSTEMTIME st; +} MCHITTESTINFO, *PMCHITTESTINFO; + +typedef struct tagNMSELCHANGE +{ + NMHDR nmhdr; + SYSTEMTIME stSelStart; + SYSTEMTIME stSelEnd; +} NMSELCHANGE, *LPNMSELCHANGE; + +typedef NMSELCHANGE NMSELECT, *LPNMSELECT; +typedef DWORD MONTHDAYSTATE, *LPMONTHDAYSTATE; + +typedef struct tagNMDAYSTATE +{ + NMHDR nmhdr; + SYSTEMTIME stStart; + int cDayState; + LPMONTHDAYSTATE prgDayState; +} NMDAYSTATE, *LPNMDAYSTATE; + + +/* macros */ + +#define MonthCal_GetCurSel(hmc, pst) \ + (BOOL)SNDMSGA(hmc, MCM_GETCURSEL, 0, (LPARAM)(pst)) +#define MonthCal_SetCurSel(hmc, pst) \ + (BOOL)SNDMSGA(hmc, MCM_SETCURSEL, 0, (LPARAM)(pst)) +#define MonthCal_GetMaxSelCount(hmc) \ + (DWORD)SNDMSGA(hmc, MCM_GETMAXSELCOUNT, 0, 0L) +#define MonthCal_SetMaxSelCount(hmc, n) \ + (BOOL)SNDMSGA(hmc, MCM_SETMAXSELCOUNT, (WPARAM)(n), 0L) +#define MonthCal_GetSelRange(hmc, rgst) \ + SNDMSGA(hmc, MCM_GETSELRANGE, 0, (LPARAM) (rgst)) +#define MonthCal_SetSelRange(hmc, rgst) \ + SNDMSGA(hmc, MCM_SETSELRANGE, 0, (LPARAM) (rgst)) +#define MonthCal_GetMonthRange(hmc, gmr, rgst) \ + (DWORD)SNDMSGA(hmc, MCM_GETMONTHRANGE, (WPARAM)(gmr), (LPARAM)(rgst)) +#define MonthCal_SetDayState(hmc, cbds, rgds) \ + SNDMSGA(hmc, MCM_SETDAYSTATE, (WPARAM)(cbds), (LPARAM)(rgds)) +#define MonthCal_GetMinReqRect(hmc, prc) \ + SNDMSGA(hmc, MCM_GETMINREQRECT, 0, (LPARAM)(prc)) +#define MonthCal_SetColor(hmc, iColor, clr)\ + SNDMSGA(hmc, MCM_SETCOLOR, iColor, clr) +#define MonthCal_GetColor(hmc, iColor) \ + SNDMSGA(hmc, MCM_SETCOLOR, iColor, 0) +#define MonthCal_GetToday(hmc, pst)\ + (BOOL)SNDMSGA(hmc, MCM_GETTODAY, 0, (LPARAM)pst) +#define MonthCal_SetToday(hmc, pst)\ + SNDMSGA(hmc, MCM_SETTODAY, 0, (LPARAM)pst) +#define MonthCal_HitTest(hmc, pinfo) \ + SNDMSGA(hmc, MCM_HITTEST, 0, (LPARAM)(PMCHITTESTINFO)pinfo) +#define MonthCal_SetFirstDayOfWeek(hmc, iDay) \ + SNDMSGA(hmc, MCM_SETFIRSTDAYOFWEEK, 0, iDay) +#define MonthCal_GetFirstDayOfWeek(hmc) \ + (DWORD)SNDMSGA(hmc, MCM_GETFIRSTDAYOFWEEK, 0, 0) +#define MonthCal_GetRange(hmc, rgst) \ + (DWORD)SNDMSGA(hmc, MCM_GETRANGE, 0, (LPARAM)(rgst)) +#define MonthCal_SetRange(hmc, gd, rgst) \ + (BOOL)SNDMSGA(hmc, MCM_SETRANGE, (WPARAM)(gd), (LPARAM)(rgst)) +#define MonthCal_GetMonthDelta(hmc) \ + (int)SNDMSGA(hmc, MCM_GETMONTHDELTA, 0, 0) +#define MonthCal_SetMonthDelta(hmc, n) \ + (int)SNDMSGA(hmc, MCM_SETMONTHDELTA, n, 0) +#define MonthCal_GetMaxTodayWidth(hmc) \ + (DWORD)SNDMSGA(hmc, MCM_GETMAXTODAYWIDTH, 0, 0) +#define MonthCal_SetUnicodeFormat(hwnd, fUnicode) \ + (BOOL)SNDMSGA((hwnd), MCM_SETUNICODEFORMAT, (WPARAM)(fUnicode), 0) +#define MonthCal_GetUnicodeFormat(hwnd) \ + (BOOL)SNDMSGA((hwnd), MCM_GETUNICODEFORMAT, 0, 0) + + +/************************************************************************** + * Date and time picker control + */ + +#define DATETIMEPICK_CLASSA "SysDateTimePick32" +#if defined(__GNUC__) +# define DATETIMEPICK_CLASSW (const WCHAR []){ 'S','y','s', \ + 'D','a','t','e','T','i','m','e','P','i','c','k','3','2',0 } +#elif defined(_MSC_VER) +# define DATETIMEPICK_CLASSW L"SysDateTimePick32" +#else +static const WCHAR DATETIMEPICK_CLASSW[] = { 'S','y','s', + 'D','a','t','e','T','i','m','e','P','i','c','k','3','2',0 }; +#endif +#define DATETIMEPICK_CLASS WINELIB_NAME_AW(DATETIMEPICK_CLASS) + +#define DTM_FIRST 0x1000 +#define DTN_FIRST (0U-760U) +#define DTN_LAST (0U-799U) + + +#define DTM_GETSYSTEMTIME (DTM_FIRST+1) +#define DTM_SETSYSTEMTIME (DTM_FIRST+2) +#define DTM_GETRANGE (DTM_FIRST+3) +#define DTM_SETRANGE (DTM_FIRST+4) +#define DTM_SETFORMATA (DTM_FIRST+5) +#define DTM_SETFORMATW (DTM_FIRST + 50) +#define DTM_SETFORMAT WINELIB_NAME_AW(DTM_SETFORMAT) +#define DTM_SETMCCOLOR (DTM_FIRST+6) +#define DTM_GETMCCOLOR (DTM_FIRST+7) +#define DTM_GETMONTHCAL (DTM_FIRST+8) +#define DTM_SETMCFONT (DTM_FIRST+9) +#define DTM_GETMCFONT (DTM_FIRST+10) + + +/* Datetime Notifications */ + +#define DTN_DATETIMECHANGE (DTN_FIRST + 1) +#define DTN_USERSTRINGA (DTN_FIRST + 2) +#define DTN_WMKEYDOWNA (DTN_FIRST + 3) +#define DTN_FORMATA (DTN_FIRST + 4) +#define DTN_FORMATQUERYA (DTN_FIRST + 5) +#define DTN_DROPDOWN (DTN_FIRST + 6) +#define DTN_CLOSEUP (DTN_FIRST + 7) +#define DTN_USERSTRINGW (DTN_FIRST + 15) +#define DTN_WMKEYDOWNW (DTN_FIRST + 16) +#define DTN_FORMATW (DTN_FIRST + 17) +#define DTN_FORMATQUERYW (DTN_FIRST + 18) + +#define DTN_USERSTRING WINELIB_NAME_AW(DTN_USERSTRING) +#define DTN_WMKEYDOWN WINELIB_NAME_AW(DTN_WMKEYDOWN) +#define DTN_FORMAT WINELIB_NAME_AW(DTN_FORMAT) +#define DTN_FORMATQUERY WINELIB_NAME_AW(DTN_FORMATQUERY) + +#define DTS_SHORTDATEFORMAT 0x0000 +#define DTS_UPDOWN 0x0001 +#define DTS_SHOWNONE 0x0002 +#define DTS_LONGDATEFORMAT 0x0004 +#define DTS_TIMEFORMAT 0x0009 +#define DTS_APPCANPARSE 0x0010 +#define DTS_RIGHTALIGN 0x0020 + +typedef struct tagNMDATETIMECHANGE +{ + NMHDR nmhdr; + DWORD dwFlags; + SYSTEMTIME st; +} NMDATETIMECHANGE, *LPNMDATETIMECHANGE; + +typedef struct tagNMDATETIMESTRINGA +{ + NMHDR nmhdr; + LPCSTR pszUserString; + SYSTEMTIME st; + DWORD dwFlags; +} NMDATETIMESTRINGA, *LPNMDATETIMESTRINGA; + +typedef struct tagNMDATETIMESTRINGW +{ + NMHDR nmhdr; + LPCWSTR pszUserString; + SYSTEMTIME st; + DWORD dwFlags; +} NMDATETIMESTRINGW, *LPNMDATETIMESTRINGW; + +DECL_WINELIB_TYPE_AW(NMDATETIMESTRING) +DECL_WINELIB_TYPE_AW(LPNMDATETIMESTRING) + +typedef struct tagNMDATETIMEWMKEYDOWNA +{ + NMHDR nmhdr; + int nVirtKey; + LPCSTR pszFormat; + SYSTEMTIME st; +} NMDATETIMEWMKEYDOWNA, *LPNMDATETIMEWMKEYDOWNA; + +typedef struct tagNMDATETIMEWMKEYDOWNW +{ + NMHDR nmhdr; + int nVirtKey; + LPCWSTR pszFormat; + SYSTEMTIME st; +} NMDATETIMEWMKEYDOWNW, *LPNMDATETIMEWMKEYDOWNW; + +DECL_WINELIB_TYPE_AW(NMDATETIMEWMKEYDOWN) +DECL_WINELIB_TYPE_AW(LPNMDATETIMEWMKEYDOWN) + +typedef struct tagNMDATETIMEFORMATA +{ + NMHDR nmhdr; + LPCSTR pszFormat; + SYSTEMTIME st; + LPCSTR pszDisplay; + CHAR szDisplay[64]; +} NMDATETIMEFORMATA, *LPNMDATETIMEFORMATA; + + +typedef struct tagNMDATETIMEFORMATW +{ + NMHDR nmhdr; + LPCWSTR pszFormat; + SYSTEMTIME st; + LPCWSTR pszDisplay; + WCHAR szDisplay[64]; +} NMDATETIMEFORMATW, *LPNMDATETIMEFORMATW; + +DECL_WINELIB_TYPE_AW(NMDATETIMEFORMAT) +DECL_WINELIB_TYPE_AW(LPNMDATETIMEFORMAT) + +typedef struct tagNMDATETIMEFORMATQUERYA +{ + NMHDR nmhdr; + LPCSTR pszFormat; + SIZE szMax; +} NMDATETIMEFORMATQUERYA, *LPNMDATETIMEFORMATQUERYA; + +typedef struct tagNMDATETIMEFORMATQUERYW +{ + NMHDR nmhdr; + LPCWSTR pszFormat; + SIZE szMax; +} NMDATETIMEFORMATQUERYW, *LPNMDATETIMEFORMATQUERYW; + +DECL_WINELIB_TYPE_AW(NMDATETIMEFORMATQUERY) +DECL_WINELIB_TYPE_AW(LPNMDATETIMEFORMATQUERY) + + + +#define GDT_ERROR -1 +#define GDT_VALID 0 +#define GDT_NONE 1 + +#define GDTR_MIN 0x0001 +#define GDTR_MAX 0x0002 + + +#define DateTime_GetSystemtime(hdp, pst) \ + (DWORD)SNDMSGA (hdp, DTM_GETSYSTEMTIME , 0, (LPARAM)(pst)) +#define DateTime_SetSystemtime(hdp, gd, pst) \ + (BOOL)SNDMSGA (hdp, DTM_SETSYSTEMTIME, (LPARAM)(gd), (LPARAM)(pst)) +#define DateTime_GetRange(hdp, rgst) \ + (DWORD)SNDMSGA (hdp, DTM_GETRANGE, 0, (LPARAM)(rgst)) +#define DateTime_SetRange(hdp, gd, rgst) \ + (BOOL)SNDMSGA (hdp, DTM_SETRANGE, (WPARAM)(gd), (LPARAM)(rgst)) +#define DateTime_SetFormat WINELIB_NAME_AW(DateTime_SetFormat) +#define DateTime_SetFormatA(hdp, sz) \ + (BOOL)SNDMSGA (hdp, DTM_SETFORMAT, 0, (LPARAM)(sz)) +#define DateTime_SetFormatW(hdp, sz) \ + (BOOL)SNDMSGW (hdp, DTM_SETFORMAT, 0, (LPARAM)(sz)) +#define DateTime_GetMonthCalColor(hdp, iColor) \ + SNDMSGA (hdp, DTM_GETMCCOLOR, iColor, 0) +#define DateTime_GetMonthCal(hdp) \ + (HWND) SNDMSGA (hdp, DTM_GETMONTHCAL, 0, 0) +#define DateTime_SetMonthCalFont(hdp, hfont, fRedraw) \ + SNDMSGA (hdp, DTM_SETMCFONT, (WPARAM)hfont, (LPARAM)fRedraw) +#define DateTime_GetMonthCalFont(hdp) \ + SNDMSGA (hdp, DTM_GETMCFONT, 0, 0) + + + + + + +/************************************************************************** + * UNDOCUMENTED functions + */ + +/* private heap memory functions */ + +LPVOID WINAPI COMCTL32_Alloc (DWORD); +LPVOID WINAPI COMCTL32_ReAlloc (LPVOID, DWORD); +BOOL WINAPI COMCTL32_Free (LPVOID); +DWORD WINAPI COMCTL32_GetSize (LPVOID); + +LPWSTR WINAPI COMCTL32_StrChrW (LPCWSTR, WORD); + + +INT WINAPI Str_GetPtrA (LPCSTR, LPSTR, INT); +BOOL WINAPI Str_SetPtrA (LPSTR *, LPCSTR); +INT WINAPI Str_GetPtrW (LPCWSTR, LPWSTR, INT); +BOOL WINAPI Str_SetPtrW (LPWSTR *, LPCWSTR); +#define Str_GetPtr WINELIB_NAME_AW(Str_GetPtr) +#define Str_SetPtr WINELIB_NAME_AW(Str_SetPtr) + + +/* Dynamic Storage Array */ + +typedef struct _DSA +{ + INT nItemCount; + LPVOID pData; + INT nMaxCount; + INT nItemSize; + INT nGrow; +} DSA, *HDSA; + +HDSA WINAPI DSA_Create (INT, INT); +BOOL WINAPI DSA_DeleteAllItems (const HDSA); +INT WINAPI DSA_DeleteItem (const HDSA, INT); +BOOL WINAPI DSA_Destroy (const HDSA); +BOOL WINAPI DSA_GetItem (const HDSA, INT, LPVOID); +LPVOID WINAPI DSA_GetItemPtr (const HDSA, INT); +INT WINAPI DSA_InsertItem (const HDSA, INT, LPVOID); +BOOL WINAPI DSA_SetItem (const HDSA, INT, LPVOID); + +typedef INT (CALLBACK *DSAENUMPROC)(LPVOID, DWORD); +VOID WINAPI DSA_EnumCallback (const HDSA, DSAENUMPROC, LPARAM); +BOOL WINAPI DSA_DestroyCallback (const HDSA, DSAENUMPROC, LPARAM); + + +/* Dynamic Pointer Array */ + +typedef struct _DPA +{ + INT nItemCount; + LPVOID *ptrs; + HANDLE hHeap; + INT nGrow; + INT nMaxCount; +} DPA, *HDPA; + +HDPA WINAPI DPA_Create (INT); +HDPA WINAPI DPA_CreateEx (INT, HANDLE); +BOOL WINAPI DPA_Destroy (const HDPA); +HDPA WINAPI DPA_Clone (const HDPA, const HDPA); +LPVOID WINAPI DPA_GetPtr (const HDPA, INT); +INT WINAPI DPA_GetPtrIndex (const HDPA, LPVOID); +BOOL WINAPI DPA_Grow (const HDPA, INT); +BOOL WINAPI DPA_SetPtr (const HDPA, INT, LPVOID); +INT WINAPI DPA_InsertPtr (const HDPA, INT, LPVOID); +LPVOID WINAPI DPA_DeletePtr (const HDPA, INT); +BOOL WINAPI DPA_DeleteAllPtrs (const HDPA); + +typedef INT (CALLBACK *PFNDPACOMPARE)(LPVOID, LPVOID, LPARAM); +BOOL WINAPI DPA_Sort (const HDPA, PFNDPACOMPARE, LPARAM); + +#define DPAS_SORTED 0x0001 +#define DPAS_INSERTBEFORE 0x0002 +#define DPAS_INSERTAFTER 0x0004 + +INT WINAPI DPA_Search (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT); + +#define DPAM_NOSORT 0x0001 +#define DPAM_INSERT 0x0004 +#define DPAM_DELETE 0x0008 + +typedef PVOID (CALLBACK *PFNDPAMERGE)(DWORD,PVOID,PVOID,LPARAM); +BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE, LPARAM); + +typedef INT (CALLBACK *DPAENUMPROC)(LPVOID, DWORD); +VOID WINAPI DPA_EnumCallback (const HDPA, DPAENUMPROC, LPARAM); +BOOL WINAPI DPA_DestroyCallback (const HDPA, DPAENUMPROC, LPARAM); + + +#define DPA_GetPtrCount(hdpa) (*(INT*)(hdpa)) +#define DPA_GetPtrPtr(hdpa) (*((LPVOID**)((BYTE*)(hdpa)+sizeof(INT)))) +#define DPA_FastGetPtr(hdpa,i) (DPA_GetPtrPtr(hdpa)[i]) + + +/* notification helper functions */ + +LRESULT WINAPI COMCTL32_SendNotify (HWND, HWND, UINT, LPNMHDR); + +/* type and functionality of last parameter is still unknown */ +LRESULT WINAPI COMCTL32_SendNotifyEx (HWND, HWND, UINT, LPNMHDR, DWORD); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_COMMCTRL_H */ diff --git a/install.bat b/install.bat index 0912556..55be918 100644 --- a/install.bat +++ b/install.bat @@ -5,18 +5,21 @@ goto Install :NoParameter set ROS_INSTALL=c:\reactos :Install -echo on echo Installing to %ROS_INSTALL% @echo off +set ROS_INSTALL_TESTS=%ROS_INSTALL%\test + md %ROS_INSTALL% md %ROS_INSTALL%\bin +md %ROS_INSTALL_TESTS% md %ROS_INSTALL%\symbols md %ROS_INSTALL%\system32 md %ROS_INSTALL%\system32\config md %ROS_INSTALL%\system32\drivers md %ROS_INSTALL%\media md %ROS_INSTALL%\media\fonts + copy boot.bat %ROS_INSTALL% copy bootc.lst %ROS_INSTALL% copy aboot.bat %ROS_INSTALL% @@ -35,8 +38,9 @@ copy drivers\fs\mup\mup.sys %ROS_INSTALL%\system32\drivers copy drivers\bus\acpi\acpi.sys %ROS_INSTALL%\system32\drivers copy drivers\bus\isapnp\isapnp.sys %ROS_INSTALL%\system32\drivers copy drivers\bus\pci\pci.sys %ROS_INSTALL%\system32\drivers -copy drivers\dd\ide\ide.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\floppy\floppy.sys %ROS_INSTALL%\system32\drivers +copy drivers\lib\bzip2\unbzip2.sys %ROS_INSTALL%\system32\drivers +copy drivers\lib\zlib\zlib.a %ROS_INSTALL%\system32 copy drivers\input\keyboard\keyboard.sys %ROS_INSTALL%\system32\drivers copy drivers\input\mouclass\mouclass.sys %ROS_INSTALL%\system32\drivers copy drivers\input\psaux\psaux.sys %ROS_INSTALL%\system32\drivers @@ -53,6 +57,7 @@ copy drivers\net\dd\ne2000\ne2000.sys %ROS_INSTALL%\system32\drivers copy drivers\net\dd\miniport\nscirda\nscirda.sys %ROS_INSTALL%\system32\drivers copy drivers\net\ndis\ndis.sys %ROS_INSTALL%\system32\drivers copy drivers\net\packet\packet.sys %ROS_INSTALL%\system32\drivers +copy drivers\net\tdi\tdi.sys %ROS_INSTALL%\system32\drivers copy drivers\net\tcpip\tcpip.sys %ROS_INSTALL%\system32\drivers copy drivers\net\wshtcpip\wshtcpip.dll %ROS_INSTALL%\system32 copy drivers\storage\atapi\atapi.sys %ROS_INSTALL%\system32\drivers @@ -82,6 +87,8 @@ copy lib\secur32\secur32.dll %ROS_INSTALL%\system32 copy lib\shell32\roshel32.dll %ROS_INSTALL%\system32 copy lib\snmpapi\snmpapi.dll %ROS_INSTALL%\system32 copy lib\user32\user32.dll %ROS_INSTALL%\system32 +copy lib\version\version.dll %ROS_INSTALL%\system32 +copy lib\winedbgc\winedbgc.dll %ROS_INSTALL%\system32 copy lib\winmm\winmm.dll %ROS_INSTALL%\system32 copy lib\ws2_32\ws2_32.dll %ROS_INSTALL%\system32 copy lib\ws2help\ws2help.dll %ROS_INSTALL%\system32 @@ -89,13 +96,16 @@ copy lib\wshirda\wshirda.dll %ROS_INSTALL%\system32 copy lib\wsock32\wsock32.dll %ROS_INSTALL%\system32 copy subsys\smss\smss.exe %ROS_INSTALL%\system32 copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32 +copy subsys\ntvdm\ntvdm.exe %ROS_INSTALL%\system32 copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32\drivers +copy subsys\system\usetup\usetup.exe %ROS_INSTALL%\system32 copy apps\utils\cat\cat.exe %ROS_INSTALL%\bin copy apps\utils\partinfo\partinfo.exe %ROS_INSTALL%\bin copy apps\utils\objdir\objdir.exe %ROS_INSTALL%\bin copy apps\utils\pice\module\pice.sys %ROS_INSTALL%\system32\drivers copy apps\utils\pice\module\pice.sym %ROS_INSTALL%\symbols copy apps\utils\pice\pice.cfg %ROS_INSTALL%\symbols +copy apps\utils\sc\sc.exe %ROS_INSTALL%\bin copy apps\tests\hello\hello.exe %ROS_INSTALL%\bin copy apps\tests\args\args.exe %ROS_INSTALL%\bin copy apps\tests\apc\apc.exe %ROS_INSTALL%\bin @@ -108,22 +118,45 @@ copy apps\tests\event\event.exe %ROS_INSTALL%\bin copy apps\tests\file\file.exe %ROS_INSTALL%\bin copy apps\tests\pteb\pteb.exe %ROS_INSTALL%\bin copy apps\tests\consume\consume.exe %ROS_INSTALL%\bin -copy apps\tests\vmtest\vmtest.exe %ROS_INSTALL%\bin -copy apps\tests\gditest\gditest.exe %ROS_INSTALL%\bin -copy apps\tests\dibtest\dibtest.exe %ROS_INSTALL%\bin -copy apps\tests\mstest\msserver.exe %ROS_INSTALL%\bin -copy apps\tests\mstest\msclient.exe %ROS_INSTALL%\bin -copy apps\tests\nptest\npserver.exe %ROS_INSTALL%\bin -copy apps\tests\nptest\npclient.exe %ROS_INSTALL%\bin -copy apps\tests\atomtest\atomtest.exe %ROS_INSTALL%\bin +copy apps\tests\vmtest\vmtest.exe %ROS_INSTALL_TESTS% +copy apps\tests\gditest\gditest.exe %ROS_INSTALL_TESTS% +copy apps\tests\dibtest\dibtest.exe %ROS_INSTALL_TESTS% +copy apps\tests\mstest\msserver.exe %ROS_INSTALL_TESTS% +copy apps\tests\mstest\msclient.exe %ROS_INSTALL_TESTS% +copy apps\tests\nptest\npserver.exe %ROS_INSTALL_TESTS% +copy apps\tests\nptest\npclient.exe %ROS_INSTALL_TESTS% +copy apps\tests\atomtest\atomtest.exe %ROS_INSTALL_TESTS% copy apps\tests\mutex\mutex.exe %ROS_INSTALL%\bin copy apps\tests\winhello\winhello.exe %ROS_INSTALL%\bin -copy apps\tests\sectest\sectest.exe %ROS_INSTALL%\bin -copy apps\tests\isotest\isotest.exe %ROS_INSTALL%\bin -copy apps\tests\regtest\regtest.exe %ROS_INSTALL%\bin -copy apps\tests\restest\restest.exe %ROS_INSTALL%\bin -copy apps\tests\tokentest\tokentest.exe %ROS_INSTALL%\bin +copy apps\tests\sectest\sectest.exe %ROS_INSTALL_TESTS% +copy apps\tests\isotest\isotest.exe %ROS_INSTALL_TESTS% +copy apps\tests\regtest\regtest.exe %ROS_INSTALL_TESTS% +copy apps\tests\hivetest\hivetest.exe %ROS_INSTALL_TESTS% +copy apps\tests\restest\restest.exe %ROS_INSTALL_TESTS% +copy apps\tests\tokentest\tokentest.exe %ROS_INSTALL_TESTS% +copy apps\testsets\msvcrt\fileio\fileio.exe %ROS_INSTALL_TESTS% +copy apps\testsets\msvcrt\mbtowc\mbtowc.exe %ROS_INSTALL_TESTS% +copy apps\testsets\test\test.exe %ROS_INSTALL_TESTS% +copy apps\testsets\testperl\testperl.exe %ROS_INSTALL_TESTS% copy media\fonts\helb____.ttf %ROS_INSTALL%\media\fonts copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts -copy media\nls\*.nls %ROS_INSTALL%\system32 +rem copy media\nls\*.nls %ROS_INSTALL%\system32 copy ntoskrnl\ntoskrnl.map %ROS_INSTALL%\symbols + +if "%ROS_BUILD_EXT%" == "" goto Finish + +echo Installing extra programs from rosapps directory... +call ..\rosapps\install.bat %1 + +echo Installing targets modules ported from WINE... +call ..\wine\install.bat %1 + +echo Installing targets for POSIX+ support... +call ..\posix\install.bat %1 + +echo Installing targets for OS/2 support... +call ..\os2\install.bat %1 + +echo Done. + +:Finish diff --git a/installwine.bat b/installwine.bat index ea48521..adebd5b 100644 --- a/installwine.bat +++ b/installwine.bat @@ -6,9 +6,19 @@ if "%1" == "" goto NoParameter set WINE_INSTALL=%1 goto Install :NoParameter -set WINE_INSTALL=c:\reactos\system32 + set ROS_INSTALL=c:\reactos +set WINE_INSTALL=%ROS_INSTALL%\system32 +set WINE_APP_INSTALL=%ROS_INSTALL%\bin +set WINE_TESTS_INSTALL=%ROS_INSTALL%\tests + + :Install +echo Installing libwine and wine_unicode to %WINE_INSTALL% +copy ..\wine\library\libwine.dll %WINE_INSTALL% +copy ..\wine\unicode\wine_unicode.dll %WINE_INSTALL% + + echo Installing dlls to %WINE_INSTALL% @echo off copy ..\wine\dlls\comctl32\comctl32.dll %WINE_INSTALL% @@ -18,6 +28,9 @@ copy ..\wine\dlls\dinput\dinput.dll %WINE_INSTALL% copy ..\wine\dlls\dplay\dplay.dll %WINE_INSTALL% copy ..\wine\dlls\dplayx\dplayx.dll %WINE_INSTALL% copy ..\wine\dlls\mapi32\mapi32.dll %WINE_INSTALL% +copy ..\wine\dlls\mpr\mpr.dll %WINE_INSTALL% +copy ..\wine\dlls\netapi32\netapi32.dll %WINE_INSTALL% +copy ..\wine\dlls\odbc32\odbc32.dll %WINE_INSTALL% copy ..\wine\dlls\ole32\ole32.dll %WINE_INSTALL% copy ..\wine\dlls\oleaut32\oleaut32.dll %WINE_INSTALL% copy ..\wine\dlls\olecli\olecli32.dll %WINE_INSTALL% @@ -34,28 +47,34 @@ copy ..\wine\dlls\shfolder\shfolder.dll %WINE_INSTALL% copy ..\wine\dlls\shlwapi\shlwapi.dll %WINE_INSTALL% copy ..\wine\dlls\tapi32\tapi32.dll %WINE_INSTALL% copy ..\wine\dlls\urlmon\urlmon.dll %WINE_INSTALL% +REM copy ..\wine\dlls\version\version.dll %WINE_INSTALL% copy ..\wine\dlls\wintrust\wintrust.dll %WINE_INSTALL% +copy ..\wine\dlls\winspool\winspool.drv %WINE_INSTALL% REM -echo Installing winelib programs to %ROS_INSTALL%\bin -REM -copy ..\wine\programs\clock\winclock.exe %ROS_INSTALL%\bin -copy ..\wine\programs\cmdlgtst\cmdlgtst.exe %ROS_INSTALL%\bin -copy ..\wine\programs\control\control.exe %ROS_INSTALL%\bin -copy ..\wine\programs\notepad\notepad.exe %ROS_INSTALL%\bin -copy ..\wine\programs\progman\progman.exe %ROS_INSTALL%\bin -copy ..\wine\programs\uninstaller\uninstaller.exe %ROS_INSTALL%\bin -copy ..\wine\programs\view\view.exe %ROS_INSTALL%\bin -copy ..\wine\programs\wcmd\wcmd.exe %ROS_INSTALL%\bin -copy ..\wine\programs\winefile\winefile.exe %ROS_INSTALL%\bin -copy ..\wine\programs\winemine\winmine.exe %ROS_INSTALL%\bin -copy ..\wine\programs\winver\winver.exe %ROS_INSTALL%\bin -REM -echo Installing Regression tests to %ROS_INSTALL%\bin -copy ..\wine\dlls\advapi32\tests\advapi32_test.exe %WINE_INSTALL% -copy ..\wine\dlls\kernel\tests\kernel32_test.exe %WINE_INSTALL% -copy ..\wine\dlls\ntdll\tests\ntdll_test.exe %WINE_INSTALL% -copy ..\wine\dlls\user32\tests\user32_test.exe %WINE_INSTALL% +echo Installing winelib programs to %WINE_APP_INSTALL% REM +copy ..\wine\programs\clock\winclock.exe %WINE_APP_INSTALL% +copy ..\wine\programs\cmdlgtst\cmdlgtst.exe %WINE_APP_INSTALL% +copy ..\wine\programs\control\control.exe %WINE_APP_INSTALL% +copy ..\wine\programs\notepad\notepad.exe %WINE_APP_INSTALL% +copy ..\wine\programs\progman\progman.exe %WINE_APP_INSTALL% +copy ..\wine\programs\uninstaller\uninstaller.exe %WINE_APP_INSTALL% +copy ..\wine\programs\view\view.exe %WINE_APP_INSTALL% +copy ..\wine\programs\wcmd\wcmd.exe %WINE_APP_INSTALL% +copy ..\wine\programs\winefile\winefile.exe %WINE_APP_INSTALL% +copy ..\wine\programs\winemine\winmine.exe %WINE_APP_INSTALL% +copy ..\wine\programs\winver\winver.exe %WINE_APP_INSTALL% +REM +echo Installing wine tools to %WINE_APP_INSTALL% +REM +copy ..\wine\tools\winedump\winedump.exe %WINE_APP_INSTALL% - - +REM +echo Installing Regression tests to %WINE_TESTS_INSTALL% +REM +copy ..\wine\dlls\advapi32\tests\advapi32_test.exe %WINE_TESTS_INSTALL% +copy ..\wine\dlls\kernel\tests\kernel32_test.exe %WINE_TESTS_INSTALL% +copy ..\wine\dlls\ntdll\tests\ntdll_test.exe %WINE_TESTS_INSTALL% +copy ..\wine\dlls\user32\tests\user32_test.exe %WINE_TESTS_INSTALL% +REM +pause diff --git a/lib/advapi32/.cvsignore b/lib/advapi32/.cvsignore index 5550cf6..7089dde 100644 --- a/lib/advapi32/.cvsignore +++ b/lib/advapi32/.cvsignore @@ -2,8 +2,9 @@ advapi32.a advapi32.dll advapi32.nostrip.dll advapi32.lib +advapi32.sym advapi32.coff base.tmp junk.tmp temp.exp - +*.o diff --git a/lib/advapi32/advapi32.def b/lib/advapi32/advapi32.def index da13cbc..30127ce 100644 --- a/lib/advapi32/advapi32.def +++ b/lib/advapi32/advapi32.def @@ -1,11 +1,11 @@ -; $Id$ -; -; advapi32.def -; -; ReactOS Operating System -; -; Some stack sizes are taken from Ander Norlander's .DEFs. -; + $Id$ + + advapi32.def + + ReactOS Operating System + + Some stack sizes are taken from Ander Norlander's .DEFs. + LIBRARY advapi32.dll EXPORTS AbortSystemShutdownA@4 @@ -223,8 +223,8 @@ LsaFreeMemory@4 LsaGetQuotasForAccount@8 LsaGetSystemAccessAccount@8 LsaGetUserName@8 -LsaICLookupNames@28 -LsaICLookupSids@28 +LsaICLookupNames@32 +LsaICLookupSids@32 LsaLookupNames@20 LsaLookupPrivilegeDisplayName@16 LsaLookupPrivilegeName@12 @@ -235,11 +235,11 @@ LsaOpenAccount@16 LsaOpenPolicy@16 LsaOpenSecret@16 LsaOpenTrustedDomain@16 -LsaQueryInfoTrustedDomain@12 LsaQueryInformationPolicy@12 +LsaQueryInfoTrustedDomain@12 LsaQuerySecret@20 LsaQuerySecurityObject@12 -LsaQueryTrustedDomainInfo@16 +LsaQueryTrustedDomainInfo@20 LsaRemoveAccountRights@20 LsaRemovePrivilegesFromAccount@12 LsaRetrievePrivateData@12 diff --git a/lib/advapi32/advapi32.edf b/lib/advapi32/advapi32.edf index 8893940..de3e4ee 100644 --- a/lib/advapi32/advapi32.edf +++ b/lib/advapi32/advapi32.edf @@ -174,7 +174,7 @@ GetUserNameW=GetUserNameW@8 ;I_ScGetCurrentGroupStateW=I_ScGetCurrentGroupStateW@12 ;I_ScSetServiceBitsA=I_ScSetServiceBitsA@20 ;I_ScSetServiceBitsW=I_ScSetServiceBitsW@20 -;ImpersonateLoggedOnUser=ImpersonateLoggedOnUser@4 +ImpersonateLoggedOnUser=ImpersonateLoggedOnUser@4 ;ImpersonateNamedPipeClient=ImpersonateNamedPipeClient@4 ImpersonateSelf=ImpersonateSelf@4 InitializeAcl=InitializeAcl@12 @@ -203,53 +203,67 @@ LookupPrivilegeValueA=LookupPrivilegeValueA@12 LookupPrivilegeValueW=LookupPrivilegeValueW@12 ;LookupSecurityDescriptorPartsA=LookupSecurityDescriptorPartsA@28 ;LookupSecurityDescriptorPartsW=LookupSecurityDescriptorPartsW@28 -;LsaAddAccountRights=LsaAddAccountRights@16 -;LsaAddPrivilegesToAccount=LsaAddPrivilegesToAccount@8 -;LsaClearAuditLog=LsaClearAuditLog@4 -;LsaClose=LsaClose@4 -;LsaCreateAccount=LsaCreateAccount@16 -;LsaCreateSecret=LsaCreateSecret@16 -;LsaCreateTrustedDomain=LsaCreateTrustedDomain@16 -;LsaDelete=LsaDelete@4 -;LsaDeleteTrustedDomain=LsaDeleteTrustedDomain@8 -;LsaEnumerateAccountRights=LsaEnumerateAccountRights@16 -;LsaEnumerateAccounts=LsaEnumerateAccounts@20 -;LsaEnumerateAccountsWithUserRight=LsaEnumerateAccountsWithUserRight@16 -;LsaEnumeratePrivileges=LsaEnumeratePrivileges@20 -;LsaEnumeratePrivilegesOfAccount=LsaEnumeratePrivilegesOfAccount@8 -;LsaEnumerateTrustedDomains=LsaEnumerateTrustedDomains@20 -;LsaFreeMemory=LsaFreeMemory@4 -;LsaGetQuotasForAccount=LsaGetQuotasForAccount@8 -;LsaGetSystemAccessAccount=LsaGetSystemAccessAccount@8 -;LsaGetUserName=LsaGetUserName@8 -;LsaICLookupNames=LsaICLookupNames@28 -;LsaICLookupSids=LsaICLookupSids@28 -;LsaLookupNames=LsaLookupNames@20 -;LsaLookupPrivilegeDisplayName=LsaLookupPrivilegeDisplayName@16 -;LsaLookupPrivilegeName=LsaLookupPrivilegeName@12 -;LsaLookupPrivilegeValue=LsaLookupPrivilegeValue@12 -;LsaLookupSids=LsaLookupSids@20 -;LsaNtStatusToWinError=LsaNtStatusToWinError@4 -;LsaOpenAccount=LsaOpenAccount@16 -;LsaOpenPolicy=LsaOpenPolicy@16 -;LsaOpenSecret=LsaOpenSecret@16 -;LsaOpenTrustedDomain=LsaOpenTrustedDomain@16 -;LsaQueryInfoTrustedDomain=LsaQueryInfoTrustedDomain@12 -;LsaQueryInformationPolicy=LsaQueryInformationPolicy@12 -;LsaQuerySecret=LsaQuerySecret@20 -;LsaQuerySecurityObject=LsaQuerySecurityObject@12 -;LsaQueryTrustedDomainInfo=LsaQueryTrustedDomainInfo@16 -;LsaRemoveAccountRights=LsaRemoveAccountRights@20 -;LsaRemovePrivilegesFromAccount=LsaRemovePrivilegesFromAccount@12 -;LsaRetrievePrivateData=LsaRetrievePrivateData@12 -;LsaSetInformationPolicy=LsaSetInformationPolicy@12 -;LsaSetInformationTrustedDomain=LsaSetInformationTrustedDomain@12 -;LsaSetQuotasForAccount=LsaSetQuotasForAccount@8 -;LsaSetSecret=LsaSetSecret@12 -;LsaSetSecurityObject=LsaSetSecurityObject@12 -;LsaSetSystemAccessAccount=LsaSetSystemAccessAccount@8 -;LsaSetTrustedDomainInformation=LsaSetTrustedDomainInformation@16 -;LsaStorePrivateData=LsaStorePrivateData@12 + +; 1 parameter stubs +LsaClearAuditLog=_LsaStub1@4 +LsaClose=_LsaStub1@4 +LsaDelete=_LsaStub1@4 +LsaFreeMemory=_LsaStub1@4 + +; 2 parameters stubs +LsaAddPrivilegesToAccount=_LsaStub2@8 +LsaDeleteTrustedDomain=_LsaStub2@8 +LsaEnumeratePrivilegesOfAccount=_LsaStub2@8 +LsaGetQuotasForAccount=_LsaStub2@8 +LsaGetSystemAccessAccount=_LsaStub2@8 +LsaGetUserName=_LsaStub2@8 +LsaSetQuotasForAccount=_LsaStub2@8 +LsaSetSystemAccessAccount=_LsaStub2@8 + +; 3 parameters stubs +LsaLookupPrivilegeName=_LsaStub3@12 +LsaLookupPrivilegeValue=_LsaStub3@12 +LsaQueryInfoTrustedDomain=_LsaStub3@12 +LsaQueryInformationPolicy=_LsaStub3@12 +LsaQuerySecurityObject=_LsaStub3@12 +LsaRemovePrivilegesFromAccount=_LsaStub3@12 +LsaRetrievePrivateData=_LsaStub3@12 +LsaSetInformationPolicy=_LsaStub3@12 +LsaSetInformationTrustedDomain=_LsaStub3@12 +LsaSetSecret=_LsaStub3@12 +LsaSetSecurityObject=_LsaStub3@12 +LsaStorePrivateData=_LsaStub3@12 + +; 4 parameters stubs +LsaAddAccountRights=_LsaStub4@16 +LsaCreateAccount=_LsaStub4@16 +LsaCreateSecret=_LsaStub4@16 +LsaCreateTrustedDomain=_LsaStub4@16 +LsaEnumerateAccountRights=_LsaStub4@16 +LsaEnumerateAccountsWithUserRight=_LsaStub4@16 +LsaLookupPrivilegeDisplayName=_LsaStub4@16 +LsaOpenAccount=_LsaStub4@16 +LsaOpenPolicy=_LsaStub4@16 +LsaOpenSecret=_LsaStub4@16 +LsaOpenTrustedDomain=_LsaStub4@16 +LsaSetTrustedDomainInformation=_LsaStub4@16 + +; 5 parameters stubs +LsaEnumerateAccounts=_LsaStub5@20 +LsaEnumeratePrivileges=_LsaStub5@20 +LsaEnumerateTrustedDomains=_LsaStub5@20 +LsaLookupNames=_LsaStub5@20 +LsaLookupSids=_LsaStub5@20 +LsaQuerySecret=_LsaStub5@20 +LsaQueryTrustedDomainInfo=_LsaStub5@20 +LsaRemoveAccountRights=_LsaStub5@20 + +; 8 parameters stubs +LsaICLookupNames=_LsaStub8@32 +LsaICLookupSids=_LsaStub8@32 + +LsaNtStatusToWinError=NTDLL.RtlNtStatusToDosError + MakeAbsoluteSD=MakeAbsoluteSD@44 MakeSelfRelativeSD=MakeSelfRelativeSD@12 MapGenericMask=MapGenericMask@8 diff --git a/lib/advapi32/makefile b/lib/advapi32/makefile index abe49da..dd3d4d1 100644 --- a/lib/advapi32/makefile +++ b/lib/advapi32/makefile @@ -6,11 +6,18 @@ TARGET_TYPE = dynlink TARGET_NAME = advapi32 +TARGET_CFLAGS = \ + -Wall \ + -Werror \ + -fno-builtin + +TARGET_LFLAGS = -nostartfiles -nostdlib + TARGET_SDKLIBS = ntdll.a kernel32.a # TARGET_CFLAGS = -DUNICODE -TARGET_BASE = 0x77dc0000 +TARGET_BASE = 0x77DB0000 MISC_OBJECTS=\ misc/dllmain.o \ diff --git a/lib/advapi32/misc/.cvsignore b/lib/advapi32/misc/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/advapi32/misc/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/advapi32/misc/dllmain.c b/lib/advapi32/misc/dllmain.c index c20c5e7..d42e99c 100644 --- a/lib/advapi32/misc/dllmain.c +++ b/lib/advapi32/misc/dllmain.c @@ -15,6 +15,8 @@ #define NDEBUG #include +extern BOOL RegInitialize(VOID); +extern BOOL RegCleanup(VOID); INT STDCALL DllMain(PVOID hinstDll, diff --git a/lib/advapi32/misc/shutdown.c b/lib/advapi32/misc/shutdown.c index 0c2a4b2..53f28fa 100644 --- a/lib/advapi32/misc/shutdown.c +++ b/lib/advapi32/misc/shutdown.c @@ -1,193 +1,147 @@ /* $Id$ * * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/advapi32/misc/shutdown.c - * PURPOSE: System shutdown functions + * PROJECT: ReactOS system libraries + * FILE: lib/advapi32/misc/shutdown.c + * PURPOSE: System shutdown functions * PROGRAMMER: Emanuele Aliberti * UPDATE HISTORY: - * 19990413 EA created - * 19990515 EA + * 19990413 EA created + * 19990515 EA */ #include -#include + +#define NTOS_MODE_USER +#include #define USZ {0,0,0} /********************************************************************** - * AbortSystemShutdownW + * AbortSystemShutdownW */ -BOOL +WINBOOL STDCALL -AbortSystemShutdownW( - LPWSTR lpMachineName - ) +AbortSystemShutdownW(LPCWSTR lpMachineName) { - NTSTATUS Status; - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * AbortSystemShutdownA + * AbortSystemShutdownA */ BOOL STDCALL -AbortSystemShutdownA( - LPSTR lpMachineName - ) +AbortSystemShutdownA(LPCSTR lpMachineName) { - ANSI_STRING MachineNameA; - UNICODE_STRING MachineNameW; - NTSTATUS Status; - BOOL rv; + ANSI_STRING MachineNameA; + UNICODE_STRING MachineNameW; + NTSTATUS Status; + BOOL rv; - RtlInitAnsiString( - & MachineNameA, - lpMachineName - ); - Status = RtlAnsiStringToUnicodeString( - & MachineNameW, - & MachineNameA, - TRUE - ); - if (STATUS_SUCCESS != Status) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - rv = AbortSystemShutdownW( - MachineNameW.Buffer - ); - RtlFreeAnsiString( - & MachineNameA - ); - RtlFreeUnicodeString( - & MachineNameW - ); - SetLastError(ERROR_SUCCESS); - return rv; + RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName); + Status = RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE); + if (STATUS_SUCCESS != Status) { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + rv = AbortSystemShutdownW(MachineNameW.Buffer); + RtlFreeAnsiString(&MachineNameA); + RtlFreeUnicodeString(&MachineNameW); + SetLastError(ERROR_SUCCESS); + return rv; } /********************************************************************** - * InitiateSystemShutdownW + * InitiateSystemShutdownW */ BOOL STDCALL InitiateSystemShutdownW( - LPWSTR lpMachineName, - LPWSTR lpMessage, - DWORD dwTimeout, - BOOL bForceAppsClosed, - BOOL bRebootAfterShutdown - ) + LPWSTR lpMachineName, + LPWSTR lpMessage, + DWORD dwTimeout, + BOOL bForceAppsClosed, + BOOL bRebootAfterShutdown) { - SHUTDOWN_ACTION Action = ShutdownNoReboot; - NTSTATUS Status; + SHUTDOWN_ACTION Action = ShutdownNoReboot; + NTSTATUS Status; - if (lpMachineName) - { - /* FIXME: remote machine shutdown not supported yet */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; - } - if (dwTimeout) - { - } - Status = NtShutdownSystem(Action); - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; + if (lpMachineName) { + /* FIXME: remote machine shutdown not supported yet */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; + } + if (dwTimeout) { + } + Status = NtShutdownSystem(Action); + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; } /********************************************************************** - * InitiateSystemShutdownA - */ + * InitiateSystemShutdownA +*/ BOOL STDCALL InitiateSystemShutdownA( - LPSTR lpMachineName, - LPSTR lpMessage, - DWORD dwTimeout, - BOOL bForceAppsClosed, - BOOL bRebootAfterShutdown - ) + LPSTR lpMachineName, + LPSTR lpMessage, + DWORD dwTimeout, + BOOL bForceAppsClosed, + BOOL bRebootAfterShutdown) { - ANSI_STRING MachineNameA; - ANSI_STRING MessageA; - UNICODE_STRING MachineNameW; - UNICODE_STRING MessageW; - NTSTATUS Status; - INT LastError; - BOOL rv; + ANSI_STRING MachineNameA; + ANSI_STRING MessageA; + UNICODE_STRING MachineNameW; + UNICODE_STRING MessageW; + NTSTATUS Status; + INT LastError; + BOOL rv; - if (lpMachineName) - { - RtlInitAnsiString( - & MachineNameA, - lpMachineName - ); - Status = RtlAnsiStringToUnicodeString( - & MachineNameW, - & MachineNameA, - TRUE - ); - if (STATUS_SUCCESS != Status) - { - RtlFreeAnsiString(&MachineNameA); - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - } - if (lpMessage) - { - RtlInitAnsiString( - & MessageA, - lpMessage - ); - Status = RtlAnsiStringToUnicodeString( - & MessageW, - & MessageA, - TRUE - ); - if (STATUS_SUCCESS != Status) - { - if (MachineNameW.Length) - { - RtlFreeAnsiString(&MachineNameA); - RtlFreeUnicodeString(&MachineNameW); - } - RtlFreeAnsiString(&MessageA); - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - } - rv = InitiateSystemShutdownW( - MachineNameW.Buffer, - MessageW.Buffer, - dwTimeout, - bForceAppsClosed, - bRebootAfterShutdown - ); - LastError = GetLastError(); - if (lpMachineName) - { + if (lpMachineName) { + RtlInitAnsiString(&MachineNameA, lpMachineName); + Status = RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE); + if (STATUS_SUCCESS != Status) { + RtlFreeAnsiString(&MachineNameA); + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + } + if (lpMessage) { + RtlInitAnsiString(&MessageA, lpMessage); + Status = RtlAnsiStringToUnicodeString(&MessageW, &MessageA, TRUE); + if (STATUS_SUCCESS != Status) { + if (MachineNameW.Length) { RtlFreeAnsiString(&MachineNameA); RtlFreeUnicodeString(&MachineNameW); + } + RtlFreeAnsiString(&MessageA); + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; } - if (lpMessage) - { - RtlFreeAnsiString(&MessageA); - RtlFreeUnicodeString(&MessageW); - } - SetLastError(LastError); - return rv; + } + rv = InitiateSystemShutdownW( + MachineNameW.Buffer, + MessageW.Buffer, + dwTimeout, + bForceAppsClosed, + bRebootAfterShutdown); + LastError = GetLastError(); + if (lpMachineName) { + RtlFreeAnsiString(&MachineNameA); + RtlFreeUnicodeString(&MachineNameW); + } + if (lpMessage) { + RtlFreeAnsiString(&MessageA); + RtlFreeUnicodeString(&MessageW); + } + SetLastError(LastError); + return rv; } - /* EOF */ - diff --git a/lib/advapi32/reg/.cvsignore b/lib/advapi32/reg/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/advapi32/reg/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/advapi32/reg/reg.c b/lib/advapi32/reg/reg.c index 2010eec..2957c5e 100644 --- a/lib/advapi32/reg/reg.c +++ b/lib/advapi32/reg/reg.c @@ -9,6 +9,10 @@ * Created 01/11/98 * 19990309 EA Stubs */ +#ifndef WIN32_REGDBG + +#define NTOS_MODE_USER +#include #include #include #include @@ -17,14 +21,67 @@ #define NDEBUG #include +#else /*WIN32_REGDBG*/ +#include "cm_win32.h" +#ifdef __GNUC__ +#define WINAPI __stdcall +#define WINAPIV __cdecl +#define APIENTRY __stdcall +#define DECLSPEC_IMPORT __declspec(dllimport) +#define DECLSPEC_EXPORT __declspec(dllexport) +#define DECLARE_HANDLE(n) typedef HANDLE n +#define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004) +#define ERROR_SUCCESS 0L +#define ERROR_INVALID_HANDLE 6L +#define ERROR_OUTOFMEMORY 14L +#define ERROR_INVALID_PARAMETER 87L +#define ERROR_CALL_NOT_IMPLEMENTED 120L +#define ERROR_MORE_DATA 234L + +void WINAPI SetLastError(DWORD); +BOOLEAN STDCALL RtlDosPathNameToNtPathName_U(PWSTR dosname, PUNICODE_STRING ntname, PWSTR* shortname, PCURDIR nah); +NTSTATUS STDCALL RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs); +NTSTATUS STDCALL RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs); +NTSTATUS STDCALL RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs); +NTSTATUS STDCALL RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs); + +DECLARE_HANDLE(HKEY); +typedef HKEY *PHKEY; +typedef ACCESS_MASK REGSAM; + +typedef struct value_entA { + LPSTR ve_valuename; + DWORD ve_valuelen; + DWORD ve_valueptr; + DWORD ve_type; +} VALENTA,*PVALENTA; +typedef struct value_entW { + LPWSTR ve_valuename; + DWORD ve_valuelen; + DWORD ve_valueptr; + DWORD ve_type; +} VALENTW,*PVALENTW; +#endif +#undef STDCALL +#define STDCALL _stdcall +#undef RegSetValueEx +#undef RegCreateKeyEx +#undef RegQueryInfoKey +#undef RegDeleteKey +#undef RegOpenKey +#undef RegOpenKeyEx +#undef RegEnumKeyEx +#undef RegEnumValue +#endif /*WIN32_REGDBG*/ + #define CHECK_STATUS \ { \ - if (!NT_SUCCESS(Status)) \ - { \ - LONG _ErrorCode = RtlNtStatusToDosError(Status); \ - SetLastError(_ErrorCode); \ - return _ErrorCode; \ - } \ + if (!NT_SUCCESS(Status)) \ + { \ + LONG _ErrorCode = RtlNtStatusToDosError(Status); \ + SetLastError(_ErrorCode); \ + return _ErrorCode; \ + } \ } /* GLOBALS *******************************************************************/ @@ -48,31 +105,30 @@ static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle); /* FUNCTIONS *****************************************************************/ -inline RegiTerminateWideString(LPWSTR String, DWORD Length) +inline void RegiTerminateWideString(LPWSTR String, DWORD Length) { LPWSTR AfterString = String + Length; *AfterString = 0; } /************************************************************************ - * RegInitDefaultHandles + * RegInitDefaultHandles */ BOOL -RegInitialize (VOID) +RegInitialize(VOID) { DPRINT("RegInitialize()\n"); RtlZeroMemory (DefaultHandleTable, - MAX_DEFAULT_HANDLES * sizeof(HANDLE)); - + MAX_DEFAULT_HANDLES * sizeof(HANDLE)); RtlInitializeCriticalSection(&HandleTableCS); return TRUE; } /************************************************************************ - * RegInit + * RegInit */ BOOL RegCleanup(VOID) @@ -87,7 +143,7 @@ RegCleanup(VOID) static NTSTATUS MapDefaultKey(PHKEY RealKey, - HKEY Key) + HKEY Key) { PHANDLE Handle; ULONG Index; @@ -95,39 +151,28 @@ MapDefaultKey(PHKEY RealKey, DPRINT("MapDefaultKey (Key %x)\n", Key); - if (((ULONG)Key & 0xF0000000) != 0x80000000) - { + if (((ULONG)Key & 0xF0000000) != 0x80000000) { *RealKey = Key; return STATUS_SUCCESS; - } - + } /* Handle special cases here */ Index = (ULONG)Key & 0x0FFFFFFF; - if (Index >= MAX_DEFAULT_HANDLES) return STATUS_INVALID_PARAMETER; - RtlEnterCriticalSection(&HandleTableCS); - Handle = &DefaultHandleTable[Index]; - if (*Handle == NULL) - { + if (*Handle == NULL) { /* create/open the default handle */ - switch (Index) - { + switch (Index) { case 0: /* HKEY_CLASSES_ROOT */ Status = OpenClassesRootKey(Handle); break; - case 1: /* HKEY_CURRENT_USER */ - Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, - Handle); + Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle); break; - case 2: /* HKEY_LOCAL_MACHINE */ Status = OpenLocalMachineKey(Handle); break; - case 3: /* HKEY_USERS */ Status = OpenUsersKey(Handle); break; @@ -139,20 +184,15 @@ MapDefaultKey(PHKEY RealKey, case 5: /* HKEY_CURRENT_CONFIG */ Status = OpenCurrentConfigKey(Handle); break; - default: DPRINT("MapDefaultHandle() no handle creator\n"); Status = STATUS_INVALID_PARAMETER; } - } - + } RtlLeaveCriticalSection(&HandleTableCS); - - if (NT_SUCCESS(Status)) - { + if (NT_SUCCESS(Status)) { *RealKey = (HKEY)*Handle; - } - + } return Status; } @@ -163,16 +203,12 @@ CloseDefaultKeys(VOID) ULONG i; RtlEnterCriticalSection(&HandleTableCS); - - for (i = 0; i < MAX_DEFAULT_HANDLES; i++) - { - if (DefaultHandleTable[i] != NULL) - { + for (i = 0; i < MAX_DEFAULT_HANDLES; i++) { + if (DefaultHandleTable[i] != NULL) { NtClose (DefaultHandleTable[i]); DefaultHandleTable[i] = NULL; - } - } - + } + } RtlLeaveCriticalSection(&HandleTableCS); } @@ -186,14 +222,13 @@ OpenClassesRootKey(PHANDLE KeyHandle) DPRINT("OpenClassesRootKey()\n"); InitializeObjectAttributes(&Attributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); return(NtOpenKey(KeyHandle, - KEY_ALL_ACCESS, - &Attributes)); + KEY_ALL_ACCESS, + &Attributes)); } @@ -206,14 +241,13 @@ OpenLocalMachineKey(PHANDLE KeyHandle) DPRINT("OpenLocalMachineKey()\n"); InitializeObjectAttributes(&Attributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); return(NtOpenKey(KeyHandle, - KEY_ALL_ACCESS, - &Attributes)); + KEY_ALL_ACCESS, + &Attributes)); } @@ -226,14 +260,13 @@ OpenUsersKey(PHANDLE KeyHandle) DPRINT("OpenUsersKey()\n"); InitializeObjectAttributes(&Attributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); return(NtOpenKey(KeyHandle, - KEY_ALL_ACCESS, - &Attributes)); + KEY_ALL_ACCESS, + &Attributes)); } @@ -242,23 +275,22 @@ OpenCurrentConfigKey(PHANDLE KeyHandle) { OBJECT_ATTRIBUTES Attributes; UNICODE_STRING KeyName = - UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current"); + UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current"); DPRINT("OpenCurrentConfigKey()\n"); InitializeObjectAttributes(&Attributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); return(NtOpenKey(KeyHandle, - KEY_ALL_ACCESS, - &Attributes)); + KEY_ALL_ACCESS, + &Attributes)); } /************************************************************************ - * RegCloseKey + * RegCloseKey */ LONG STDCALL RegCloseKey(HKEY hKey) @@ -268,27 +300,23 @@ RegCloseKey(HKEY hKey) /* don't close null handle or a pseudo handle */ if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000)) return ERROR_INVALID_HANDLE; - Status = NtClose (hKey); - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { LONG ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); return ErrorCode; - } - + } return ERROR_SUCCESS; } /************************************************************************ - * RegConnectRegistryA + * RegConnectRegistryA */ LONG STDCALL RegConnectRegistryA(LPCSTR lpMachineName, - HKEY hKey, - PHKEY phkResult) + HKEY hKey, + PHKEY phkResult) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return ERROR_CALL_NOT_IMPLEMENTED; @@ -296,12 +324,12 @@ RegConnectRegistryA(LPCSTR lpMachineName, /************************************************************************ - * RegConnectRegistryW + * RegConnectRegistryW */ LONG STDCALL RegConnectRegistryW(LPCWSTR lpMachineName, - HKEY hKey, - PHKEY phkResult) + HKEY hKey, + PHKEY phkResult) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return ERROR_CALL_NOT_IMPLEMENTED; @@ -309,58 +337,18 @@ RegConnectRegistryW(LPCWSTR lpMachineName, /************************************************************************ - * RegCreateKeyA - */ -LONG STDCALL -RegCreateKeyA(HKEY hKey, - LPCSTR lpSubKey, - PHKEY phkResult) -{ - return(RegCreateKeyExA(hKey, - lpSubKey, - 0, - NULL, - 0, - KEY_ALL_ACCESS, - NULL, - phkResult, - NULL)); -} - - -/************************************************************************ - * RegCreateKeyW - */ -LONG STDCALL -RegCreateKeyW(HKEY hKey, - LPCWSTR lpSubKey, - PHKEY phkResult) -{ - return(RegCreateKeyExW(hKey, - lpSubKey, - 0, - NULL, - 0, - KEY_ALL_ACCESS, - NULL, - phkResult, - NULL)); -} - - -/************************************************************************ - * RegCreateKeyExA + * RegCreateKeyExA */ LONG STDCALL RegCreateKeyExA(HKEY hKey, - LPCSTR lpSubKey, - DWORD Reserved, - LPSTR lpClass, - DWORD dwOptions, - REGSAM samDesired, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - PHKEY phkResult, - LPDWORD lpdwDisposition) + LPCSTR lpSubKey, + DWORD Reserved, + LPSTR lpClass, + DWORD dwOptions, + REGSAM samDesired, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + PHKEY phkResult, + LPDWORD lpdwDisposition) { UNICODE_STRING SubKeyString; UNICODE_STRING ClassString; @@ -371,380 +359,429 @@ RegCreateKeyExA(HKEY hKey, DPRINT("RegCreateKeyExW() called\n"); /* get the real parent key */ - Status = MapDefaultKey(&ParentKey, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&ParentKey, hKey); + if (!NT_SUCCESS(Status)) { LONG ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - + } DPRINT("ParentKey %x\n", (ULONG)ParentKey); if (lpClass != NULL) - RtlCreateUnicodeStringFromAsciiz(&ClassString, - lpClass); - RtlCreateUnicodeStringFromAsciiz(&SubKeyString, - (LPSTR)lpSubKey); - + RtlCreateUnicodeStringFromAsciiz(&ClassString, lpClass); + RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey); InitializeObjectAttributes(&Attributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - (HANDLE)ParentKey, - (PSECURITY_DESCRIPTOR)lpSecurityAttributes); - + &SubKeyString, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + (PSECURITY_DESCRIPTOR)lpSecurityAttributes); Status = NtCreateKey(phkResult, - samDesired, - &Attributes, - 0, - (lpClass == NULL)? NULL : &ClassString, - dwOptions, - (PULONG)lpdwDisposition); - + samDesired, + &Attributes, + 0, + (lpClass == NULL)? NULL : &ClassString, + dwOptions, + (PULONG)lpdwDisposition); RtlFreeUnicodeString(&SubKeyString); if (lpClass != NULL) RtlFreeUnicodeString(&ClassString); - DPRINT("Status %x\n", Status); - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { LONG ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); return ErrorCode; - } - + } return(ERROR_SUCCESS); } /************************************************************************ - * RegCreateKeyExW + * RegCreateKeyExW + */ +LONG STDCALL +RegCreateKeyExW(HKEY hKey, + LPCWSTR lpSubKey, + DWORD Reserved, + LPWSTR lpClass, + DWORD dwOptions, + REGSAM samDesired, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + PHKEY phkResult, + LPDWORD lpdwDisposition) +{ + UNICODE_STRING SubKeyString; + UNICODE_STRING ClassString; + OBJECT_ATTRIBUTES Attributes; + NTSTATUS Status; + HKEY ParentKey; + + DPRINT("RegCreateKeyExW() called\n"); + + /* get the real parent key */ + Status = MapDefaultKey (&ParentKey, hKey); + if (!NT_SUCCESS(Status)) { + LONG ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + DPRINT("ParentKey %x\n", (ULONG)ParentKey); + RtlInitUnicodeString (&ClassString, lpClass); + RtlInitUnicodeString (&SubKeyString, lpSubKey); + InitializeObjectAttributes (&Attributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + (PSECURITY_DESCRIPTOR)lpSecurityAttributes); + Status = NtCreateKey (phkResult, + samDesired, + &Attributes, + 0, + (lpClass == NULL)? NULL : &ClassString, + dwOptions, + (PULONG)lpdwDisposition); + DPRINT("Status %x\n", Status); + if (!NT_SUCCESS(Status)) { + LONG ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; +} + + +/************************************************************************ + * RegCreateKeyA + */ +LONG STDCALL +RegCreateKeyA(HKEY hKey, + LPCSTR lpSubKey, + PHKEY phkResult) +{ + return(RegCreateKeyExA(hKey, + lpSubKey, + 0, + NULL, + 0, + KEY_ALL_ACCESS, + NULL, + phkResult, + NULL)); +} + + +/************************************************************************ + * RegCreateKeyW */ LONG STDCALL -RegCreateKeyExW(HKEY hKey, - LPCWSTR lpSubKey, - DWORD Reserved, - LPWSTR lpClass, - DWORD dwOptions, - REGSAM samDesired, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - PHKEY phkResult, - LPDWORD lpdwDisposition) +RegCreateKeyW(HKEY hKey, + LPCWSTR lpSubKey, + PHKEY phkResult) { - UNICODE_STRING SubKeyString; - UNICODE_STRING ClassString; - OBJECT_ATTRIBUTES Attributes; - NTSTATUS Status; - HKEY ParentKey; - - DPRINT("RegCreateKeyExW() called\n"); - - /* get the real parent key */ - Status = MapDefaultKey (&ParentKey, hKey); - if (!NT_SUCCESS(Status)) - { - LONG ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - DPRINT("ParentKey %x\n", (ULONG)ParentKey); - RtlInitUnicodeString (&ClassString, lpClass); - RtlInitUnicodeString (&SubKeyString, lpSubKey); - - InitializeObjectAttributes (&Attributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - (HANDLE)ParentKey, - (PSECURITY_DESCRIPTOR)lpSecurityAttributes); - - Status = NtCreateKey (phkResult, - samDesired, - &Attributes, - 0, - (lpClass == NULL)? NULL : &ClassString, - dwOptions, - (PULONG)lpdwDisposition); - DPRINT("Status %x\n", Status); - if (!NT_SUCCESS(Status)) - { - LONG ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + return(RegCreateKeyExW(hKey, + lpSubKey, + 0, + NULL, + 0, + KEY_ALL_ACCESS, + NULL, + phkResult, + NULL)); } /************************************************************************ - * RegDeleteKeyA + * RegDeleteKeyA */ LONG STDCALL RegDeleteKeyA( - HKEY hKey, - LPCSTR lpSubKey - ) + HKEY hKey, + LPCSTR lpSubKey) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyStringW; - ANSI_STRING SubKeyStringA; -// HANDLE ParentKey; - HKEY ParentKey; - HANDLE TargetKey; - NTSTATUS Status; - LONG ErrorCode; - - Status = MapDefaultKey(&ParentKey, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - RtlInitAnsiString(&SubKeyStringA, - (LPSTR)lpSubKey); - RtlAnsiStringToUnicodeString(&SubKeyStringW, - &SubKeyStringA, - TRUE); - - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyStringW, - OBJ_CASE_INSENSITIVE, - (HANDLE)ParentKey, - NULL); - - Status = NtOpenKey (&TargetKey, - DELETE, - &ObjectAttributes); - - RtlFreeUnicodeString (&SubKeyStringW); - - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - Status = NtDeleteKey(TargetKey); - - NtClose(TargetKey); - - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - return ERROR_SUCCESS; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING SubKeyStringW; + ANSI_STRING SubKeyStringA; +// HANDLE ParentKey; + HKEY ParentKey; + HANDLE TargetKey; + NTSTATUS Status; + LONG ErrorCode; + + Status = MapDefaultKey(&ParentKey, hKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + RtlInitAnsiString(&SubKeyStringA, (LPSTR)lpSubKey); + RtlAnsiStringToUnicodeString(&SubKeyStringW, &SubKeyStringA, TRUE); + InitializeObjectAttributes (&ObjectAttributes, + &SubKeyStringW, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + NULL); + Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes); + RtlFreeUnicodeString(&SubKeyStringW); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; + } + Status = NtDeleteKey(TargetKey); + NtClose(TargetKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegDeleteKeyW + * RegDeleteKeyW */ LONG STDCALL RegDeleteKeyW( - HKEY hKey, - LPCWSTR lpSubKey - ) + HKEY hKey, + LPCWSTR lpSubKey) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HKEY ParentKey; - HANDLE TargetKey; - NTSTATUS Status; - LONG ErrorCode; - - Status = MapDefaultKey(&ParentKey, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - (HANDLE)ParentKey, - NULL); - - Status = NtOpenKey (&TargetKey, - DELETE, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - Status = NtDeleteKey(TargetKey); - - NtClose(TargetKey); - - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - return ERROR_SUCCESS; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING SubKeyString; + HKEY ParentKey; + HANDLE TargetKey; + NTSTATUS Status; + LONG ErrorCode; + + Status = MapDefaultKey(&ParentKey, hKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey); + + InitializeObjectAttributes (&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + NULL); + Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + Status = NtDeleteKey(TargetKey); + NtClose(TargetKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegDeleteValueA + * RegDeleteValueA */ LONG STDCALL RegDeleteValueA( - HKEY hKey, - LPCSTR lpValueName - ) + HKEY hKey, + LPCSTR lpValueName) { - UNICODE_STRING ValueNameW; - ANSI_STRING ValueNameA; - NTSTATUS Status; - LONG ErrorCode; - HKEY KeyHandle; - - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - RtlInitAnsiString(&ValueNameA, - (LPSTR)lpValueName); - RtlAnsiStringToUnicodeString(&ValueNameW, - &ValueNameA, - TRUE); - - Status = NtDeleteValueKey(KeyHandle, - &ValueNameW); - - RtlFreeUnicodeString (&ValueNameW); - - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + UNICODE_STRING ValueNameW; + ANSI_STRING ValueNameA; + NTSTATUS Status; + LONG ErrorCode; + HKEY KeyHandle; + + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + RtlInitAnsiString(&ValueNameA, (LPSTR)lpValueName); + RtlAnsiStringToUnicodeString(&ValueNameW, &ValueNameA, TRUE); + Status = NtDeleteValueKey(KeyHandle, &ValueNameW); + RtlFreeUnicodeString (&ValueNameW); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegDeleteValueW + * RegDeleteValueW */ LONG STDCALL RegDeleteValueW( - HKEY hKey, - LPCWSTR lpValueName - ) + HKEY hKey, + LPCWSTR lpValueName) { - UNICODE_STRING ValueName; - NTSTATUS Status; - LONG ErrorCode; - HKEY KeyHandle; - - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - RtlInitUnicodeString(&ValueName, - (LPWSTR)lpValueName); - - Status = NtDeleteValueKey(KeyHandle, - &ValueName); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - - SetLastError (ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + UNICODE_STRING ValueName; + NTSTATUS Status; + LONG ErrorCode; + HKEY KeyHandle; + + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + RtlInitUnicodeString(&ValueName, (LPWSTR)lpValueName); + Status = NtDeleteValueKey(KeyHandle, &ValueName); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegEnumKeyA + * RegEnumKeyExW */ LONG STDCALL -RegEnumKeyA( - HKEY hKey, - DWORD dwIndex, - LPSTR lpName, - DWORD cbName - ) +RegEnumKeyExW( + HKEY hKey, + DWORD dwIndex, + LPWSTR lpName, + LPDWORD lpcbName, + LPDWORD lpReserved, + LPWSTR lpClass, + LPDWORD lpcbClass, + PFILETIME lpftLastWriteTime) +{ + PKEY_NODE_INFORMATION KeyInfo; + NTSTATUS Status; + DWORD dwError = ERROR_SUCCESS; + ULONG BufferSize; + ULONG ResultSize; + HKEY KeyHandle; + + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError (dwError); + return dwError; + } + + BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR); + if (lpClass) + BufferSize += *lpcbClass; + + // + // I think this is a memory leak, always allocated again below ??? + // + // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); + // + + /* We don't know the exact size of the data returned, so call + NtEnumerateKey() with a buffer size determined from parameters + to this function. If that call fails with a status code of + STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */ + while (TRUE) { + KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); + if (KeyInfo == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; + } + Status = NtEnumerateKey( + KeyHandle, + (ULONG)dwIndex, + KeyNodeInformation, + KeyInfo, + BufferSize, + &ResultSize); + + DPRINT("NtEnumerateKey() returned status 0x%X\n", Status); + + if (Status == STATUS_BUFFER_OVERFLOW) { + RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo); + BufferSize = ResultSize; + continue; + } + if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError(dwError); + break; + } else { + if ((lpClass) && (*lpcbClass != 0) && (KeyInfo->ClassLength > *lpcbClass)) { + dwError = ERROR_MORE_DATA; + SetLastError(dwError); + break; + } + RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength); + *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR)); + RegiTerminateWideString(lpName, *lpcbName); + if (lpClass) { + RtlMoveMemory(lpClass, + (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset), + KeyInfo->ClassLength); + *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR)); + } + if (lpftLastWriteTime) { + /* FIXME: Fill lpftLastWriteTime */ + } + break; + } + } + RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo); + return dwError; +} + + +/************************************************************************ + * RegEnumKeyW + */ +LONG +STDCALL +RegEnumKeyW( + HKEY hKey, + DWORD dwIndex, + LPWSTR lpName, + DWORD cbName) { - DWORD dwLength = cbName; - - return RegEnumKeyExA(hKey, - dwIndex, - lpName, - &dwLength, - NULL, - NULL, - NULL, - NULL); + DWORD dwLength = cbName; + + return RegEnumKeyExW(hKey, + dwIndex, + lpName, + &dwLength, + NULL, + NULL, + NULL, + NULL); } /************************************************************************ - * RegEnumKeyExA + * RegEnumKeyExA */ LONG STDCALL RegEnumKeyExA( - HKEY hKey, - DWORD dwIndex, - LPSTR lpName, - LPDWORD lpcbName, - LPDWORD lpReserved, - LPSTR lpClass, - LPDWORD lpcbClass, - PFILETIME lpftLastWriteTime - ) + HKEY hKey, + DWORD dwIndex, + LPSTR lpName, + LPDWORD lpcbName, + LPDWORD lpReserved, + LPSTR lpClass, + LPDWORD lpcbClass, + PFILETIME lpftLastWriteTime) { WCHAR Name[MAX_PATH+1]; UNICODE_STRING UnicodeStringName; @@ -758,47 +795,37 @@ RegEnumKeyExA( DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n", hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass); - if ((lpClass) && (!lpcbClass)) - { + if ((lpClass) && (!lpcbClass)) { SetLastError(ERROR_INVALID_PARAMETER); return ERROR_INVALID_PARAMETER; } - RtlInitUnicodeString(&UnicodeStringName, NULL); UnicodeStringName.Buffer = &Name[0]; UnicodeStringName.MaximumLength = sizeof(Name); - RtlInitUnicodeString(&UnicodeStringClass, NULL); - - if (lpClass) - { + if (lpClass) { UnicodeStringClass.Buffer = &Class[0]; UnicodeStringClass.MaximumLength = sizeof(Class); ClassLength = *lpcbClass; - } - else - { + } else { ClassLength = 0; } - NameLength = *lpcbName; - ErrorCode = RegEnumKeyExW( - hKey, - dwIndex, - UnicodeStringName.Buffer, - &NameLength, + hKey, + dwIndex, + UnicodeStringName.Buffer, + &NameLength, lpReserved, - UnicodeStringClass.Buffer, - &ClassLength, - lpftLastWriteTime); + UnicodeStringClass.Buffer, + &ClassLength, + lpftLastWriteTime); if (ErrorCode != ERROR_SUCCESS) return ErrorCode; UnicodeStringName.Length = NameLength * sizeof(WCHAR); UnicodeStringClass.Length = ClassLength * sizeof(WCHAR); - RtlInitAnsiString(&AnsiString, NULL); AnsiString.Buffer = lpName; AnsiString.MaximumLength = *lpcbName; @@ -810,322 +837,216 @@ RegEnumKeyExA( DPRINT("Key Namea Length %d\n", *lpcbName); DPRINT("Key Namea %s\n", lpName); - if (lpClass) - { + if (lpClass) { RtlInitAnsiString(&AnsiString, NULL); AnsiString.Buffer = lpClass; AnsiString.MaximumLength = *lpcbClass; RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE); *lpcbClass = AnsiString.Length; } - return ERROR_SUCCESS; } /************************************************************************ - * RegEnumKeyExW + * RegEnumKeyA */ LONG STDCALL -RegEnumKeyExW( - HKEY hKey, - DWORD dwIndex, - LPWSTR lpName, - LPDWORD lpcbName, - LPDWORD lpReserved, - LPWSTR lpClass, - LPDWORD lpcbClass, - PFILETIME lpftLastWriteTime - ) +RegEnumKeyA( + HKEY hKey, + DWORD dwIndex, + LPSTR lpName, + DWORD cbName) { - PKEY_NODE_INFORMATION KeyInfo; - NTSTATUS Status; - DWORD dwError = ERROR_SUCCESS; - ULONG BufferSize; - ULONG ResultSize; - HKEY KeyHandle; + DWORD dwLength = cbName; + + return RegEnumKeyExA(hKey, + dwIndex, + lpName, + &dwLength, + NULL, + NULL, + NULL, + NULL); +} - Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError (dwError); - return dwError; - } - BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR); - if (lpClass) - BufferSize += *lpcbClass; +/************************************************************************ + * RegEnumValueW + */ +LONG +STDCALL +RegEnumValueW( + HKEY hKey, + DWORD dwIndex, + LPWSTR lpValueName, + LPDWORD lpcbValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData) +{ + PKEY_VALUE_FULL_INFORMATION ValueInfo; + NTSTATUS Status; + DWORD dwError = ERROR_SUCCESS; + ULONG BufferSize; + ULONG ResultSize; + HKEY KeyHandle; - // - // I think this is a memory leak, always allocated again below ??? - // - // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); - // + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError(dwError); + return(dwError); + } + BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) + *lpcbValueName * sizeof(WCHAR); + if (lpcbData) + BufferSize += *lpcbData; /* We don't know the exact size of the data returned, so call - NtEnumerateKey() with a buffer size determined from parameters + NtEnumerateValueKey() with a buffer size determined from parameters to this function. If that call fails with a status code of STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */ while (TRUE) { - KeyInfo = RtlAllocateHeap( - RtlGetProcessHeap(), - 0, - BufferSize); - if (KeyInfo == NULL) - { + ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); + if (ValueInfo == NULL) { SetLastError(ERROR_OUTOFMEMORY); return ERROR_OUTOFMEMORY; } + Status = NtEnumerateValueKey( + KeyHandle, + (ULONG)dwIndex, + KeyValueFullInformation, + ValueInfo, + BufferSize, + &ResultSize); - Status = NtEnumerateKey( - KeyHandle, - (ULONG)dwIndex, - KeyNodeInformation, - KeyInfo, - BufferSize, - &ResultSize); - - DPRINT("NtEnumerateKey() returned status 0x%X\n", Status); + DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); - if (Status == STATUS_BUFFER_OVERFLOW) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo); + if (Status == STATUS_BUFFER_OVERFLOW) { + RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); BufferSize = ResultSize; continue; } - - if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError(dwError); + if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError(dwError); break; - } - else - { - if ((lpClass) && (*lpcbClass != 0) && (KeyInfo->ClassLength > *lpcbClass)) - { - dwError = ERROR_MORE_DATA; - SetLastError(dwError); + } else { + if ((lpData) && (*lpcbData != 0) && (ValueInfo->DataLength > *lpcbData)) { + dwError = ERROR_MORE_DATA; + SetLastError(dwError); break; } - - RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength); - *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR)); - RegiTerminateWideString(lpName, *lpcbName); - - if (lpClass) - { - RtlMoveMemory(lpClass, - (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset), - KeyInfo->ClassLength); - *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR)); - } - - if (lpftLastWriteTime) - { - /* FIXME: Fill lpftLastWriteTime */ - } - + memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength); + *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR)); + RegiTerminateWideString(lpValueName, *lpcbValueName); + if (lpType) + *lpType = ValueInfo->Type; + if (lpData) { + memcpy(lpData, + //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset), + (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), + ValueInfo->DataLength); + *lpcbData = (DWORD)ValueInfo->DataLength; +/* + RtlCopyMemory((PCHAR) ValueFullInformation + ValueFullInformation->DataOffset, + DataCell->Data, + ValueCell->DataSize & LONG_MAX); + */ + } break; - } + } } - - RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo); - - return dwError; -} - - -/************************************************************************ - * RegEnumKeyW - */ -LONG -STDCALL -RegEnumKeyW( - HKEY hKey, - DWORD dwIndex, - LPWSTR lpName, - DWORD cbName - ) -{ - DWORD dwLength = cbName; - - return RegEnumKeyExW(hKey, - dwIndex, - lpName, - &dwLength, - NULL, - NULL, - NULL, - NULL); + RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo); + return dwError; } /************************************************************************ - * RegEnumValueA + * RegEnumValueA */ LONG STDCALL RegEnumValueA( - HKEY hKey, - DWORD dwIndex, - LPSTR lpValueName, - LPDWORD lpcbValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) + HKEY hKey, + DWORD dwIndex, + LPSTR lpValueName, + LPDWORD lpcbValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData) { WCHAR ValueName[MAX_PATH+1]; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; LONG ErrorCode; DWORD ValueNameLength; - + BYTE* lpDataBuffer = NULL; + DWORD cbData = 0; + DWORD Type; + ANSI_STRING AnsiDataString; + UNICODE_STRING UnicodeDataString; + + if (lpData != NULL /*&& lpcbData != NULL*/) { + cbData = *lpcbData; // this should always be valid if lpData is valid + lpDataBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, (*lpcbData) * sizeof(WCHAR)); + if (lpDataBuffer == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; + } + } RtlInitUnicodeString(&UnicodeString, NULL); UnicodeString.Buffer = &ValueName[0]; UnicodeString.MaximumLength = sizeof(ValueName); - ValueNameLength = *lpcbValueName; - ErrorCode = RegEnumValueW( - hKey, - dwIndex, - UnicodeString.Buffer, - &ValueNameLength, - lpReserved, - lpType, - lpData, - lpcbData); - + hKey, + dwIndex, + UnicodeString.Buffer, + &ValueNameLength, + lpReserved, + &Type, + lpDataBuffer, + &cbData); if (ErrorCode != ERROR_SUCCESS) return ErrorCode; - UnicodeString.Length = ValueNameLength * sizeof(WCHAR); - RtlInitAnsiString(&AnsiString, NULL); AnsiString.Buffer = lpValueName; AnsiString.MaximumLength = *lpcbValueName; RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); *lpcbValueName = AnsiString.Length; - - return ERROR_SUCCESS; -} - - -/************************************************************************ - * RegEnumValueW - */ -LONG -STDCALL -RegEnumValueW( - HKEY hKey, - DWORD dwIndex, - LPWSTR lpValueName, - LPDWORD lpcbValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) -{ - PKEY_VALUE_FULL_INFORMATION ValueInfo; - NTSTATUS Status; - DWORD dwError = ERROR_SUCCESS; - ULONG BufferSize; - ULONG ResultSize; - HKEY KeyHandle; - - Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError(dwError); - return(dwError); - } - - BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) + - *lpcbValueName * sizeof(WCHAR); - if (lpcbData) - BufferSize += *lpcbData; - - /* We don't know the exact size of the data returned, so call - NtEnumerateValueKey() with a buffer size determined from parameters - to this function. If that call fails with a status code of - STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */ - while (TRUE) { - ValueInfo = RtlAllocateHeap( - RtlGetProcessHeap(), - 0, - BufferSize); - if (ValueInfo == NULL) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } - - Status = NtEnumerateValueKey( - KeyHandle, - (ULONG)dwIndex, - KeyValueFullInformation, - ValueInfo, - BufferSize, - &ResultSize); - - DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); - - if (Status == STATUS_BUFFER_OVERFLOW) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); - BufferSize = ResultSize; - continue; - } - - if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError(dwError); - break; - } - else - { - if ((lpData) && (*lpcbData != 0) && (ValueInfo->DataLength > *lpcbData)) - { - dwError = ERROR_MORE_DATA; - SetLastError(dwError); - break; +// if (lpData != lpDataBuffer) { // did we use a temp buffer + if (lpDataBuffer) { // did we use a temp buffer + if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) { + RtlInitUnicodeString(&UnicodeDataString, NULL); + UnicodeDataString.Buffer = (WCHAR*)lpDataBuffer; + UnicodeDataString.MaximumLength = (*lpcbData) * sizeof(WCHAR); + UnicodeDataString.Length = cbData /* * sizeof(WCHAR)*/; + RtlInitAnsiString(&AnsiDataString, NULL); + AnsiDataString.Buffer = lpData; + AnsiDataString.MaximumLength = *lpcbData; + RtlUnicodeStringToAnsiString(&AnsiDataString, &UnicodeDataString, FALSE); + *lpcbData = AnsiDataString.Length; +// else if (Type == REG_EXPAND_SZ) { + } else { + memcpy(lpData, lpDataBuffer, min(*lpcbData, cbData)); + *lpcbData = cbData; } - - memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength); - *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR)); - RegiTerminateWideString(lpValueName, *lpcbValueName); - - if (lpType) - *lpType = ValueInfo->Type; - - if (lpData) - { - memcpy(lpData, - (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), - ValueInfo->DataLength); - *lpcbData = (DWORD)ValueInfo->DataLength; - } - - break; - } + RtlFreeHeap(RtlGetProcessHeap(), 0, lpDataBuffer); } - - RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo); - - return dwError; + if (lpType != NULL) { + *lpType = Type; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegFlushKey + * RegFlushKey */ LONG STDCALL RegFlushKey(HKEY hKey) @@ -1136,108 +1057,96 @@ RegFlushKey(HKEY hKey) if (hKey == HKEY_PERFORMANCE_DATA) return(ERROR_SUCCESS); - - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - + } Status = NtFlushKey(KeyHandle); - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - + } return(ERROR_SUCCESS); } /************************************************************************ - * RegGetKeySecurity + * RegGetKeySecurity */ LONG STDCALL -RegGetKeySecurity ( - HKEY hKey, - SECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR pSecurityDescriptor, - LPDWORD lpcbSecurityDescriptor - ) +RegGetKeySecurity( + HKEY hKey, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, + LPDWORD lpcbSecurityDescriptor) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegLoadKeyA + * RegLoadKeyA */ LONG STDCALL -RegLoadKey( - HKEY hKey, - LPCSTR lpSubKey, - LPCSTR lpFile - ) +RegLoadKeyA( + HKEY hKey, + LPCSTR lpSubKey, + LPCSTR lpFile) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegLoadKeyW + * RegLoadKeyW */ LONG STDCALL RegLoadKeyW( - HKEY hKey, - LPCWSTR lpSubKey, - LPCWSTR lpFile - ) + HKEY hKey, + LPCWSTR lpSubKey, + LPCWSTR lpFile) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegNotifyChangeKeyValue + * RegNotifyChangeKeyValue */ LONG STDCALL RegNotifyChangeKeyValue( - HKEY hKey, - BOOL bWatchSubtree, - DWORD dwNotifyFilter, - HANDLE hEvent, - BOOL fAsynchronous - ) + HKEY hKey, + BOOL bWatchSubtree, + DWORD dwNotifyFilter, + HANDLE hEvent, + BOOL fAsynchronous) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegOpenKeyA + * RegOpenKeyA */ LONG STDCALL RegOpenKeyA(HKEY hKey, - LPCSTR lpSubKey, - PHKEY phkResult) + LPCSTR lpSubKey, + PHKEY phkResult) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SubKeyString; @@ -1245,106 +1154,79 @@ RegOpenKeyA(HKEY hKey, LONG ErrorCode; NTSTATUS Status; - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - - RtlCreateUnicodeStringFromAsciiz(&SubKeyString, - (LPSTR)lpSubKey); - + } + RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey); InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - Status = NtOpenKey(phkResult, - KEY_ALL_ACCESS, - &ObjectAttributes); - + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + Status = NtOpenKey(phkResult, KEY_ALL_ACCESS, &ObjectAttributes); RtlFreeUnicodeString(&SubKeyString); - - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } + } return(ERROR_SUCCESS); } /************************************************************************ - * RegOpenKeyW + * RegOpenKeyW * - * 19981101 Ariadne - * 19990525 EA + * 19981101 Ariadne + * 19990525 EA */ LONG STDCALL -RegOpenKeyW ( - HKEY hKey, - LPCWSTR lpSubKey, - PHKEY phkResult - ) +RegOpenKeyW( + HKEY hKey, + LPCWSTR lpSubKey, + PHKEY phkResult) { - NTSTATUS errCode; - UNICODE_STRING SubKeyString; - OBJECT_ATTRIBUTES ObjectAttributes; - HKEY KeyHandle; - LONG ErrorCode; - - errCode = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(errCode)) - { - ErrorCode = RtlNtStatusToDosError(errCode); - - SetLastError (ErrorCode); - return ErrorCode; - } - - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - errCode = NtOpenKey( - phkResult, - KEY_ALL_ACCESS, - & ObjectAttributes - ); - if ( !NT_SUCCESS(errCode) ) - { - ErrorCode = RtlNtStatusToDosError(errCode); - - SetLastError(ErrorCode); - return ErrorCode; - } - return ERROR_SUCCESS; + NTSTATUS errCode; + UNICODE_STRING SubKeyString; + OBJECT_ATTRIBUTES ObjectAttributes; + HKEY KeyHandle; + LONG ErrorCode; + + errCode = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError (ErrorCode); + return ErrorCode; + } + RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey); + InitializeObjectAttributes(&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + errCode = NtOpenKey(phkResult, KEY_ALL_ACCESS, &ObjectAttributes); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError(ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } /************************************************************************ - * RegOpenKeyExA + * RegOpenKeyExA */ LONG STDCALL RegOpenKeyExA(HKEY hKey, - LPCSTR lpSubKey, - DWORD ulOptions, - REGSAM samDesired, - PHKEY phkResult) + LPCSTR lpSubKey, + DWORD ulOptions, + REGSAM samDesired, + PHKEY phkResult) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SubKeyString; @@ -1352,52 +1234,38 @@ RegOpenKeyExA(HKEY hKey, LONG ErrorCode; NTSTATUS Status; - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - - RtlCreateUnicodeStringFromAsciiz(&SubKeyString, - (LPSTR)lpSubKey); - + } + RtlCreateUnicodeStringFromAsciiz(&SubKeyString, (LPSTR)lpSubKey); InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - Status = NtOpenKey(phkResult, - samDesired, - &ObjectAttributes); - + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + Status = NtOpenKey(phkResult, samDesired, &ObjectAttributes); RtlFreeUnicodeString(&SubKeyString); - - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - + } return(ERROR_SUCCESS); } /************************************************************************ - * RegOpenKeyExW + * RegOpenKeyExW */ LONG STDCALL RegOpenKeyExW(HKEY hKey, - LPCWSTR lpSubKey, - DWORD ulOptions, - REGSAM samDesired, - PHKEY phkResult) + LPCWSTR lpSubKey, + DWORD ulOptions, + REGSAM samDesired, + PHKEY phkResult) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SubKeyString; @@ -1405,118 +1273,50 @@ RegOpenKeyExW(HKEY hKey, LONG ErrorCode; NTSTATUS Status; - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); return(ErrorCode); - } - - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - + } + if (lpSubKey != NULL) { + RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey); + } else { + RtlInitUnicodeString(&SubKeyString, (LPWSTR)L""); + } InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - Status = NtOpenKey(phkResult, - samDesired, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + Status = NtOpenKey(phkResult, samDesired, &ObjectAttributes); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); return(ErrorCode); - } - return(ERROR_SUCCESS); -} - - -/************************************************************************ - * RegQueryInfoKeyA - */ -LONG -STDCALL -RegQueryInfoKeyA( - HKEY hKey, - LPSTR lpClass, - LPDWORD lpcbClass, - LPDWORD lpReserved, - LPDWORD lpcSubKeys, - LPDWORD lpcbMaxSubKeyLen, - LPDWORD lpcbMaxClassLen, - LPDWORD lpcValues, - LPDWORD lpcbMaxValueNameLen, - LPDWORD lpcbMaxValueLen, - LPDWORD lpcbSecurityDescriptor, - PFILETIME lpftLastWriteTime - ) -{ - WCHAR ClassName[MAX_PATH]; - UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - LONG ErrorCode; - - RtlInitUnicodeString(&UnicodeString, NULL); - - if (lpClass) - { - UnicodeString.Buffer = &ClassName[0]; - UnicodeString.MaximumLength = sizeof(ClassName); - } - - ErrorCode = RegQueryInfoKeyW( - hKey, - UnicodeString.Buffer, - lpcbClass, - lpReserved, - lpcSubKeys, - lpcbMaxSubKeyLen, - lpcbMaxClassLen, - lpcValues, - lpcbMaxValueNameLen, - lpcbMaxValueLen, - lpcbSecurityDescriptor, - lpftLastWriteTime); - - if ((ErrorCode == ERROR_SUCCESS) && (lpClass)) - { - RtlInitAnsiString(&AnsiString, NULL); - AnsiString.Buffer = lpClass; - AnsiString.MaximumLength = *lpcbClass; - RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); - *lpcbClass = AnsiString.Length; } - - return ErrorCode; + return(ERROR_SUCCESS); } /************************************************************************ - * RegQueryInfoKeyW + * RegQueryInfoKeyW */ LONG STDCALL RegQueryInfoKeyW( - HKEY hKey, - LPWSTR lpClass, - LPDWORD lpcbClass, - LPDWORD lpReserved, - LPDWORD lpcSubKeys, - LPDWORD lpcbMaxSubKeyLen, - LPDWORD lpcbMaxClassLen, - LPDWORD lpcValues, - LPDWORD lpcbMaxValueNameLen, - LPDWORD lpcbMaxValueLen, - LPDWORD lpcbSecurityDescriptor, - PFILETIME lpftLastWriteTime - ) + HKEY hKey, + LPWSTR lpClass, + LPDWORD lpcbClass, + LPDWORD lpReserved, + LPDWORD lpcSubKeys, + LPDWORD lpcbMaxSubKeyLen, + LPDWORD lpcbMaxClassLen, + LPDWORD lpcValues, + LPDWORD lpcbMaxValueNameLen, + LPDWORD lpcbMaxValueLen, + LPDWORD lpcbSecurityDescriptor, + PFILETIME lpftLastWriteTime) { KEY_FULL_INFORMATION FullInfoBuffer; PKEY_FULL_INFORMATION FullInfo; @@ -1526,237 +1326,256 @@ RegQueryInfoKeyW( LONG ErrorCode; ULONG Length; - if ((lpClass) && (!lpcbClass)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + if ((lpClass) && (!lpcbClass)) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } Status = MapDefaultKey(&KeyHandle, hKey); CHECK_STATUS; - if (lpClass) - { + if (lpClass) { FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass; FullInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize); - if (!FullInfo) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } - + if (!FullInfo) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; + } FullInfo->ClassLength = *lpcbClass; - } - else - { + } else { FullInfoSize = sizeof(KEY_FULL_INFORMATION); FullInfo = &FullInfoBuffer; FullInfo->ClassLength = 1; } - FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); - Status = NtQueryKey( KeyHandle, KeyFullInformation, FullInfo, FullInfoSize, &Length); - - if (!NT_SUCCESS(Status)) - { - if (lpClass) - { + if (!NT_SUCCESS(Status)) { + if (lpClass) { RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo); } - - ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); - return ErrorCode; - } - - if (lpcSubKeys) - { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; + } + if (lpcSubKeys) { *lpcSubKeys = FullInfo->SubKeys; } - - if (lpcbMaxSubKeyLen) - { + if (lpcbMaxSubKeyLen) { *lpcbMaxSubKeyLen = FullInfo->MaxNameLen; } - - if (lpcbMaxClassLen) - { + if (lpcbMaxClassLen) { *lpcbMaxClassLen = FullInfo->MaxClassLen; } - - if (lpcValues) - { + if (lpcValues) { *lpcValues = FullInfo->Values; } - - if (lpcbMaxValueNameLen) - { + if (lpcbMaxValueNameLen) { *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen; } - - if (lpcbMaxValueLen) - { + if (lpcbMaxValueLen) { *lpcbMaxValueLen = FullInfo->MaxValueDataLen; } - - if (lpcbSecurityDescriptor) - { + if (lpcbSecurityDescriptor) { *lpcbSecurityDescriptor = 0; /* FIXME */ } - - if (lpftLastWriteTime != NULL) - { + if (lpftLastWriteTime != NULL) { lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart; lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart; } - - if (lpClass) - { + if (lpClass) { wcsncpy(lpClass, FullInfo->Class, *lpcbClass); RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo); } - SetLastError(ERROR_SUCCESS); - return ERROR_SUCCESS; + return ERROR_SUCCESS; +} + + +/************************************************************************ + * RegQueryInfoKeyA + */ +LONG +STDCALL +RegQueryInfoKeyA( + HKEY hKey, + LPSTR lpClass, + LPDWORD lpcbClass, + LPDWORD lpReserved, + LPDWORD lpcSubKeys, + LPDWORD lpcbMaxSubKeyLen, + LPDWORD lpcbMaxClassLen, + LPDWORD lpcValues, + LPDWORD lpcbMaxValueNameLen, + LPDWORD lpcbMaxValueLen, + LPDWORD lpcbSecurityDescriptor, + PFILETIME lpftLastWriteTime) +{ + WCHAR ClassName[MAX_PATH]; + UNICODE_STRING UnicodeString; + ANSI_STRING AnsiString; + LONG ErrorCode; + + RtlInitUnicodeString(&UnicodeString, NULL); + if (lpClass) { + UnicodeString.Buffer = &ClassName[0]; + UnicodeString.MaximumLength = sizeof(ClassName); + } + ErrorCode = RegQueryInfoKeyW( + hKey, + UnicodeString.Buffer, + lpcbClass, + lpReserved, + lpcSubKeys, + lpcbMaxSubKeyLen, + lpcbMaxClassLen, + lpcValues, + lpcbMaxValueNameLen, + lpcbMaxValueLen, + lpcbSecurityDescriptor, + lpftLastWriteTime); + + if ((ErrorCode == ERROR_SUCCESS) && (lpClass)) { + RtlInitAnsiString(&AnsiString, NULL); + AnsiString.Buffer = lpClass; + AnsiString.MaximumLength = *lpcbClass; + RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); + *lpcbClass = AnsiString.Length; + } + return ErrorCode; } /************************************************************************ - * RegQueryMultipleValuesA + * RegQueryMultipleValuesA */ LONG STDCALL RegQueryMultipleValuesA( - HKEY hKey, - PVALENTA val_list, - DWORD num_vals, - LPSTR lpValueBuf, - LPDWORD ldwTotsize - ) + HKEY hKey, + PVALENTA val_list, + DWORD num_vals, + LPSTR lpValueBuf, + LPDWORD ldwTotsize) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegQueryMultipleValuesW + * RegQueryMultipleValuesW */ LONG STDCALL RegQueryMultipleValuesW( - HKEY hKey, - PVALENTW val_list, - DWORD num_vals, - LPWSTR lpValueBuf, - LPDWORD ldwTotsize - ) + HKEY hKey, + PVALENTW val_list, + DWORD num_vals, + LPWSTR lpValueBuf, + LPDWORD ldwTotsize) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegQueryValueA + * RegQueryValueExW */ LONG STDCALL -RegQueryValueA( - HKEY hKey, - LPCSTR lpSubKey, - LPSTR lpValue, - PLONG lpcbValue - ) +RegQueryValueExW( + HKEY hKey, + LPCWSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData) { - WCHAR SubKeyNameBuffer[MAX_PATH+1]; - UNICODE_STRING SubKeyName; - UNICODE_STRING Value; - ANSI_STRING AnsiString; - LONG ValueSize; - LONG ErrorCode; + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; + UNICODE_STRING ValueName; + NTSTATUS Status; + DWORD dwError = ERROR_SUCCESS; + ULONG BufferSize; + ULONG ResultSize; + HKEY KeyHandle; - if ((lpValue) && (!lpcbValue)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n", + hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0); + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError(dwError); + return(dwError); } - - RtlInitUnicodeString(&SubKeyName, NULL); - RtlInitUnicodeString(&Value, NULL); - - if ((lpSubKey) && (strlen(lpSubKey) != 0)) - { - RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey); - SubKeyName.Buffer = &SubKeyNameBuffer[0]; - SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer); - RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE); + if ((lpData) && (!lpcbData)) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } - - if (lpValue) - { - ValueSize = *lpcbValue * sizeof(WCHAR); - Value.MaximumLength = ValueSize; - Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize); - if (!Value.Buffer) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } + RtlInitUnicodeString (&ValueName, lpValueName); + BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData; + ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(), + 0, + BufferSize); + if (ValueInfo == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; } - else - { - ValueSize = 0; + Status = NtQueryValueKey (hKey, + &ValueName, + KeyValuePartialInformation, + ValueInfo, + BufferSize, + &ResultSize); + DPRINT("Status 0x%X\n", Status); + if (Status == STATUS_BUFFER_TOO_SMALL) { + /* Return ERROR_SUCCESS and the buffer space needed for a successful call */ + dwError = ERROR_SUCCESS; } - - ErrorCode = RegQueryValueW( - hKey, - (LPCWSTR)SubKeyName.Buffer, - Value.Buffer, - &ValueSize); - - if (ErrorCode == ERROR_SUCCESS) - { - Value.Length = ValueSize; - RtlInitAnsiString(&AnsiString, NULL); - AnsiString.Buffer = lpValue; - AnsiString.MaximumLength = *lpcbValue; - RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE); + else if (!NT_SUCCESS(Status)) { + dwError = RtlNtStatusToDosError(Status); + SetLastError(dwError); } - - *lpcbValue = ValueSize; - - if (Value.Buffer) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer); + else { + if (lpType) { + *lpType = ValueInfo->Type; + } + RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength); + if ((ValueInfo->Type == REG_SZ) || + (ValueInfo->Type == REG_MULTI_SZ) || + (ValueInfo->Type == REG_EXPAND_SZ)) { + ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0; + } } - - return ErrorCode; + DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength); + if (NULL != lpcbData) { + *lpcbData = (DWORD)ValueInfo->DataLength; + } + RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); + return dwError; } /************************************************************************ - * RegQueryValueExA + * RegQueryValueExA */ LONG STDCALL RegQueryValueExA( - HKEY hKey, - LPCSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) + HKEY hKey, + LPCSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData) { WCHAR ValueNameBuffer[MAX_PATH+1]; UNICODE_STRING ValueName; @@ -1764,362 +1583,261 @@ RegQueryValueExA( ANSI_STRING AnsiString; LONG ErrorCode; DWORD ResultSize; - DWORD Type; + DWORD Type; /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */ - if ((lpData) && (!lpcbData)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + if ((lpData) && (!lpcbData)) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } - RtlInitUnicodeString(&ValueData, NULL); - - if (lpData) - { + if (lpData) { ValueData.MaximumLength = *lpcbData * sizeof(WCHAR); - ValueData.Buffer = RtlAllocateHeap( + ValueData.Buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, ValueData.MaximumLength); - if (!ValueData.Buffer) - { + if (!ValueData.Buffer) { SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; + return ERROR_OUTOFMEMORY; } } - RtlInitAnsiString(&AnsiString, (LPSTR)lpValueName); RtlInitUnicodeString(&ValueName, NULL); ValueName.Buffer = &ValueNameBuffer[0]; ValueName.MaximumLength = sizeof(ValueNameBuffer); RtlAnsiStringToUnicodeString(&ValueName, &AnsiString, FALSE); - - if (lpcbData) - { + if (lpcbData) { ResultSize = *lpcbData; - } - else - { + } else { ResultSize = 0; } - ErrorCode = RegQueryValueExW( - hKey, - ValueName.Buffer, - lpReserved, - &Type, - (LPBYTE)ValueData.Buffer, - &ResultSize); - - if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL)) - { - if (lpType) - { + hKey, + ValueName.Buffer, + lpReserved, + &Type, + (LPBYTE)ValueData.Buffer, + &ResultSize); + if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL)) { + if (lpType) { *lpType = Type; } - - if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) - { + if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) { ValueData.Length = ResultSize; RtlInitAnsiString(&AnsiString, NULL); AnsiString.Buffer = lpData; AnsiString.MaximumLength = *lpcbData; RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE); - } - else - { + } else { RtlMoveMemory(lpData, ValueData.Buffer, ResultSize); } } - - if (lpcbData) - { + if (lpcbData) { *lpcbData = ResultSize; } - - if (ValueData.Buffer) - { + if (ValueData.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData.Buffer); } - return ErrorCode; } /************************************************************************ - * RegQueryValueExW + * RegQueryValueW */ LONG STDCALL -RegQueryValueExW( - HKEY hKey, - LPCWSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) +RegQueryValueW( + HKEY hKey, + LPCWSTR lpSubKey, + LPWSTR lpValue, + PLONG lpcbValue) { - PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; - UNICODE_STRING ValueName; - NTSTATUS Status; - DWORD dwError = ERROR_SUCCESS; - ULONG BufferSize; - ULONG ResultSize; - HKEY KeyHandle; - - DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n", - hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0); - - Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError(dwError); - return(dwError); - } + NTSTATUS errCode; + UNICODE_STRING SubKeyString; + OBJECT_ATTRIBUTES ObjectAttributes; + HKEY KeyHandle; + HANDLE RealKey; + LONG ErrorCode; + BOOL CloseRealKey; - if ((lpData) && (!lpcbData)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + errCode = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError (ErrorCode); + return ErrorCode; } - - RtlInitUnicodeString (&ValueName, - lpValueName); - - BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData; - ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(), - 0, - BufferSize); - if (ValueInfo == NULL) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; + if ((lpSubKey) && (wcslen(lpSubKey) != 0)) { + RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey); + InitializeObjectAttributes(&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + errCode = NtOpenKey( + &RealKey, + KEY_ALL_ACCESS, + & ObjectAttributes); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError(ErrorCode); + return ErrorCode; + } + CloseRealKey = TRUE; + } else { + RealKey = hKey; + CloseRealKey = FALSE; } - - Status = NtQueryValueKey (hKey, - &ValueName, - KeyValuePartialInformation, - ValueInfo, - BufferSize, - &ResultSize); - - DPRINT("Status 0x%X\n", Status); - - if (Status == STATUS_BUFFER_TOO_SMALL) - { - /* Return ERROR_SUCCESS and the buffer space needed for a successful call */ - dwError = ERROR_SUCCESS; + ErrorCode = RegQueryValueExW( + RealKey, + NULL, + NULL, + NULL, + (LPBYTE)lpValue, + (LPDWORD)lpcbValue); + if (CloseRealKey) { + NtClose(RealKey); } - else if (!NT_SUCCESS(Status)) - { - dwError = RtlNtStatusToDosError(Status); - SetLastError(dwError); - } - else - { - if (lpType) - { - *lpType = ValueInfo->Type; - } - - RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength); - if ((ValueInfo->Type == REG_SZ) || - (ValueInfo->Type == REG_MULTI_SZ) || - (ValueInfo->Type == REG_EXPAND_SZ)) - { - ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0; - } - } - - DPRINT("Type %d ResultSize %d\n", ValueInfo->Type, ResultSize); - - *lpcbData = (DWORD)ResultSize; - - RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); - - return dwError; + return ErrorCode; } /************************************************************************ - * RegQueryValueW + * RegQueryValueA */ LONG STDCALL -RegQueryValueW( - HKEY hKey, - LPCWSTR lpSubKey, - LPWSTR lpValue, - PLONG lpcbValue - ) +RegQueryValueA( + HKEY hKey, + LPCSTR lpSubKey, + LPSTR lpValue, + PLONG lpcbValue) { - NTSTATUS errCode; - UNICODE_STRING SubKeyString; - OBJECT_ATTRIBUTES ObjectAttributes; - HKEY KeyHandle; - HANDLE RealKey; - LONG ErrorCode; - BOOL CloseRealKey; - - errCode = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(errCode)) - { - ErrorCode = RtlNtStatusToDosError(errCode); - SetLastError (ErrorCode); - return ErrorCode; - } - - if ((lpSubKey) && (wcslen(lpSubKey) != 0)) - { + WCHAR SubKeyNameBuffer[MAX_PATH+1]; + UNICODE_STRING SubKeyName; + UNICODE_STRING Value; + ANSI_STRING AnsiString; + LONG ValueSize; + LONG ErrorCode; - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - errCode = NtOpenKey( - &RealKey, - KEY_ALL_ACCESS, - & ObjectAttributes - ); - if ( !NT_SUCCESS(errCode) ) - { - ErrorCode = RtlNtStatusToDosError(errCode); - SetLastError(ErrorCode); - return ErrorCode; - } - CloseRealKey = TRUE; + if ((lpValue) && (!lpcbValue)) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } - else - { - RealKey = hKey; - CloseRealKey = FALSE; + RtlInitUnicodeString(&SubKeyName, NULL); + RtlInitUnicodeString(&Value, NULL); + if ((lpSubKey) && (strlen(lpSubKey) != 0)) { + RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey); + SubKeyName.Buffer = &SubKeyNameBuffer[0]; + SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer); + RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE); } - - ErrorCode = RegQueryValueExW( - RealKey, - NULL, - NULL, - NULL, - (LPBYTE)lpValue, - (LPDWORD)lpcbValue); - - if (CloseRealKey) - { - NtClose(RealKey); + if (lpValue) { + ValueSize = *lpcbValue * sizeof(WCHAR); + Value.MaximumLength = ValueSize; + Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize); + if (!Value.Buffer) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; + } + } else { + ValueSize = 0; + } + ErrorCode = RegQueryValueW( + hKey, + (LPCWSTR)SubKeyName.Buffer, + Value.Buffer, + &ValueSize); + if (ErrorCode == ERROR_SUCCESS) { + Value.Length = ValueSize; + RtlInitAnsiString(&AnsiString, NULL); + AnsiString.Buffer = lpValue; + AnsiString.MaximumLength = *lpcbValue; + RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE); + } + *lpcbValue = ValueSize; + if (Value.Buffer) { + RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer); } - return ErrorCode; } /************************************************************************ - * RegReplaceKeyA + * RegReplaceKeyA */ LONG STDCALL RegReplaceKeyA( - HKEY hKey, - LPCSTR lpSubKey, - LPCSTR lpNewFile, - LPCSTR lpOldFile - ) + HKEY hKey, + LPCSTR lpSubKey, + LPCSTR lpNewFile, + LPCSTR lpOldFile) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegReplaceKeyW + * RegReplaceKeyW */ LONG STDCALL RegReplaceKeyW( - HKEY hKey, - LPCWSTR lpSubKey, - LPCWSTR lpNewFile, - LPCWSTR lpOldFile - ) + HKEY hKey, + LPCWSTR lpSubKey, + LPCWSTR lpNewFile, + LPCWSTR lpOldFile) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegRestoreKeyA + * RegRestoreKeyA */ LONG STDCALL RegRestoreKeyA( - HKEY hKey, - LPCSTR lpFile, - DWORD dwFlags - ) + HKEY hKey, + LPCSTR lpFile, + DWORD dwFlags) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegRestoreKeyW + * RegRestoreKeyW */ LONG STDCALL RegRestoreKeyW( - HKEY hKey, - LPCWSTR lpFile, - DWORD dwFlags - ) + HKEY hKey, + LPCWSTR lpFile, + DWORD dwFlags) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; -} - - -/************************************************************************ - * RegSaveKeyA - */ -LONG STDCALL -RegSaveKeyA(HKEY hKey, - LPCSTR lpFile, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) -{ - UNICODE_STRING FileName; - LONG ErrorCode; - - RtlCreateUnicodeStringFromAsciiz(&FileName, - (LPSTR)lpFile); - ErrorCode = RegSaveKeyW(hKey, - FileName.Buffer, - lpSecurityAttributes); - RtlFreeUnicodeString(&FileName); - - return(ErrorCode); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegSaveKeyW + * RegSaveKeyW */ LONG STDCALL RegSaveKeyW(HKEY hKey, - LPCWSTR lpFile, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) + LPCWSTR lpFile, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) { PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; OBJECT_ATTRIBUTES ObjectAttributes; @@ -2130,155 +1848,146 @@ RegSaveKeyW(HKEY hKey, NTSTATUS Status; LONG ErrorCode; - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - + } if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFile, - &NtName, - NULL, - NULL)) - { + &NtName, NULL, NULL)) { SetLastError(ERROR_INVALID_PARAMETER); return(ERROR_INVALID_PARAMETER); - } - + } if (lpSecurityAttributes != NULL) - SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; - + SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; InitializeObjectAttributes(&ObjectAttributes, - &NtName, - OBJ_CASE_INSENSITIVE, - NULL, - SecurityDescriptor); - + &NtName, + OBJ_CASE_INSENSITIVE, + NULL, + SecurityDescriptor); Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, - FILE_CREATE, - FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_CREATE, + FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); RtlFreeUnicodeString(&NtName); - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - - Status = NtSaveKey(KeyHandle, - FileHandle); + } + Status = NtSaveKey(KeyHandle, FileHandle); NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { + if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - + } return(ERROR_SUCCESS); } /************************************************************************ - * RegSetKeySecurity + * RegSaveKeyA + */ +LONG STDCALL +RegSaveKeyA(HKEY hKey, + LPCSTR lpFile, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + UNICODE_STRING FileName; + LONG ErrorCode; + + RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile); + ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes); + RtlFreeUnicodeString(&FileName); + return(ErrorCode); +} + + +/************************************************************************ + * RegSetKeySecurity */ LONG STDCALL RegSetKeySecurity( - HKEY hKey, - SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG? */ - PSECURITY_DESCRIPTOR pSecurityDescriptor - ) + HKEY hKey, + SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG? */ + PSECURITY_DESCRIPTOR pSecurityDescriptor + ) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegSetValueA + * RegSetValueExW */ LONG STDCALL -RegSetValueA( - HKEY hKey, - LPCSTR lpSubKey, - DWORD dwType, - LPCSTR lpData, - DWORD cbData - ) +RegSetValueExW( + HKEY hKey, + LPCWSTR lpValueName, + DWORD Reserved, + DWORD dwType, + CONST BYTE* lpData, + DWORD cbData) { - WCHAR SubKeyNameBuffer[MAX_PATH+1]; - UNICODE_STRING SubKeyName; - UNICODE_STRING Data; - ANSI_STRING AnsiString; - LONG DataSize; + UNICODE_STRING ValueName; + PUNICODE_STRING pValueName; + HKEY KeyHandle; + NTSTATUS Status; LONG ErrorCode; - if (!lpData) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + Status = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; } - - RtlInitUnicodeString(&SubKeyName, NULL); - RtlInitUnicodeString(&Data, NULL); - - if ((lpSubKey) && (strlen(lpSubKey) != 0)) - { - RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey); - SubKeyName.Buffer = &SubKeyNameBuffer[0]; - SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer); - RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE); + if (lpValueName) { + RtlInitUnicodeString(&ValueName, lpValueName); + pValueName = &ValueName; + } else { + pValueName = NULL; } - - DataSize = cbData * sizeof(WCHAR); - Data.MaximumLength = DataSize; - Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize); - if (!Data.Buffer) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; + Status = NtSetValueKey( + KeyHandle, + pValueName, + 0, + dwType, + (PVOID)lpData, + (ULONG)cbData); + if (!NT_SUCCESS(Status)) { + LONG ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; } - - ErrorCode = RegSetValueW( - hKey, - (LPCWSTR)SubKeyName.Buffer, - dwType, - Data.Buffer, - DataSize); - - RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer); - - return ErrorCode; + return ERROR_SUCCESS; } /************************************************************************ - * RegSetValueExA + * RegSetValueExA */ LONG STDCALL RegSetValueExA( - HKEY hKey, - LPCSTR lpValueName, - DWORD Reserved, - DWORD dwType, - CONST BYTE *lpData, - DWORD cbData - ) + HKEY hKey, + LPCSTR lpValueName, + DWORD Reserved, + DWORD dwType, + CONST BYTE* lpData, + DWORD cbData) { UNICODE_STRING ValueName; LPWSTR pValueName; @@ -2288,24 +1997,17 @@ RegSetValueExA( LPBYTE pData; DWORD DataSize; - if (!lpData) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; + if (!lpData) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } - - if ((lpValueName) && (strlen(lpValueName) != 0)) - { + if ((lpValueName) && (strlen(lpValueName) != 0)) { RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName); pValueName = (LPWSTR)ValueName.Buffer; - } - else - { + } else { pValueName = NULL; } - - if ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ)) - { + if ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ)) { RtlInitAnsiString(&AnsiString, NULL); AnsiString.Buffer = (LPSTR)lpData; AnsiString.Length = cbData; @@ -2313,198 +2015,162 @@ RegSetValueExA( RtlAnsiStringToUnicodeString(&Data, &AnsiString, TRUE); pData = (LPBYTE)Data.Buffer; DataSize = cbData * sizeof(WCHAR); - } - else - { + } else { RtlInitUnicodeString(&Data, NULL); pData = (LPBYTE)lpData; DataSize = cbData; } - ErrorCode = RegSetValueExW( - hKey, - pValueName, - Reserved, - dwType, + hKey, + pValueName, + Reserved, + dwType, pData, - DataSize); - - if (pValueName) - { + DataSize); + if (pValueName) { RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName.Buffer); } - - if (Data.Buffer) - { + if (Data.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer); } - return ErrorCode; } /************************************************************************ - * RegSetValueExW + * RegSetValueW */ LONG STDCALL -RegSetValueExW( - HKEY hKey, - LPCWSTR lpValueName, - DWORD Reserved, - DWORD dwType, - CONST BYTE *lpData, - DWORD cbData - ) +RegSetValueW( + HKEY hKey, + LPCWSTR lpSubKey, + DWORD dwType, + LPCWSTR lpData, + DWORD cbData) { - UNICODE_STRING ValueName; - PUNICODE_STRING pValueName; - HKEY KeyHandle; - NTSTATUS Status; - LONG ErrorCode; + NTSTATUS errCode; + UNICODE_STRING SubKeyString; + OBJECT_ATTRIBUTES ObjectAttributes; + HKEY KeyHandle; + HANDLE RealKey; + LONG ErrorCode; + BOOL CloseRealKey; - Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); - return ErrorCode; - } - - if (lpValueName) - { - RtlInitUnicodeString(&ValueName, lpValueName); - pValueName = &ValueName; + errCode = MapDefaultKey(&KeyHandle, hKey); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError (ErrorCode); + return ErrorCode; } - else - { - pValueName = NULL; + if ((lpSubKey) && (wcslen(lpSubKey) != 0)) { + RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey); + InitializeObjectAttributes(&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + errCode = NtOpenKey(&RealKey, KEY_ALL_ACCESS, &ObjectAttributes); + if (!NT_SUCCESS(errCode)) { + ErrorCode = RtlNtStatusToDosError(errCode); + SetLastError(ErrorCode); + return ErrorCode; + } + CloseRealKey = TRUE; + } else { + RealKey = hKey; + CloseRealKey = FALSE; } - - Status = NtSetValueKey( - KeyHandle, - pValueName, - 0, - dwType, - (PVOID)lpData, - (ULONG)cbData); - if (!NT_SUCCESS(Status)) - { - LONG ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + ErrorCode = RegSetValueExW( + RealKey, + NULL, + 0, + dwType, + (LPBYTE)lpData, + cbData); + if (CloseRealKey) { + NtClose(RealKey); + } + return ErrorCode; } /************************************************************************ - * RegSetValueW + * RegSetValueA */ LONG STDCALL -RegSetValueW( - HKEY hKey, - LPCWSTR lpSubKey, - DWORD dwType, - LPCWSTR lpData, - DWORD cbData - ) +RegSetValueA( + HKEY hKey, + LPCSTR lpSubKey, + DWORD dwType, + LPCSTR lpData, + DWORD cbData) { - NTSTATUS errCode; - UNICODE_STRING SubKeyString; - OBJECT_ATTRIBUTES ObjectAttributes; - HKEY KeyHandle; - HANDLE RealKey; - LONG ErrorCode; - BOOL CloseRealKey; - - errCode = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(errCode)) - { - ErrorCode = RtlNtStatusToDosError(errCode); - SetLastError (ErrorCode); - return ErrorCode; - } - - if ((lpSubKey) && (wcslen(lpSubKey) != 0)) - { + WCHAR SubKeyNameBuffer[MAX_PATH+1]; + UNICODE_STRING SubKeyName; + UNICODE_STRING Data; + ANSI_STRING AnsiString; + LONG DataSize; + LONG ErrorCode; - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - - errCode = NtOpenKey( - &RealKey, - KEY_ALL_ACCESS, - & ObjectAttributes - ); - if ( !NT_SUCCESS(errCode) ) - { - ErrorCode = RtlNtStatusToDosError(errCode); - SetLastError(ErrorCode); - return ErrorCode; - } - CloseRealKey = TRUE; + if (!lpData) { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; } - else - { - RealKey = hKey; - CloseRealKey = FALSE; + RtlInitUnicodeString(&SubKeyName, NULL); + RtlInitUnicodeString(&Data, NULL); + if ((lpSubKey) && (strlen(lpSubKey) != 0)) { + RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey); + SubKeyName.Buffer = &SubKeyNameBuffer[0]; + SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer); + RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE); } - - ErrorCode = RegSetValueExW( - RealKey, - NULL, - 0, - dwType, - (LPBYTE)lpData, - cbData); - - if (CloseRealKey) - { - NtClose(RealKey); + DataSize = cbData * sizeof(WCHAR); + Data.MaximumLength = DataSize; + Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize); + if (!Data.Buffer) { + SetLastError(ERROR_OUTOFMEMORY); + return ERROR_OUTOFMEMORY; } - + ErrorCode = RegSetValueW( + hKey, + (LPCWSTR)SubKeyName.Buffer, + dwType, + Data.Buffer, + DataSize); + RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer); return ErrorCode; } /************************************************************************ - * RegUnLoadKeyA + * RegUnLoadKeyA */ LONG STDCALL RegUnLoadKeyA( - HKEY hKey, - LPCSTR lpSubKey - ) + HKEY hKey, + LPCSTR lpSubKey) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /************************************************************************ - * RegUnLoadKeyW + * RegUnLoadKeyW */ LONG STDCALL RegUnLoadKeyW( - HKEY hKey, - LPCWSTR lpSubKey - ) + HKEY hKey, + LPCWSTR lpSubKey) { UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; } /* EOF */ diff --git a/lib/advapi32/sec/.cvsignore b/lib/advapi32/sec/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/advapi32/sec/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/advapi32/sec/ac.c b/lib/advapi32/sec/ac.c index 9c82d4f..2761a8c 100644 --- a/lib/advapi32/sec/ac.c +++ b/lib/advapi32/sec/ac.c @@ -6,8 +6,8 @@ * PURPOSE: ACL/ACE functions */ -#include -#include +#define NTOS_MODE_USER +#include #include diff --git a/lib/advapi32/sec/lsa.c b/lib/advapi32/sec/lsa.c index c6041da..864e03c 100644 --- a/lib/advapi32/sec/lsa.c +++ b/lib/advapi32/sec/lsa.c @@ -8,579 +8,128 @@ * UPDATE HISTORY: * 19990322 EA created * 19990515 EA stubs + * 20030202 KJK compressed stubs */ #include #include - -/********************************************************************** - * LsaAddAccountRights - */ -INT -STDCALL -LsaAddAccountRights (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaAddPrivilegesToAccount - */ -INT -STDCALL -LsaAddPrivilegesToAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaClearAuditLog - */ -INT -STDCALL -LsaClearAuditLog (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaClose - */ -INT -STDCALL -LsaClose (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaCreateAccount - */ -INT -STDCALL -LsaCreateAccount ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaCreateSecret - */ -INT -STDCALL -LsaCreateSecret (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaCreateTrustedDomain - */ -INT -STDCALL -LsaCreateTrustedDomain (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaDelete - */ -INT -STDCALL -LsaDelete (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaDeleteTrustedDomain - */ -INT -STDCALL -LsaDeleteTrustedDomain (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumerateAccountRights - */ -INT -STDCALL -LsaEnumerateAccountRights (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumerateAccounts - */ -INT -STDCALL -LsaEnumerateAccounts (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumerateAccountsWithUserRight - */ -INT -STDCALL -LsaEnumerateAccountsWithUserRight (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumeratePrivileges - */ -INT -STDCALL -LsaEnumeratePrivileges (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumeratePrivilegesOfAccount - */ -INT -STDCALL -LsaEnumeratePrivilegesOfAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaEnumerateTrustedDomains - */ -INT -STDCALL -LsaEnumerateTrustedDomains (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaFreeMemory - */ -INT -STDCALL -LsaFreeMemory (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaGetQuotasForAccount - */ -INT -STDCALL -LsaGetQuotasForAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaGetSystemAccessAccount - */ -INT -STDCALL -LsaGetSystemAccessAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaGetUserName - */ -INT -STDCALL -LsaGetUserName (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaICLookupNames - */ -INT -STDCALL -LsaICLookupNames (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaICLookupSids - */ -INT -STDCALL -LsaICLookupSids (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaLookupNames - */ -INT -STDCALL -LsaLookupNames (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaLookupPrivilegeDisplayName - */ -INT -STDCALL -LsaLookupPrivilegeDisplayName (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaLookupPrivilegeName - */ -INT -STDCALL -LsaLookupPrivilegeName (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaLookupPrivilegeValue - */ -INT -STDCALL -LsaLookupPrivilegeValue (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaLookupSids - */ -INT -STDCALL -LsaLookupSids (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaNtStatusToWinError - */ -INT -STDCALL -LsaNtStatusToWinError (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaOpenAccount - */ -INT -STDCALL -LsaOpenAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaOpenPolicy - */ -INT -STDCALL -LsaOpenPolicy (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaOpenSecret - */ -INT -STDCALL -LsaOpenSecret (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaOpenTrustedDomain - */ -INT -STDCALL -LsaOpenTrustedDomain (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaQueryInfoTrustedDomain - */ -INT -STDCALL -LsaQueryInfoTrustedDomain (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaQueryInformationPolicy - */ -INT -STDCALL -LsaQueryInformationPolicy (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaQuerySecret - */ -INT -STDCALL -LsaQuerySecret (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaQuerySecurityObject - */ -INT -STDCALL -LsaQuerySecurityObject (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaQueryTrustedDomainInfo - */ -INT -STDCALL -LsaQueryTrustedDomainInfo (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaRemoveAccountRights - */ -INT -STDCALL -LsaRemoveAccountRights (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaRemovePrivilegesFromAccount - */ -INT -STDCALL -LsaRemovePrivilegesFromAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaRetrievePrivateData - */ -INT -STDCALL -LsaRetrievePrivateData (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetInformationPolicy - */ -INT -STDCALL -LsaSetInformationPolicy (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetInformationTrustedDomain - */ -INT -STDCALL -LsaSetInformationTrustedDomain (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; +/* +LsaClearAuditLog +LsaClose +LsaDelete +LsaFreeMemory +*/ +NTSTATUS STDCALL _LsaStub1(ULONG_PTR Unknown0) +{ + return STATUS_NOT_IMPLEMENTED; +} + +/* +LsaAddPrivilegesToAccount +LsaDeleteTrustedDomain +LsaEnumeratePrivilegesOfAccount +LsaGetQuotasForAccount +LsaGetSystemAccessAccount +LsaGetUserName +LsaSetQuotasForAccount +LsaSetSystemAccessAccount +*/ +NTSTATUS STDCALL _LsaStub2(ULONG_PTR Unknown0, ULONG_PTR Unknown1) +{ + return STATUS_NOT_IMPLEMENTED; +} + +/* +LsaLookupPrivilegeName +LsaLookupPrivilegeValue +LsaQueryInfoTrustedDomain +LsaQueryInformationPolicy +LsaQuerySecurityObject +LsaRemovePrivilegesFromAccount +LsaRetrievePrivateData +LsaSetInformationPolicy +LsaSetInformationTrustedDomain +LsaSetSecret +LsaSetSecurityObject +LsaStorePrivateData +*/ +NTSTATUS STDCALL _LsaStub3 +( + ULONG_PTR Unknown0, + ULONG_PTR Unknown1, + ULONG_PTR Unknown2 +) +{ + return STATUS_NOT_IMPLEMENTED; +} + +/* +LsaAddAccountRights +LsaCreateAccount +LsaCreateSecret +LsaCreateTrustedDomain +LsaEnumerateAccountRights +LsaEnumerateAccountsWithUserRight +LsaLookupPrivilegeDisplayName +LsaOpenAccount +LsaOpenPolicy +LsaOpenSecret +LsaOpenTrustedDomain +LsaSetTrustedDomainInformation +*/ +NTSTATUS STDCALL _LsaStub4 +( + ULONG_PTR Unknown0, + ULONG_PTR Unknown1, + ULONG_PTR Unknown2, + ULONG_PTR Unknown3 +) +{ + return STATUS_NOT_IMPLEMENTED; +} + +/* +LsaEnumerateAccounts +LsaEnumeratePrivileges +LsaEnumerateTrustedDomains +LsaLookupNames +LsaLookupSids +LsaQuerySecret +LsaQueryTrustedDomainInfo +LsaRemoveAccountRights +*/ +NTSTATUS STDCALL _LsaStub5 +( + ULONG_PTR Unknown0, + ULONG_PTR Unknown1, + ULONG_PTR Unknown2, + ULONG_PTR Unknown3, + ULONG_PTR Unknown4 +) +{ + return STATUS_NOT_IMPLEMENTED; +} + +/* +LsaICLookupNames +LsaICLookupSids +*/ +NTSTATUS STDCALL _LsaStub8 +( + ULONG_PTR Unknown0, + ULONG_PTR Unknown1, + ULONG_PTR Unknown2, + ULONG_PTR Unknown3, + ULONG_PTR Unknown4, + ULONG_PTR Unknown5, + ULONG_PTR Unknown6, + ULONG_PTR Unknown7 +) +{ + return STATUS_NOT_IMPLEMENTED; } -/********************************************************************** - * LsaSetQuotasForAccount - */ -INT -STDCALL -LsaSetQuotasForAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetSecret - */ -INT -STDCALL -LsaSetSecret (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetSecurityObject - */ -INT -STDCALL -LsaSetSecurityObject (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetSystemAccessAccount - */ -INT -STDCALL -LsaSetSystemAccessAccount (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaSetTrustedDomainInformation - */ -INT -STDCALL -LsaSetTrustedDomainInformation (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/********************************************************************** - * LsaStorePrivateData - */ -INT -STDCALL -LsaStorePrivateData (VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - /* EOF */ diff --git a/lib/advapi32/sec/misc.c b/lib/advapi32/sec/misc.c index 9c6e602..e0e52c5 100644 --- a/lib/advapi32/sec/misc.c +++ b/lib/advapi32/sec/misc.c @@ -1,8 +1,8 @@ /* */ -#include -#include +#define NTOS_MODE_USER +#include #include @@ -75,6 +75,13 @@ MapGenericMask(PDWORD AccessMask, } +WINBOOL +STDCALL +ImpersonateLoggedOnUser(HANDLE hToken) +{ + return FALSE; +} + BOOL STDCALL ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) { diff --git a/lib/advapi32/sec/sec.c b/lib/advapi32/sec/sec.c index 03fa134..72b4e71 100644 --- a/lib/advapi32/sec/sec.c +++ b/lib/advapi32/sec/sec.c @@ -8,8 +8,8 @@ * Created 01/11/98 */ -#include -#include +#define NTOS_MODE_USER +#include #include diff --git a/lib/advapi32/sec/sid.c b/lib/advapi32/sec/sid.c index 5cd6de2..5b31323 100644 --- a/lib/advapi32/sec/sid.c +++ b/lib/advapi32/sec/sid.c @@ -6,8 +6,8 @@ * PURPOSE: Security ID functions */ -#include -#include +#define NTOS_MODE_USER +#include #include diff --git a/lib/advapi32/service/.cvsignore b/lib/advapi32/service/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/advapi32/service/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/advapi32/service/scm.c b/lib/advapi32/service/scm.c index 57ae15e..f1198fa 100644 --- a/lib/advapi32/service/scm.c +++ b/lib/advapi32/service/scm.c @@ -6,373 +6,387 @@ * PURPOSE: Service control manager functions * PROGRAMMER: Emanuele Aliberti * UPDATE HISTORY: - * 19990413 EA created - * 19990515 EA + * 19990413 EA created + * 19990515 EA */ /* INCLUDES ******************************************************************/ +#define NTOS_MODE_USER +#include #include -#include +#include +#include + +#define DBG +#include /* FUNCTIONS *****************************************************************/ /********************************************************************** - * ChangeServiceConfigA + * ChangeServiceConfigA */ BOOL STDCALL ChangeServiceConfigA( - SC_HANDLE hService, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCSTR lpBinaryPathName, - LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCSTR lpDependencies, - LPCSTR lpServiceStartName, - LPCSTR lpPassword, - LPCSTR lpDisplayName - ) + SC_HANDLE hService, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCSTR lpBinaryPathName, + LPCSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCSTR lpDependencies, + LPCSTR lpServiceStartName, + LPCSTR lpPassword, + LPCSTR lpDisplayName) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * ChangeServiceConfigW + * ChangeServiceConfigW */ BOOL STDCALL ChangeServiceConfigW( - SC_HANDLE hService, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCWSTR lpBinaryPathName, - LPCWSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCWSTR lpDependencies, - LPCWSTR lpServiceStartName, - LPCWSTR lpPassword, - LPCWSTR lpDisplayName - ) + SC_HANDLE hService, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCWSTR lpBinaryPathName, + LPCWSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCWSTR lpDependencies, + LPCWSTR lpServiceStartName, + LPCWSTR lpPassword, + LPCWSTR lpDisplayName) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * CloseServiceHandle + * CloseServiceHandle */ BOOL STDCALL -CloseServiceHandle( SC_HANDLE hSCObject ) +CloseServiceHandle(SC_HANDLE hSCObject) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + HANDLE hPipe; + DPRINT("CloseServiceHandle() - called.\n"); +// SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + if (!CloseHandle(hPipe)) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + return TRUE; } /********************************************************************** - * ControlService + * ControlService */ BOOL STDCALL -ControlService( - SC_HANDLE hService, - DWORD dwControl, - LPSERVICE_STATUS lpServiceStatus - ) +ControlService(SC_HANDLE hService, + DWORD dwControl, + LPSERVICE_STATUS lpServiceStatus) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * CreateServiceA + * CreateServiceA */ SC_HANDLE STDCALL CreateServiceA( - SC_HANDLE hSCManager, - LPCSTR lpServiceName, - LPCSTR lpDisplayName, - DWORD dwDesiredAccess, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCSTR lpBinaryPathName, - LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCSTR lpDependencies, - LPCSTR lpServiceStartName, - LPCSTR lpPassword - ) + SC_HANDLE hSCManager, + LPCSTR lpServiceName, + LPCSTR lpDisplayName, + DWORD dwDesiredAccess, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCSTR lpBinaryPathName, + LPCSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCSTR lpDependencies, + LPCSTR lpServiceStartName, + LPCSTR lpPassword) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; } /********************************************************************** - * CreateServiceW + * CreateServiceW */ SC_HANDLE STDCALL CreateServiceW( - SC_HANDLE hSCManager, - LPCWSTR lpServiceName, - LPCWSTR lpDisplayName, - DWORD dwDesiredAccess, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCWSTR lpBinaryPathName, - LPCWSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCWSTR lpDependencies, - LPCWSTR lpServiceStartName, - LPCWSTR lpPassword - ) + SC_HANDLE hSCManager, + LPCWSTR lpServiceName, + LPCWSTR lpDisplayName, + DWORD dwDesiredAccess, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCWSTR lpBinaryPathName, + LPCWSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCWSTR lpDependencies, + LPCWSTR lpServiceStartName, + LPCWSTR lpPassword) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; } /********************************************************************** - * DeleteService + * DeleteService */ BOOL STDCALL -DeleteService( SC_HANDLE hService ) +DeleteService(SC_HANDLE hService) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumDependentServicesA + * EnumDependentServicesA */ BOOL STDCALL EnumDependentServicesA( - SC_HANDLE hService, - DWORD dwServiceState, - LPENUM_SERVICE_STATUSA lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned - ) + SC_HANDLE hService, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSA lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumDependentServicesW + * EnumDependentServicesW */ BOOL STDCALL EnumDependentServicesW( - SC_HANDLE hService, - DWORD dwServiceState, - LPENUM_SERVICE_STATUSW lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned - ) + SC_HANDLE hService, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSW lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumServiceGroupW + * EnumServiceGroupW * * (unknown) */ BOOL STDCALL EnumServiceGroupW ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6, - DWORD Unknown7, - DWORD Unknown8 - ) + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5, + DWORD Unknown6, + DWORD Unknown7, + DWORD Unknown8) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumServicesStatusA + * EnumServicesStatusA */ BOOL STDCALL EnumServicesStatusA ( - SC_HANDLE hSCManager, - DWORD dwServiceType, - DWORD dwServiceState, - LPENUM_SERVICE_STATUSA lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned, - LPDWORD lpResumeHandle - ) + SC_HANDLE hSCManager, + DWORD dwServiceType, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSA lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumServicesStatusExA + * EnumServicesStatusExA */ BOOL STDCALL -EnumServicesStatusExA(VOID) +EnumServicesStatusExA(SC_HANDLE hSCManager, + SC_ENUM_TYPE InfoLevel, + DWORD dwServiceType, + DWORD dwServiceState, + LPBYTE lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle, + LPCSTR pszGroupName) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumServicesStatusExW + * EnumServicesStatusExW */ BOOL STDCALL -EnumServicesStatusExW(VOID) +EnumServicesStatusExW(SC_HANDLE hSCManager, + SC_ENUM_TYPE InfoLevel, + DWORD dwServiceType, + DWORD dwServiceState, + LPBYTE lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle, + LPCWSTR pszGroupName) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * EnumServicesStatusW + * EnumServicesStatusW */ BOOL STDCALL EnumServicesStatusW( - SC_HANDLE hSCManager, - DWORD dwServiceType, - DWORD dwServiceState, - LPENUM_SERVICE_STATUSW lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned, - LPDWORD lpResumeHandle - ) + SC_HANDLE hSCManager, + DWORD dwServiceType, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSW lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * GetServiceDisplayNameA + * GetServiceDisplayNameA */ BOOL STDCALL GetServiceDisplayNameA( - SC_HANDLE hSCManager, - LPCSTR lpServiceName, - LPSTR lpDisplayName, - LPDWORD lpcchBuffer - ) + SC_HANDLE hSCManager, + LPCSTR lpServiceName, + LPSTR lpDisplayName, + LPDWORD lpcchBuffer) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * GetServiceDisplayNameW + * GetServiceDisplayNameW */ BOOL STDCALL GetServiceDisplayNameW( - SC_HANDLE hSCManager, - LPCWSTR lpServiceName, - LPWSTR lpDisplayName, - LPDWORD lpcchBuffer - ) + SC_HANDLE hSCManager, + LPCWSTR lpServiceName, + LPWSTR lpDisplayName, + LPDWORD lpcchBuffer) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * GetServiceKeyNameA + * GetServiceKeyNameA */ BOOL STDCALL GetServiceKeyNameA( - SC_HANDLE hSCManager, - LPCSTR lpDisplayName, - LPSTR lpServiceName, - LPDWORD lpcchBuffer - ) + SC_HANDLE hSCManager, + LPCSTR lpDisplayName, + LPSTR lpServiceName, + LPDWORD lpcchBuffer) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * GetServiceKeyNameW + * GetServiceKeyNameW */ BOOL STDCALL GetServiceKeyNameW( - SC_HANDLE hSCManager, - LPCWSTR lpDisplayName, - LPWSTR lpServiceName, - LPDWORD lpcchBuffer - ) + SC_HANDLE hSCManager, + LPCWSTR lpDisplayName, + LPWSTR lpServiceName, + LPDWORD lpcchBuffer) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * LockServiceDatabase + * LockServiceDatabase */ SC_LOCK STDCALL -LockServiceDatabase( - SC_HANDLE hSCManager - ) +LockServiceDatabase(SC_HANDLE hSCManager) { - SetLastError (ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; } /********************************************************************** - * OpenSCManagerA + * OpenSCManagerA */ SC_HANDLE STDCALL OpenSCManagerA(LPCSTR lpMachineName, - LPCSTR lpDatabaseName, - DWORD dwDesiredAccess) + LPCSTR lpDatabaseName, + DWORD dwDesiredAccess) { SC_HANDLE Handle; UNICODE_STRING MachineNameW; @@ -380,369 +394,400 @@ OpenSCManagerA(LPCSTR lpMachineName, ANSI_STRING MachineNameA; ANSI_STRING DatabaseNameA; + DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess); + RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName); - RtlAnsiStringToUnicodeString(&MachineNameW, - &MachineNameA, - TRUE); + RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE); RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName); - RtlAnsiStringToUnicodeString(&DatabaseNameW, - &DatabaseNameA, - TRUE); + RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE); - Handle = OpenSCManagerW(MachineNameW.Buffer, - DatabaseNameW.Buffer, - dwDesiredAccess); + Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL, + lpDatabaseName ? DatabaseNameW.Buffer : NULL, + dwDesiredAccess); - RtlFreeHeap(GetProcessHeap(), - 0, - MachineNameW.Buffer); - RtlFreeHeap(GetProcessHeap(), - 0, - DatabaseNameW.Buffer); - - return(Handle); + RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer); + RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer); + return Handle; } /********************************************************************** - * OpenSCManagerW + * OpenSCManagerW */ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName, - LPCWSTR lpDatabaseName, - DWORD dwDesiredAccess) -{ - HANDLE hPipe; - DWORD dwMode; - DWORD dwWait; - BOOL fSuccess; - HANDLE hStartEvent; - LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs"; - - if(lpMachineName == NULL || wcslen(lpMachineName) == 0) - { - if(lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) - { return(NULL); } - - // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled - hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX")); - if(hStartEvent == NULL) - { - SetLastError(ERROR_DATABASE_DOES_NOT_EXIST); - return (NULL); - } - dwWait = WaitForSingleObject(hStartEvent, INFINITE); - if(dwWait == WAIT_FAILED) - { - SetLastError(ERROR_ACCESS_DENIED); - return (NULL); - } - CloseHandle(hStartEvent); - - // Try to open a named pipe; wait for it, if necessary - while(1) - { - hPipe = CreateFileW(lpszPipeName, // pipe name - dwDesiredAccess, - 0, // no sharing - NULL, // no security attributes - OPEN_EXISTING, // opens existing pipe - 0, // default attributes - NULL); // no template file - - // Break if the pipe handle is valid - if(hPipe != INVALID_HANDLE_VALUE) - break; - - // Exit if an error other than ERROR_PIPE_BUSY occurs - if(GetLastError()!= ERROR_PIPE_BUSY) - { return(NULL); } - - // All pipe instances are busy, so wait for 20 seconds - if(!WaitNamedPipeW(lpszPipeName, 20000)) - { return(NULL); } - } - - // The pipe connected; change to message-read mode - dwMode = PIPE_READMODE_MESSAGE; - fSuccess = SetNamedPipeHandleState( - hPipe, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - if(!fSuccess) - { - CloseHandle(hPipe); - return(NULL); - } + LPCWSTR lpDatabaseName, + DWORD dwDesiredAccess) +{ + HANDLE hPipe; + DWORD dwMode; + DWORD dwWait; + BOOL fSuccess; + HANDLE hStartEvent; + LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs"; + + DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess); + + if (lpMachineName == NULL || wcslen(lpMachineName) == 0) { + if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) { + DPRINT("OpenSCManagerW() - Invalid parameters.\n"); + return NULL; + } + + DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n"); + + // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled + hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX")); + if (hStartEvent == NULL) { + SetLastError(ERROR_DATABASE_DOES_NOT_EXIST); + DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n"); + return NULL; + } + + DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent); + +#if 1 + dwWait = WaitForSingleObject(hStartEvent, INFINITE); + if (dwWait == WAIT_FAILED) { + DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n"); + SetLastError(ERROR_ACCESS_DENIED); + return NULL; + } +#else + { + DWORD Count; + + /* wait for event creation (by SCM) for max. 20 seconds */ + for (Count = 0; Count < 20; Count++) + { + dwWait = WaitForSingleObject(hStartEvent, 1000); + if (dwWait == WAIT_FAILED) { + DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n"); + Sleep(1000); + } else { + break; + } + } + + if (dwWait == WAIT_FAILED) + { + DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n"); + } + + } +#endif + + DPRINT("OpenSCManagerW() - Closing handle to event...\n"); + + CloseHandle(hStartEvent); + + // Try to open a named pipe; wait for it, if necessary + while (1) { + DWORD dwLastError; + DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n"); + hPipe = CreateFileW(lpszPipeName, // pipe name + dwDesiredAccess, + 0, // no sharing + NULL, // no security attributes + OPEN_EXISTING, // opens existing pipe + 0, // default attributes + NULL); // no template file + + DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe); + // Break if the pipe handle is valid + if (hPipe != INVALID_HANDLE_VALUE) { + break; + } + + // Exit if an error other than ERROR_PIPE_BUSY occurs + dwLastError = GetLastError(); + if (dwLastError != ERROR_PIPE_BUSY) { + DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError); + return NULL; + } + + // All pipe instances are busy, so wait for 20 seconds + if (!WaitNamedPipeW(lpszPipeName, 20000)) { + DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n"); + return NULL; + } + } + + // The pipe connected; change to message-read mode + dwMode = PIPE_READMODE_MESSAGE; + fSuccess = SetNamedPipeHandleState( + hPipe, // pipe handle + &dwMode, // new pipe mode + NULL, // don't set maximum bytes + NULL); // don't set maximum time + if (!fSuccess) { + CloseHandle(hPipe); + DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n"); + return NULL; + } #if 0 - // Send a message to the pipe server - lpvMessage = (argc > 1) ? argv[1] : "default message"; - - fSuccess = WriteFile( - hPipe, // pipe handle - lpvMessage, // message - strlen(lpvMessage) + 1, // message length - &cbWritten, // bytes written - NULL); // not overlapped - if(!fSuccess) - { - CloseHandle(hPipe); - return(NULL); - } - - do - { - // Read from the pipe - fSuccess = ReadFile( - hPipe, // pipe handle - chBuf, // buffer to receive reply - 512, // size of buffer - &cbRead, // number of bytes read - NULL); // not overlapped - - if(! fSuccess && GetLastError() != ERROR_MORE_DATA) - break; - - // Reply from the pipe is written to STDOUT. - if(!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) - break; - } while(!fSuccess); // repeat loop if ERROR_MORE_DATA - - //CloseHandle(hPipe); + // Send a message to the pipe server + lpvMessage = (argc > 1) ? argv[1] : "default message"; + + fSuccess = WriteFile( + hPipe, // pipe handle + lpvMessage, // message + strlen(lpvMessage) + 1, // message length + &cbWritten, // bytes written + NULL); // not overlapped + if (!fSuccess) { + CloseHandle(hPipe); + DPRINT("OpenSCManagerW() - Failed to write to pipe.\n"); + return NULL; + } + + do { + DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n"); + // Read from the pipe + fSuccess = ReadFile( + hPipe, // pipe handle + chBuf, // buffer to receive reply + 512, // size of buffer + &cbRead, // number of bytes read + NULL); // not overlapped + + if (!fSuccess && GetLastError() != ERROR_MORE_DATA) { + break; + } + + // Reply from the pipe is written to STDOUT. + if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) { + break; + } + } while(!fSuccess); // repeat loop if ERROR_MORE_DATA + + DPRINT("OpenSCManagerW() - I/O loop completed.\n"); + //CloseHandle(hPipe); #endif - return(hPipe); - } - else - { - /* FIXME: Connect to remote SCM */ - return(NULL); - } + DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe); + return hPipe; + } else { + /* FIXME: Connect to remote SCM */ + DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n"); + return NULL; + } } /********************************************************************** - * OpenServiceA + * OpenServiceA */ SC_HANDLE STDCALL OpenServiceA(SC_HANDLE hSCManager, - LPCSTR lpServiceName, - DWORD dwDesiredAccess) + LPCSTR lpServiceName, + DWORD dwDesiredAccess) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return(NULL); + return NULL; } /********************************************************************** - * OpenServiceW + * OpenServiceW */ SC_HANDLE STDCALL OpenServiceW( - SC_HANDLE hSCManager, - LPCWSTR lpServiceName, - DWORD dwDesiredAccess - ) + SC_HANDLE hSCManager, + LPCWSTR lpServiceName, + DWORD dwDesiredAccess + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; } /********************************************************************** - * PrivilegedServiceAuditAlarmA + * PrivilegedServiceAuditAlarmA */ BOOL STDCALL PrivilegedServiceAuditAlarmA( - LPCSTR SubsystemName, - LPCSTR ServiceName, - HANDLE ClientToken, - PPRIVILEGE_SET Privileges, - BOOL AccessGranted - ) + LPCSTR SubsystemName, + LPCSTR ServiceName, + HANDLE ClientToken, + PPRIVILEGE_SET Privileges, + BOOL AccessGranted) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * PrivilegedServiceAuditAlarmW + * PrivilegedServiceAuditAlarmW */ BOOL STDCALL PrivilegedServiceAuditAlarmW( - LPCWSTR SubsystemName, - LPCWSTR ServiceName, - HANDLE ClientToken, - PPRIVILEGE_SET Privileges, - BOOL AccessGranted - ) + LPCWSTR SubsystemName, + LPCWSTR ServiceName, + HANDLE ClientToken, + PPRIVILEGE_SET Privileges, + BOOL AccessGranted) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 1; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 1; } /********************************************************************** - * QueryServiceConfigA + * QueryServiceConfigA */ BOOL STDCALL QueryServiceConfigA( - SC_HANDLE hService, - LPQUERY_SERVICE_CONFIGA lpServiceConfig, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded - ) + SC_HANDLE hService, + LPQUERY_SERVICE_CONFIGA lpServiceConfig, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceConfigW + * QueryServiceConfigW */ BOOL STDCALL QueryServiceConfigW( - SC_HANDLE hService, - LPQUERY_SERVICE_CONFIGW lpServiceConfig, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded - ) + SC_HANDLE hService, + LPQUERY_SERVICE_CONFIGW lpServiceConfig, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceLockStatusA + * QueryServiceLockStatusA */ BOOL STDCALL QueryServiceLockStatusA( - SC_HANDLE hSCManager, - LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded - ) + SC_HANDLE hSCManager, + LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceLockStatusW + * QueryServiceLockStatusW */ BOOL STDCALL QueryServiceLockStatusW( - SC_HANDLE hSCManager, - LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded - ) + SC_HANDLE hSCManager, + LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceObjectSecurity + * QueryServiceObjectSecurity */ BOOL STDCALL QueryServiceObjectSecurity( - SC_HANDLE hService, - SECURITY_INFORMATION dwSecurityInformation, - PSECURITY_DESCRIPTOR lpSecurityDescriptor, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded - ) + SC_HANDLE hService, + SECURITY_INFORMATION dwSecurityInformation, + PSECURITY_DESCRIPTOR lpSecurityDescriptor, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceStatus + * QueryServiceStatus */ BOOL STDCALL QueryServiceStatus( - SC_HANDLE hService, - LPSERVICE_STATUS lpServiceStatus - ) + SC_HANDLE hService, + LPSERVICE_STATUS lpServiceStatus) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * QueryServiceStatusEx + * QueryServiceStatusEx */ BOOL STDCALL -QueryServiceStatusEx(VOID) +QueryServiceStatusEx(SC_HANDLE hService, + SC_STATUS_TYPE InfoLevel, + LPBYTE lpBuffer, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * StartServiceA + * StartServiceA */ BOOL STDCALL StartServiceA( - SC_HANDLE hService, - DWORD dwNumServiceArgs, - LPCSTR *lpServiceArgVectors - ) + SC_HANDLE hService, + DWORD dwNumServiceArgs, + LPCSTR *lpServiceArgVectors) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * StartServiceW + * StartServiceW */ BOOL STDCALL StartServiceW( - SC_HANDLE hService, - DWORD dwNumServiceArgs, - LPCWSTR *lpServiceArgVectors - ) + SC_HANDLE hService, + DWORD dwNumServiceArgs, + LPCWSTR *lpServiceArgVectors) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /********************************************************************** - * UnlockServiceDatabase + * UnlockServiceDatabase */ BOOL STDCALL -UnlockServiceDatabase( - SC_LOCK ScLock - ) +UnlockServiceDatabase(SC_LOCK ScLock) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } diff --git a/lib/advapi32/service/sctrl.c b/lib/advapi32/service/sctrl.c index b407f1a..9fb8d2d 100644 --- a/lib/advapi32/service/sctrl.c +++ b/lib/advapi32/service/sctrl.c @@ -12,8 +12,11 @@ /* INCLUDES ******************************************************************/ +#define NTOS_MODE_USER +#include #include -#include +#include +#include #define NDEBUG #include @@ -34,7 +37,7 @@ typedef struct static ULONG ActiveServiceCount; static PACTIVE_SERVICE ActiveServices; -static PHANDLE ActiveServicesThreadHandles; +/* static PHANDLE ActiveServicesThreadHandles; */ /* uncomment when in use */ /* FUNCTIONS *****************************************************************/ @@ -314,9 +317,6 @@ BOOL STDCALL StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable) { ULONG i; - HANDLE h; - DWORD Tid; - DWORD r; HANDLE hPipe; DWORD dwError; @@ -346,7 +346,7 @@ StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable) } dwError = ScConnectControlPipe(&hPipe); - if (dwError = ERROR_SUCCESS) + if (dwError == ERROR_SUCCESS) { /* FIXME: free the service table */ return(FALSE); diff --git a/lib/advapi32/token/.cvsignore b/lib/advapi32/token/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/advapi32/token/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/advapi32/token/token.c b/lib/advapi32/token/token.c index e276036..b27fe6f 100644 --- a/lib/advapi32/token/token.c +++ b/lib/advapi32/token/token.c @@ -8,8 +8,9 @@ * Created 01/11/98 */ +#define NTOS_MODE_USER +#include #include -#include WINBOOL STDCALL diff --git a/lib/crtdll/assert/assert.c b/lib/crtdll/assert/assert.c deleted file mode 100644 index 2191a42..0000000 --- a/lib/crtdll/assert/assert.c +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include - -void _assert(const char *msg, const char *file, int line) -{ - /* Assertion failed at foo.c line 45: x -#include +#include +#include -char * -_cgets(char *string) + +char *_cgets(char *string) { unsigned len = 0; unsigned int maxlen_wanted; diff --git a/lib/crtdll/conio/cprintf.c b/lib/crtdll/conio/cprintf.c index 21c33a9..da3ca0c 100644 --- a/lib/crtdll/conio/cprintf.c +++ b/lib/crtdll/conio/cprintf.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int _cprintf(const char *fmt, ...) diff --git a/lib/crtdll/conio/cputs.c b/lib/crtdll/conio/cputs.c index 37cd12a..396c71e 100644 --- a/lib/crtdll/conio/cputs.c +++ b/lib/crtdll/conio/cputs.c @@ -8,10 +8,10 @@ * 28/12/98: Created */ #include -#include -#include -#include -#include +#include +#include +#include +#include int _cputs(const char *_str) { diff --git a/lib/crtdll/conio/cscanf.c b/lib/crtdll/conio/cscanf.c index 42a8779..eb3743a 100644 --- a/lib/crtdll/conio/cscanf.c +++ b/lib/crtdll/conio/cscanf.c @@ -1,19 +1,18 @@ -#include -#include -#include +#include +#include +#include +#include -int -_cscanf(char *fmt, ...) +int _cscanf(char *fmt, ...) { - int cnt; + int cnt; - va_list ap; - - //fixme cscanf should scan the console's keyboard - va_start(ap, fmt); - cnt = __vscanf(fmt, ap); - va_end(ap); - return cnt; -} + va_list ap; + //fixme cscanf should scan the console's keyboard + va_start(ap, fmt); + cnt = __vscanf(fmt, ap); + va_end(ap); + return cnt; +} diff --git a/lib/crtdll/conio/getch.c b/lib/crtdll/conio/getch.c index 6830ac5..070a867 100644 --- a/lib/crtdll/conio/getch.c +++ b/lib/crtdll/conio/getch.c @@ -8,32 +8,40 @@ * 28/12/98: Created */ #include -#include -#include -#include +#include +#include +#include +#include -extern int char_avail; -extern int ungot_char; +int _getch(void) +{ + DWORD NumberOfCharsRead = 0; + char c; + if (char_avail) { + c = ungot_char; + char_avail = 0; + } else { + ReadConsoleA(_get_osfhandle(stdin->_file), + &c, + 1, + &NumberOfCharsRead, + NULL); + } + if (c == 10) + c = 13; + putchar(c); + return c; +} -int -_getch(void) +#if 0 +int _getche(void) { - - DWORD NumberOfCharsRead = 0; - char c; - if (char_avail) - { - c = ungot_char; - char_avail = 0; - } - else - { - ReadConsoleA(_get_osfhandle(stdin->_file), &c,1,&NumberOfCharsRead ,NULL); - - } - if ( c == 10 ) - c = 13; - putchar(c); - return c; + int c; + + c = _getch(); + _putch(c); + + return c; } +#endif diff --git a/lib/crtdll/conio/getche.c b/lib/crtdll/conio/getche.c index 247634b..f994649 100644 --- a/lib/crtdll/conio/getche.c +++ b/lib/crtdll/conio/getche.c @@ -10,13 +10,11 @@ * 28/12/98: Created */ -#include -#include +#include +#include -extern int char_avail; -int -getche(void) +int getche(void) { if (char_avail) /* diff --git a/lib/crtdll/conio/kbhit.c b/lib/crtdll/conio/kbhit.c index 1232d72..292d709 100644 --- a/lib/crtdll/conio/kbhit.c +++ b/lib/crtdll/conio/kbhit.c @@ -9,17 +9,15 @@ */ #include -#include -#include +#include +#include // FIXME PeekCosoleInput returns more than keyboard hits -extern int char_avail; -int -_kbhit(void) +int _kbhit(void) { - INPUT_RECORD InputRecord; + //INPUT_RECORD InputRecord; DWORD NumberRead=0; if (char_avail) return(1); diff --git a/lib/crtdll/conio/putch.c b/lib/crtdll/conio/putch.c index b207680..84397b8 100644 --- a/lib/crtdll/conio/putch.c +++ b/lib/crtdll/conio/putch.c @@ -7,15 +7,15 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include #include +#include int _putch( int c ) { DWORD NumberOfCharsWritten; + if ( WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL) ) { return -1; } - return NumberOfCharsWritten; } diff --git a/lib/crtdll/conio/ungetch.c b/lib/crtdll/conio/ungetch.c index 730ac39..8b974bb 100644 --- a/lib/crtdll/conio/ungetch.c +++ b/lib/crtdll/conio/ungetch.c @@ -10,15 +10,16 @@ * 28/12/98: Created */ -#include +#include +#include + #define EOF -1 int char_avail = 0; -char ungot_char = 0; +int ungot_char = 0; -int -_ungetch(int c) +int _ungetch(int c) { if (char_avail) return(EOF); diff --git a/lib/crtdll/ctype/ctype.c b/lib/crtdll/ctype/ctype.c new file mode 100644 index 0000000..5861d6d --- /dev/null +++ b/lib/crtdll/ctype/ctype.c @@ -0,0 +1,264 @@ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ +#include + +unsigned short _ctype[] = { + 0, /* , 0xFFFF */ + _CONTROL, /* CTRL+@, 0x00 */ + _CONTROL, /* CTRL+A, 0x01 */ + _CONTROL, /* CTRL+B, 0x02 */ + _CONTROL, /* CTRL+C, 0x03 */ + _CONTROL, /* CTRL+D, 0x04 */ + _CONTROL, /* CTRL+E, 0x05 */ + _CONTROL, /* CTRL+F, 0x06 */ + _CONTROL, /* CTRL+G, 0x07 */ + _CONTROL, /* CTRL+H, 0x08 */ + _CONTROL | _SPACE, /* CTRL+I, 0x09 */ + _CONTROL | _SPACE, /* CTRL+J, 0x0a */ + _CONTROL | _SPACE, /* CTRL+K, 0x0b */ + _CONTROL | _SPACE, /* CTRL+L, 0x0c */ + _CONTROL | _SPACE, /* CTRL+M, 0x0d */ + _CONTROL, /* CTRL+N, 0x0e */ + _CONTROL, /* CTRL+O, 0x0f */ + _CONTROL, /* CTRL+P, 0x10 */ + _CONTROL, /* CTRL+Q, 0x11 */ + _CONTROL, /* CTRL+R, 0x12 */ + _CONTROL, /* CTRL+S, 0x13 */ + _CONTROL, /* CTRL+T, 0x14 */ + _CONTROL, /* CTRL+U, 0x15 */ + _CONTROL, /* CTRL+V, 0x16 */ + _CONTROL, /* CTRL+W, 0x17 */ + _CONTROL, /* CTRL+X, 0x18 */ + _CONTROL, /* CTRL+Y, 0x19 */ + _CONTROL, /* CTRL+Z, 0x1a */ + _CONTROL, /* CTRL+[, 0x1b */ + _CONTROL, /* CTRL+\, 0x1c */ + _CONTROL, /* CTRL+], 0x1d */ + _CONTROL, /* CTRL+^, 0x1e */ + _CONTROL, /* CTRL+_, 0x1f */ + _SPACE | _BLANK, /* ` ', 0x20 */ + _PUNCT, /* `!', 0x21 */ + _PUNCT, /* 0x22 */ + _PUNCT, /* `#', 0x23 */ + _PUNCT, /* `$', 0x24 */ + _PUNCT, /* `%', 0x25 */ + _PUNCT, /* `&', 0x26 */ + _PUNCT, /* 0x27 */ + _PUNCT, /* `(', 0x28 */ + _PUNCT, /* `)', 0x29 */ + _PUNCT, /* `*', 0x2a */ + _PUNCT, /* `+', 0x2b */ + _PUNCT, /* `,', 0x2c */ + _PUNCT, /* `-', 0x2d */ + _PUNCT, /* `.', 0x2e */ + _PUNCT, /* `/', 0x2f */ + _DIGIT | _HEX, /* `0', 0x30 */ + _DIGIT | _HEX, /* `1', 0x31 */ + _DIGIT | _HEX, /* `2', 0x32 */ + _DIGIT | _HEX, /* `3', 0x33 */ + _DIGIT | _HEX, /* `4', 0x34 */ + _DIGIT | _HEX, /* `5', 0x35 */ + _DIGIT | _HEX, /* `6', 0x36 */ + _DIGIT | _HEX, /* `7', 0x37 */ + _DIGIT | _HEX, /* `8', 0x38 */ + _DIGIT | _HEX, /* `9', 0x39 */ + _PUNCT, /* `:', 0x3a */ + _PUNCT, /* `;', 0x3b */ + _PUNCT, /* `<', 0x3c */ + _PUNCT, /* `=', 0x3d */ + _PUNCT, /* `>', 0x3e */ + _PUNCT, /* `?', 0x3f */ + _PUNCT, /* `@', 0x40 */ + _UPPER | _HEX, /* `A', 0x41 */ + _UPPER | _HEX, /* `B', 0x42 */ + _UPPER | _HEX, /* `C', 0x43 */ + _UPPER | _HEX, /* `D', 0x44 */ + _UPPER | _HEX, /* `E', 0x45 */ + _UPPER | _HEX, /* `F', 0x46 */ + _UPPER, /* `G', 0x47 */ + _UPPER, /* `H', 0x48 */ + _UPPER, /* `I', 0x49 */ + _UPPER, /* `J', 0x4a */ + _UPPER, /* `K', 0x4b */ + _UPPER, /* `L', 0x4c */ + _UPPER, /* `M', 0x4d */ + _UPPER, /* `N', 0x4e */ + _UPPER, /* `O', 0x4f */ + _UPPER, /* `P', 0x50 */ + _UPPER, /* `Q', 0x51 */ + _UPPER, /* `R', 0x52 */ + _UPPER, /* `S', 0x53 */ + _UPPER, /* `T', 0x54 */ + _UPPER, /* `U', 0x55 */ + _UPPER, /* `V', 0x56 */ + _UPPER, /* `W', 0x57 */ + _UPPER, /* `X', 0x58 */ + _UPPER, /* `Y', 0x59 */ + _UPPER, /* `Z', 0x5a */ + _PUNCT, /* `[', 0x5b */ + _PUNCT, /* 0x5c */ + _PUNCT, /* `]', 0x5d */ + _PUNCT, /* `^', 0x5e */ + _PUNCT, /* `_', 0x5f */ + _PUNCT, /* 0x60 */ + _LOWER | _HEX, /* `a', 0x61 */ + _LOWER | _HEX, /* `b', 0x62 */ + _LOWER | _HEX, /* `c', 0x63 */ + _LOWER | _HEX, /* `d', 0x64 */ + _LOWER | _HEX, /* `e', 0x65 */ + _LOWER | _HEX, /* `f', 0x66 */ + _LOWER, /* `g', 0x67 */ + _LOWER, /* `h', 0x68 */ + _LOWER, /* `i', 0x69 */ + _LOWER, /* `j', 0x6a */ + _LOWER, /* `k', 0x6b */ + _LOWER, /* `l', 0x6c */ + _LOWER, /* `m', 0x6d */ + _LOWER, /* `n', 0x6e */ + _LOWER, /* `o', 0x6f */ + _LOWER, /* `p', 0x70 */ + _LOWER, /* `q', 0x71 */ + _LOWER, /* `r', 0x72 */ + _LOWER, /* `s', 0x73 */ + _LOWER, /* `t', 0x74 */ + _LOWER, /* `u', 0x75 */ + _LOWER, /* `v', 0x76 */ + _LOWER, /* `w', 0x77 */ + _LOWER, /* `x', 0x78 */ + _LOWER, /* `y', 0x79 */ + _LOWER, /* `z', 0x7a */ + _PUNCT, /* `{', 0x7b */ + _PUNCT, /* `|', 0x7c */ + _PUNCT, /* `}', 0x7d */ + _PUNCT, /* `~', 0x7e */ + _CONTROL, /* 0x7f */ + 0, /* 0x80 */ + 0, /* 0x81 */ + 0, /* 0x82 */ + 0, /* 0x83 */ + 0, /* 0x84 */ + 0, /* 0x85 */ + 0, /* 0x86 */ + 0, /* 0x87 */ + 0, /* 0x88 */ + 0, /* 0x89 */ + 0, /* 0x8a */ + 0, /* 0x8b */ + 0, /* 0x8c */ + 0, /* 0x8d */ + 0, /* 0x8e */ + 0, /* 0x8f */ + 0, /* 0x90 */ + 0, /* 0x91 */ + 0, /* 0x92 */ + 0, /* 0x93 */ + 0, /* 0x94 */ + 0, /* 0x95 */ + 0, /* 0x96 */ + 0, /* 0x97 */ + 0, /* 0x98 */ + 0, /* 0x99 */ + 0, /* 0x9a */ + 0, /* 0x9b */ + 0, /* 0x9c */ + 0, /* 0x9d */ + 0, /* 0x9e */ + 0, /* 0x9f */ + 0, /* 0xa0 */ + 0, /* 0xa1 */ + 0, /* 0xa2 */ + 0, /* 0xa3 */ + 0, /* 0xa4 */ + 0, /* 0xa5 */ + 0, /* 0xa6 */ + 0, /* 0xa7 */ + 0, /* 0xa8 */ + 0, /* 0xa9 */ + 0, /* 0xaa */ + 0, /* 0xab */ + 0, /* 0xac */ + 0, /* 0xad */ + 0, /* 0xae */ + 0, /* 0xaf */ + 0, /* 0xb0 */ + 0, /* 0xb1 */ + 0, /* 0xb2 */ + 0, /* 0xb3 */ + 0, /* 0xb4 */ + 0, /* 0xb5 */ + 0, /* 0xb6 */ + 0, /* 0xb7 */ + 0, /* 0xb8 */ + 0, /* 0xb9 */ + 0, /* 0xba */ + 0, /* 0xbb */ + 0, /* 0xbc */ + 0, /* 0xbd */ + 0, /* 0xbe */ + 0, /* 0xbf */ + 0, /* 0xc0 */ + 0, /* 0xc1 */ + 0, /* 0xc2 */ + 0, /* 0xc3 */ + 0, /* 0xc4 */ + 0, /* 0xc5 */ + 0, /* 0xc6 */ + 0, /* 0xc7 */ + 0, /* 0xc8 */ + 0, /* 0xc9 */ + 0, /* 0xca */ + 0, /* 0xcb */ + 0, /* 0xcc */ + 0, /* 0xcd */ + 0, /* 0xce */ + 0, /* 0xcf */ + 0, /* 0xd0 */ + 0, /* 0xd1 */ + 0, /* 0xd2 */ + 0, /* 0xd3 */ + 0, /* 0xd4 */ + 0, /* 0xd5 */ + 0, /* 0xd6 */ + 0, /* 0xd7 */ + 0, /* 0xd8 */ + 0, /* 0xd9 */ + 0, /* 0xda */ + 0, /* 0xdb */ + 0, /* 0xdc */ + 0, /* 0xdd */ + 0, /* 0xde */ + 0, /* 0xdf */ + 0, /* 0xe0 */ + 0, /* 0xe1 */ + 0, /* 0xe2 */ + 0, /* 0xe3 */ + 0, /* 0xe4 */ + 0, /* 0xe5 */ + 0, /* 0xe6 */ + 0, /* 0xe7 */ + 0, /* 0xe8 */ + 0, /* 0xe9 */ + 0, /* 0xea */ + 0, /* 0xeb */ + 0, /* 0xec */ + 0, /* 0xed */ + 0, /* 0xee */ + 0, /* 0xef */ + 0, /* 0xf0 */ + 0, /* 0xf1 */ + 0, /* 0xf2 */ + 0, /* 0xf3 */ + 0, /* 0xf4 */ + 0, /* 0xf5 */ + 0, /* 0xf6 */ + 0, /* 0xf7 */ + 0, /* 0xf8 */ + 0, /* 0xf9 */ + 0, /* 0xfa */ + 0, /* 0xfb */ + 0, /* 0xfc */ + 0, /* 0xfd */ + 0, /* 0xfe */ + 0 /* 0xff */ +}; + +/* EOF */ diff --git a/lib/crtdll/ctype/isalnum.c b/lib/crtdll/ctype/isalnum.c index 66a591b..cf741ce 100644 --- a/lib/crtdll/ctype/isalnum.c +++ b/lib/crtdll/ctype/isalnum.c @@ -7,17 +7,17 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include +#include #undef isalnum int isalnum(int c) { - return _isctype(c,_ALPHA | _DIGIT); + return _isctype(c, _ALPHA | _DIGIT); } #undef iswalnum int iswalnum(wint_t c) { - return iswctype(c,_ALPHA | _DIGIT); + return iswctype(c, _ALPHA | _DIGIT); } diff --git a/lib/crtdll/ctype/isalpha.c b/lib/crtdll/ctype/isalpha.c index 3e0c496..fecee0a 100644 --- a/lib/crtdll/ctype/isalpha.c +++ b/lib/crtdll/ctype/isalpha.c @@ -1,23 +1,25 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/putch.c + * FILE: lib/crtdll/ctype/isalpha.c * PURPOSE: Checks if a character is alphanumeric * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 28/12/98: Created */ -#include +#include + #undef isalpha + int isalpha(int c) { - return _isctype(c,_ALPHA); + return _isctype(c, _ALPHA); } #undef iswalpha int iswalpha(wint_t c) { - return iswctype(c,_ALPHA); + return iswctype(c, _ALPHA); } diff --git a/lib/crtdll/ctype/isascii.c b/lib/crtdll/ctype/isascii.c index 4ef4daf..5536f02 100644 --- a/lib/crtdll/ctype/isascii.c +++ b/lib/crtdll/ctype/isascii.c @@ -1,29 +1,21 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/getch.c - * PURPOSE: Writes a character to stdout + * FILE: lib/crtdll/ctype/isascii.c + * PURPOSE: Checks if a character is ascii * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 28/12/98: Created */ -#include +#include int __isascii(int c) { - return (!((c)&(~0x7f))) ; + return (!((c)&(~0x7f))); } int iswascii(wint_t c) { - return __isascii(c); + return __isascii(c); } - - - - - - - - diff --git a/lib/crtdll/ctype/iscntrl.c b/lib/crtdll/ctype/iscntrl.c index 4eef7f8..cd51e8d 100644 --- a/lib/crtdll/ctype/iscntrl.c +++ b/lib/crtdll/ctype/iscntrl.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef iscntrl int iscntrl(int c) { - return _isctype(c,_CONTROL); + return _isctype(c, _CONTROL); } #undef iswcntrl int iswcntrl(wint_t c) { - return iswctype(c,_CONTROL); + return iswctype(c, _CONTROL); } diff --git a/lib/crtdll/ctype/iscsym.c b/lib/crtdll/ctype/iscsym.c index 4f1c1d6..40352dc 100644 --- a/lib/crtdll/ctype/iscsym.c +++ b/lib/crtdll/ctype/iscsym.c @@ -7,8 +7,8 @@ * UPDATE HISTORY: * 28/12/98: Created */ +#include -#include int __iscsymf(int c) { diff --git a/lib/crtdll/ctype/isctype.c b/lib/crtdll/ctype/isctype.c index 19db72a..dfe8229 100644 --- a/lib/crtdll/ctype/isctype.c +++ b/lib/crtdll/ctype/isctype.c @@ -1,270 +1,14 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include -unsigned short _ctype[] = { - 0, /* , 0xFFFF */ - _CONTROL, /* CTRL+@, 0x00 */ - _CONTROL, /* CTRL+A, 0x01 */ - _CONTROL, /* CTRL+B, 0x02 */ - _CONTROL, /* CTRL+C, 0x03 */ - _CONTROL, /* CTRL+D, 0x04 */ - _CONTROL, /* CTRL+E, 0x05 */ - _CONTROL, /* CTRL+F, 0x06 */ - _CONTROL, /* CTRL+G, 0x07 */ - _CONTROL, /* CTRL+H, 0x08 */ - _CONTROL | _SPACE, /* CTRL+I, 0x09 */ - _CONTROL | _SPACE, /* CTRL+J, 0x0a */ - _CONTROL | _SPACE, /* CTRL+K, 0x0b */ - _CONTROL | _SPACE, /* CTRL+L, 0x0c */ - _CONTROL | _SPACE, /* CTRL+M, 0x0d */ - _CONTROL, /* CTRL+N, 0x0e */ - _CONTROL, /* CTRL+O, 0x0f */ - _CONTROL, /* CTRL+P, 0x10 */ - _CONTROL, /* CTRL+Q, 0x11 */ - _CONTROL, /* CTRL+R, 0x12 */ - _CONTROL, /* CTRL+S, 0x13 */ - _CONTROL, /* CTRL+T, 0x14 */ - _CONTROL, /* CTRL+U, 0x15 */ - _CONTROL, /* CTRL+V, 0x16 */ - _CONTROL, /* CTRL+W, 0x17 */ - _CONTROL, /* CTRL+X, 0x18 */ - _CONTROL, /* CTRL+Y, 0x19 */ - _CONTROL, /* CTRL+Z, 0x1a */ - _CONTROL, /* CTRL+[, 0x1b */ - _CONTROL, /* CTRL+\, 0x1c */ - _CONTROL, /* CTRL+], 0x1d */ - _CONTROL, /* CTRL+^, 0x1e */ - _CONTROL, /* CTRL+_, 0x1f */ - _SPACE | _BLANK, /* ` ', 0x20 */ - _PUNCT, /* `!', 0x21 */ - _PUNCT, /* 0x22 */ - _PUNCT, /* `#', 0x23 */ - _PUNCT, /* `$', 0x24 */ - _PUNCT, /* `%', 0x25 */ - _PUNCT, /* `&', 0x26 */ - _PUNCT, /* 0x27 */ - _PUNCT, /* `(', 0x28 */ - _PUNCT, /* `)', 0x29 */ - _PUNCT, /* `*', 0x2a */ - _PUNCT, /* `+', 0x2b */ - _PUNCT, /* `,', 0x2c */ - _PUNCT, /* `-', 0x2d */ - _PUNCT, /* `.', 0x2e */ - _PUNCT, /* `/', 0x2f */ - _DIGIT | _HEX, /* `0', 0x30 */ - _DIGIT | _HEX, /* `1', 0x31 */ - _DIGIT | _HEX, /* `2', 0x32 */ - _DIGIT | _HEX, /* `3', 0x33 */ - _DIGIT | _HEX, /* `4', 0x34 */ - _DIGIT | _HEX, /* `5', 0x35 */ - _DIGIT | _HEX, /* `6', 0x36 */ - _DIGIT | _HEX, /* `7', 0x37 */ - _DIGIT | _HEX, /* `8', 0x38 */ - _DIGIT | _HEX, /* `9', 0x39 */ - _PUNCT, /* `:', 0x3a */ - _PUNCT, /* `;', 0x3b */ - _PUNCT, /* `<', 0x3c */ - _PUNCT, /* `=', 0x3d */ - _PUNCT, /* `>', 0x3e */ - _PUNCT, /* `?', 0x3f */ - _PUNCT, /* `@', 0x40 */ - _UPPER | _HEX, /* `A', 0x41 */ - _UPPER | _HEX, /* `B', 0x42 */ - _UPPER | _HEX, /* `C', 0x43 */ - _UPPER | _HEX, /* `D', 0x44 */ - _UPPER | _HEX, /* `E', 0x45 */ - _UPPER | _HEX, /* `F', 0x46 */ - _UPPER, /* `G', 0x47 */ - _UPPER, /* `H', 0x48 */ - _UPPER, /* `I', 0x49 */ - _UPPER, /* `J', 0x4a */ - _UPPER, /* `K', 0x4b */ - _UPPER, /* `L', 0x4c */ - _UPPER, /* `M', 0x4d */ - _UPPER, /* `N', 0x4e */ - _UPPER, /* `O', 0x4f */ - _UPPER, /* `P', 0x50 */ - _UPPER, /* `Q', 0x51 */ - _UPPER, /* `R', 0x52 */ - _UPPER, /* `S', 0x53 */ - _UPPER, /* `T', 0x54 */ - _UPPER, /* `U', 0x55 */ - _UPPER, /* `V', 0x56 */ - _UPPER, /* `W', 0x57 */ - _UPPER, /* `X', 0x58 */ - _UPPER, /* `Y', 0x59 */ - _UPPER, /* `Z', 0x5a */ - _PUNCT, /* `[', 0x5b */ - _PUNCT, /* 0x5c */ - _PUNCT, /* `]', 0x5d */ - _PUNCT, /* `^', 0x5e */ - _PUNCT, /* `_', 0x5f */ - _PUNCT, /* 0x60 */ - _LOWER | _HEX, /* `a', 0x61 */ - _LOWER | _HEX, /* `b', 0x62 */ - _LOWER | _HEX, /* `c', 0x63 */ - _LOWER | _HEX, /* `d', 0x64 */ - _LOWER | _HEX, /* `e', 0x65 */ - _LOWER | _HEX, /* `f', 0x66 */ - _LOWER, /* `g', 0x67 */ - _LOWER, /* `h', 0x68 */ - _LOWER, /* `i', 0x69 */ - _LOWER, /* `j', 0x6a */ - _LOWER, /* `k', 0x6b */ - _LOWER, /* `l', 0x6c */ - _LOWER, /* `m', 0x6d */ - _LOWER, /* `n', 0x6e */ - _LOWER, /* `o', 0x6f */ - _LOWER, /* `p', 0x70 */ - _LOWER, /* `q', 0x71 */ - _LOWER, /* `r', 0x72 */ - _LOWER, /* `s', 0x73 */ - _LOWER, /* `t', 0x74 */ - _LOWER, /* `u', 0x75 */ - _LOWER, /* `v', 0x76 */ - _LOWER, /* `w', 0x77 */ - _LOWER, /* `x', 0x78 */ - _LOWER, /* `y', 0x79 */ - _LOWER, /* `z', 0x7a */ - _PUNCT, /* `{', 0x7b */ - _PUNCT, /* `|', 0x7c */ - _PUNCT, /* `}', 0x7d */ - _PUNCT, /* `~', 0x7e */ - _CONTROL, /* 0x7f */ - 0, /* 0x80 */ - 0, /* 0x81 */ - 0, /* 0x82 */ - 0, /* 0x83 */ - 0, /* 0x84 */ - 0, /* 0x85 */ - 0, /* 0x86 */ - 0, /* 0x87 */ - 0, /* 0x88 */ - 0, /* 0x89 */ - 0, /* 0x8a */ - 0, /* 0x8b */ - 0, /* 0x8c */ - 0, /* 0x8d */ - 0, /* 0x8e */ - 0, /* 0x8f */ - 0, /* 0x90 */ - 0, /* 0x91 */ - 0, /* 0x92 */ - 0, /* 0x93 */ - 0, /* 0x94 */ - 0, /* 0x95 */ - 0, /* 0x96 */ - 0, /* 0x97 */ - 0, /* 0x98 */ - 0, /* 0x99 */ - 0, /* 0x9a */ - 0, /* 0x9b */ - 0, /* 0x9c */ - 0, /* 0x9d */ - 0, /* 0x9e */ - 0, /* 0x9f */ - 0, /* 0xa0 */ - 0, /* 0xa1 */ - 0, /* 0xa2 */ - 0, /* 0xa3 */ - 0, /* 0xa4 */ - 0, /* 0xa5 */ - 0, /* 0xa6 */ - 0, /* 0xa7 */ - 0, /* 0xa8 */ - 0, /* 0xa9 */ - 0, /* 0xaa */ - 0, /* 0xab */ - 0, /* 0xac */ - 0, /* 0xad */ - 0, /* 0xae */ - 0, /* 0xaf */ - 0, /* 0xb0 */ - 0, /* 0xb1 */ - 0, /* 0xb2 */ - 0, /* 0xb3 */ - 0, /* 0xb4 */ - 0, /* 0xb5 */ - 0, /* 0xb6 */ - 0, /* 0xb7 */ - 0, /* 0xb8 */ - 0, /* 0xb9 */ - 0, /* 0xba */ - 0, /* 0xbb */ - 0, /* 0xbc */ - 0, /* 0xbd */ - 0, /* 0xbe */ - 0, /* 0xbf */ - 0, /* 0xc0 */ - 0, /* 0xc1 */ - 0, /* 0xc2 */ - 0, /* 0xc3 */ - 0, /* 0xc4 */ - 0, /* 0xc5 */ - 0, /* 0xc6 */ - 0, /* 0xc7 */ - 0, /* 0xc8 */ - 0, /* 0xc9 */ - 0, /* 0xca */ - 0, /* 0xcb */ - 0, /* 0xcc */ - 0, /* 0xcd */ - 0, /* 0xce */ - 0, /* 0xcf */ - 0, /* 0xd0 */ - 0, /* 0xd1 */ - 0, /* 0xd2 */ - 0, /* 0xd3 */ - 0, /* 0xd4 */ - 0, /* 0xd5 */ - 0, /* 0xd6 */ - 0, /* 0xd7 */ - 0, /* 0xd8 */ - 0, /* 0xd9 */ - 0, /* 0xda */ - 0, /* 0xdb */ - 0, /* 0xdc */ - 0, /* 0xdd */ - 0, /* 0xde */ - 0, /* 0xdf */ - 0, /* 0xe0 */ - 0, /* 0xe1 */ - 0, /* 0xe2 */ - 0, /* 0xe3 */ - 0, /* 0xe4 */ - 0, /* 0xe5 */ - 0, /* 0xe6 */ - 0, /* 0xe7 */ - 0, /* 0xe8 */ - 0, /* 0xe9 */ - 0, /* 0xea */ - 0, /* 0xeb */ - 0, /* 0xec */ - 0, /* 0xed */ - 0, /* 0xee */ - 0, /* 0xef */ - 0, /* 0xf0 */ - 0, /* 0xf1 */ - 0, /* 0xf2 */ - 0, /* 0xf3 */ - 0, /* 0xf4 */ - 0, /* 0xf5 */ - 0, /* 0xf6 */ - 0, /* 0xf7 */ - 0, /* 0xf8 */ - 0, /* 0xf9 */ - 0, /* 0xfa */ - 0, /* 0xfb */ - 0, /* 0xfc */ - 0, /* 0xfd */ - 0, /* 0xfe */ - 0 /* 0xff */ -}; + +extern unsigned short _ctype[]; unsigned short *_pctype_dll = _ctype + 1; unsigned short *_pwctype_dll = _ctype + 1; -int _isctype (unsigned int c, int ctypeFlags) + +int _isctype(unsigned int c, int ctypeFlags) { return (_pctype_dll[(unsigned char)(c & 0xFF)] & ctypeFlags); } diff --git a/lib/crtdll/ctype/isdigit.c b/lib/crtdll/ctype/isdigit.c index 93afd37..e84881d 100644 --- a/lib/crtdll/ctype/isdigit.c +++ b/lib/crtdll/ctype/isdigit.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef isdigit int isdigit(int c) { - return _isctype(c,_DIGIT); + return _isctype(c, _DIGIT); } #undef iswdigit int iswdigit(wint_t c) { - return iswctype(c,_DIGIT); + return iswctype(c, _DIGIT); } diff --git a/lib/crtdll/ctype/isgraph.c b/lib/crtdll/ctype/isgraph.c index ead804c..39c500c 100644 --- a/lib/crtdll/ctype/isgraph.c +++ b/lib/crtdll/ctype/isgraph.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include #undef isgraph int isgraph(int c) diff --git a/lib/crtdll/ctype/islower.c b/lib/crtdll/ctype/islower.c index 4ce38e1..34cc31a 100644 --- a/lib/crtdll/ctype/islower.c +++ b/lib/crtdll/ctype/islower.c @@ -1,13 +1,14 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef islower int islower(int c) { - return _isctype(c,_LOWER); + return _isctype(c, _LOWER); } int iswlower(wint_t c) { - return iswctype(c,_LOWER); + return iswctype(c, _LOWER); } diff --git a/lib/crtdll/ctype/isprint.c b/lib/crtdll/ctype/isprint.c index a75435d..8c6dbf5 100644 --- a/lib/crtdll/ctype/isprint.c +++ b/lib/crtdll/ctype/isprint.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include #undef isprint int isprint(int c) diff --git a/lib/crtdll/ctype/ispunct.c b/lib/crtdll/ctype/ispunct.c index 57f0ab1..5a06ae4 100644 --- a/lib/crtdll/ctype/ispunct.c +++ b/lib/crtdll/ctype/ispunct.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef ispunct int ispunct(int c) { - return _isctype(c,_PUNCT); + return _isctype(c, _PUNCT); } #undef iswpunct int iswpunct(wint_t c) { - return iswctype(c,_PUNCT); + return iswctype(c, _PUNCT); } diff --git a/lib/crtdll/ctype/isspace.c b/lib/crtdll/ctype/isspace.c index 0e90ae7..723b8b0 100644 --- a/lib/crtdll/ctype/isspace.c +++ b/lib/crtdll/ctype/isspace.c @@ -7,7 +7,9 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include + +#include + #undef isspace int isspace(int c) diff --git a/lib/crtdll/ctype/isupper.c b/lib/crtdll/ctype/isupper.c index d0d95e0..a7e67b2 100644 --- a/lib/crtdll/ctype/isupper.c +++ b/lib/crtdll/ctype/isupper.c @@ -1,13 +1,14 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef isupper int isupper(int c) { - return _isctype(c,_UPPER); + return _isctype(c, _UPPER); } int iswupper(wint_t c) { - return iswctype(c,_UPPER); + return iswctype(c, _UPPER); } diff --git a/lib/crtdll/ctype/isxdigit.c b/lib/crtdll/ctype/isxdigit.c index 02c8c63..63f8464 100644 --- a/lib/crtdll/ctype/isxdigit.c +++ b/lib/crtdll/ctype/isxdigit.c @@ -1,15 +1,16 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include + #undef isxdigit int isxdigit(int c) { - return _isctype(c,_HEX); + return _isctype(c, _HEX); } #undef iswxdigit int iswxdigit(wint_t c) { - return iswctype(c,_HEX); + return iswctype(c, _HEX); } diff --git a/lib/crtdll/ctype/toascii.c b/lib/crtdll/ctype/toascii.c index 86d8ff3..f26d5af 100644 --- a/lib/crtdll/ctype/toascii.c +++ b/lib/crtdll/ctype/toascii.c @@ -1,9 +1,9 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include int __toascii(int c) { - return ((unsigned)(c) & 0x7F ); + return((unsigned)(c) & 0x7F); } diff --git a/lib/crtdll/ctype/tolower.c b/lib/crtdll/ctype/tolower.c index e3152d1..e2c188c 100644 --- a/lib/crtdll/ctype/tolower.c +++ b/lib/crtdll/ctype/tolower.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include #undef tolower int tolower(int c) @@ -24,12 +24,13 @@ int _tolower(int c) return(c); } +/* wchar_t _towlower(wchar_t c) { if (iswctype (c, _UPPER)) return (c - (L'A' - L'a')); return(c); } - +*/ diff --git a/lib/crtdll/ctype/toupper.c b/lib/crtdll/ctype/toupper.c index e0c8aa0..666cee2 100644 --- a/lib/crtdll/ctype/toupper.c +++ b/lib/crtdll/ctype/toupper.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include + #undef toupper int toupper(int c) @@ -25,9 +25,12 @@ int _toupper(int c) return(c); } +/* wchar_t _towupper(wchar_t c) { if (iswctype (c, _LOWER)) return (c + (L'A' - L'a')); return(c); } +*/ + diff --git a/lib/crtdll/direct/chdir.c b/lib/crtdll/direct/chdir.c index 19a4a9f..eb8061d 100644 --- a/lib/crtdll/direct/chdir.c +++ b/lib/crtdll/direct/chdir.c @@ -1,18 +1,13 @@ #include -#include -#include +#include +#include - -int _chdir( const char *_path ) +int _chdir(const char* _path) { - if ( _path[1] == ':') - _chdrive(tolower(_path[0] - 'a')+1); - if ( !SetCurrentDirectoryA((char *)_path) ) - return -1; - - return 0; + if (_path[1] == ':') + _chdrive(tolower(_path[0] - 'a')+1); + if (!SetCurrentDirectoryA((char*)_path)) + return -1; + return 0; } - - - diff --git a/lib/crtdll/direct/chdrive.c b/lib/crtdll/direct/chdrive.c index 84d04c6..1522904 100644 --- a/lib/crtdll/direct/chdrive.c +++ b/lib/crtdll/direct/chdrive.c @@ -1,26 +1,24 @@ -#include -#include -#include #include +#include +#include +#include -int cur_drive = 0; +int cur_drive = 0; -int _chdrive( int drive ) +int _chdrive(int drive) { - char d[3]; - if (!( drive >= 1 && drive <= 26 )) - return -1; - - if ( cur_drive != drive ) { - cur_drive = drive; - d[0] = toupper(cur_drive + '@'); - d[1] = ':'; - d[2] = 0; - SetCurrentDirectoryA(d); - } - + char d[3]; - return 0; + if (!( drive >= 1 && drive <= 26)) + return -1; + if (cur_drive != drive) { + cur_drive = drive; + d[0] = toupper(cur_drive + '@'); + d[1] = ':'; + d[2] = 0; + SetCurrentDirectoryA(d); + } + return 0; } diff --git a/lib/crtdll/direct/getcwd.c b/lib/crtdll/direct/getcwd.c index 65f8985..67638b9 100644 --- a/lib/crtdll/direct/getcwd.c +++ b/lib/crtdll/direct/getcwd.c @@ -1,25 +1,22 @@ #include -#include -#include +#include +#include - -char *_getcwd( char *buffer, int maxlen ) +char *_getcwd(char* buffer, int maxlen) { - char *cwd; - int len; - if ( buffer == NULL ) { - cwd = malloc(MAX_PATH); - len = MAX_PATH; - } - else { - cwd = buffer; - len = maxlen; - } - - if ( GetCurrentDirectoryA(len,cwd) == 0 ) - return NULL; + char *cwd; + int len; - return cwd; + if (buffer == NULL) { + cwd = malloc(MAX_PATH); + len = MAX_PATH; + } else { + cwd = buffer; + len = maxlen; + } + if (GetCurrentDirectoryA(len, cwd) == 0) { + return NULL; + } + return cwd; } - diff --git a/lib/crtdll/direct/getdcwd.c b/lib/crtdll/direct/getdcwd.c index 0b2a8b5..bbf79fd 100644 --- a/lib/crtdll/direct/getdcwd.c +++ b/lib/crtdll/direct/getdcwd.c @@ -1,23 +1,19 @@ #include -#include +#include -char* _getdcwd (int nDrive, char* caBuffer, int nBufLen) +char* _getdcwd(int nDrive, char* caBuffer, int nBufLen) { - int i =0; - int dr = _getdrive(); - - if ( nDrive < 1 || nDrive > 26 ) - return NULL; - - if ( dr != nDrive ) - _chdrive(nDrive); - - i = GetCurrentDirectoryA(nBufLen,caBuffer); - if ( i == nBufLen ) - return NULL; - - if ( dr != nDrive ) - _chdrive(dr); - - return caBuffer; + int i =0; + int dr = _getdrive(); + + if (nDrive < 1 || nDrive > 26) + return NULL; + if (dr != nDrive) + _chdrive(nDrive); + i = GetCurrentDirectoryA(nBufLen, caBuffer); + if (i == nBufLen) + return NULL; + if (dr != nDrive) + _chdrive(dr); + return caBuffer; } diff --git a/lib/crtdll/direct/getdfree.c b/lib/crtdll/direct/getdfree.c index 766362b..cd90b43 100644 --- a/lib/crtdll/direct/getdfree.c +++ b/lib/crtdll/direct/getdfree.c @@ -1,20 +1,20 @@ -#include #include -#include +#include +#include -unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace) +unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t* _diskspace) { - char RootPathName[10]; - RootPathName[0] = toupper(_drive +'@'); - RootPathName[1] = ':'; - RootPathName[2] = '\\'; - RootPathName[3] = 0; - if ( _diskspace == NULL ) - return 0; + char RootPathName[10]; - if ( !GetDiskFreeSpaceA(RootPathName,(LPDWORD)&_diskspace->sectors_per_cluster,(LPDWORD)&_diskspace->bytes_per_sector, - (LPDWORD )&_diskspace->avail_clusters,(LPDWORD )&_diskspace->total_clusters ) ) - return 0; - return _diskspace->avail_clusters; + RootPathName[0] = toupper(_drive +'@'); + RootPathName[1] = ':'; + RootPathName[2] = '\\'; + RootPathName[3] = 0; + if (_diskspace == NULL) + return 0; + if (!GetDiskFreeSpaceA(RootPathName,(LPDWORD)&_diskspace->sectors_per_cluster,(LPDWORD)&_diskspace->bytes_per_sector, + (LPDWORD )&_diskspace->avail_clusters,(LPDWORD )&_diskspace->total_clusters)) + return 0; + return _diskspace->avail_clusters; } diff --git a/lib/crtdll/direct/getdrive.c b/lib/crtdll/direct/getdrive.c index a57e9ba..5638c65 100644 --- a/lib/crtdll/direct/getdrive.c +++ b/lib/crtdll/direct/getdrive.c @@ -1,26 +1,24 @@ -#include -#include #include - -extern int cur_drive; +#include +#include +extern int cur_drive; -int _getdrive( void ) +int _getdrive(void) { - char Buffer[MAX_PATH]; + char Buffer[MAX_PATH]; - if ( cur_drive == 0 ) { - GetCurrentDirectoryA(MAX_PATH,Buffer); - cur_drive = toupper(Buffer[0] - '@'); - } - - return cur_drive; + if (cur_drive == 0) { + GetCurrentDirectoryA(MAX_PATH, Buffer); + cur_drive = toupper(Buffer[0] - '@'); + } + return cur_drive; } unsigned long _getdrives(void) { //fixme get logical drives //return GetLogicalDrives(); - return 5; // drive A and C + return 5; // drive A and C } diff --git a/lib/crtdll/direct/mkdir.c b/lib/crtdll/direct/mkdir.c index 19191f8..e568b9c 100644 --- a/lib/crtdll/direct/mkdir.c +++ b/lib/crtdll/direct/mkdir.c @@ -1,10 +1,10 @@ -#include #include +#include -int _mkdir( const char *_path ) +int _mkdir(const char* _path) { - if (!CreateDirectoryA(_path,NULL)) - return -1; - return 0; + if (!CreateDirectoryA(_path, NULL)) + return -1; + return 0; } diff --git a/lib/crtdll/direct/rmdir.c b/lib/crtdll/direct/rmdir.c index c6736de..a057acd 100644 --- a/lib/crtdll/direct/rmdir.c +++ b/lib/crtdll/direct/rmdir.c @@ -1,11 +1,10 @@ -#include #include +#include - -int _rmdir( const char *_path ) +int _rmdir(const char* _path) { - if (!RemoveDirectoryA(_path)) - return -1; - return 0; + if (!RemoveDirectoryA(_path)) + return -1; + return 0; } diff --git a/lib/crtdll/dirent/dirent.c b/lib/crtdll/dirent/dirent.c index 018eb1d..9374c95 100644 --- a/lib/crtdll/dirent/dirent.c +++ b/lib/crtdll/dirent/dirent.c @@ -15,15 +15,15 @@ * */ -#include -/* #include */ -#include -#include -#include -#include -#include - -#include +#include +/* #include */ +#include +#include +#include +#include +#include + +#include #define SUFFIX "*" #define SLASH "\\" diff --git a/lib/crtdll/except/abnorter.c b/lib/crtdll/except/abnorter.c index 2efd11a..bced295 100644 --- a/lib/crtdll/except/abnorter.c +++ b/lib/crtdll/except/abnorter.c @@ -1,7 +1,13 @@ #include + +#ifdef __GNUC__ + int _abnormal_termination(void) { printf("Abnormal Termination\n"); // return AbnormalTermination(); } + +#else +#endif diff --git a/lib/crtdll/except/exhand2.c b/lib/crtdll/except/exhand2.c index be66fb4..875b5da 100644 --- a/lib/crtdll/except/exhand2.c +++ b/lib/crtdll/except/exhand2.c @@ -1,11 +1,28 @@ #include +#include + + +#ifdef __GNUC__ +#else +#endif + +ULONG DbgPrint(PCH Format, ...) +{ + return 0; +} + +VOID STDCALL +MsvcrtDebug(ULONG Value) +{ + //DbgPrint("MsvcrtDebug 0x%.08x\n", Value); +} + EXCEPTION_DISPOSITION _except_handler2( -struct _EXCEPTION_RECORD *ExceptionRecord, -void *Frame, -struct _CONTEXT *ContextRecord, -void *DispatcherContext) + struct _EXCEPTION_RECORD* ExceptionRecord, void* Frame, + struct _CONTEXT *ContextRecord, void* DispatcherContext) { - printf("exception handler\n"); + //printf("_except_handler2()\n"); + return 0; } diff --git a/lib/crtdll/except/matherr.c b/lib/crtdll/except/matherr.c index e921e84..01de05c 100644 --- a/lib/crtdll/except/matherr.c +++ b/lib/crtdll/except/matherr.c @@ -1,22 +1,36 @@ +#include +#include + + struct _exception { - int type; - char *name; - double arg1; - double arg2; - double retval; - } ; - -int _matherr(struct _exception *e) + int type; + char* name; + double arg1; + double arg2; + double retval; +} ; + + +int _matherr(struct _exception* e) { return 0; } + + +// not exported by NTDLL +void __setusermatherr(int (*handler)(struct _exception*)) +{ + +} + + #define _FPIEEE_RECORD void int _fpieee_flt( - unsigned long exception_code, - struct _EXCEPTION_POINTERS *ExceptionPointer, - int (* handler)(_FPIEEE_RECORD *) + unsigned long exception_code, + struct _EXCEPTION_POINTERS* ExceptionPointer, + int (*handler)(_FPIEEE_RECORD*) ) { - return 0; + return 0; } diff --git a/lib/crtdll/float/chgsign.c b/lib/crtdll/float/chgsign.c index 589cc40..40aaac2 100644 --- a/lib/crtdll/float/chgsign.c +++ b/lib/crtdll/float/chgsign.c @@ -1,10 +1,12 @@ -#include -#include +#include +#include -double _chgsign( double __x ) + +double _chgsign(double __x) { - double_t *x = (double_t *)&x; - if ( x->sign == 1 ) + double_t* x = (double_t*)&x; + + if (x->sign == 1) x->sign = 0; else x->sign = 1; diff --git a/lib/crtdll/float/clearfp.c b/lib/crtdll/float/clearfp.c index e824752..38dfd6e 100644 --- a/lib/crtdll/float/clearfp.c +++ b/lib/crtdll/float/clearfp.c @@ -1,13 +1,14 @@ -#include +#include unsigned int _clearfp (void) { - unsigned short __res = _statusfp(); - +#ifdef __GNUC__ __asm__ __volatile__ ( "fclex \n\t" ); +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/crtdll/float/cntrlfp.c b/lib/crtdll/float/cntrlfp.c index 2ebdb0a..0019f84 100644 --- a/lib/crtdll/float/cntrlfp.c +++ b/lib/crtdll/float/cntrlfp.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include unsigned int _controlfp (unsigned int unNew, unsigned int unMask) { @@ -9,8 +9,8 @@ unsigned int _controlfp (unsigned int unNew, unsigned int unMask) unsigned int _control87 (unsigned int unNew, unsigned int unMask) { - register unsigned int __res; +#ifdef __GNUC__ __asm__ __volatile__ ( "pushl %%eax \n\t" /* make room on stack */ "fstcw (%%esp) \n\t" @@ -30,9 +30,8 @@ __asm__ __volatile__ ( "fldcw (%%esp) \n\t" "popl %%edx \n\t" - :"=r" (__res):"r" (unNew),"r" (unMask): "ax", "dx", "cx"); -/* :"=a" (__res):"c" (unNew),"d" (unMask):"ax", "dx", "cx"); */ - +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/crtdll/float/copysign.c b/lib/crtdll/float/copysign.c index a59c08a..444eed6 100644 --- a/lib/crtdll/float/copysign.c +++ b/lib/crtdll/float/copysign.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include double _copysign (double __d, double __s) { diff --git a/lib/crtdll/float/fpclass.c b/lib/crtdll/float/fpclass.c index 06c404f..512670a 100644 --- a/lib/crtdll/float/fpclass.c +++ b/lib/crtdll/float/fpclass.c @@ -1,6 +1,7 @@ -#include -#include -#include +#include +#include +#include + #define _FPCLASS_SNAN 0x0001 /* signaling NaN */ #define _FPCLASS_QNAN 0x0002 /* quiet NaN */ @@ -28,38 +29,35 @@ typedef int fpclass_t; fpclass_t _fpclass(double __d) { - double_t *d = (double_t *)&__d; + double_t* d = (double_t*)&__d; - if ( d->exponent == 0 ) { - if ( d->mantissah == 0 && d->mantissal == 0 ) { - if ( d->sign ==0 ) + if (d->exponent == 0) { + if (d->mantissah == 0 && d->mantissal == 0) { + if (d->sign ==0) return FP_NZERO; else return FP_PZERO; } else { - if ( d->sign ==0 ) + if (d->sign ==0) return FP_NDENORM; else return FP_PDENORM; } } - if (d->exponent == 0x7ff ) { - if ( d->mantissah == 0 && d->mantissal == 0 ) { - if ( d->sign ==0 ) + if (d->exponent == 0x7ff) { + if (d->mantissah == 0 && d->mantissal == 0) { + if (d->sign ==0) return FP_NINF; else return FP_PINF; } - else if ( d->mantissah == 0 && d->mantissal != 0 ) { + else if (d->mantissah == 0 && d->mantissal != 0) { return FP_QNAN; } - else if ( d->mantissah == 0 && d->mantissal != 0 ) { + else if (d->mantissah == 0 && d->mantissal != 0) { return FP_SNAN; } } - return 0; } - - diff --git a/lib/crtdll/float/fpreset.c b/lib/crtdll/float/fpreset.c index 6e8dd3d..46245b7 100644 --- a/lib/crtdll/float/fpreset.c +++ b/lib/crtdll/float/fpreset.c @@ -1,6 +1,7 @@ -#include +#include -void _fpreset (void) + +void _fpreset(void) { /* FIXME: This causes an exception */ // __asm__ __volatile__("fninit\n\t"); diff --git a/lib/crtdll/float/isnan.c b/lib/crtdll/float/isnan.c index d6f4ac0..3e64137 100644 --- a/lib/crtdll/float/isnan.c +++ b/lib/crtdll/float/isnan.c @@ -16,43 +16,40 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include +#include +#include +#include + int _isnan(double __x) { - double_t * x = (double_t *)&__x; - return ( x->exponent == 0x7ff && ( x->mantissah != 0 || x->mantissal != 0 )); + double_t* x = (double_t*)&__x; + return (x->exponent == 0x7ff && (x->mantissah != 0 || x->mantissal != 0)); } int _isnanl(long double __x) { - /* Intel's extended format has the normally implicit 1 explicit present. Sigh! */ - long_double_t * x = (long_double_t *)&__x; + long_double_t* x = (long_double_t*)&__x; /* IEEE 854 NaN's have the maximum possible exponent and a nonzero mantissa. */ return (( x->exponent == 0x7fff) - && ( (x->mantissah & 0x80000000) != 0) - && ( (x->mantissah & (unsigned int)0x7fffffff) != 0 || x->mantissal != 0 )); + && ((x->mantissah & 0x80000000) != 0) + && ((x->mantissah & (unsigned int)0x7fffffff) != 0 || x->mantissal != 0)); } - int _isinf(double __x) { - double_t * x = (double_t *)&__x; - return ( x->exponent == 0x7ff && ( x->mantissah == 0 && x->mantissal == 0 )); + double_t* x = (double_t*)&__x; + return (x->exponent == 0x7ff && (x->mantissah == 0 && x->mantissal == 0)); } - - -int _finite( double x ) +int _finite(double x) { return !_isinf(x); } @@ -62,16 +59,14 @@ int _isinfl(long double __x) /* Intel's extended format has the normally implicit 1 explicit present. Sigh! */ - long_double_t * x = (long_double_t *)&__x; + long_double_t* x = (long_double_t*)&__x; /* An IEEE 854 infinity has an exponent with the maximum possible value and a zero mantissa. */ - if ( x->exponent == 0x7fff && ( (x->mantissah == 0x80000000 ) && x->mantissal == 0 )) + if (x->exponent == 0x7fff && ((x->mantissah == 0x80000000) && x->mantissal == 0)) return x->sign ? -1 : 1; return 0; } - - diff --git a/lib/crtdll/float/logb.c b/lib/crtdll/float/logb.c index 8b89627..d71c654 100644 --- a/lib/crtdll/float/logb.c +++ b/lib/crtdll/float/logb.c @@ -18,14 +18,17 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -double _logb (double __x); +#include double _logb (double __x) { - register double __value, __junk; + register double __value; +#ifdef __GNUC__ + register double __junk; __asm __volatile__ ("fxtract\n\t" : "=t" (__junk), "=u" (__value) : "0" (__x)); - +#else +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/float/nafter.c b/lib/crtdll/float/nafter.c index 5e2a2ad..9237716 100644 --- a/lib/crtdll/float/nafter.c +++ b/lib/crtdll/float/nafter.c @@ -1,11 +1,12 @@ -#include +#include -double _nextafter( double x, double y ) + +double _nextafter(double x, double y) { - if ( x == y) + if (x == y) return x; - if ( isnan(x) || isnan(y) ) + if (isnan(x) || isnan(y)) return x; return x; diff --git a/lib/crtdll/float/scalb.c b/lib/crtdll/float/scalb.c index e035584..a2d1eac 100644 --- a/lib/crtdll/float/scalb.c +++ b/lib/crtdll/float/scalb.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include double _scalb( double __x, long e ) { @@ -8,5 +8,4 @@ double _scalb( double __x, long e ) x->exponent += e; return __x; - } diff --git a/lib/crtdll/float/statfp.c b/lib/crtdll/float/statfp.c index 5cfeabf..6792fd9 100644 --- a/lib/crtdll/float/statfp.c +++ b/lib/crtdll/float/statfp.c @@ -1,14 +1,16 @@ -#include +#include unsigned int _statusfp (void) { register unsigned short __res; - +#ifdef __GNUC__ __asm__ __volatile__ ( "fstsw %0 \n\t" // "movzwl %ax, %eax" :"=a" (__res) ); +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/crtdll/io/access.c b/lib/crtdll/io/access.c index 47f66cd..4babf62 100644 --- a/lib/crtdll/io/access.c +++ b/lib/crtdll/io/access.c @@ -1,38 +1,30 @@ -#include #include +#include +#include +#define NDEBUG +#include -#ifndef F_OK - #define F_OK 0x01 -#endif -#ifndef R_OK - #define R_OK 0x02 -#endif -#ifndef W_OK - #define W_OK 0x04 -#endif -#ifndef X_OK - #define X_OK 0x08 -#endif -#ifndef D_OK - #define D_OK 0x10 -#endif int _access( const char *_path, int _amode ) { - DWORD Attributes = GetFileAttributesA(_path); + DWORD Attributes = GetFileAttributesA(_path); + DPRINT("_access('%s', %x)\n", _path, _amode); - if ( Attributes == -1 ) - return -1; - - if ( (_amode & W_OK) == W_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY ) - return -1; - } - if ( (_amode & D_OK) == D_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) - return -1; - } - - return 0; - + if (Attributes == -1) { + __set_errno(ENOENT); + return -1; + } + if ((_amode & W_OK) == W_OK) { + if ((Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { + __set_errno(EACCES); + return -1; + } + } + if ((_amode & D_OK) == D_OK) { + if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { + __set_errno(EACCES); + return -1; + } + } + return 0; } diff --git a/lib/crtdll/io/chmod.c b/lib/crtdll/io/chmod.c index be48dbf..0f54898 100644 --- a/lib/crtdll/io/chmod.c +++ b/lib/crtdll/io/chmod.c @@ -1,31 +1,33 @@ #include -#include +#include + +#define NDEBUG +#include + #define mode_t int -int -_chmod(const char *filename, mode_t mode) + +int _chmod(const char* filename, mode_t mode) { - DWORD FileAttributes = 0; - - FileAttributes = GetFileAttributes(filename); - if ( FileAttributes == -1 ) - return -1; - - if ( mode == 0 ) - return -1; - - - if ( (mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) - FileAttributes &= FILE_ATTRIBUTE_READONLY; - else if ( ((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE) ) - FileAttributes &= FILE_ATTRIBUTE_NORMAL; - else - FileAttributes &= FILE_ATTRIBUTE_NORMAL; - - - - if ( SetFileAttributes(filename,FileAttributes) == FALSE ) - return -1; - - return 1; + DWORD FileAttributes = 0; + DPRINT("_chmod('%s', %x)\n", filename, mode); + + FileAttributes = GetFileAttributesA(filename); + if ( FileAttributes == -1 ) + return -1; + + if ( mode == 0 ) + return -1; + + if ((mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) + FileAttributes &= FILE_ATTRIBUTE_READONLY; + else if (((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE)) + FileAttributes &= FILE_ATTRIBUTE_NORMAL; + else + FileAttributes &= FILE_ATTRIBUTE_NORMAL; + + if (SetFileAttributesA(filename, FileAttributes) == FALSE) + return -1; + + return 1; } diff --git a/lib/crtdll/io/chsize.c b/lib/crtdll/io/chsize.c index 9fd2ce2..865bec2 100644 --- a/lib/crtdll/io/chsize.c +++ b/lib/crtdll/io/chsize.c @@ -1,8 +1,12 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ -#include +#include + +#define NDEBUG +#include int _chsize(int _fd, long size) { + DPRINT("_chsize(fd %d, size %d)\n", _fd, size); if (lseek(_fd, size, 0) == -1) return -1; if (_write(_fd, 0, 0) < 0) diff --git a/lib/crtdll/io/close.c b/lib/crtdll/io/close.c index 2ca7aa8..65d6230 100644 --- a/lib/crtdll/io/close.c +++ b/lib/crtdll/io/close.c @@ -1,14 +1,16 @@ -#include #include -#include +#include +#include +#define NDEBUG +#include -int _close(int _fd) +int _close(int _fd) { - if ( _fd == -1 ) - return -1; - if ( CloseHandle(_get_osfhandle(_fd)) == FALSE ) - return -1; - return __fileno_close(_fd); - + DPRINT("_close(fd %d)\n", _fd); + if (_fd == -1) + return -1; + if (CloseHandle(_get_osfhandle(_fd)) == FALSE) + return -1; + return __fileno_close(_fd); } diff --git a/lib/crtdll/io/commit.c b/lib/crtdll/io/commit.c index 8c9d787..90b243b 100644 --- a/lib/crtdll/io/commit.c +++ b/lib/crtdll/io/commit.c @@ -1,9 +1,8 @@ #include -#include -#include -#include +#include +#include +#include -int _commode_dll = _IOCOMMIT; int _commit(int _fd) { diff --git a/lib/crtdll/io/create.c b/lib/crtdll/io/create.c index 4456a82..2a617b3 100644 --- a/lib/crtdll/io/create.c +++ b/lib/crtdll/io/create.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int _creat(const char *filename, int mode) { diff --git a/lib/crtdll/io/dup.c b/lib/crtdll/io/dup.c index f2a22ce..6711658 100644 --- a/lib/crtdll/io/dup.c +++ b/lib/crtdll/io/dup.c @@ -1,12 +1,18 @@ +/* $Id$ */ #include -#include +#include +#include // fixme change type of mode argument to mode_t int __fileno_alloc(HANDLE hFile, int mode); int __fileno_getmode(int _fd); -int _dup( int handle ) +int _dup(int handle) { - return __fileno_alloc(_get_osfhandle(handle), __fileno_getmode(handle)); + HANDLE hFile; + int fd; + hFile = _get_osfhandle(handle); + fd = __fileno_alloc(hFile, __fileno_getmode(handle)); + return fd; } diff --git a/lib/crtdll/io/dup2.c b/lib/crtdll/io/dup2.c index 98ea368..ff43f3f 100644 --- a/lib/crtdll/io/dup2.c +++ b/lib/crtdll/io/dup2.c @@ -1,6 +1,5 @@ -#include -#include -#include +#include +#include int _dup2( int handle1, int handle2 ) { diff --git a/lib/crtdll/io/eof.c b/lib/crtdll/io/eof.c index baf3952..344e7eb 100644 --- a/lib/crtdll/io/eof.c +++ b/lib/crtdll/io/eof.c @@ -1,5 +1,5 @@ #include -#include +#include int _eof( int _fd ) { @@ -12,8 +12,4 @@ int _eof( int _fd ) return 1; return 0; - - - - } diff --git a/lib/crtdll/io/filelen.c b/lib/crtdll/io/filelen.c index b234bf4..231a3c9 100644 --- a/lib/crtdll/io/filelen.c +++ b/lib/crtdll/io/filelen.c @@ -1,8 +1,8 @@ #include -#include +#include -long -_filelength(int _fd) + +long _filelength(int _fd) { return GetFileSize(_get_osfhandle(_fd),NULL); } diff --git a/lib/crtdll/io/find.c b/lib/crtdll/io/find.c index 25ff5f7..83b379b 100644 --- a/lib/crtdll/io/find.c +++ b/lib/crtdll/io/find.c @@ -1,81 +1,77 @@ #include -#include -#include -#include +#include +#include +#include +int _findclose(int handle) +{ + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; + return FindClose((void*)handle); +} -int _findfirst(const char *_name, struct _finddata_t *result) +int _findfirst(const char* _name, struct _finddata_t* result) { + WIN32_FIND_DATAA FindFileData; + char dir[MAX_PATH]; + long hFindFile; + int len = 0; - WIN32_FIND_DATA FindFileData; - char dir[MAX_PATH]; - long hFindFile; - int len = 0; - - if ( _name == NULL || _name[0] == 0 ) { - len = GetCurrentDirectory(MAX_PATH-4,dir); - if (dir[len-1] != '\\') { - dir[len] = '\\'; - dir[len+1] = 0; - } - strcat(dir,"*.*"); - } - else - strcpy(dir,_name); - hFindFile = (long)FindFirstFileA( dir, &FindFileData ); - if ( hFindFile == -1 ) { - memset(result,0,sizeof(struct _finddata_t)); - return -1; + if (_name == NULL || _name[0] == 0) { + len = GetCurrentDirectoryA(MAX_PATH-4,dir); + if (dir[len-1] != '\\') { + dir[len] = '\\'; + dir[len+1] = 0; } - result->attrib = FindFileData.dwFileAttributes; + strcat(dir,"*.*"); + } else { + strcpy(dir,_name); + } + hFindFile = (long)FindFirstFileA(dir, &FindFileData); + if (hFindFile == -1) { + memset(result,0,sizeof(struct _finddata_t)); + return -1; + } - result->time_create = FileTimeToUnixTime( &FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime( &FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime( &FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName,260); - - // if no wildcard the find file handle can be closed right away - // a return value of 0 can flag this. - - if(!strchr(dir,'*') && !strchr(dir,'?')) { - _findclose(hFindFile); - return 0; - } - - - return hFindFile; + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName,MAX_PATH); + + // if no wildcard the find file handle can be closed right away + // a return value of 0 can flag this. + + if (!strchr(dir,'*') && !strchr(dir,'?')) { + _findclose(hFindFile); + return 0; + } + return hFindFile; } -int _findnext(int handle, struct _finddata_t *result) +int _findnext(int handle, struct _finddata_t* result) { - WIN32_FIND_DATA FindFileData; - - // check no wildcards or invalid handle - if ( handle == 0 || handle == -1) - return 0; - - + WIN32_FIND_DATAA FindFileData; - if ( !FindNextFile((void *)handle, &FindFileData ) ) - return -1; - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime( &FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime( &FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime( &FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName,260); + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) return 0; -} -int _findclose(int handle) -{ - // check no wildcards or invalid handle - if ( handle == 0 || handle == -1) - return 0; - return FindClose((void *)handle); + if (!FindNextFileA((void*)handle, &FindFileData)) + return -1; + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName, MAX_PATH); + + return 0; } + diff --git a/lib/crtdll/io/fmode.c b/lib/crtdll/io/fmode.c index 79347bd..870ac3a 100644 --- a/lib/crtdll/io/fmode.c +++ b/lib/crtdll/io/fmode.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #undef _fmode unsigned int _fmode = O_TEXT; diff --git a/lib/crtdll/io/isatty.c b/lib/crtdll/io/isatty.c index a452414..3ed7a80 100644 --- a/lib/crtdll/io/isatty.c +++ b/lib/crtdll/io/isatty.c @@ -1,11 +1,13 @@ -#include -#include +#include +#include +#define NDEBUG +#include int _isatty( int fd ) { struct stat buf; - + DPRINT("_isatty(fd %d)\n", fd); if (_fstat (fd, &buf) < 0) return 0; if (S_ISCHR (buf.st_mode)) diff --git a/lib/crtdll/io/locking.c b/lib/crtdll/io/locking.c index b846ef5..a3d79a7 100644 --- a/lib/crtdll/io/locking.c +++ b/lib/crtdll/io/locking.c @@ -1,10 +1,11 @@ #include -#include +#include -int _locking( int _fd, int mode, long nbytes ) + +int _locking(int _fd, int mode, long nbytes) { long offset = _lseek(_fd, 0L, 1); - if ( !LockFile(_get_osfhandle(_fd),offset,0,nbytes,0) ) + if (!LockFile(_get_osfhandle(_fd),offset,0,nbytes,0)) return -1; return 0; diff --git a/lib/crtdll/io/lseek.c b/lib/crtdll/io/lseek.c index c585445..36b2126 100644 --- a/lib/crtdll/io/lseek.c +++ b/lib/crtdll/io/lseek.c @@ -1,9 +1,9 @@ #include -#include -#include +#include +#include + long _lseek(int _fildes, long _offset, int _whence) { return _llseek((HFILE)filehnd(_fildes),_offset,_whence); } - diff --git a/lib/crtdll/io/mktemp.c b/lib/crtdll/io/mktemp.c index a5499ec..9029be1 100644 --- a/lib/crtdll/io/mktemp.c +++ b/lib/crtdll/io/mktemp.c @@ -13,9 +13,12 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include + +#define NDEBUG +#include char* _mktemp (char *_template) @@ -24,8 +27,7 @@ char* _mktemp (char *_template) char *cp, *dp; int i, len, xcount, loopcnt; - - + DPRINT("_mktemp('%s')\n", _template); len = strlen (_template); cp = _template + len; diff --git a/lib/crtdll/io/open.c b/lib/crtdll/io/open.c index 4cc7e33..928cb88 100644 --- a/lib/crtdll/io/open.c +++ b/lib/crtdll/io/open.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/io/open.c @@ -14,147 +15,140 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include + +#define STD_AUX_HANDLE 3 +#define STD_PRINTER_HANDLE 4 typedef struct _fileno_modes_type { - HANDLE hFile; - int mode; - int fd; + HANDLE hFile; + int mode; + int fd; } fileno_modes_type; +int __fileno_alloc(HANDLE hFile, int mode); + fileno_modes_type *fileno_modes = NULL; int maxfno = 5; int minfno = 5; -char __is_text_file(FILE *p) +char __is_text_file(FILE* p) { - if ( p == NULL || fileno_modes == NULL ) + if (p == NULL || fileno_modes == NULL) return FALSE; return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT)); } - - - -int __fileno_alloc(HANDLE hFile, int mode); - - -int _open(const char *_path, int _oflag,...) +int _open(const char* _path, int _oflag,...) { - HANDLE hFile; - DWORD dwDesiredAccess = 0; - DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - DWORD dwCreationDistribution = 0; - DWORD dwFlagsAndAttributes = 0; - int mode; - va_list arg; - - va_start (arg, _oflag); - mode = va_arg(arg,int); - va_end (arg); - if ( (mode == S_IWRITE) || (mode == 0) ) - dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY; - - /* - * - * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) - * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) - * - */ - if (( _oflag & _O_RDWR ) == _O_RDWR ) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ ; - else if (( _oflag & _O_WRONLY ) == _O_WRONLY ) - dwDesiredAccess |= GENERIC_WRITE ; - else - dwDesiredAccess |= GENERIC_READ ; - - if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) ) - dwCreationDistribution |= CREATE_NEW; - - else if (( _oflag & O_TRUNC ) == O_TRUNC ) { - if (( _oflag & O_CREAT ) == O_CREAT ) - dwCreationDistribution |= CREATE_ALWAYS; - else if (( _oflag & O_RDONLY ) != O_RDONLY ) - dwCreationDistribution |= TRUNCATE_EXISTING; - } - else if (( _oflag & _O_APPEND ) == _O_APPEND ) - dwCreationDistribution |= OPEN_EXISTING; - else if (( _oflag & _O_CREAT ) == _O_CREAT ) - dwCreationDistribution |= OPEN_ALWAYS; - else - dwCreationDistribution |= OPEN_EXISTING; - - if (( _oflag & _O_RANDOM ) == _O_RANDOM ) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL ) - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - - if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY ) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED ) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - hFile = CreateFileA(_path, - dwDesiredAccess, - dwShareMode, - NULL, - dwCreationDistribution, - dwFlagsAndAttributes, - NULL); - if (hFile == (HANDLE)-1) - return -1; - return __fileno_alloc(hFile,_oflag); - -// _O_APPEND Moves file pointer to end of file before every write operation. + HANDLE hFile; + DWORD dwDesiredAccess = 0; + DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + DWORD dwCreationDistribution = 0; + DWORD dwFlagsAndAttributes = 0; + int mode; + va_list arg; + + va_start(arg, _oflag); + mode = va_arg(arg,int); + va_end (arg); + if ((mode == S_IWRITE) || (mode == 0)) + dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY; + /* + * + * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) + * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) + * + */ + if (( _oflag & _O_RDWR ) == _O_RDWR ) + dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ ; + else if (( _oflag & _O_WRONLY ) == _O_WRONLY ) + dwDesiredAccess |= GENERIC_WRITE ; + else + dwDesiredAccess |= GENERIC_READ ; + + if ((_oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL)) + dwCreationDistribution |= CREATE_NEW; + + else if ((_oflag & O_TRUNC) == O_TRUNC) { + if ((_oflag & O_CREAT) == O_CREAT) + dwCreationDistribution |= CREATE_ALWAYS; + else if ((_oflag & O_RDONLY ) != O_RDONLY) + dwCreationDistribution |= TRUNCATE_EXISTING; + } + else if ((_oflag & _O_APPEND) == _O_APPEND) + dwCreationDistribution |= OPEN_EXISTING; + else if ((_oflag & _O_CREAT) == _O_CREAT) + dwCreationDistribution |= OPEN_ALWAYS; + else + dwCreationDistribution |= OPEN_EXISTING; + + if ((_oflag & _O_RANDOM) == _O_RANDOM) + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; + if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL) + dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; + + if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) + dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; + + if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) + dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; + + hFile = CreateFileA(_path, + dwDesiredAccess, + dwShareMode, + NULL, + dwCreationDistribution, + dwFlagsAndAttributes, + NULL); + if (hFile == (HANDLE)-1) + return -1; + return __fileno_alloc(hFile,_oflag); + +// _O_APPEND Moves file pointer to end of file before every write operation. } - - int __fileno_alloc(HANDLE hFile, int mode) { - int i; /* Check for bogus values */ if (hFile < 0) - return -1; + return -1; for(i=minfno;i= maxfno ) - return (void *)-1; - - if ( fileno_modes[fileno].fd == -1 ) - return (void *)-1; - return fileno_modes[fileno].hFile; -} - -int __fileno_dup2( int handle1, int handle2 ) -{ - if ( handle1 >= maxfno ) - return -1; - - if ( handle1 < 0 ) - return -1; - if ( handle2 >= maxfno ) - return -1; - - if ( handle2 < 0 ) - return -1; - - memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes)); - - - return handle1; + if (fileno < 0) + return (void*)-1; + switch (fileno) { + case 0: + return GetStdHandle(STD_INPUT_HANDLE); + case 1: + return GetStdHandle(STD_OUTPUT_HANDLE); + case 2: + return GetStdHandle(STD_ERROR_HANDLE); + case 3: + return GetStdHandle(STD_AUX_HANDLE); + case 4: + return GetStdHandle(STD_PRINTER_HANDLE); + default: + break; + } + if (fileno >= maxfno) + return (void*)-1; + if (fileno_modes[fileno].fd == -1) + return (void*)-1; + return fileno_modes[fileno].hFile; } int __fileno_setmode(int _fd, int _newmode) { - int m; - if ( _fd < minfno ) - return -1; - - if ( _fd >= maxfno ) - return -1; + int m; - m = fileno_modes[_fd].mode; - fileno_modes[_fd].mode = _newmode; - return m; + if (_fd < minfno) { + return -1; + } + if (_fd >= maxfno) + return -1; + m = fileno_modes[_fd].mode; + fileno_modes[_fd].mode = _newmode; + return m; } int __fileno_getmode(int _fd) { - if ( _fd < minfno ) - return -1; - - if ( _fd >= maxfno ) - return -1; - - return fileno_modes[_fd].mode; - + if (_fd < minfno) { + return -1; + } + if (_fd >= maxfno) + return -1; + return fileno_modes[_fd].mode; } - -int __fileno_close(int _fd) +int __fileno_close(int _fd) { - if ( _fd < 0 ) - return -1; - - if ( _fd >= maxfno ) - return -1; + if (_fd < 0) { + return -1; + } + if (_fd >= maxfno) + return -1; + fileno_modes[_fd].fd = -1; + fileno_modes[_fd].hFile = (HANDLE)-1; + return 0; +} - fileno_modes[_fd].fd = -1; - fileno_modes[_fd].hFile = (HANDLE)-1; - return 0; +int _open_osfhandle(void *osfhandle, int flags) +{ + return __fileno_alloc((HANDLE)osfhandle, flags); } -int _open_osfhandle (void *osfhandle, int flags ) +void *_get_osfhandle(int fileno) { - return __fileno_alloc((HANDLE)osfhandle, flags); -} + return filehnd(fileno); +} -void *_get_osfhandle( int fileno ) +int __fileno_dup2(int handle1, int handle2) { - return filehnd(fileno); + if (handle1 >= maxfno) { + return -1; + } + if (handle1 < 0) + return -1; + if (handle2 >= maxfno) + return -1; + if (handle2 < 0) + return -1; + memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes)); + return handle1; } diff --git a/lib/crtdll/io/pipe.c b/lib/crtdll/io/pipe.c index 8c67f7a..9b7f8b5 100644 --- a/lib/crtdll/io/pipe.c +++ b/lib/crtdll/io/pipe.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/io/pipe.c @@ -8,8 +9,8 @@ * 28/12/98: Appropriated for Reactos */ #include -#include -#include +#include +#include int _pipe(int _fildes[2], unsigned int size, int mode ) diff --git a/lib/crtdll/io/read.c b/lib/crtdll/io/read.c index e5dc4ad..1e6c0d2 100644 --- a/lib/crtdll/io/read.c +++ b/lib/crtdll/io/read.c @@ -1,14 +1,19 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/io/read.c * PURPOSE: Reads a file * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: - * 28/12/98: Created + * 28/12/1998: Created */ -#include #include +#include +#include + +#define NDEBUG +#include size_t _read(int _fd, void *_buf, size_t _nbyte) { diff --git a/lib/crtdll/io/setmode.c b/lib/crtdll/io/setmode.c index ea6f7e8..81cdedd 100644 --- a/lib/crtdll/io/setmode.c +++ b/lib/crtdll/io/setmode.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/io/setmode.c @@ -8,12 +9,16 @@ * 28/12/98: Created */ -#include -#include -#include +#include +#include +#include + +#define NDEBUG +#include int _setmode(int _fd, int _newmode) { + DPRINT("_setmod(fd %d, newmode %x)\n", _fd, _newmode); return __fileno_setmode(_fd, _newmode); } diff --git a/lib/crtdll/io/sopen.c b/lib/crtdll/io/sopen.c index 5d42157..b7c06d1 100644 --- a/lib/crtdll/io/sopen.c +++ b/lib/crtdll/io/sopen.c @@ -1,4 +1,4 @@ -#include +#include int _sopen(char *path,int access,int shflag,int mode) diff --git a/lib/crtdll/io/tell.c b/lib/crtdll/io/tell.c index ce53df0..990a477 100644 --- a/lib/crtdll/io/tell.c +++ b/lib/crtdll/io/tell.c @@ -1,10 +1,9 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include -off_t -_tell(int _file) +off_t _tell(int _file) { return _lseek(_file, 0, SEEK_CUR); } diff --git a/lib/crtdll/io/umask.c b/lib/crtdll/io/umask.c index 7a8323b..fd4af98 100644 --- a/lib/crtdll/io/umask.c +++ b/lib/crtdll/io/umask.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include unsigned _unMode_dll = 022; diff --git a/lib/crtdll/io/unlink.c b/lib/crtdll/io/unlink.c index 65ef9d4..b29415d 100644 --- a/lib/crtdll/io/unlink.c +++ b/lib/crtdll/io/unlink.c @@ -8,7 +8,7 @@ * 28/12/98: Created */ #include -#include +#include diff --git a/lib/crtdll/io/utime.c b/lib/crtdll/io/utime.c index 90b9921..27da039 100644 --- a/lib/crtdll/io/utime.c +++ b/lib/crtdll/io/utime.c @@ -1,8 +1,9 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + int _utime(const char* filename, struct _utimbuf* buf) { @@ -18,5 +19,4 @@ int _utime(const char* filename, struct _utimbuf* buf) if ( _close(fn) < 0 ) return -1; return ret; - } diff --git a/lib/crtdll/io/write.c b/lib/crtdll/io/write.c index 30f0f26..6d9dd84 100644 --- a/lib/crtdll/io/write.c +++ b/lib/crtdll/io/write.c @@ -7,8 +7,8 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include #include +#include diff --git a/lib/crtdll/locale/locale.c b/lib/crtdll/locale/locale.c index d72fcb0..f7e3cd8 100644 --- a/lib/crtdll/locale/locale.c +++ b/lib/crtdll/locale/locale.c @@ -1,12 +1,11 @@ -#include -#include -#include +#include +#include +#include #include int _current_category; /* used by setlocale */ const char *_current_locale; -int __mb_cur_max_dll = 1; int parse_locale(char *locale, char *lang, char *country, char *code_page); @@ -140,4 +139,3 @@ struct lconv *localeconv(void) { return (struct lconv *) &_lconv; } - diff --git a/lib/crtdll/makefile b/lib/crtdll/makefile index e834864..b7d83d8 100644 --- a/lib/crtdll/makefile +++ b/lib/crtdll/makefile @@ -2,25 +2,50 @@ PATH_TO_TOP = ../.. +PATH_TO_MSVCRT = ../msvcrt + +TARGET_DEFONLY = yes + TARGET_TYPE = dynlink TARGET_NAME = crtdll -TARGET_LFLAGS = -nostartfiles +TARGET_BASE = 0x77630000 -TARGET_SDKLIBS = kernel32.a +TARGET_LFLAGS = -nostartfiles -TARGET_BASE = 0x77630000 +TARGET_CFLAGS = -D_MSVCRT_LIB_ -TARGET_DEFONLY = yes +TARGET_SDKLIBS = kernel32.a ntdll.a TARGET_OBJECTS = $(TARGET_NAME).o -TARGET_CLEAN = assert/*.o conio/*.o ctype/*.o direct/*.o dirent/*.o \ - except/*.o float/*.o io/*.o libc/*.o locale/*.o malloc/*.o \ - math/*.o mbstring/*.o misc/*.o process/*.o quad/*.o search/*.o \ - setjmp/*.o stdio/*.o stdlib/*.o string/*.o sys_stat/*.o tchar/*.o \ - time/*.o wchar/*.o signal/*.o +TARGET_CLEAN = \ + conio/*.o \ + ctype/*.o \ + direct/*.o \ + dirent/*.o \ + except/*.o \ + float/*.o \ + io/*.o \ + libc/*.o \ + locale/*.o \ + malloc/*.o \ + math/*.o \ + mbstring/*.o \ + misc/*.o \ + process/*.o \ + quad/*.o \ + search/*.o \ + setjmp/*.o \ + signal/*.o \ + stdio/*.o \ + stdlib/*.o \ + string/*.o \ + sys_stat/*.o \ + tchar/*.o \ + time/*.o \ + wchar/*.o include $(PATH_TO_TOP)/rules.mak @@ -28,133 +53,465 @@ include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk -ASSERT_OBJECTS = assert/assert.o - -CTYPE_OBJECTS = ctype/isalnum.o \ - ctype/isalpha.o ctype/isascii.o ctype/iscntrl.o ctype/isdigit.o ctype/isgraph.o \ - ctype/islower.o ctype/isprint.o ctype/ispunct.o ctype/isspace.o ctype/isupper.o \ - ctype/isxdigit.o ctype/toascii.o ctype/tolower.o ctype/toupper.o\ - ctype/iscsym.o ctype/isctype.o - -CONIO_OBJECTS = conio/cputs.o conio/getch.o conio/getche.o conio/putch.o conio/ungetch.o\ - conio/kbhit.o conio/cgets.o conio/cprintf.o conio/cscanf.o - -DIRECT_OBJECTS = direct/chdir.o direct/chdrive.o direct/getcwd.o direct/getdrive.o \ - direct/rmdir.o direct/mkdir.o direct/getdfree.o direct/getdcwd.o - -EXCEPT_OBJECTS = except/unwind.o except/abnorter.o except/exhand2.o except/matherr.o - -LOCALE_OBJECTS = locale/locale.o - -MALLOC_OBJECTS = malloc/expand.o malloc/heap.o - - -MISC_OBJECTS = misc/GetArgs.o misc/dllmain.o misc/setnew.o misc/purecall.o misc/initterm.o\ - misc/amsg.o - -MBSTRING_OBJECTS = mbstring/mbsnicmp.o mbstring/mbsnset.o mbstring/mbsnextc.o mbstring/mbsnicoll.o mbstring/islead.o mbstring/mbsspnp.o \ - mbstring/mbspbrk.o mbstring/mbsspn.o mbstring/mbbtype.o mbstring/mbscat.o mbstring/mbschr.o \ - mbstring/mbccpy.o mbstring/mbslen.o mbstring/mbsrchr.o mbstring/mbsset.o mbstring/mbsncat.o mbstring/mbsncmp.o \ - mbstring/mbscmp.o mbstring/mbsncoll.o mbstring/mbscoll.o mbstring/mbsncpy.o mbstring/mbscpy.o mbstring/mbscspn.o \ - mbstring/mbsdup.o mbstring/mbsicmp.o mbstring/mbsicoll.o mbstring/mbsnccnt.o mbstring/mbsrev.o mbstring/mbsstr.o \ - mbstring/mbsinc.o mbstring/mbsdec.o mbstring/mbsninc.o mbstring/mbclen.o mbstring/iskana.o mbstring/jmstojis.o \ - mbstring/jistojms.o mbstring/iskpun.o mbstring/iskmoji.o mbstring/ismbgra.o mbstring/ismbpri.o mbstring/isuppr.o \ - mbstring/islwr.o mbstring/ismbkaln.o mbstring/mbstrlen.o mbstring/ismbc.o \ - mbstring/ismbtrl.o mbstring/ismblead.o mbstring/ischira.o mbstring/hanzen.o mbstring/ismbaln.o mbstring/ismbal.o \ - mbstring/ismbpun.o mbstring/mbslwr.o mbstring/mbsupr.o mbstring/mbstok.o - -STRING_OBJECTS = string/memchr.o string/memcmp.o string/strcat.o \ - string/strchr.o string/strcmp.o string/strcoll.o \ - string/strcpy.o string/strcspn.o string/memcpy.o \ - string/strlen.o string/strncat.o string/strncmp.o \ - string/strncpy.o string/strpbrk.o string/strrchr.o \ - string/strspn.o string/strstr.o string/strtok.o \ - string/strxfrm.o string/memmove.o string/memset.o \ - string/strdup.o string/strlwr.o string/strupr.o \ - string/str_old.o string/strerror.o string/stricmp.o\ - string/strnlen.o string/strnicmp.o string/strrev.o\ - string/memccpy.o string/memicmp.o string/strset.o - -WCHAR_OBJECTS = wchar/wcscat.o wchar/wcschr.o wchar/wcscmp.o \ - wchar/wcscoll.o wchar/wcscpy.o wchar/wcscspn.o \ - wchar/wcsdup.o wchar/wcsicmp.o wchar/wcslen.o \ - wchar/wcslwr.o wchar/wcsncat.o wchar/wcsncmp.o \ - wchar/wcsncpy.o wchar/wcsnlen.o wchar/wcspbrk.o wchar/wcsrchr.o\ - wchar/wcsrev.o wchar/wcsset.o wchar/wcsspn.o wchar/wcsstr.o\ - wchar/wcstod.o wchar/wcstok.o wchar/wcstol.o wchar/wcsupr.o\ - wchar/wcsxfrm.o wchar/wtoi.o wchar/wcstombs.o wchar/wcsnicmp.o - -SETJMP_OBJECTS = setjmp/setjmp.o - -STDIO_OBJECTS = stdio/getenv.o stdio/filbuf.o \ - stdio/fclose.o stdio/feof.o stdio/ferror.o stdio/fileno.o\ - stdio/fflush.o stdio/fgetc.o stdio/fgetpos.o stdio/fgets.o stdio/flsbuf.o \ - stdio/fopen.o stdio/fprintf.o stdio/fputc.o stdio/fputs.o stdio/setvbuf.o\ - stdio/fread.o stdio/freopen.o stdio/fscanf.o stdio/fseek.o \ - stdio/fsetpos.o stdio/ftell.o stdio/fwalk.o stdio/fwrite.o stdio/getc.o \ - stdio/getchar.o stdio/gets.o stdio/getw.o stdio/perror.o stdio/clearerr.o \ - stdio/putc.o stdio/putchar.o stdio/puts.o stdio/putw.o stdio/fputchar.o\ - stdio/remove.o stdio/rename.o stdio/rewind.o stdio/allocfil.o\ - stdio/setbuf.o stdio/setbuffe.o stdlib/obsol.o stdio/setlineb.o\ - stdio/scanf.o stdio/sscanf.o stdio/vscanf.o stdio/vsscanf.o stdio/vfscanf.o\ - stdio/stdiohk.o stdio/stdhnd.o stdio/tempnam.o stdio/tmpfile.o stdio/tmpnam.o \ - stdio/ungetc.o stdio/printf.o stdio/vfprintf.o stdio/vprintf.o stdio/sprintf.o\ - stdio/fdopen.o stdio/vsprintf.o stdio/frlist.o stdio/fgetchar.o stdio/rmtmp.o\ - stdio/fsopen.o stdio/popen.o stdio/vfwprint.o +CONIO_OBJECTS = \ + $(PATH_TO_MSVCRT)/conio/cgets.o \ + $(PATH_TO_MSVCRT)/conio/cprintf.o \ + $(PATH_TO_MSVCRT)/conio/cputs.o \ + $(PATH_TO_MSVCRT)/conio/cscanf.o \ + $(PATH_TO_MSVCRT)/conio/getch.o \ + $(PATH_TO_MSVCRT)/conio/getche.o \ + $(PATH_TO_MSVCRT)/conio/kbhit.o \ + $(PATH_TO_MSVCRT)/conio/putch.o \ + $(PATH_TO_MSVCRT)/conio/ungetch.o + +CTYPE_OBJECTS = \ + $(PATH_TO_MSVCRT)/ctype/ctype.o \ + $(PATH_TO_MSVCRT)/ctype/isalnum.o \ + $(PATH_TO_MSVCRT)/ctype/isalpha.o \ + $(PATH_TO_MSVCRT)/ctype/isascii.o \ + $(PATH_TO_MSVCRT)/ctype/iscntrl.o \ + $(PATH_TO_MSVCRT)/ctype/isdigit.o \ + $(PATH_TO_MSVCRT)/ctype/isgraph.o \ + $(PATH_TO_MSVCRT)/ctype/islower.o \ + $(PATH_TO_MSVCRT)/ctype/isprint.o \ + $(PATH_TO_MSVCRT)/ctype/ispunct.o \ + $(PATH_TO_MSVCRT)/ctype/isspace.o \ + $(PATH_TO_MSVCRT)/ctype/isupper.o \ + $(PATH_TO_MSVCRT)/ctype/isxdigit.o \ + $(PATH_TO_MSVCRT)/ctype/toascii.o \ + $(PATH_TO_MSVCRT)/ctype/tolower.o \ + $(PATH_TO_MSVCRT)/ctype/toupper.o \ + $(PATH_TO_MSVCRT)/ctype/iscsym.o \ + ctype/isctype.o + +DIRECT_OBJECTS = \ + $(PATH_TO_MSVCRT)/direct/chdir.o \ + $(PATH_TO_MSVCRT)/direct/chdrive.o \ + $(PATH_TO_MSVCRT)/direct/getcwd.o \ + $(PATH_TO_MSVCRT)/direct/getdcwd.o \ + $(PATH_TO_MSVCRT)/direct/getdfree.o \ + $(PATH_TO_MSVCRT)/direct/getdrive.o \ + $(PATH_TO_MSVCRT)/direct/mkdir.o \ + $(PATH_TO_MSVCRT)/direct/rmdir.o + +EXCEPT_OBJECTS = \ + except/abnorter.o \ + except/exhand2.o \ + except/matherr.o \ + except/unwind.o + +FLOAT_OBJECTS = \ + $(PATH_TO_MSVCRT)/float/chgsign.o \ + $(PATH_TO_MSVCRT)/float/clearfp.o \ + $(PATH_TO_MSVCRT)/float/cntrlfp.o \ + $(PATH_TO_MSVCRT)/float/copysign.o \ + $(PATH_TO_MSVCRT)/float/fpclass.o \ + $(PATH_TO_MSVCRT)/float/fpreset.o \ + $(PATH_TO_MSVCRT)/float/isnan.o \ + $(PATH_TO_MSVCRT)/float/logb.o \ + $(PATH_TO_MSVCRT)/float/nafter.o \ + $(PATH_TO_MSVCRT)/float/scalb.o \ + $(PATH_TO_MSVCRT)/float/statfp.o + +IO_OBJECTS = \ + $(PATH_TO_MSVCRT)/io/access.o \ + $(PATH_TO_MSVCRT)/io/chmod.o \ + $(PATH_TO_MSVCRT)/io/chsize.o \ + $(PATH_TO_MSVCRT)/io/close.o \ + $(PATH_TO_MSVCRT)/io/commit.o \ + io/create.o \ + io/dup.o \ + $(PATH_TO_MSVCRT)/io/dup2.o \ + io/eof.o \ + $(PATH_TO_MSVCRT)/io/filelen.o \ + io/find.o \ + io/fmode.o \ + $(PATH_TO_MSVCRT)/io/isatty.o \ + $(PATH_TO_MSVCRT)/io/locking.o \ + io/lseek.o \ + $(PATH_TO_MSVCRT)/io/mktemp.o \ + io/open.o \ + io/pipe.o \ + io/read.o \ + $(PATH_TO_MSVCRT)/io/setmode.o \ + $(PATH_TO_MSVCRT)/io/sopen.o \ + $(PATH_TO_MSVCRT)/io/tell.o \ + $(PATH_TO_MSVCRT)/io/umask.o \ + io/unlink.o \ + $(PATH_TO_MSVCRT)/io/utime.o \ + io/write.o + +LOCALE_OBJECTS = \ + $(PATH_TO_MSVCRT)/locale/locale.o + +MATH_OBJECTS = \ + $(PATH_TO_MSVCRT)/math/acos.o \ + math/acosh.o \ + $(PATH_TO_MSVCRT)/math/asin.o \ + math/asinh.o \ + $(PATH_TO_MSVCRT)/math/atan.o \ + $(PATH_TO_MSVCRT)/math/atan2.o\ + math/atanh.o \ + $(PATH_TO_MSVCRT)/math/cabs.o \ + math/ceil.o \ + $(PATH_TO_MSVCRT)/math/cos.o \ + $(PATH_TO_MSVCRT)/math/cosh.o \ + $(PATH_TO_MSVCRT)/math/exp.o \ + $(PATH_TO_MSVCRT)/math/fabs.o\ + math/floor.o \ + $(PATH_TO_MSVCRT)/math/fmod.o \ + $(PATH_TO_MSVCRT)/math/frexp.o \ + $(PATH_TO_MSVCRT)/math/ftol.o \ + math/huge_val.o \ + $(PATH_TO_MSVCRT)/math/hypot.o \ + $(PATH_TO_MSVCRT)/math/j0_y0.o \ + $(PATH_TO_MSVCRT)/math/j1_y1.o \ + $(PATH_TO_MSVCRT)/math/jn_yn.o \ + $(PATH_TO_MSVCRT)/math/ldexp.o \ + $(PATH_TO_MSVCRT)/math/log.o \ + $(PATH_TO_MSVCRT)/math/log10.o \ + $(PATH_TO_MSVCRT)/math/modf.o \ + $(PATH_TO_MSVCRT)/math/pow.o \ + $(PATH_TO_MSVCRT)/math/sin.o \ + $(PATH_TO_MSVCRT)/math/sinh.o \ + $(PATH_TO_MSVCRT)/math/sqrt.o \ + $(PATH_TO_MSVCRT)/math/stubs.o \ + $(PATH_TO_MSVCRT)/math/tan.o \ + $(PATH_TO_MSVCRT)/math/tanh.o + +MALLOC_OBJECTS = \ + malloc/expand.o \ + malloc/heap.o + +MBSTRING_OBJECTS = \ + $(PATH_TO_MSVCRT)/mbstring/hanzen.o \ + $(PATH_TO_MSVCRT)/mbstring/ischira.o \ + $(PATH_TO_MSVCRT)/mbstring/iskana.o \ + $(PATH_TO_MSVCRT)/mbstring/iskpun.o \ + $(PATH_TO_MSVCRT)/mbstring/islead.o \ + $(PATH_TO_MSVCRT)/mbstring/islwr.o \ + $(PATH_TO_MSVCRT)/mbstring/iskmoji.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbal.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbaln.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbc.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbgra.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbkaln.o \ + $(PATH_TO_MSVCRT)/mbstring/ismblead.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbpri.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbpun.o \ + $(PATH_TO_MSVCRT)/mbstring/ismbtrl.o \ + $(PATH_TO_MSVCRT)/mbstring/isuppr.o \ + $(PATH_TO_MSVCRT)/mbstring/jistojms.o \ + $(PATH_TO_MSVCRT)/mbstring/jmstojis.o \ + $(PATH_TO_MSVCRT)/mbstring/mbbtype.o \ + $(PATH_TO_MSVCRT)/mbstring/mbccpy.o \ + $(PATH_TO_MSVCRT)/mbstring/mbclen.o \ + $(PATH_TO_MSVCRT)/mbstring/mbscat.o \ + $(PATH_TO_MSVCRT)/mbstring/mbschr.o \ + $(PATH_TO_MSVCRT)/mbstring/mbscmp.o \ + $(PATH_TO_MSVCRT)/mbstring/mbscoll.o \ + $(PATH_TO_MSVCRT)/mbstring/mbscpy.o \ + $(PATH_TO_MSVCRT)/mbstring/mbscspn.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsdec.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsdup.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsicmp.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsicoll.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsinc.o \ + $(PATH_TO_MSVCRT)/mbstring/mbslen.o \ + $(PATH_TO_MSVCRT)/mbstring/mbslwr.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsncat.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsnccnt.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsncmp.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsncoll.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsncpy.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsnextc.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsnicmp.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsnicoll.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsninc.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsnset.o \ + $(PATH_TO_MSVCRT)/mbstring/mbspbrk.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsrchr.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsrev.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsset.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsspn.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsspnp.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsstr.o \ + $(PATH_TO_MSVCRT)/mbstring/mbstok.o \ + $(PATH_TO_MSVCRT)/mbstring/mbstrlen.o \ + $(PATH_TO_MSVCRT)/mbstring/mbsupr.o + +MISC_OBJECTS = \ + misc/amsg.o \ + $(PATH_TO_MSVCRT)/misc/assert.o \ + misc/debug.o \ + misc/dllmain.o \ + misc/GetArgs.o \ + $(PATH_TO_MSVCRT)/misc/initterm.o \ + misc/purecall.o \ + misc/setnew.o + +PROCESS_OBJECTS = \ + process/_cwait.o \ + process/_system.o\ + $(PATH_TO_MSVCRT)/process/dll.o \ + process/spawnl.o \ + process/spawnlp.o \ + process/spawnlpe.o \ + process/spawnvp.o \ + process/spawnv.o \ + process/spawnve.o \ + process/spawnle.o \ + process/execl.o \ + process/execlp.o \ + process/execlpe.o \ + process/execvpe.o \ + process/execvp.o \ + process/execv.o \ + process/execle.o \ + process/execve.o \ + $(PATH_TO_MSVCRT)/process/procid.o \ + process/thread.o \ + $(PATH_TO_MSVCRT)/process/threadid.o + +QUAD_OBJECTS = \ + quad/qdivrem.o \ + quad/divdi3.o \ + quad/moddi3.o \ + quad/udivdi3.o \ + quad/umoddi3.o + +SEARCH_OBJECTS = \ + $(PATH_TO_MSVCRT)/search/lfind.o \ + $(PATH_TO_MSVCRT)/search/lsearch.o + +SETJMP_OBJECTS = \ + $(PATH_TO_MSVCRT)/setjmp/setjmp.o + +SIGNAL_OBJECTS = \ + signal/xcptfil.o \ + signal/xcptinfo.o \ + $(PATH_TO_MSVCRT)/signal/signal.o + +STDIO_OBJECTS = \ + $(PATH_TO_MSVCRT)/stdio/allocfil.o \ + stdio/getenv.o \ + $(PATH_TO_MSVCRT)/stdio/clearerr.o \ + $(PATH_TO_MSVCRT)/stdio/fclose.o \ + $(PATH_TO_MSVCRT)/stdio/fdopen.o \ + $(PATH_TO_MSVCRT)/stdio/feof.o \ + stdio/ferror.o \ + stdio/fflush.o \ + $(PATH_TO_MSVCRT)/stdio/fgetc.o \ + stdio/fgetchar.o \ + $(PATH_TO_MSVCRT)/stdio/fgetpos.o \ + stdio/fgets.o \ + stdio/filbuf.o \ + stdio/fileno.o \ + $(PATH_TO_MSVCRT)/stdio/flsbuf.o \ + stdio/fopen.o \ + $(PATH_TO_MSVCRT)/stdio/fprintf.o \ + $(PATH_TO_MSVCRT)/stdio/fputc.o \ + stdio/fputchar.o\ + stdio/fputs.o \ + stdio/fread.o \ + stdio/freopen.o \ + stdio/fscanf.o \ + $(PATH_TO_MSVCRT)/stdio/fseek.o \ + $(PATH_TO_MSVCRT)/stdio/fsetpos.o \ + stdio/frlist.o \ + stdio/fsopen.o \ + stdio/ftell.o \ + $(PATH_TO_MSVCRT)/stdio/fwalk.o \ + stdio/fwrite.o \ + stdio/getc.o \ + stdio/getchar.o \ + stdio/gets.o \ + $(PATH_TO_MSVCRT)/stdio/getw.o \ + stdio/perror.o \ + stdio/popen.o \ + stdio/printf.o \ + stdio/putc.o \ + stdio/putchar.o \ + stdio/puts.o \ + $(PATH_TO_MSVCRT)/stdio/putw.o \ + stdio/remove.o \ + $(PATH_TO_MSVCRT)/stdio/rename.o \ + $(PATH_TO_MSVCRT)/stdio/rewind.o \ + $(PATH_TO_MSVCRT)/stdio/rmtmp.o \ + stdio/scanf.o \ + $(PATH_TO_MSVCRT)/stdio/setbuf.o \ + stdio/setbuffe.o \ + stdio/setlineb.o \ + $(PATH_TO_MSVCRT)/stdio/setvbuf.o \ + $(PATH_TO_MSVCRT)/stdio/sprintf.o \ + $(PATH_TO_MSVCRT)/stdio/sscanf.o \ + $(PATH_TO_MSVCRT)/stdio/stdhnd.o \ + stdio/stdiohk.o \ + $(PATH_TO_MSVCRT)/stdio/tempnam.o \ + $(PATH_TO_MSVCRT)/stdio/tmpfile.o \ + $(PATH_TO_MSVCRT)/stdio/tmpnam.o \ + $(PATH_TO_MSVCRT)/stdio/ungetc.o \ + stdio/vfprintf.o \ + stdio/vfscanf.o \ + stdio/vfwprint.o \ + $(PATH_TO_MSVCRT)/stdio/vprintf.o \ + $(PATH_TO_MSVCRT)/stdio/vscanf.o \ + $(PATH_TO_MSVCRT)/stdio/vsprintf.o \ + $(PATH_TO_MSVCRT)/stdio/vsscanf.o -QUAD_OBJECTS = quad/qdivrem.o quad/divdi3.o quad/moddi3.o quad/udivdi3.o quad/umoddi3.o - -IO_OBJECTS = io/access.o io/close.o io/create.o io/dup.o io/dup2.o io/find.o io/isatty.o io/lseek.o \ - io/open.o io/read.o io/setmode.o io/unlink.o io/write.o io/fmode.o io/mktemp.o\ - io/chmod.o io/chsize.o io/commit.o io/locking.o io/pipe.o io/sopen.o io/filelen.o\ - io/umask.o io/tell.o io/eof.o io/utime.o - -SEARCH_OBJECTS = search/lsearch.o search/lfind.o - -STDLIB_OBJECTS = stdlib/abort.o stdlib/abs.o stdlib/atexit.o stdlib/atof.o stdlib/atoi.o \ - stdlib/bsearch.o stdlib/div.o stdlib/errno.o stdlib/_exit.o \ - stdlib/fullpath.o stdlib/labs.o stdlib/ldiv.o stdlib/itoa.o\ - stdlib/makepath.o stdlib/malloc.o stdlib/putenv.o stdlib/qsort.o \ - stdlib/rand.o stdlib/senv.o stdlib/splitp.o stdlib/strtod.o stdlib/strtol.o \ - stdlib/strtoul.o stdlib/swab.o stdlib/atol.o stdlib/rot.o stdlib/wcstomb.o\ - stdlib/ecvt.o stdlib/ecvtbuf.o stdlib/gcvt.o stdlib/fcvt.o stdlib/fcvtbuf.o\ - stdlib/mbstowcs.o stdlib/itow.o - -SIGNAL_OBJECTS = signal/signal.o signal/xcptfil.o signal/xcptinfo.o - -PROCESS_OBJECTS = process/_cwait.o process/dll.o process/spawnl.o process/spawnlp.o process/spawnlpe.o process/spawnvp.o \ - process/spawnv.o process/spawnve.o process/spawnle.o process/execl.o process/execlp.o process/execlpe.o \ - process/execvpe.o process/execvp.o process/execv.o process/execle.o process/_system.o\ - process/execve.o process/threadid.o process/thread.o process/procid.o - -TCHAR_OBJECTS = tchar/strdec.o tchar/strinc.o tchar/strninc.o tchar/strncnt.o tchar/strnextc.o tchar/strspnp.o - -TIME_OBJECTS = time/ctime.o time/difftime.o time/strftime.o time/time.o time/clock.o time/strdate.o\ - time/strtime.o - -FLOAT_OBJECTS = float/fpreset.o float/clearfp.o float/cntrlfp.o float/statfp.o float/logb.o\ - float/chgsign.o float/fpclass.o float/isnan.o float/nafter.o float/scalb.o\ - float/copysign.o - -SYS_STAT_OBJECTS = sys_stat/fstat.o sys_stat/stat.o sys_stat/futime.o sys_stat/ftime.o\ - sys_stat/systime.o - -MATH_OBJECTS = math/acos.o math/acosh.o math/asin.o math/asinh.o math/atan.o math/atan2.o\ - math/atanh.o math/ceil.o math/cos.o math/cosh.o math/exp.o math/fabs.o\ - math/floor.o math/fmod.o math/frexp.o math/huge_val.o math/hypot.o\ - math/ldexp.o math/log.o math/log10.o math/modf.o math/pow.o\ - math/sin.o math/sinh.o math/sqrt.o math/tan.o\ - math/tanh.o math/stubs.o math/j0_y0.o math/j1_y1.o math/jn_yn.o\ - math/cabs.o math/ftol.o - -OBJECTS = $(MISC_OBJECTS) $(STDLIB_OBJECTS) $(IO_OBJECTS) \ - $(FLOAT_OBJECTS) $(ASSERT_OBJECTS) $(PROCESS_OBJECTS) \ - $(STDIO_OBJECTS) $(CTYPE_OBJECTS) $(MATH_OBJECTS) \ - $(STRING_OBJECTS) $(TIME_OBJECTS) $(WCHAR_OBJECTS) \ - $(SYS_STAT_OBJECTS) $(MALLOC_OBJECTS) $(MBSTRING_OBJECTS)\ - $(SEARCH_OBJECTS) $(CONIO_OBJECTS) $(DIRECT_OBJECTS) \ - $(SIGNAL_OBJECTS) $(SETJMP_OBJECTS) $(LOCALE_OBJECTS) \ - $(EXCEPT_OBJECTS) $(TCHAR_OBJECTS) +STDLIB_OBJECTS = \ + $(PATH_TO_MSVCRT)/stdlib/_exit.o \ + $(PATH_TO_MSVCRT)/stdlib/abort.o \ + $(PATH_TO_MSVCRT)/stdlib/abs.o \ + $(PATH_TO_MSVCRT)/stdlib/atexit.o \ + $(PATH_TO_MSVCRT)/stdlib/atof.o \ + $(PATH_TO_MSVCRT)/stdlib/atoi.o \ + $(PATH_TO_MSVCRT)/stdlib/atol.o \ + $(PATH_TO_MSVCRT)/stdlib/bsearch.o \ + $(PATH_TO_MSVCRT)/stdlib/div.o \ + $(PATH_TO_MSVCRT)/stdlib/ecvt.o \ + $(PATH_TO_MSVCRT)/stdlib/ecvtbuf.o \ + stdlib/errno.o \ + $(PATH_TO_MSVCRT)/stdlib/fcvt.o \ + $(PATH_TO_MSVCRT)/stdlib/fcvtbuf.o \ + stdlib/fullpath.o \ + $(PATH_TO_MSVCRT)/stdlib/gcvt.o \ + $(PATH_TO_MSVCRT)/stdlib/itoa.o \ + stdlib/itow.o \ + $(PATH_TO_MSVCRT)/stdlib/labs.o \ + $(PATH_TO_MSVCRT)/stdlib/ldiv.o \ + $(PATH_TO_MSVCRT)/stdlib/makepath.o \ + stdlib/malloc.o \ + stdlib/mbstowcs.o \ + $(PATH_TO_MSVCRT)/stdlib/obsol.o \ + stdlib/putenv.o \ + stdlib/qsort.o \ + stdlib/rand.o \ + $(PATH_TO_MSVCRT)/stdlib/rot.o \ + $(PATH_TO_MSVCRT)/stdlib/senv.o \ + $(PATH_TO_MSVCRT)/stdlib/splitp.o \ + $(PATH_TO_MSVCRT)/stdlib/strtod.o \ + $(PATH_TO_MSVCRT)/stdlib/strtol.o \ + $(PATH_TO_MSVCRT)/stdlib/strtoul.o \ + $(PATH_TO_MSVCRT)/stdlib/swab.o \ + $(PATH_TO_MSVCRT)/stdlib/wcstomb.o \ + +STRING_OBJECTS = \ + $(PATH_TO_MSVCRT)/string/memccpy.o \ + $(PATH_TO_MSVCRT)/string/memchr.o \ + $(PATH_TO_MSVCRT)/string/memcmp.o \ + $(PATH_TO_MSVCRT)/string/memcpy.o \ + $(PATH_TO_MSVCRT)/string/memicmp.o \ + $(PATH_TO_MSVCRT)/string/memmove.o \ + $(PATH_TO_MSVCRT)/string/memset.o \ + $(PATH_TO_MSVCRT)/string/strcat.o \ + $(PATH_TO_MSVCRT)/string/strchr.o \ + $(PATH_TO_MSVCRT)/string/strcmp.o \ + $(PATH_TO_MSVCRT)/string/strcoll.o \ + $(PATH_TO_MSVCRT)/string/strcpy.o \ + $(PATH_TO_MSVCRT)/string/strcspn.o \ + $(PATH_TO_MSVCRT)/string/strdup.o \ + string/strerror.o \ + $(PATH_TO_MSVCRT)/string/stricmp.o \ + $(PATH_TO_MSVCRT)/string/strlen.o \ + $(PATH_TO_MSVCRT)/string/strlwr.o \ + $(PATH_TO_MSVCRT)/string/strncat.o \ + $(PATH_TO_MSVCRT)/string/strncmp.o \ + $(PATH_TO_MSVCRT)/string/strncpy.o \ + $(PATH_TO_MSVCRT)/string/strnicmp.o \ + $(PATH_TO_MSVCRT)/string/strnlen.o \ + $(PATH_TO_MSVCRT)/string/strpbrk.o \ + $(PATH_TO_MSVCRT)/string/strrchr.o \ + $(PATH_TO_MSVCRT)/string/strrev.o \ + $(PATH_TO_MSVCRT)/string/strset.o \ + $(PATH_TO_MSVCRT)/string/strspn.o \ + $(PATH_TO_MSVCRT)/string/strstr.o \ + string/strtok.o \ + $(PATH_TO_MSVCRT)/string/strupr.o \ + string/str_old.o \ + $(PATH_TO_MSVCRT)/string/strxfrm.o + +SYS_STAT_OBJECTS = \ + sys_stat/fstat.o \ + $(PATH_TO_MSVCRT)/sys_stat/futime.o \ + sys_stat/ftime.o \ + sys_stat/systime.o \ + sys_stat/stat.o + +TCHAR_OBJECTS = \ + tchar/strdec.o \ + tchar/strinc.o \ + tchar/strninc.o \ + tchar/strncnt.o \ + tchar/strnextc.o \ + tchar/strspnp.o + +TIME_OBJECTS = \ + $(PATH_TO_MSVCRT)/time/clock.o \ + $(PATH_TO_MSVCRT)/time/ctime.o \ + $(PATH_TO_MSVCRT)/time/difftime.o \ + $(PATH_TO_MSVCRT)/time/strdate.o \ + $(PATH_TO_MSVCRT)/time/strftime.o \ + $(PATH_TO_MSVCRT)/time/strtime.o \ + $(PATH_TO_MSVCRT)/time/time.o \ + time/tz_vars.o \ + +WSTRING_OBJECTS = \ + $(PATH_TO_MSVCRT)/wstring/wcscat.o \ + $(PATH_TO_MSVCRT)/wstring/wcschr.o \ + $(PATH_TO_MSVCRT)/wstring/wcscmp.o \ + wchar/wcscoll.o \ + $(PATH_TO_MSVCRT)/wstring/wcscpy.o \ + $(PATH_TO_MSVCRT)/wstring/wcscspn.o \ + $(PATH_TO_MSVCRT)/wstring/wcsdup.o \ + $(PATH_TO_MSVCRT)/wstring/wcsicmp.o \ + wchar/wcslen.o \ + $(PATH_TO_MSVCRT)/wstring/wcslwr.o \ + $(PATH_TO_MSVCRT)/wstring/wcsncat.o \ + $(PATH_TO_MSVCRT)/wstring/wcsncmp.o \ + $(PATH_TO_MSVCRT)/wstring/wcsncpy.o \ + $(PATH_TO_MSVCRT)/wstring/wcsnlen.o \ + $(PATH_TO_MSVCRT)/wstring/wcspbrk.o \ + $(PATH_TO_MSVCRT)/wstring/wcsrchr.o \ + $(PATH_TO_MSVCRT)/wstring/wcsrev.o \ + $(PATH_TO_MSVCRT)/wstring/wcsset.o \ + $(PATH_TO_MSVCRT)/wstring/wcsspn.o \ + $(PATH_TO_MSVCRT)/wstring/wcsstr.o \ + wchar/wcstod.o \ + wchar/wcstok.o \ + wchar/wcstol.o \ + $(PATH_TO_MSVCRT)/wstring/wcsupr.o \ + $(PATH_TO_MSVCRT)/wstring/wcsxfrm.o \ + wchar/wtoi.o \ + wchar/wcstombs.o \ + $(PATH_TO_MSVCRT)/wstring/wcsnicmp.o + + +OBJECTS = \ + $(CONIO_OBJECTS) \ + $(CTYPE_OBJECTS) \ + $(DIRECT_OBJECTS) \ + $(EXCEPT_OBJECTS) \ + $(FLOAT_OBJECTS) \ + $(IO_OBJECTS) \ + $(LOCALE_OBJECTS) \ + $(MALLOC_OBJECTS) \ + $(MATH_OBJECTS) \ + $(MBSTRING_OBJECTS)\ + $(MISC_OBJECTS) \ + $(PROCESS_OBJECTS) \ + $(SEARCH_OBJECTS) \ + $(SETJMP_OBJECTS) \ + $(SIGNAL_OBJECTS) \ + $(STDIO_OBJECTS) \ + $(STDLIB_OBJECTS) \ + $(STRING_OBJECTS) \ + $(SYS_STAT_OBJECTS) \ + $(TCHAR_OBJECTS) \ + $(TIME_OBJECTS) \ + $(WSTRING_OBJECTS) $(TARGET_NAME).o: $(OBJECTS) $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o + +# EOF diff --git a/lib/crtdll/malloc/expand.c b/lib/crtdll/malloc/expand.c index 321330b..408757f 100644 --- a/lib/crtdll/malloc/expand.c +++ b/lib/crtdll/malloc/expand.c @@ -1,44 +1,42 @@ #include #include -#include -#include +#include +#include -void *_expand( void *pold, size_t size ) +void* _expand(void* pold, size_t size) { PHEAP_BUCKET pbucket; - PHEAP_SUBALLOC psub; - PHEAP_FRAGMENT pfrag=(PHEAP_FRAGMENT)((LPVOID)pold-HEAP_FRAG_ADMIN_SIZE); + PHEAP_SUBALLOC psub; + PHEAP_FRAGMENT pfrag = (PHEAP_FRAGMENT)((LPVOID)pold-HEAP_FRAG_ADMIN_SIZE); /* sanity checks */ - if(pfrag->Magic!=HEAP_FRAG_MAGIC) + if (pfrag->Magic != HEAP_FRAG_MAGIC) return NULL; /* get bucket size */ - psub=pfrag->Sub; - pbucket=psub->Bucket; - if(size<=pbucket->Size) - { + psub = pfrag->Sub; + pbucket = psub->Bucket; + if(size <= pbucket->Size) { pfrag->Size=size; return pold; } else - return NULL; - + return NULL; return NULL; } -size_t _msize (void* pBlock) +size_t _msize(void* pBlock) { PHEAP_BUCKET pbucket; - PHEAP_SUBALLOC psub; - PHEAP_FRAGMENT pfrag=(PHEAP_FRAGMENT)((LPVOID)pBlock-HEAP_FRAG_ADMIN_SIZE); + PHEAP_SUBALLOC psub; + PHEAP_FRAGMENT pfrag = (PHEAP_FRAGMENT)((LPVOID)pBlock-HEAP_FRAG_ADMIN_SIZE); /* sanity checks */ - if(pfrag->Magic!=HEAP_FRAG_MAGIC) + if (pfrag->Magic != HEAP_FRAG_MAGIC) return 0; /* get bucket size */ - psub=pfrag->Sub; - pbucket=psub->Bucket; + psub = pfrag->Sub; + pbucket = psub->Bucket; return pbucket->Size; } diff --git a/lib/crtdll/malloc/heap.c b/lib/crtdll/malloc/heap.c index 11d9907..5737e75 100644 --- a/lib/crtdll/malloc/heap.c +++ b/lib/crtdll/malloc/heap.c @@ -1,29 +1,30 @@ #include -#include +#include -int _heapchk (void) +int _heapchk(void) { if (!HeapValidate(GetProcessHeap(), 0, NULL)) return -1; return 0; } -int _heapmin (void) + +int _heapmin(void) { - if ( !HeapCompact( GetProcessHeap(), 0 )) + if (!HeapCompact(GetProcessHeap(), 0)) return -1; return 0; } -int _heapset (unsigned int unFill) + +int _heapset(unsigned int unFill) { - if ( _heapchk() == -1 ) + if (_heapchk() == -1) return -1; return 0; } - -int _heapwalk ( struct _heapinfo *entry) +int _heapwalk(struct _heapinfo* entry) { return 0; } diff --git a/lib/crtdll/math/acos.c b/lib/crtdll/math/acos.c index 776ddd2..23376a6 100644 --- a/lib/crtdll/math/acos.c +++ b/lib/crtdll/math/acos.c @@ -18,9 +18,10 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include -double acos (double __x) + +double acos(double __x) { - return atan2 (sqrt (1.0 - __x * __x), __x); + return atan2(sqrt(1.0 - __x * __x), __x); } diff --git a/lib/crtdll/math/acosh.c b/lib/crtdll/math/acosh.c index 15f556c..cb1dbed 100644 --- a/lib/crtdll/math/acosh.c +++ b/lib/crtdll/math/acosh.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -double -acosh(double x) + +double acosh(double x) { - return log(x + sqrt(x*x - 1)); + return log(x + sqrt(x*x - 1)); } diff --git a/lib/crtdll/math/asin.c b/lib/crtdll/math/asin.c index 4109811..fa57df2 100644 --- a/lib/crtdll/math/asin.c +++ b/lib/crtdll/math/asin.c @@ -18,9 +18,10 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include -double asin (double __x) + +double asin(double __x) { - return atan2 (__x, sqrt (1.0 - __x * __x)); + return atan2(__x, sqrt(1.0 - __x * __x)); } diff --git a/lib/crtdll/math/asinh.c b/lib/crtdll/math/asinh.c index 7089ebc..402c46e 100644 --- a/lib/crtdll/math/asinh.c +++ b/lib/crtdll/math/asinh.c @@ -1,9 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -double -asinh(double x) + +double asinh(double x) { - return x>0 ? log(x + sqrt(x*x + 1)) : -log(sqrt(x*x+1)-x); + return x>0 ? log(x + sqrt(x*x + 1)) : -log(sqrt(x*x+1)-x); } - diff --git a/lib/crtdll/math/atan.c b/lib/crtdll/math/atan.c index 853385b..af0e219 100644 --- a/lib/crtdll/math/atan.c +++ b/lib/crtdll/math/atan.c @@ -18,15 +18,20 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + double atan (double __x); double atan (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fld1\n\t" "fpatan" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_atan(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/atan2.c b/lib/crtdll/math/atan2.c index f23be33..28079d0 100644 --- a/lib/crtdll/math/atan2.c +++ b/lib/crtdll/math/atan2.c @@ -1,12 +1,18 @@ + +#include + double atan2 (double __y, double __x); double atan2 (double __y, double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fpatan\n\t" "fld %%st(0)" : "=t" (__value) : "0" (__x), "u" (__y)); - +#else + __value = linkme_atan2(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/atanh.c b/lib/crtdll/math/atanh.c index fdfb319..ee12288 100644 --- a/lib/crtdll/math/atanh.c +++ b/lib/crtdll/math/atanh.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -double -atanh(double x) + +double atanh(double x) { return log((1+x)/(1-x)) / 2.0; } diff --git a/lib/crtdll/math/cabs.c b/lib/crtdll/math/cabs.c index 2c3ada9..73d4643 100644 --- a/lib/crtdll/math/cabs.c +++ b/lib/crtdll/math/cabs.c @@ -1,4 +1,4 @@ -#include +#include double _cabs( struct _complex z ) { diff --git a/lib/crtdll/math/ceil.c b/lib/crtdll/math/ceil.c index eedff4f..7434cf4 100644 --- a/lib/crtdll/math/ceil.c +++ b/lib/crtdll/math/ceil.c @@ -1,10 +1,9 @@ -#include - -double ceil (double __x); +#include double ceil (double __x) { register double __value; +#ifdef __GNUC__ __volatile unsigned short int __cw, __cwtmp; __asm __volatile ("fnstcw %0" : "=m" (__cw)); @@ -12,7 +11,9 @@ double ceil (double __x) __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); __asm __volatile ("fldcw %0" : : "m" (__cw)); - +#else + __value = linkme_ceil(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/cos.c b/lib/crtdll/math/cos.c index 07edd8b..981380e 100644 --- a/lib/crtdll/math/cos.c +++ b/lib/crtdll/math/cos.c @@ -1,11 +1,16 @@ +#include + double cos (double __x); double cos (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fcos" : "=t" (__value): "0" (__x)); - +#else + __value = linkme_cos(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/cosh.c b/lib/crtdll/math/cosh.c index 85e95f0..10fadd6 100644 --- a/lib/crtdll/math/cosh.c +++ b/lib/crtdll/math/cosh.c @@ -1,8 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include + double cosh(double x) { - const double ebig = exp(fabs(x)); - return (ebig + 1.0/ebig) / 2.0; + const double ebig = exp(fabs(x)); + return (ebig + 1.0/ebig) / 2.0; } diff --git a/lib/crtdll/math/exp.c b/lib/crtdll/math/exp.c index 71df0e0..2707cf8 100644 --- a/lib/crtdll/math/exp.c +++ b/lib/crtdll/math/exp.c @@ -18,11 +18,13 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double exp (double __x); double exp (double __x) { +#ifdef __GNUC__ register double __value, __exponent; __asm __volatile__ ("fldl2e # e^x = 2^(x * log2(e))\n\t" @@ -39,4 +41,7 @@ double exp (double __x) : "=t" (__value) : "0" (__value), "u" (__exponent)); return __value; +#else + return linkme_exp(__x); +#endif /*__GNUC__*/ } diff --git a/lib/crtdll/math/fabs.c b/lib/crtdll/math/fabs.c index a2a8bdc..5db505a 100644 --- a/lib/crtdll/math/fabs.c +++ b/lib/crtdll/math/fabs.c @@ -18,15 +18,19 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double fabs (double __x); double fabs (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fabs" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_fabs(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/floor.c b/lib/crtdll/math/floor.c index 7403a52..b799387 100644 --- a/lib/crtdll/math/floor.c +++ b/lib/crtdll/math/floor.c @@ -18,12 +18,14 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double floor (double __x); double floor (double __x) { register double __value; +#ifdef __GNUC__ __volatile unsigned short int __cw, __cwtmp; __asm __volatile ("fnstcw %0" : "=m" (__cw)); @@ -31,7 +33,9 @@ double floor (double __x) __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); __asm __volatile ("fldcw %0" : : "m" (__cw)); - +#else + __value = linkme_floor(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/fmod.c b/lib/crtdll/math/fmod.c index 5618cf3..263d687 100644 --- a/lib/crtdll/math/fmod.c +++ b/lib/crtdll/math/fmod.c @@ -18,18 +18,22 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double fmod (double __x, double __y); double fmod (double __x, double __y) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("1: fprem\n\t" "fstsw %%ax\n\t" "sahf\n\t" "jp 1b" : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); - +#else + __value = linkme_fmod(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/frexp.c b/lib/crtdll/math/frexp.c index 8b3390d..b85cd98 100644 --- a/lib/crtdll/math/frexp.c +++ b/lib/crtdll/math/frexp.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include double frexp(double __x, int *exptr) diff --git a/lib/crtdll/math/ftol.c b/lib/crtdll/math/ftol.c index b20aef4..1753090 100644 --- a/lib/crtdll/math/ftol.c +++ b/lib/crtdll/math/ftol.c @@ -1,5 +1,6 @@ -#include +#include -long _ftol(double fl) { +long _ftol(double fl) +{ return (long)fl; } diff --git a/lib/crtdll/math/huge_val.c b/lib/crtdll/math/huge_val.c index 91eefa0..6b92fcb 100644 --- a/lib/crtdll/math/huge_val.c +++ b/lib/crtdll/math/huge_val.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include #undef _HUGE double_t _HUGE = { 0x00000, 0x00000, 0x7ff, 0x0 }; diff --git a/lib/crtdll/math/hypot.c b/lib/crtdll/math/hypot.c index 08e3492..aded378 100644 --- a/lib/crtdll/math/hypot.c +++ b/lib/crtdll/math/hypot.c @@ -16,9 +16,9 @@ * */ -#include -#include -#include +#include +#include +#include /* Approximate square roots of DBL_MAX and DBL_MIN. Numbers between these two shouldn't neither overflow nor underflow @@ -78,7 +78,7 @@ _hypot(double x, double y) #ifdef TEST -#include +#include int main(void) diff --git a/lib/crtdll/math/j0_y0.c b/lib/crtdll/math/j0_y0.c index 7512077..83035ee 100644 --- a/lib/crtdll/math/j0_y0.c +++ b/lib/crtdll/math/j0_y0.c @@ -1,4 +1,5 @@ -#include +#include + double _j0(double x) { diff --git a/lib/crtdll/math/j1_y1.c b/lib/crtdll/math/j1_y1.c index 90e2fb1..55d6bd6 100644 --- a/lib/crtdll/math/j1_y1.c +++ b/lib/crtdll/math/j1_y1.c @@ -1,4 +1,5 @@ -#include +#include + double _j1(double x) { diff --git a/lib/crtdll/math/jn_yn.c b/lib/crtdll/math/jn_yn.c index b641a81..8a3c833 100644 --- a/lib/crtdll/math/jn_yn.c +++ b/lib/crtdll/math/jn_yn.c @@ -1,4 +1,5 @@ -#include +#include + double _jn(int n, double x) { diff --git a/lib/crtdll/math/ldexp.c b/lib/crtdll/math/ldexp.c index 4599fd5..9c60344 100644 --- a/lib/crtdll/math/ldexp.c +++ b/lib/crtdll/math/ldexp.c @@ -18,14 +18,19 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + double ldexp (double __x, int __y); double ldexp (double __x, int __y) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fscale" : "=t" (__value) : "0" (__x), "u" ((double) __y)); - +#else + __value = linkme_ldexp(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/log.c b/lib/crtdll/math/log.c index c19c30f..014c78a 100644 --- a/lib/crtdll/math/log.c +++ b/lib/crtdll/math/log.c @@ -18,16 +18,21 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + double log (double __x); double log (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fldln2\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_log(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/log10.c b/lib/crtdll/math/log10.c index b57b1a5..58e8cd6 100644 --- a/lib/crtdll/math/log10.c +++ b/lib/crtdll/math/log10.c @@ -18,17 +18,21 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double log10 (double __x); double log10 (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fldlg2\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_log10(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/modf.c b/lib/crtdll/math/modf.c index 6864e52..336a7d7 100644 --- a/lib/crtdll/math/modf.c +++ b/lib/crtdll/math/modf.c @@ -10,9 +10,9 @@ * ==================================================== */ -#include -#include -#include +#include +#include +#include @@ -20,7 +20,6 @@ double modf(double __x, double *__i) { - double_t * x = (double_t *)&__x; double_t * iptr = ( double_t *)__i; @@ -39,7 +38,7 @@ double modf(double __x, double *__i) return 0.0; } - i = (0x000fffff)>>j0; + i = (0x000fffff)>>j0; iptr->sign = x->sign; iptr->exponent = x->exponent; iptr->mantissah = x->mantissah&(~i); @@ -48,48 +47,43 @@ double modf(double __x, double *__i) __x = 0.0; x->sign = iptr->sign; return __x; - } - return __x - *__i; + } + return __x - *__i; } } else if (j0>51) { /* no fraction part */ - *__i = __x; - if ( _isnan(__x) || _isinf(__x) ) - return __x; - - - __x = 0.0; - x->sign = iptr->sign; + *__i = __x; + if ( _isnan(__x) || _isinf(__x) ) return __x; - } else { /* fraction part in low x */ + __x = 0.0; + x->sign = iptr->sign; + return __x; + } else { /* fraction part in low x */ - i = ((unsigned)(0xffffffff))>>(j0-20); - iptr->sign = x->sign; - iptr->exponent = x->exponent; - iptr->mantissah = x->mantissah; - iptr->mantissal = x->mantissal&(~i); - if ( __x == *__i ) { - __x = 0.0; - x->sign = iptr->sign; - return __x; - } - return __x - *__i; + i = ((unsigned)(0xffffffff))>>(j0-20); + iptr->sign = x->sign; + iptr->exponent = x->exponent; + iptr->mantissah = x->mantissah; + iptr->mantissal = x->mantissal&(~i); + if ( __x == *__i ) { + __x = 0.0; + x->sign = iptr->sign; + return __x; + } + return __x - *__i; } } long double modfl(long double __x, long double *__i) { - - long_double_t * x = (long_double_t *)&__x; long_double_t * iptr = (long_double_t *)__i; int j0; unsigned int i; j0 = x->exponent - 0x3fff; /* exponent of x */ - - + if(j0<32) { /* integer part in high x */ if(j0<0) { /* |x|<1 */ *__i = 0.0L; @@ -97,7 +91,7 @@ long double modfl(long double __x, long double *__i) return __x; } else { - i = ((unsigned int)(0xffffffff))>>(j0+1); + i = ((unsigned int)(0xffffffff))>>(j0+1); if ( x->mantissal == 0 && (x->mantissal & i) == 0 ) { *__i = __x; __x = 0.0L; @@ -106,36 +100,33 @@ long double modfl(long double __x, long double *__i) } iptr->sign = x->sign; iptr->exponent = x->exponent; - iptr->mantissah = x->mantissah&((~i)); + iptr->mantissah = x->mantissah&((~i)); iptr->mantissal = 0; - - return __x - *__i; + return __x - *__i; } } else if (j0>63) { /* no fraction part */ - *__i = __x; - if ( _isnanl(__x) || _isinfl(__x) ) - return __x; - - __x = 0.0L; - x->sign = iptr->sign; + *__i = __x; + if ( _isnanl(__x) || _isinfl(__x) ) return __x; + + __x = 0.0L; + x->sign = iptr->sign; + return __x; } else { /* fraction part in low x */ - i = ((unsigned int)(0xffffffff))>>(j0-32); - if ( x->mantissal == 0 ) { - *__i = __x; - __x = 0.0L; - x->sign = iptr->sign; - return __x; - } - iptr->sign = x->sign; - iptr->exponent = x->exponent; - iptr->mantissah = x->mantissah; - iptr->mantissal = x->mantissal&(~i); + i = ((unsigned int)(0xffffffff))>>(j0-32); + if ( x->mantissal == 0 ) { + *__i = __x; + __x = 0.0L; + x->sign = iptr->sign; + return __x; + } + iptr->sign = x->sign; + iptr->exponent = x->exponent; + iptr->mantissah = x->mantissah; + iptr->mantissal = x->mantissal&(~i); - return __x - *__i; - - + return __x - *__i; } } diff --git a/lib/crtdll/math/pow.c b/lib/crtdll/math/pow.c index 37810ac..641fda1 100644 --- a/lib/crtdll/math/pow.c +++ b/lib/crtdll/math/pow.c @@ -18,6 +18,8 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + double pow (double __x, double __y); double __log2 (double __x); @@ -25,18 +27,24 @@ double __log2 (double __x); double __log2 (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fld1\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + //__value = linkme_log2(__x); + __value = 0; +#endif /*__GNUC__*/ return __value; } double pow (double __x, double __y) { - register double __value, __exponent; + register double __value; +#ifdef __GNUC__ + register double __exponent; long __p = (long) __y; if (__x == 0.0 && __y > 0.0) @@ -74,7 +82,9 @@ double pow (double __x, double __y) __asm __volatile__ ("fscale" : "=t" (__value) : "0" (__value), "u" (__exponent)); - +#else + __value = linkme_pow(__x, __y); +#endif /*__GNUC__*/ return __value; } @@ -82,4 +92,3 @@ long double powl (long double __x,long double __y) { return pow(__x,__y/2)*pow(__x,__y/2); } - diff --git a/lib/crtdll/math/sin.c b/lib/crtdll/math/sin.c index 80d7630..db070a3 100644 --- a/lib/crtdll/math/sin.c +++ b/lib/crtdll/math/sin.c @@ -18,15 +18,19 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double sin (double __x); double sin (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fsin" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_sin(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/sinh.c b/lib/crtdll/math/sinh.c index 7acb21f..5a0b2be 100644 --- a/lib/crtdll/math/sinh.c +++ b/lib/crtdll/math/sinh.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include double sinh(double x) { diff --git a/lib/crtdll/math/sqrt.c b/lib/crtdll/math/sqrt.c index a17cec1..d414fcd 100644 --- a/lib/crtdll/math/sqrt.c +++ b/lib/crtdll/math/sqrt.c @@ -17,16 +17,19 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#include double sqrt (double __x); double sqrt (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fsqrt" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_sqrt(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/stubs.c b/lib/crtdll/math/stubs.c index 65b6010..57eb090 100644 --- a/lib/crtdll/math/stubs.c +++ b/lib/crtdll/math/stubs.c @@ -1,84 +1,85 @@ -#include +#include -double _CIsin (double x); -double _CIcos (double x); -double _CItan (double x); -double _CIsinh (double x); -double _CIcosh (double x); -double _CItanh (double x); -double _CIasin (double x); -double _CIacos (double x); -double _CIatan (double x); -double _CIatan2 (double y, double x); -double _CIexp (double x); -double _CIlog (double x); -double _CIlog10 (double x); -double _CIpow (double x, double y); -double _CIsqrt (double x); -double _CIfmod (double x, double y); +double _CIsin(double x); +double _CIcos(double x); +double _CItan(double x); +double _CIsinh(double x); +double _CIcosh(double x); +double _CItanh(double x); +double _CIasin(double x); +double _CIacos(double x); +double _CIatan(double x); +double _CIatan2(double y, double x); +double _CIexp(double x); +double _CIlog(double x); +double _CIlog10(double x); +double _CIpow(double x, double y); +double _CIsqrt(double x); +double _CIfmod(double x, double y); -double _CIsin (double x) + +double _CIsin(double x) { return sin(x); } -double _CIcos (double x) +double _CIcos(double x) { return cos(x); } -double _CItan (double x) +double _CItan(double x) { return tan(x); } -double _CIsinh (double x) +double _CIsinh(double x) { return sinh(x); } -double _CIcosh (double x) +double _CIcosh(double x) { return cosh(x); } -double _CItanh (double x) +double _CItanh(double x) { return tanh(x); } -double _CIasin (double x) +double _CIasin(double x) { return asin(x); } -double _CIacos (double x) +double _CIacos(double x) { return acos(x); } -double _CIatan (double x) +double _CIatan(double x) { return atan(x); } -double _CIatan2 (double y, double x) +double _CIatan2(double y, double x) { - return atan2(y,x); + return atan2(y, x); } -double _CIexp (double x) +double _CIexp(double x) { return exp(x); } -double _CIlog (double x) +double _CIlog(double x) { return log(x); } -double _CIlog10 (double x) +double _CIlog10(double x) { return log10(x); } -double _CIpow (double x, double y) +double _CIpow(double x, double y) { - return pow(x,y); + return pow(x, y); } -double _CIsqrt (double x) +double _CIsqrt(double x) { return sqrt(x); } -double _CIfmod (double x, double y) +double _CIfmod(double x, double y) { - return fmod(x,y); + return fmod(x, y); } diff --git a/lib/crtdll/math/tan.c b/lib/crtdll/math/tan.c index 2a460a9..1acc036 100644 --- a/lib/crtdll/math/tan.c +++ b/lib/crtdll/math/tan.c @@ -18,16 +18,20 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include double tan (double __x); double tan (double __x) { register double __value; +#ifdef __GNUC__ register double __value2 __attribute__ ((unused)); __asm __volatile__ ("fptan" : "=t" (__value2), "=u" (__value) : "0" (__x)); - +#else + __value = linkme_tan(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/crtdll/math/tanh.c b/lib/crtdll/math/tanh.c index 12b0012..da1eabb 100644 --- a/lib/crtdll/math/tanh.c +++ b/lib/crtdll/math/tanh.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include + +#include double tanh(double x) { @@ -14,4 +15,3 @@ double tanh(double x) return (ebig - esmall) / (ebig + esmall); } } - diff --git a/lib/crtdll/mbstring/hanzen.c b/lib/crtdll/mbstring/hanzen.c index 23df35a..f640d4e 100644 --- a/lib/crtdll/mbstring/hanzen.c +++ b/lib/crtdll/mbstring/hanzen.c @@ -9,7 +9,7 @@ * 12/04/99: Created */ -#include +#include static unsigned short han_to_zen_ascii_table[0x5f] = { 0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166, diff --git a/lib/crtdll/mbstring/ischira.c b/lib/crtdll/mbstring/ischira.c index 87a2236..0b6ca56 100644 --- a/lib/crtdll/mbstring/ischira.c +++ b/lib/crtdll/mbstring/ischira.c @@ -8,25 +8,26 @@ * 12/04/99: Created */ -#include -#include +#include +#include -int _ismbchira( unsigned int c ) + +int _ismbchira(unsigned int c) { return ((c>=0x829F) && (c<=0x82F1)); } -int _ismbckata( unsigned int c ) +int _ismbckata(unsigned int c) { return ((c>=0x8340) && (c<=0x8396)); } -unsigned int _mbctohira( unsigned int c ) +unsigned int _mbctohira(unsigned int c) { return c; } -unsigned int _mbctokata( unsigned int c ) +unsigned int _mbctokata(unsigned int c) { return c; } diff --git a/lib/crtdll/mbstring/iskana.c b/lib/crtdll/mbstring/iskana.c index b61ff8b..5793a1f 100644 --- a/lib/crtdll/mbstring/iskana.c +++ b/lib/crtdll/mbstring/iskana.c @@ -8,8 +8,8 @@ Modified from Taiji Yamada japanese code system utilities * 12/04/99: Created */ -#include -#include +#include +#include int _ismbbkana(unsigned char c) { diff --git a/lib/crtdll/mbstring/iskmoji.c b/lib/crtdll/mbstring/iskmoji.c index 3884552..b9bceac 100644 --- a/lib/crtdll/mbstring/iskmoji.c +++ b/lib/crtdll/mbstring/iskmoji.c @@ -1,4 +1,4 @@ -#include +#include int _ismbbkalpha(unsigned char c) { diff --git a/lib/crtdll/mbstring/iskpun.c b/lib/crtdll/mbstring/iskpun.c index e515354..a690c17 100644 --- a/lib/crtdll/mbstring/iskpun.c +++ b/lib/crtdll/mbstring/iskpun.c @@ -7,7 +7,7 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include +#include int _ismbbkpunct( unsigned int c ) { diff --git a/lib/crtdll/mbstring/islead.c b/lib/crtdll/mbstring/islead.c index 6026c34..08ff0a6 100644 --- a/lib/crtdll/mbstring/islead.c +++ b/lib/crtdll/mbstring/islead.c @@ -1,5 +1,5 @@ #include -#include +#include int isleadbyte(char *mbstr) { diff --git a/lib/crtdll/mbstring/islwr.c b/lib/crtdll/mbstring/islwr.c index f64eade..01c9cf4 100644 --- a/lib/crtdll/mbstring/islwr.c +++ b/lib/crtdll/mbstring/islwr.c @@ -8,8 +8,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include // code page 952 only int _ismbclower( unsigned int c ) diff --git a/lib/crtdll/mbstring/ismbal.c b/lib/crtdll/mbstring/ismbal.c index d62d5d1..ee14c43 100644 --- a/lib/crtdll/mbstring/ismbal.c +++ b/lib/crtdll/mbstring/ismbal.c @@ -7,10 +7,8 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include - -int _ismbbkalnum( unsigned int c ); +#include +#include int _ismbbalpha(unsigned char c) { diff --git a/lib/crtdll/mbstring/ismbaln.c b/lib/crtdll/mbstring/ismbaln.c index 2c85873..622a87b 100644 --- a/lib/crtdll/mbstring/ismbaln.c +++ b/lib/crtdll/mbstring/ismbaln.c @@ -1,7 +1,6 @@ -#include -#include +#include +#include -int _ismbbkalnum( unsigned int c ); int _ismbbalnum(unsigned char c) { diff --git a/lib/crtdll/mbstring/ismbc.c b/lib/crtdll/mbstring/ismbc.c index ad8c8c6..a79edbd 100644 --- a/lib/crtdll/mbstring/ismbc.c +++ b/lib/crtdll/mbstring/ismbc.c @@ -1,4 +1,4 @@ -#include +#include int _ismbbalpha(unsigned char c); int _ismbbalnum(unsigned char c); @@ -87,7 +87,6 @@ int _ismbclegal(unsigned int c) return _ismbbtrail(c&0xFF); return 0; - } int _ismbcl0(unsigned int c) diff --git a/lib/crtdll/mbstring/ismbgra.c b/lib/crtdll/mbstring/ismbgra.c index 6b3469f..f0ec05b 100644 --- a/lib/crtdll/mbstring/ismbgra.c +++ b/lib/crtdll/mbstring/ismbgra.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _ismbbgraph(unsigned char c) { diff --git a/lib/crtdll/mbstring/ismbkaln.c b/lib/crtdll/mbstring/ismbkaln.c index 64340ab..f4e5bc8 100644 --- a/lib/crtdll/mbstring/ismbkaln.c +++ b/lib/crtdll/mbstring/ismbkaln.c @@ -7,8 +7,8 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include +#include +#include int _ismbbkalnum( unsigned int c ) { diff --git a/lib/crtdll/mbstring/ismblead.c b/lib/crtdll/mbstring/ismblead.c index 9282210..f15f3ec 100644 --- a/lib/crtdll/mbstring/ismblead.c +++ b/lib/crtdll/mbstring/ismblead.c @@ -9,9 +9,9 @@ * 12/04/99: Created */ -#include -#include -#include +#include +#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/ismbpri.c b/lib/crtdll/mbstring/ismbpri.c index 76d4075..dcd997d 100644 --- a/lib/crtdll/mbstring/ismbpri.c +++ b/lib/crtdll/mbstring/ismbpri.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _ismbbprint(unsigned char c) { diff --git a/lib/crtdll/mbstring/ismbpun.c b/lib/crtdll/mbstring/ismbpun.c index eb418e4..0575693 100644 --- a/lib/crtdll/mbstring/ismbpun.c +++ b/lib/crtdll/mbstring/ismbpun.c @@ -1,10 +1,8 @@ - //iskana() :(0xA1 <= c <= 0xDF) - //iskpun() :(0xA1 <= c <= 0xA6) - //iskmoji() :(0xA7 <= c <= 0xDF) -#include -#include -#include +#include +#include +#include + int _ismbbpunct(unsigned char c) { @@ -12,3 +10,6 @@ int _ismbbpunct(unsigned char c) return (ispunct(c) || _ismbbkana(c)); } + //iskana() :(0xA1 <= c <= 0xDF) + //iskpun() :(0xA1 <= c <= 0xA6) + //iskmoji() :(0xA7 <= c <= 0xDF) diff --git a/lib/crtdll/mbstring/ismbtrl.c b/lib/crtdll/mbstring/ismbtrl.c index f6d7b40..aeeff7e 100644 --- a/lib/crtdll/mbstring/ismbtrl.c +++ b/lib/crtdll/mbstring/ismbtrl.c @@ -8,8 +8,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/isuppr.c b/lib/crtdll/mbstring/isuppr.c index 05afc64..110b9a8 100644 --- a/lib/crtdll/mbstring/isuppr.c +++ b/lib/crtdll/mbstring/isuppr.c @@ -8,8 +8,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include // code page 952 only int _ismbcupper( unsigned int c ) diff --git a/lib/crtdll/mbstring/jistojms.c b/lib/crtdll/mbstring/jistojms.c index a34e311..c05d80e 100644 --- a/lib/crtdll/mbstring/jistojms.c +++ b/lib/crtdll/mbstring/jistojms.c @@ -1,4 +1,4 @@ -#include +#include unsigned short _mbcjistojms(unsigned short c) { diff --git a/lib/crtdll/mbstring/jmstojis.c b/lib/crtdll/mbstring/jmstojis.c index f3496aa..62c948d 100644 --- a/lib/crtdll/mbstring/jmstojis.c +++ b/lib/crtdll/mbstring/jmstojis.c @@ -1,4 +1,4 @@ -#include +#include unsigned short _mbcjmstojis(unsigned short c) { diff --git a/lib/crtdll/mbstring/mbbtype.c b/lib/crtdll/mbstring/mbbtype.c index 06d6de8..6ecb193 100644 --- a/lib/crtdll/mbstring/mbbtype.c +++ b/lib/crtdll/mbstring/mbbtype.c @@ -8,8 +8,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include int _mbbtype(unsigned char c , int type) { diff --git a/lib/crtdll/mbstring/mbccpy.c b/lib/crtdll/mbstring/mbccpy.c index d78af8d..fe05428 100644 --- a/lib/crtdll/mbstring/mbccpy.c +++ b/lib/crtdll/mbstring/mbccpy.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbclen.c b/lib/crtdll/mbstring/mbclen.c index c579932..c4286e2 100644 --- a/lib/crtdll/mbstring/mbclen.c +++ b/lib/crtdll/mbstring/mbclen.c @@ -1,6 +1,5 @@ -#include - -#include +#include +#include size_t _mbclen(const unsigned char *s) diff --git a/lib/crtdll/mbstring/mbscat.c b/lib/crtdll/mbstring/mbscat.c index 62b3d05..4212308 100644 --- a/lib/crtdll/mbstring/mbscat.c +++ b/lib/crtdll/mbstring/mbscat.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbscat(unsigned char *dst, const unsigned char *src) { diff --git a/lib/crtdll/mbstring/mbschr.c b/lib/crtdll/mbstring/mbschr.c index f9be9c8..9e73aee 100644 --- a/lib/crtdll/mbstring/mbschr.c +++ b/lib/crtdll/mbstring/mbschr.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbschr(const unsigned char *str, unsigned int c) { diff --git a/lib/crtdll/mbstring/mbscmp.c b/lib/crtdll/mbstring/mbscmp.c index ad48d16..ad2a133 100644 --- a/lib/crtdll/mbstring/mbscmp.c +++ b/lib/crtdll/mbstring/mbscmp.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int _mbscmp(const unsigned char *str1, const unsigned char *str2) { diff --git a/lib/crtdll/mbstring/mbscoll.c b/lib/crtdll/mbstring/mbscoll.c index d3236cd..dad12be 100644 --- a/lib/crtdll/mbstring/mbscoll.c +++ b/lib/crtdll/mbstring/mbscoll.c @@ -8,7 +8,7 @@ * 12/04/99: Created */ -#include +#include int colldif(unsigned short c1, unsigned short c2); @@ -54,6 +54,7 @@ int _mbscoll(const unsigned char *str1, const unsigned char *str2) return 0; } +#if 0 int _mbsbcoll(const unsigned char *str1, const unsigned char *str2) { unsigned char *s1 = (unsigned char *)str1; @@ -93,3 +94,4 @@ int _mbsbcoll(const unsigned char *str1, const unsigned char *str2) } ; return 0; } +#endif diff --git a/lib/crtdll/mbstring/mbscpy.c b/lib/crtdll/mbstring/mbscpy.c index 1c66e61..c904566 100644 --- a/lib/crtdll/mbstring/mbscpy.c +++ b/lib/crtdll/mbstring/mbscpy.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include unsigned char * _mbscpy(unsigned char *dst, const unsigned char *str) { diff --git a/lib/crtdll/mbstring/mbscspn.c b/lib/crtdll/mbstring/mbscspn.c index 055adce..46783ee 100644 --- a/lib/crtdll/mbstring/mbscspn.c +++ b/lib/crtdll/mbstring/mbscspn.c @@ -1,4 +1,5 @@ -#include +#include + // not correct size_t _mbscspn(const unsigned char *s1, const unsigned char *s2) { diff --git a/lib/crtdll/mbstring/mbsdec.c b/lib/crtdll/mbstring/mbsdec.c index 00b58f3..0836f15 100644 --- a/lib/crtdll/mbstring/mbsdec.c +++ b/lib/crtdll/mbstring/mbsdec.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbsdec(const unsigned char *str, const unsigned char *cur) { diff --git a/lib/crtdll/mbstring/mbsdup.c b/lib/crtdll/mbstring/mbsdup.c index ac50252..00dc9d0 100644 --- a/lib/crtdll/mbstring/mbsdup.c +++ b/lib/crtdll/mbstring/mbsdup.c @@ -9,8 +9,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include unsigned char * _mbsdup(const unsigned char *_s) { diff --git a/lib/crtdll/mbstring/mbsicmp.c b/lib/crtdll/mbstring/mbsicmp.c index f8103c5..db88fed 100644 --- a/lib/crtdll/mbstring/mbsicmp.c +++ b/lib/crtdll/mbstring/mbsicmp.c @@ -7,9 +7,9 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include -#include +#include +#include +#include int _mbsicmp(const unsigned char *str1, const unsigned char *str2) { diff --git a/lib/crtdll/mbstring/mbsicoll.c b/lib/crtdll/mbstring/mbsicoll.c index 6b2da15..32020cc 100644 --- a/lib/crtdll/mbstring/mbsicoll.c +++ b/lib/crtdll/mbstring/mbsicoll.c @@ -7,9 +7,10 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include -#include +#include +#include +#include + int colldif(unsigned short c1, unsigned short c2); int _mbsicoll(const unsigned char *str1, const unsigned char *str2) { diff --git a/lib/crtdll/mbstring/mbsinc.c b/lib/crtdll/mbstring/mbsinc.c index d062006..30e42e9 100644 --- a/lib/crtdll/mbstring/mbsinc.c +++ b/lib/crtdll/mbstring/mbsinc.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbsinc(const unsigned char *s) { diff --git a/lib/crtdll/mbstring/mbslen.c b/lib/crtdll/mbstring/mbslen.c index 3eca134..06386b2 100644 --- a/lib/crtdll/mbstring/mbslen.c +++ b/lib/crtdll/mbstring/mbslen.c @@ -1,4 +1,4 @@ -#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbslwr.c b/lib/crtdll/mbstring/mbslwr.c index cdbdf5f..67663ea 100644 --- a/lib/crtdll/mbstring/mbslwr.c +++ b/lib/crtdll/mbstring/mbslwr.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include unsigned int _mbbtolower(unsigned int c) { @@ -7,34 +7,33 @@ unsigned int _mbbtolower(unsigned int c) return tolower(c); return c; } + // code page 952 #define CASE_DIFF (0x8281 - 0x8260) unsigned int _mbctolower(unsigned int c) { - - if ((c & 0xFF00) != 0) { -// true multibyte case conversion needed - if ( _ismbclower(c) ) - return c + CASE_DIFF; - - } else - return _mbbtolower(c); - - return 0; + if ((c & 0xFF00) != 0) { + // true multibyte case conversion needed + if (_ismbclower(c)) + return c + CASE_DIFF; + } else { + return _mbbtolower(c); + } + return 0; } unsigned char * _mbslwr(unsigned char *x) { - unsigned char *y=x; + unsigned char *y=x; - while (*y) { - if (!_ismbblead(*y) ) - *y = tolower(*y); - else { - *y=_mbctolower(*(unsigned short *)y); - y++; - } + while (*y) { + if (!_ismbblead(*y)) { + *y = tolower(*y); + } else { + *y=_mbctolower(*(unsigned short *)y); + y++; } - return x; + } + return x; } diff --git a/lib/crtdll/mbstring/mbsncat.c b/lib/crtdll/mbstring/mbsncat.c index 9cc580f..22bee36 100644 --- a/lib/crtdll/mbstring/mbsncat.c +++ b/lib/crtdll/mbstring/mbsncat.c @@ -8,8 +8,8 @@ * 12/04/99: Created */ -#include -#include +#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbsnccnt.c b/lib/crtdll/mbstring/mbsnccnt.c index 1e30c9b..daa4484 100644 --- a/lib/crtdll/mbstring/mbsnccnt.c +++ b/lib/crtdll/mbstring/mbsnccnt.c @@ -1,4 +1,4 @@ -#include +#include size_t _mbsnccnt(const unsigned char *str, size_t n) { diff --git a/lib/crtdll/mbstring/mbsncmp.c b/lib/crtdll/mbstring/mbsncmp.c index 00bd789..8e1011b 100644 --- a/lib/crtdll/mbstring/mbsncmp.c +++ b/lib/crtdll/mbstring/mbsncmp.c @@ -8,7 +8,7 @@ * 12/04/99: Created */ -#include +#include int _mbsncmp(const unsigned char *str1, const unsigned char *str2, size_t n) { diff --git a/lib/crtdll/mbstring/mbsncoll.c b/lib/crtdll/mbstring/mbsncoll.c index 157f4ef..1a35922 100644 --- a/lib/crtdll/mbstring/mbsncoll.c +++ b/lib/crtdll/mbstring/mbsncoll.c @@ -7,7 +7,7 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include +#include int colldif(unsigned short c1, unsigned short c2); diff --git a/lib/crtdll/mbstring/mbsncpy.c b/lib/crtdll/mbstring/mbsncpy.c index 41fe445..2090c48 100644 --- a/lib/crtdll/mbstring/mbsncpy.c +++ b/lib/crtdll/mbstring/mbsncpy.c @@ -8,7 +8,8 @@ * 12/04/99: Created */ -#include +#include + unsigned char *_mbsncpy(unsigned char *str1, const unsigned char *str2, size_t n) { @@ -43,6 +44,13 @@ unsigned char *_mbsncpy(unsigned char *str1, const unsigned char *str2, size_t n return str1; } + +// +//The _mbsnbcpy function copies count bytes from src to dest. If src is shorter +//than dest, the string is padded with null characters. If dest is less than or +//equal to count it is not terminated with a null character. +// + unsigned char * _mbsnbcpy(unsigned char *str1, const unsigned char *str2, size_t n) { unsigned char *s1 = (unsigned char *)str1; @@ -54,8 +62,10 @@ unsigned char * _mbsnbcpy(unsigned char *str1, const unsigned char *str2, size_t return 0; do { - if (*s2 == 0) + if (*s2 == 0) { + *s1 = *s2; break; + } if ( !_ismbblead(*s2) ) { diff --git a/lib/crtdll/mbstring/mbsnextc.c b/lib/crtdll/mbstring/mbsnextc.c index 5d3bb0a..7a11cd5 100644 --- a/lib/crtdll/mbstring/mbsnextc.c +++ b/lib/crtdll/mbstring/mbsnextc.c @@ -1,8 +1,7 @@ -#include +#include unsigned int _mbsnextc (const unsigned char *src) { - unsigned char *char_src = (unsigned char *)src; unsigned short *short_src = (unsigned short *)src; @@ -14,5 +13,4 @@ unsigned int _mbsnextc (const unsigned char *src) else return *short_src; return 0; - } diff --git a/lib/crtdll/mbstring/mbsnicmp.c b/lib/crtdll/mbstring/mbsnicmp.c index 49c7c3f..93f6b49 100644 --- a/lib/crtdll/mbstring/mbsnicmp.c +++ b/lib/crtdll/mbstring/mbsnicmp.c @@ -1,15 +1,17 @@ -#include +#include + size_t _mbclen2(const unsigned int s); unsigned int _mbbtoupper(unsigned int c); -int _mbsnicmp(const unsigned char *s1, const unsigned char *s2, size_t n) + +int _mbsnicmp(const unsigned char* s1, const unsigned char* s2, size_t n) { if (n == 0) return 0; do { if (_mbbtoupper(*s1) != _mbbtoupper(*s2)) - return _mbbtoupper(*(unsigned const char *)s1) - _mbbtoupper(*(unsigned const char *)s2); + return _mbbtoupper(*(unsigned const char*)s1) - _mbbtoupper(*(unsigned const char*)s2); s1 += _mbclen2(*s1); s2 += _mbclen2(*s2); @@ -21,13 +23,13 @@ int _mbsnicmp(const unsigned char *s1, const unsigned char *s2, size_t n) return 0; } -int _mbsnbicmp(const unsigned char *s1, const unsigned char *s2, size_t n) +int _mbsnbicmp(const unsigned char* s1, const unsigned char* s2, size_t n) { if (n == 0) return 0; do { if (_mbbtoupper(*s1) != _mbbtoupper(*s2)) - return _mbbtoupper(*(unsigned const char *)s1) - _mbbtoupper(*(unsigned const char *)s2); + return _mbbtoupper(*(unsigned const char*)s1) - _mbbtoupper(*(unsigned const char*)s2); s1 += _mbclen2(*s1); s2 += _mbclen2(*s2); diff --git a/lib/crtdll/mbstring/mbsnicoll.c b/lib/crtdll/mbstring/mbsnicoll.c index 4b066e8..3fead6d 100644 --- a/lib/crtdll/mbstring/mbsnicoll.c +++ b/lib/crtdll/mbstring/mbsnicoll.c @@ -1,9 +1,10 @@ -#include +#include int _mbsnicoll(const unsigned char *s1, const unsigned char *s2, size_t n) { return 0; } + int _mbsnbicoll(const unsigned char *s1, const unsigned char *s2, size_t n) { return 0; diff --git a/lib/crtdll/mbstring/mbsninc.c b/lib/crtdll/mbstring/mbsninc.c index 3fb1235..6ce0f7c 100644 --- a/lib/crtdll/mbstring/mbsninc.c +++ b/lib/crtdll/mbstring/mbsninc.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbsninc(const unsigned char *str, size_t n) { diff --git a/lib/crtdll/mbstring/mbsnset.c b/lib/crtdll/mbstring/mbsnset.c index 6c78d31..75befef 100644 --- a/lib/crtdll/mbstring/mbsnset.c +++ b/lib/crtdll/mbstring/mbsnset.c @@ -7,7 +7,7 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbspbrk.c b/lib/crtdll/mbstring/mbspbrk.c index 7b6e327..0e36d10 100644 --- a/lib/crtdll/mbstring/mbspbrk.c +++ b/lib/crtdll/mbstring/mbspbrk.c @@ -1,4 +1,4 @@ -#include +#include // not correct unsigned char * _mbspbrk(const unsigned char *s1, const unsigned char *s2) { diff --git a/lib/crtdll/mbstring/mbsrchr.c b/lib/crtdll/mbstring/mbsrchr.c index 824e639..3a2a8d6 100644 --- a/lib/crtdll/mbstring/mbsrchr.c +++ b/lib/crtdll/mbstring/mbsrchr.c @@ -8,7 +8,7 @@ * 12/04/99: Created */ -#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbsrev.c b/lib/crtdll/mbstring/mbsrev.c index 57cc335..5509c9d 100644 --- a/lib/crtdll/mbstring/mbsrev.c +++ b/lib/crtdll/mbstring/mbsrev.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbsrev(unsigned char *s) { diff --git a/lib/crtdll/mbstring/mbsset.c b/lib/crtdll/mbstring/mbsset.c index e840ed4..4c6f14c 100644 --- a/lib/crtdll/mbstring/mbsset.c +++ b/lib/crtdll/mbstring/mbsset.c @@ -8,7 +8,7 @@ * 12/04/99: Created */ -#include +#include size_t _mbclen2(const unsigned int s); diff --git a/lib/crtdll/mbstring/mbsspn.c b/lib/crtdll/mbstring/mbsspn.c index 6ad7fef..c9ca1ac 100644 --- a/lib/crtdll/mbstring/mbsspn.c +++ b/lib/crtdll/mbstring/mbsspn.c @@ -1,4 +1,5 @@ -#include +#include + // not correct size_t _mbsspn(const unsigned char *s1, const unsigned char *s2) { diff --git a/lib/crtdll/mbstring/mbsspnp.c b/lib/crtdll/mbstring/mbsspnp.c index d8ec9e1..37b8f36 100644 --- a/lib/crtdll/mbstring/mbsspnp.c +++ b/lib/crtdll/mbstring/mbsspnp.c @@ -1,4 +1,5 @@ -#include +#include + // not correct unsigned char * _mbsspnp(const unsigned char *s1, const unsigned char *s2) { diff --git a/lib/crtdll/mbstring/mbsstr.c b/lib/crtdll/mbstring/mbsstr.c index 321b36b..089eb13 100644 --- a/lib/crtdll/mbstring/mbsstr.c +++ b/lib/crtdll/mbstring/mbsstr.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include unsigned char *_mbsstr(const unsigned char *src1,const unsigned char *src2) { diff --git a/lib/crtdll/mbstring/mbstok.c b/lib/crtdll/mbstring/mbstok.c index 538b856..3c68097 100644 --- a/lib/crtdll/mbstring/mbstok.c +++ b/lib/crtdll/mbstring/mbstok.c @@ -1,4 +1,4 @@ -#include +#include unsigned char * _mbstok(unsigned char *s, unsigned char *delim) { diff --git a/lib/crtdll/mbstring/mbstrlen.c b/lib/crtdll/mbstring/mbstrlen.c index 7cfd19f..aa35677 100644 --- a/lib/crtdll/mbstring/mbstrlen.c +++ b/lib/crtdll/mbstring/mbstrlen.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include size_t _mbstrlen( const char *string ) { diff --git a/lib/crtdll/mbstring/mbsupr.c b/lib/crtdll/mbstring/mbsupr.c index 90e5b0f..46d0b4a 100644 --- a/lib/crtdll/mbstring/mbsupr.c +++ b/lib/crtdll/mbstring/mbsupr.c @@ -7,8 +7,8 @@ * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include +#include +#include unsigned int _mbbtoupper(unsigned int c) { diff --git a/lib/crtdll/misc/GetArgs.c b/lib/crtdll/misc/GetArgs.c index 1b9a9d9..c20e700 100644 --- a/lib/crtdll/misc/GetArgs.c +++ b/lib/crtdll/misc/GetArgs.c @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include char *_pgmptr_dll; diff --git a/lib/crtdll/misc/amsg.c b/lib/crtdll/misc/amsg.c index 3ea80ee..02d53fc 100644 --- a/lib/crtdll/misc/amsg.c +++ b/lib/crtdll/misc/amsg.c @@ -1,24 +1,24 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/kbhit.c - * PURPOSE: Checks for keyboard hits + * FILE: lib/crtdll/misc/amsg.c + * PURPOSE: Print runtime error messages * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 28/12/98: Created */ -#include -#include -#include +#include +#include +#include -int _aexit_rtn_dll(int exitcode) +int _aexit_rtn_dll(int exitcode) { _exit(exitcode); } -void _amsg_exit (int errnum) +void _amsg_exit(int errnum) { fprintf(stderr,strerror(errnum)); - _aexit_rtn_dll(-1); + _aexit_rtn_dll(-1); } diff --git a/lib/crtdll/misc/assert.c b/lib/crtdll/misc/assert.c new file mode 100644 index 0000000..0469371 --- /dev/null +++ b/lib/crtdll/misc/assert.c @@ -0,0 +1,13 @@ +/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include +#include +#include +#include + + +void _assert(const char* msg, const char* file, int line) +{ + /* Assertion failed at foo.c line 45: x -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include /* NOTE: The code for initializing the _argv, _argc, and environ variables diff --git a/lib/crtdll/misc/debug.c b/lib/crtdll/misc/debug.c new file mode 100644 index 0000000..16b94a5 --- /dev/null +++ b/lib/crtdll/misc/debug.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + + +void debug_printf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + HANDLE OutputHandle; + + AllocConsole(); + OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + va_start(args,fmt); + vsprintf(buffer,fmt,args); + WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); + va_end(args); +} diff --git a/lib/crtdll/misc/dllcrt1.c b/lib/crtdll/misc/dllcrt1.c index a609c0f..bfc9402 100644 --- a/lib/crtdll/misc/dllcrt1.c +++ b/lib/crtdll/misc/dllcrt1.c @@ -26,11 +26,12 @@ * */ -#include -#include -#include +#include +#include +#include #include + /* See note in crt0.c */ #include "init.c" @@ -46,12 +47,11 @@ extern void __do_global_dtors(); extern BOOL WINAPI DllMain(HANDLE, DWORD, LPVOID); BOOL WINAPI -DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +DllMainCRTStartup(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { BOOL bRet; - if (dwReason == DLL_PROCESS_ATTACH) - { + if (dwReason == DLL_PROCESS_ATTACH) { _mingw32_init_mainargs(); #ifdef __GNUC__ @@ -68,8 +68,7 @@ DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) bRet = DllMain(hDll, dwReason, lpReserved); #ifdef __GNUC__ - if (dwReason == DLL_PROCESS_DETACH) - { + if (dwReason == DLL_PROCESS_DETACH) { /* From libgcc.a, calls global class destructors. */ __do_global_dtors(); } @@ -87,7 +86,7 @@ DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) * Thanks to Andrey A. Smirnov for pointing this one out. */ int -atexit (void (*pfn)()) +atexit(void (*pfn)()) { return 0; } diff --git a/lib/crtdll/misc/dllmain.c b/lib/crtdll/misc/dllmain.c index acf81f7..8c7676b 100644 --- a/lib/crtdll/misc/dllmain.c +++ b/lib/crtdll/misc/dllmain.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * dllmain.c * * A stub DllMain function which will be called by DLLs which do not @@ -25,25 +26,28 @@ #include #include -#include +#include #include -void debug_printf(char* fmt, ...) -{ - va_list args; - char buffer[255]; - HANDLE OutputHandle; - - AllocConsole(); - OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); - va_start(args,fmt); - vsprintf(buffer,fmt,args); - WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); - va_end(args); -} -BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +/* EXTERNAL PROTOTYPES ********************************************************/ + +void debug_printf(char* fmt, ...); + + +/* LIBRARY GLOBAL VARIABLES ***************************************************/ + +int __mb_cur_max_dll = 1; +int _commode_dll = _IOCOMMIT; + + +/* LIBRARY ENTRY POINT ********************************************************/ + +BOOL +WINAPI +DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { return TRUE; } +/* EOF */ diff --git a/lib/crtdll/misc/gccmain.c b/lib/crtdll/misc/gccmain.c index 1c7f5d0..f5c8ff9 100644 --- a/lib/crtdll/misc/gccmain.c +++ b/lib/crtdll/misc/gccmain.c @@ -18,16 +18,16 @@ */ /* Needed for the atexit prototype. */ -#include +#include + typedef void (*func_ptr) (void); extern func_ptr __CTOR_LIST__[]; extern func_ptr __DTOR_LIST__[]; -void -__do_global_dtors (void) +void __do_global_dtors(void) { - static func_ptr *p = __DTOR_LIST__ + 1; + static func_ptr* p = __DTOR_LIST__ + 1; /* * Call each destructor in the destructor list until a null pointer @@ -40,10 +40,9 @@ __do_global_dtors (void) } } -void -__do_global_ctors (void) +void __do_global_ctors(void) { - unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; + unsigned long nptrs = (unsigned long)__CTOR_LIST__[0]; unsigned i; /* @@ -51,8 +50,7 @@ __do_global_ctors (void) * is terminated with a null entry. Otherwise the first entry was * the number of pointers in the list. */ - if (nptrs == -1) - { + if (nptrs == -1) { for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++) ; } @@ -60,24 +58,21 @@ __do_global_ctors (void) /* * Go through the list backwards calling constructors. */ - for (i = nptrs; i >= 1; i--) - { + for (i = nptrs; i >= 1; i--) { __CTOR_LIST__[i] (); } /* * Register the destructors for processing on exit. */ - atexit (__do_global_dtors); + atexit(__do_global_dtors); } static int initialized = 0; -void -__main (void) +void __main(void) { - if (! initialized) - { + if (!initialized) { initialized = 1; __do_global_ctors (); } diff --git a/lib/crtdll/misc/init.c b/lib/crtdll/misc/init.c index 2ee3da1..71cd144 100644 --- a/lib/crtdll/misc/init.c +++ b/lib/crtdll/misc/init.c @@ -29,8 +29,8 @@ * Access to a standard 'main'-like argument count and list. Also included * is a table of environment variables. */ -int _argc = 0; -char** _argv = 0; +int _argc = 0; +char** _argv = 0; /* NOTE: Thanks to Pedro A. Aranda Gutiirrez for pointing * this out to me. GetMainArgs (used below) takes a fourth argument @@ -44,13 +44,9 @@ char** _argv = 0; * defining _CRT_glob and setting it to zero, like this: * int _CRT_glob = 0; */ -extern int _CRT_glob; +extern int _CRT_glob; -#ifdef __MSVCRT__ -extern void __getmainargs(int *, char***, char***, int); -#else extern void __GetMainArgs(int *, char***, char***, int); -#endif /* * Initialize the _argc, _argv and environ variables. @@ -58,18 +54,18 @@ extern void __GetMainArgs(int *, char***, char***, int); static void _mingw32_init_mainargs (void) { - /* The environ variable is provided directly in stdlib.h through - * a dll function call. */ - char** dummy_environ; + /* The environ variable is provided directly in stdlib.h through + * a dll function call. */ + char** dummy_environ; - /* - * Microsoft's runtime provides a function for doing just that. - */ -#ifdef __MSVCRT__ - (void) __getmainargs(&_argc, &_argv, &dummy_environ, _CRT_glob); + /* + * Microsoft's runtime provides a function for doing just that. + */ +#ifdef _MSVCRT_LIB_ + (void) __getmainargs(&_argc, &_argv, &dummy_environ, _CRT_glob); #else - /* CRTDLL version */ - (void) __GetMainArgs(&_argc, &_argv, &dummy_environ, _CRT_glob); + /* CRTDLL version */ + (void) __GetMainArgs(&_argc, &_argv, &dummy_environ, _CRT_glob); #endif } diff --git a/lib/crtdll/misc/initterm.c b/lib/crtdll/misc/initterm.c index c834b61..c71da89 100644 --- a/lib/crtdll/misc/initterm.c +++ b/lib/crtdll/misc/initterm.c @@ -1,14 +1,10 @@ -#include +#include -void _initterm ( - void (* fStart[])(void), - void (* fEnd[])(void) - ) +void _initterm(void (*fStart[])(void), void (*fEnd[])(void)) { int i = 0; - if ( fStart == NULL || fEnd == NULL ) return; @@ -19,13 +15,11 @@ void _initterm ( i++; } } + + typedef int (* _onexit_t)(void); -_onexit_t __dllonexit ( - _onexit_t func, - void (** fStart[])(void), - void (** fEnd[])(void) - ) +_onexit_t __dllonexit(_onexit_t func, void (** fStart[])(void), void (** fEnd[])(void)) { } diff --git a/lib/crtdll/misc/main.c b/lib/crtdll/misc/main.c index 4d1446b..5ca5e53 100644 --- a/lib/crtdll/misc/main.c +++ b/lib/crtdll/misc/main.c @@ -26,21 +26,20 @@ * */ -#include -#include +#include +#include #include + #define ISSPACE(a) (a == ' ' || a == '\t') -extern int PASCAL WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR szCmdLine, - int nShow); +extern int PASCAL WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR szCmdLine, int nShow); -int -main (int argc, char* argv[], char* environ[]) +int main(int argc, char* argv[], char* environ[]) { - char* szCmd; + char* szCmd; STARTUPINFO startinfo; - int nRet; + int nRet; /* Get the command line passed to the process. */ szCmd = GetCommandLineA(); @@ -92,4 +91,3 @@ main (int argc, char* argv[], char* environ[]) return nRet; } - diff --git a/lib/crtdll/misc/setnew.c b/lib/crtdll/misc/setnew.c index 885bd3b..9f0ad6f 100644 --- a/lib/crtdll/misc/setnew.c +++ b/lib/crtdll/misc/setnew.c @@ -1,29 +1,28 @@ -#include +#include -typedef int (* new_handler_t)( size_t ); +typedef int (*new_handler_t)(size_t); new_handler_t new_handler; #undef _set_new_handler new_handler_t _set_new_handler__FPFUi_i(new_handler_t hnd) { - new_handler_t old = new_handler; - - new_handler = hnd; - - return old; + new_handler_t old = new_handler; + + new_handler = hnd; + return old; } #undef delete -void __builtin_delete (void* m) +void __builtin_delete(void* m) { - if ( m != NULL ) - free( m ); + if (m != NULL) + free(m); } #undef new -void * __builtin_new (unsigned int s ) +void* __builtin_new(unsigned int s) { - return malloc( s ); + return malloc( s ); } diff --git a/lib/crtdll/process/_cwait.c b/lib/crtdll/process/_cwait.c index 628a72d..d3a9b66 100644 --- a/lib/crtdll/process/_cwait.c +++ b/lib/crtdll/process/_cwait.c @@ -8,23 +8,24 @@ * 04/03/99: Created */ #include -#include -#include -#include +#include +#include +#include -int _cwait (int* pnStatus, int hProc, int nAction) + +int _cwait(int* pnStatus, int hProc, int nAction) { - DWORD ExitCode; + DWORD ExitCode; nAction = 0; - if ( WaitForSingleObject((void *)hProc,INFINITE) != WAIT_OBJECT_0 ) { + if (WaitForSingleObject((void*)hProc, INFINITE) != WAIT_OBJECT_0) { __set_errno(ECHILD); return -1; } - if ( !GetExitCodeProcess((void *)hProc,&ExitCode) ) + if (!GetExitCodeProcess((void*)hProc, &ExitCode)) return -1; if (pnStatus != NULL) - *pnStatus = (int)ExitCode; + *pnStatus = (int)ExitCode; return hProc; } diff --git a/lib/crtdll/process/_system.c b/lib/crtdll/process/_system.c index f6d5b67..01e87f4 100644 --- a/lib/crtdll/process/_system.c +++ b/lib/crtdll/process/_system.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/process/system.c @@ -8,9 +9,9 @@ * 04/03/99: Created */ #include -#include -#include -#include +#include +#include +#include int system(const char *command) { diff --git a/lib/crtdll/process/dll.c b/lib/crtdll/process/dll.c index 71a33b1..daa003d 100644 --- a/lib/crtdll/process/dll.c +++ b/lib/crtdll/process/dll.c @@ -9,23 +9,22 @@ */ #include -#include +#include -void *_loaddll (char *name) + +void* _loaddll(char* name) { return LoadLibraryA(name); } -int _unloaddll(void *handle) +int _unloaddll(void* handle) { return FreeLibrary(handle); } -FARPROC _getdllprocaddr(void *hModule,char * lpProcName, int iOrdinal) +FARPROC _getdllprocaddr(void* hModule, char* lpProcName, int iOrdinal) { - - - if ( lpProcName != NULL ) + if (lpProcName != NULL) return GetProcAddress(hModule, lpProcName); else return GetProcAddress(hModule, (LPSTR)iOrdinal); diff --git a/lib/crtdll/process/execl.c b/lib/crtdll/process/execl.c index 1d05476..132869e 100644 --- a/lib/crtdll/process/execl.c +++ b/lib/crtdll/process/execl.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #include int _execl(const char* szPath, const char* szArgv0, ...) diff --git a/lib/crtdll/process/execle.c b/lib/crtdll/process/execle.c index f907798..5ccacf6 100644 --- a/lib/crtdll/process/execle.c +++ b/lib/crtdll/process/execle.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include // fixme rewrite to pass the array variants to va_list variant diff --git a/lib/crtdll/process/execlp.c b/lib/crtdll/process/execlp.c index 1b97589..00384c6 100644 --- a/lib/crtdll/process/execlp.c +++ b/lib/crtdll/process/execlp.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _execlp(const char *szPath, const char *szArgv0, ...) { diff --git a/lib/crtdll/process/execlpe.c b/lib/crtdll/process/execlpe.c index 785dff0..e6e6f21 100644 --- a/lib/crtdll/process/execlpe.c +++ b/lib/crtdll/process/execlpe.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int execlpe(const char *path, const char *szArgv0, ... /*, const char **envp */) diff --git a/lib/crtdll/process/execv.c b/lib/crtdll/process/execv.c index d1d2bb8..01cc594 100644 --- a/lib/crtdll/process/execv.c +++ b/lib/crtdll/process/execv.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _execv(const char* szPath, char* const* szaArgv) { diff --git a/lib/crtdll/process/execve.c b/lib/crtdll/process/execve.c index 3ea6ae9..2ee6ad1 100644 --- a/lib/crtdll/process/execve.c +++ b/lib/crtdll/process/execve.c @@ -1,7 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include + int _execve(const char* szPath, char* const* szaArgv, char* const* szaEnv) { - return spawnve(P_OVERLAY, szPath, szaArgv, szaEnv); + return spawnve(P_OVERLAY, szPath, szaArgv, szaEnv); } diff --git a/lib/crtdll/process/execvp.c b/lib/crtdll/process/execvp.c index 7dd5a22..72ce3bd 100644 --- a/lib/crtdll/process/execvp.c +++ b/lib/crtdll/process/execvp.c @@ -1,7 +1,7 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details *///#include -//#include -#include -#include +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details *///#include +//#include +#include +#include int _execvp(const char* szPath, char* const* szaArgv) { diff --git a/lib/crtdll/process/execvpe.c b/lib/crtdll/process/execvpe.c index b7393eb..c894f5f 100644 --- a/lib/crtdll/process/execvpe.c +++ b/lib/crtdll/process/execvpe.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include int _execvpe(const char* szPath, char* const* szaArgv, char* const* szaEnv) { diff --git a/lib/crtdll/process/procid.c b/lib/crtdll/process/procid.c index 26e92cb..a8616fb 100644 --- a/lib/crtdll/process/procid.c +++ b/lib/crtdll/process/procid.c @@ -1,10 +1,8 @@ #include -#include +#include int _getpid (void) { - //fixme GetCurrentProcessId - //return (int)GetCurrentProcessId(); - return 1; + return (int)GetCurrentProcessId(); } diff --git a/lib/crtdll/process/spawnl.c b/lib/crtdll/process/spawnl.c index c2518d4..9e80762 100644 --- a/lib/crtdll/process/spawnl.c +++ b/lib/crtdll/process/spawnl.c @@ -1,21 +1,22 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #include + int _spawnl(int nMode, const char* szPath, const char* szArgv0,...) { - char *szArg[100]; - const char *a; + char* szArg[100]; + const char* a; int i = 1; va_list l = 0; szArg[0]=(char*)szArgv0; va_start(l,szArgv0); do { - a = va_arg(l,const char *); - szArg[i++] = (char *)a; - } while ( a != NULL && i < 100 ); + a = va_arg(l, const char*); + szArg[i++] = (char*)a; + } while (a != NULL && i < 100); return _spawnve(nMode, szPath, szArg, _environ); } diff --git a/lib/crtdll/process/spawnle.c b/lib/crtdll/process/spawnle.c index 9a8e2dd..27c354f 100644 --- a/lib/crtdll/process/spawnle.c +++ b/lib/crtdll/process/spawnle.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _spawnle(int mode, const char *path, const char *szArgv0, ... /*, const char **envp */) diff --git a/lib/crtdll/process/spawnlp.c b/lib/crtdll/process/spawnlp.c index 58ed2ed..4e95080 100644 --- a/lib/crtdll/process/spawnlp.c +++ b/lib/crtdll/process/spawnlp.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #include int _spawnlp(int nMode, const char* szPath, const char* szArgv0, ...) diff --git a/lib/crtdll/process/spawnlpe.c b/lib/crtdll/process/spawnlpe.c index cfd73f9..81abee8 100644 --- a/lib/crtdll/process/spawnlpe.c +++ b/lib/crtdll/process/spawnlpe.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _spawnlpe(int mode, const char *path, const char *szArgv0, ... /*, const char **envp */) diff --git a/lib/crtdll/process/spawnv.c b/lib/crtdll/process/spawnv.c index cf25274..e497112 100644 --- a/lib/crtdll/process/spawnv.c +++ b/lib/crtdll/process/spawnv.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _spawnv(int nMode, const char* szPath, char* const* szaArgv) { diff --git a/lib/crtdll/process/spawnve.c b/lib/crtdll/process/spawnve.c index 1b698b9..5e2c193 100644 --- a/lib/crtdll/process/spawnve.c +++ b/lib/crtdll/process/spawnve.c @@ -3,15 +3,13 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include - -#include -#include -#include -#include -//#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #ifndef F_OK @@ -34,105 +32,87 @@ int _fileinfo_dll = 0; static int -direct_exec_tail(const char *program, const char *args, - char * const envp[], - PROCESS_INFORMATION *ProcessInformation) +direct_exec_tail(const char* program, const char* args, + char* const envp[], + PROCESS_INFORMATION* ProcessInformation) { - - static STARTUPINFO StartupInfo; - - StartupInfo.cb = sizeof(STARTUPINFO); - StartupInfo.lpReserved= NULL; - StartupInfo.dwFlags = 0; - StartupInfo.wShowWindow = SW_SHOWDEFAULT; - StartupInfo.lpReserved2 = NULL; - StartupInfo.cbReserved2 = 0; - - - if (! CreateProcessA((char *)program,(char *)args,NULL,NULL,FALSE,0,(char **)envp,NULL,&StartupInfo,ProcessInformation) ) - { - __set_errno( GetLastError() ); - return -1; - } - - return (int)ProcessInformation->hProcess; + static STARTUPINFO StartupInfo; + + StartupInfo.cb = sizeof(STARTUPINFO); + StartupInfo.lpReserved= NULL; + StartupInfo.dwFlags = 0; + StartupInfo.wShowWindow = SW_SHOWDEFAULT; + StartupInfo.lpReserved2 = NULL; + StartupInfo.cbReserved2 = 0; + if (!CreateProcessA((char*)program,(char*)args,NULL,NULL,FALSE,0,(char**)envp,NULL,&StartupInfo,ProcessInformation)) { + __set_errno( GetLastError() ); + return -1; + } + return (int)ProcessInformation->hProcess; } -static int vdm_exec(const char *program, char **argv, char **envp, - PROCESS_INFORMATION *ProcessInformation) +static int vdm_exec(const char* program, char** argv, char** envp, + PROCESS_INFORMATION* ProcessInformation) { - static char args[1024]; - int i = 0; - args[0] = 0; - - strcpy(args,"vdm.exe "); - while(argv[i] != NULL ) { - strcat(args,argv[i]); - strcat(args," "); + static char args[1024]; + int i = 0; + args[0] = 0; + + strcpy(args, "vdm.exe "); + while (argv[i] != NULL) { + strcat(args, argv[i]); + strcat(args, " "); i++; - } - - return direct_exec_tail(program,args,envp,ProcessInformation); + } + return direct_exec_tail(program,args,envp,ProcessInformation); } -static int go32_exec(const char *program, char **argv, char **envp, - PROCESS_INFORMATION *ProcessInformation) +static int go32_exec(const char* program, char** argv, char** envp, + PROCESS_INFORMATION* ProcessInformation) { - - - static char args[1024]; - static char envblock[2048]; - char * penvblock; - int i = 0; - - - envblock[0] = 0; - penvblock=envblock; - - while(envp[i] != NULL ) { + static char args[1024]; + static char envblock[2048]; + char* penvblock; + int i = 0; + + envblock[0] = 0; + penvblock=envblock; + while(envp[i] != NULL ) { strcat(penvblock,envp[i]); - penvblock+=strlen(envp[i])+1; + penvblock+=strlen(envp[i])+1; i++; - } - penvblock[0]=0; - - args[0] = 0; - i = 0; - while(argv[i] != NULL ) { + } + penvblock[0]=0; + args[0] = 0; + i = 0; + while(argv[i] != NULL ) { strcat(args,argv[i]); strcat(args," "); i++; - } - - return direct_exec_tail(program,args,envp,ProcessInformation); + } + return direct_exec_tail(program,args,envp,ProcessInformation); } -int -command_exec(const char *program, char **argv, char **envp, - PROCESS_INFORMATION *ProcessInformation) +int command_exec(const char* program, char** argv, char** envp, + PROCESS_INFORMATION* ProcessInformation) { - static char args[1024]; - int i = 0; - - + static char args[1024]; + int i = 0; - args[0] = 0; - - strcpy(args,"cmd.exe /c "); - while(argv[i] != NULL ) { + args[0] = 0; + strcpy(args,"cmd.exe /c "); + while(argv[i] != NULL ) { strcat(args,argv[i]); strcat(args," "); i++; - } - - return direct_exec_tail(program,args,envp,ProcessInformation); - + } + return direct_exec_tail(program,args,envp,ProcessInformation); } -static int script_exec(const char *program, char **argv, char **envp, - PROCESS_INFORMATION *ProcessInformation) +static int script_exec(const char* program, char** argv, char** envp, + PROCESS_INFORMATION* ProcessInformation) { - return 0; + return 0; } @@ -141,23 +121,22 @@ static int script_exec(const char *program, char **argv, char **envp, those extensions that can be *omitted* when you invoke the executable from one of the shells used on MSDOS. */ static struct { - const char *extension; - int (*interp)(const char *, char **, char **, - PROCESS_INFORMATION *); + const char* extension; + int (*interp)(const char*, char**, char**, PROCESS_INFORMATION*); } interpreters[] = { - { ".com", vdm_exec }, - { ".exe", go32_exec }, - { ".dll", go32_exec }, - { ".cmd", command_exec }, - { ".bat", command_exec }, - { ".btm", command_exec }, - { ".sh", script_exec }, /* for compatibility with ms_sh */ - { ".ksh", script_exec }, - { ".pl", script_exec }, /* Perl */ - { ".sed", script_exec }, - { "", go32_exec }, - { 0, script_exec }, /* every extension not mentioned above calls it */ - { 0, 0 }, + { ".com", vdm_exec }, + { ".exe", go32_exec }, + { ".dll", go32_exec }, + { ".cmd", command_exec }, + { ".bat", command_exec }, + { ".btm", command_exec }, + { ".sh", script_exec }, /* for compatibility with ms_sh */ + { ".ksh", script_exec }, + { ".pl", script_exec }, /* Perl */ + { ".sed", script_exec }, + { "", go32_exec }, + { 0, script_exec }, /* every extension not mentioned above calls it */ + { 0, 0 }, }; /* This is the index into the above array of the interpreter @@ -166,173 +145,143 @@ static struct { /*-------------------------------------------------*/ - - - -int _spawnve(int mode, const char *path, char *const argv[], char *const envp[]) +int _spawnve(int mode, const char* path, char* const argv[], char* const envp[]) { - /* This is the one that does the work! */ - PROCESS_INFORMATION ProcessInformation; - union { char *const *x; char **p; } u; - int i = -1; - char **argvp; - char **envpp; - char rpath[FILENAME_MAX], *rp, *rd=0; - int e = errno; - int is_dir = 0; - int found = 0; - DWORD ExitCode; - - if (path == 0 || argv[0] == 0) - { - errno = EINVAL; - return -1; - } - if (strlen(path) > FILENAME_MAX - 1) - { - errno = ENAMETOOLONG; - return -1; - } - - u.x = argv; argvp = u.p; - u.x = envp; envpp = u.p; - - fflush(stdout); /* just in case */ - for (rp=rpath; *path; *rp++ = *path++) - { + /* This is the one that does the work! */ + PROCESS_INFORMATION ProcessInformation; + union { char* const* x; char** p; } u; + int i = -1; + char** argvp; + char** envpp; + char rpath[FILENAME_MAX], *rp, *rd = 0; + int e = errno; + int is_dir = 0; + int found = 0; + DWORD ExitCode; + + if (path == 0 || argv[0] == 0) { + errno = EINVAL; + return -1; + } + if (strlen(path) > FILENAME_MAX - 1) { + errno = ENAMETOOLONG; + return -1; + } + u.x = argv; argvp = u.p; + u.x = envp; envpp = u.p; + fflush(stdout); /* just in case */ + for (rp=rpath; *path; *rp++ = *path++) { if (*path == '.') - rd = rp; - if (*path == '\\' || *path == '/') - rd = 0; - } - *rp = 0; - - /* If LFN is supported on the volume where rpath resides, we - might have something like foo.bar.exe or even foo.exe.com. - If so, look for RPATH.ext before even trying RPATH itself. */ - if (!rd) - { - for (i=0; interpreters[i].extension; i++) - { - strcpy(rp, interpreters[i].extension); - if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) - { - found = 1; - break; - } + rd = rp; + if (*path == '\\' || *path == '/') + rd = 0; + } + *rp = 0; + + /* If LFN is supported on the volume where rpath resides, we + might have something like foo.bar.exe or even foo.exe.com. + If so, look for RPATH.ext before even trying RPATH itself. */ + if (!rd) { + for (i=0; interpreters[i].extension; i++) { + strcpy(rp, interpreters[i].extension); + if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) { + found = 1; + break; + } + } } - } - if (!found) - { - const char *rpath_ext; + if (!found) { + const char *rpath_ext; - if (rd) - { - i = 0; - rpath_ext = rd; + if (rd) { + i = 0; + rpath_ext = rd; + } else { + i = INTERP_NO_EXT; + rpath_ext = ""; + } + for ( ; interpreters[i].extension; i++) + if (_stricmp(rpath_ext, interpreters[i].extension) == 0 + && _access(rpath, F_OK) == 0 + && !(is_dir = (_access(rpath, D_OK) == 0))) + { + found = 1; + break; + } + } + if (!found) { + errno = is_dir ? EISDIR : ENOENT; + return -1; } - else - { - i = INTERP_NO_EXT; - rpath_ext = ""; + errno = e; + i = interpreters[i].interp(rpath, argvp, envpp, &ProcessInformation); + if (mode == P_OVERLAY) + exit(i); + if (mode == P_WAIT) { + WaitForSingleObject(ProcessInformation.hProcess,INFINITE); + GetExitCodeProcess(ProcessInformation.hProcess,&ExitCode); + i = (int)ExitCode; } - for ( ; interpreters[i].extension; i++) - if (_stricmp(rpath_ext, interpreters[i].extension) == 0 - && _access(rpath, F_OK) == 0 - && !(is_dir = (_access(rpath, D_OK) == 0))) - { - found = 1; - break; - } - } - if (!found) - { - errno = is_dir ? EISDIR : ENOENT; - return -1; - } - errno = e; - i = interpreters[i].interp(rpath, argvp, envpp, &ProcessInformation); - if (mode == P_OVERLAY) - exit(i); - if (mode == P_WAIT) - { - WaitForSingleObject(ProcessInformation.hProcess,INFINITE); - GetExitCodeProcess(ProcessInformation.hProcess,&ExitCode); - i = (int)ExitCode; - } - return i; + return i; } - - - -const char * find_exec(char * path,char *rpath) +const char* find_exec(char* path, char* rpath) { - char *rp, *rd=0; - int i; - int is_dir = 0; - int found = 0; - if (path == 0 ) - return 0; - if (strlen(path) > FILENAME_MAX - 1) - return path; - - /* copy path in rpath */ - for (rd=path,rp=rpath; *rd; *rp++ = *rd++) + char *rp, *rd=0; + int i; + int is_dir = 0; + int found = 0; + + if (path == 0 ) + return 0; + if (strlen(path) > FILENAME_MAX - 1) + return path; + + /* copy path in rpath */ + for (rd=path,rp=rpath; *rd; *rp++ = *rd++) ; - *rp = 0; - /* try first with the name as is */ - for (i=0; interpreters[i].extension; i++) - { - strcpy(rp, interpreters[i].extension); - if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) - { - found = 1; - break; + *rp = 0; + /* try first with the name as is */ + for (i=0; interpreters[i].extension; i++) { + strcpy(rp, interpreters[i].extension); + if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) { + found = 1; + break; + } } - } - - if (!found) - { - /* search in the PATH */ - char winpath[MAX_PATH]; - if( GetEnvironmentVariableA("PATH",winpath,MAX_PATH)) - { - char *ep=winpath; - while( *ep) - { - if(*ep == ';') ep++; - rp=rpath; - for ( ; *ep && (*ep != ';') ; *rp++ = *ep++) - ; - *rp++='/'; - for (rd=path ; *rd ; *rp++ = *rd++) - ; - - for (i=0; interpreters[i].extension; i++) - { - strcpy(rp, interpreters[i].extension); - if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) - { - found = 1; - break; - } + if (!found) { + /* search in the PATH */ + char winpath[MAX_PATH]; + if (GetEnvironmentVariableA("PATH", winpath, MAX_PATH)) { + char* ep = winpath; + while (*ep) { + if (*ep == ';') ep++; + rp = rpath; + for ( ; *ep && (*ep != ';') ; *rp++ = *ep++) + ; + *rp++ = '/'; + for (rd = path ; *rd ; *rp++ = *rd++) + ; + for (i = 0; interpreters[i].extension; i++) { + strcpy(rp, interpreters[i].extension); + if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0))) { + found = 1; + break; + } + } + if (found) break; + } } - if (found) break; - } } - } - if (!found) - return path; - - return rpath; + if (!found) + return path; + return rpath; } int _spawnvpe(int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv) { - char rpath[FILENAME_MAX]; - - return _spawnve(nMode, find_exec((char*)szPath,rpath), szaArgv, szaEnv); + char rpath[FILENAME_MAX]; + return _spawnve(nMode, find_exec((char*)szPath,rpath), szaArgv, szaEnv); } diff --git a/lib/crtdll/process/spawnvp.c b/lib/crtdll/process/spawnvp.c index aecd80e..8a6862b 100644 --- a/lib/crtdll/process/spawnvp.c +++ b/lib/crtdll/process/spawnvp.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _spawnvp(int nMode, const char* szPath, char* const* szaArgv) { diff --git a/lib/crtdll/process/spawnvpe.c b/lib/crtdll/process/spawnvpe.c index bdad981..fdafde3 100644 --- a/lib/crtdll/process/spawnvpe.c +++ b/lib/crtdll/process/spawnvpe.c @@ -1,7 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _spawnvpe(int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv) diff --git a/lib/crtdll/process/thread.c b/lib/crtdll/process/thread.c index c2a12d3..2a79a26 100644 --- a/lib/crtdll/process/thread.c +++ b/lib/crtdll/process/thread.c @@ -1,12 +1,16 @@ +/* $Id$ + * + */ #include -#include -#include -#include +#include +#include +#include -unsigned long - _beginthread (void (*pfuncStart)(void *), - unsigned unStackSize, void* pArgList) +unsigned long _beginthread( + void (*pfuncStart)(void*), + unsigned unStackSize, + void* pArgList) { DWORD ThreadId; HANDLE hThread; @@ -20,6 +24,7 @@ unsigned long } return (unsigned long)hThread; } + void _endthread(void) { //fixme ExitThread diff --git a/lib/crtdll/process/threadid.c b/lib/crtdll/process/threadid.c index 3b5c9aa..14bb978 100644 --- a/lib/crtdll/process/threadid.c +++ b/lib/crtdll/process/threadid.c @@ -1,5 +1,5 @@ #include -#include +#include unsigned long __threadid (void) { diff --git a/lib/crtdll/quad/divdi3.c b/lib/crtdll/quad/divdi3.c index e0f375e..44e037b 100644 --- a/lib/crtdll/quad/divdi3.c +++ b/lib/crtdll/quad/divdi3.c @@ -37,7 +37,7 @@ * $Id$ */ -#include +#include /* * Divide two signed quads. diff --git a/lib/crtdll/quad/moddi3.c b/lib/crtdll/quad/moddi3.c index 272461e..de457eb 100644 --- a/lib/crtdll/quad/moddi3.c +++ b/lib/crtdll/quad/moddi3.c @@ -37,7 +37,7 @@ * $Id$ */ -#include +#include /* * Return remainder after dividing two signed quads. diff --git a/lib/crtdll/quad/qdivrem.c b/lib/crtdll/quad/qdivrem.c index 06f827a..99dfd50 100644 --- a/lib/crtdll/quad/qdivrem.c +++ b/lib/crtdll/quad/qdivrem.c @@ -42,7 +42,7 @@ * section 4.3.1, pp. 257--259. */ -#include +#include #define B (1 << HALF_BITS) /* digit base */ diff --git a/lib/crtdll/quad/udivdi3.c b/lib/crtdll/quad/udivdi3.c index 224e8a2..fddc16f 100644 --- a/lib/crtdll/quad/udivdi3.c +++ b/lib/crtdll/quad/udivdi3.c @@ -38,7 +38,7 @@ * $Id$ */ -#include +#include /* * Divide two unsigned quads. diff --git a/lib/crtdll/quad/umoddi3.c b/lib/crtdll/quad/umoddi3.c index 7843805..cc007dd 100644 --- a/lib/crtdll/quad/umoddi3.c +++ b/lib/crtdll/quad/umoddi3.c @@ -37,7 +37,7 @@ * $Id$ */ -#include +#include /* * Return remainder after dividing two unsigned quads. diff --git a/lib/crtdll/search/lfind.c b/lib/crtdll/search/lfind.c index 1569735..8bfa458 100644 --- a/lib/crtdll/search/lfind.c +++ b/lib/crtdll/search/lfind.c @@ -1,14 +1,15 @@ -#include -#include +#include +#include void *_lfind(const void *key, const void *base, size_t *nelp, size_t width, int (*compar)(const void *, const void *)) { - char *char_base = (char *)base; + char* char_base = (char*)base; int i; - for(i=0;i<*nelp;i++) { - if ( compar(key,char_base) == 0) + + for (i = 0; i < *nelp; i++) { + if (compar(key, char_base) == 0) return char_base; char_base += width; } diff --git a/lib/crtdll/search/lsearch.c b/lib/crtdll/search/lsearch.c index f388d07..8434ebb 100644 --- a/lib/crtdll/search/lsearch.c +++ b/lib/crtdll/search/lsearch.c @@ -1,16 +1,21 @@ -#include -#include -#include +#include +#include +#include void *_lsearch(const void *key, void *base, size_t *nelp, size_t width, int (*compar)(const void *, const void *)) { - void *ret_find = _lfind(key,base,nelp,width,compar); - if ( ret_find != NULL ) - return ret_find; + void *ret_find = _lfind(key,base,nelp,width,compar); - memcpy( base + (*nelp*width), key, width ); - (*nelp)++; - return base ; + if (ret_find != NULL) + return ret_find; + +#ifdef __GNUC__ + memcpy(base + (*nelp*width), key, width); +#else + memcpy((int*)base + (*nelp*width), key, width); +#endif + (*nelp)++; + return base; } diff --git a/lib/crtdll/setjmp/setjmp.c b/lib/crtdll/setjmp/setjmp.c index dc0d5fa..95709d3 100644 --- a/lib/crtdll/setjmp/setjmp.c +++ b/lib/crtdll/setjmp/setjmp.c @@ -21,6 +21,7 @@ int longjmp( jmp_buf env, int value ) //push ebp generated by the compiler //mov ebp, esp +#ifdef __GNUC__ __asm__ __volatile__ ( "movl 8(%ebp),%edi\n\t" /* get jmp_buf */ "movl 12(%ebp),%eax\n\t" /* store retval in j->eax */ @@ -85,18 +86,18 @@ int longjmp( jmp_buf env, int value ) "iret\n\t" /* actually jump to new cs:eip loading flags */ ); +#else +#endif /*__GNUC__*/ return value; // dummy return never reached } - +#ifdef __GNUC__ int _setjmp( jmp_buf env ) { //push ebp generated by the compiler //mov ebp, esp - __asm__ __volatile__ ( - "pushl %edi\n\t" "movl 8(%ebp),%edi\n\t" @@ -134,10 +135,8 @@ int _setjmp( jmp_buf env ) "popl %edi\n\t" ); - - - - - return 0; } + +#else +#endif /*__GNUC__*/ diff --git a/lib/crtdll/signal/signal.c b/lib/crtdll/signal/signal.c index 2e221f4..69d90a6 100644 --- a/lib/crtdll/signal/signal.c +++ b/lib/crtdll/signal/signal.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void _default_handler(int signal); diff --git a/lib/crtdll/signal/xcptinfo.c b/lib/crtdll/signal/xcptinfo.c index d32f760..4971a52 100644 --- a/lib/crtdll/signal/xcptinfo.c +++ b/lib/crtdll/signal/xcptinfo.c @@ -1,4 +1,4 @@ -#include +#include void **__pxcptinfoptrs (void) { diff --git a/lib/crtdll/stdio/allocfil.c b/lib/crtdll/stdio/allocfil.c index b0f9e64..7d86ebb 100644 --- a/lib/crtdll/stdio/allocfil.c +++ b/lib/crtdll/stdio/allocfil.c @@ -1,8 +1,8 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include FILE * __alloc_file(void); diff --git a/lib/crtdll/stdio/clearerr.c b/lib/crtdll/stdio/clearerr.c index 0543ed0..5055fa7 100644 --- a/lib/crtdll/stdio/clearerr.c +++ b/lib/crtdll/stdio/clearerr.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include #ifdef clearerr #undef clearerr diff --git a/lib/crtdll/stdio/doscan.c b/lib/crtdll/stdio/doscan.c index a14f773..09868e2 100644 --- a/lib/crtdll/stdio/doscan.c +++ b/lib/crtdll/stdio/doscan.c @@ -1,10 +1,10 @@ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include #define atold atof @@ -16,7 +16,7 @@ int _doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *), const char *fmt, va_list argp); -//#include +//#include #define SPC 01 #define STP 02 diff --git a/lib/crtdll/stdio/fclose.c b/lib/crtdll/stdio/fclose.c index 1b141c5..74b3b0c 100644 --- a/lib/crtdll/stdio/fclose.c +++ b/lib/crtdll/stdio/fclose.c @@ -1,12 +1,12 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include // changed check for writable stream diff --git a/lib/crtdll/stdio/fdopen.c b/lib/crtdll/stdio/fdopen.c index 2427466..d543e25 100644 --- a/lib/crtdll/stdio/fdopen.c +++ b/lib/crtdll/stdio/fdopen.c @@ -1,8 +1,9 @@ -#include -#include +#include +#include FILE * __alloc_file(void); + FILE *_fdopen(int handle, char *mode) { FILE *file; @@ -48,15 +49,6 @@ FILE *_fdopen(int handle, char *mode) file->_flag = _IOWRT; file->_base = file->_ptr = NULL; + return file; } - - - - - - - - - - diff --git a/lib/crtdll/stdio/feof.c b/lib/crtdll/stdio/feof.c index 8f6f01f..a2487d8 100644 --- a/lib/crtdll/stdio/feof.c +++ b/lib/crtdll/stdio/feof.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include #ifdef feof #undef feof diff --git a/lib/crtdll/stdio/ferror.c b/lib/crtdll/stdio/ferror.c index 06d77c1..05110cd 100644 --- a/lib/crtdll/stdio/ferror.c +++ b/lib/crtdll/stdio/ferror.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #ifdef ferror #undef ferror diff --git a/lib/crtdll/stdio/fflush.c b/lib/crtdll/stdio/fflush.c index 0dc66f2..09982cb 100644 --- a/lib/crtdll/stdio/fflush.c +++ b/lib/crtdll/stdio/fflush.c @@ -11,13 +11,13 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include int fflush(FILE *f) @@ -88,8 +88,8 @@ int fflush(FILE *f) do { n = _write(fileno(f), base, rn); if (n <= 0) { - f->_flag |= _IOERR; - return EOF; + f->_flag |= _IOERR; + return EOF; } rn -= n; base += n; diff --git a/lib/crtdll/stdio/fgetc.c b/lib/crtdll/stdio/fgetc.c index 33ed518..7ce598c 100644 --- a/lib/crtdll/stdio/fgetc.c +++ b/lib/crtdll/stdio/fgetc.c @@ -9,17 +9,15 @@ 25/02/99: Added fgetwc */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include -int -fgetc(FILE *f) +int fgetc(FILE *f) { return getc(f); } -wint_t -fgetwc(FILE *f) +wint_t fgetwc(FILE *f) { return getwc(f); } diff --git a/lib/crtdll/stdio/fgetchar.c b/lib/crtdll/stdio/fgetchar.c index 392f7e2..bb6b947 100644 --- a/lib/crtdll/stdio/fgetchar.c +++ b/lib/crtdll/stdio/fgetchar.c @@ -1,6 +1,28 @@ -#include -#include -#include +/* $Id$ + * + * ReactOS msvcrt library + * + * fgetchar.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 +#include int _fgetchar (void) { diff --git a/lib/crtdll/stdio/fgetpos.c b/lib/crtdll/stdio/fgetpos.c index e063164..3c5abf4 100644 --- a/lib/crtdll/stdio/fgetpos.c +++ b/lib/crtdll/stdio/fgetpos.c @@ -1,9 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include -int -fgetpos(FILE *stream, fpos_t *pos) +int fgetpos(FILE *stream, fpos_t *pos) { if (stream && pos) { diff --git a/lib/crtdll/stdio/fgets.c b/lib/crtdll/stdio/fgets.c index df78963..c2eaffa 100644 --- a/lib/crtdll/stdio/fgets.c +++ b/lib/crtdll/stdio/fgets.c @@ -1,16 +1,41 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fgets.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 + */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -char * -fgets(char *s, int n, FILE *f) +#include +#include + + +char* fgets(char* s, int n, FILE* f) { int c=0; char *cs; cs = s; - while (--n>0 && (c = getc(f)) != EOF) - { + while (--n>0 && (c = getc(f)) != EOF) { *cs++ = c; if (c == '\n') break; diff --git a/lib/crtdll/stdio/fgetws.c b/lib/crtdll/stdio/fgetws.c new file mode 100644 index 0000000..282b8fc --- /dev/null +++ b/lib/crtdll/stdio/fgetws.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include +#include + +//wchar_t* fgetws(wchar_t* wcaBuffer, int nBufferSize, FILE* fileRead); +//char* fgets(char *s, int n, FILE *f); +//int _getw(FILE *stream); +/* +// Read a word (int) from STREAM. +int _getw(FILE *stream) +{ + int w; + + // Is there a better way? + if (fread( &w, sizeof(w), 1, stream) != 1) + return(EOF); + return(w); +} + +//getc can be a macro +#undef getc + +int getc(FILE *fp) +{ + int c = -1; +// check for invalid stream + if ( !__validfp (fp) ) { + __set_errno(EINVAL); + return EOF; + } +// check for read access on stream + if ( !OPEN4READING(fp) ) { + __set_errno(EINVAL); + return -1; + } + if(fp->_cnt > 0) { + fp->_cnt--; + c = (int)*fp->_ptr++; + } + else { + c = _filbuf(fp); + } + return c; +} + */ + +wchar_t* fgetws(wchar_t* s, int n, FILE* f) +{ + int c = 0; + wchar_t* cs; + + cs = s; + while (--n > 0 && (c = _getw(f)) != EOF) { + *cs++ = c; + if (c == L'\n') + break; + } + if (c == EOF && cs == s) { + return NULL; + } + *cs++ = L'\0'; + return s; +} diff --git a/lib/crtdll/stdio/filbuf.c b/lib/crtdll/stdio/filbuf.c index b9b008a..b98f48b 100644 --- a/lib/crtdll/stdio/filbuf.c +++ b/lib/crtdll/stdio/filbuf.c @@ -2,14 +2,14 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include int _readcnv(int fn, void *buf, size_t siz ); diff --git a/lib/crtdll/stdio/fileno.c b/lib/crtdll/stdio/fileno.c index f895187..81eb779 100644 --- a/lib/crtdll/stdio/fileno.c +++ b/lib/crtdll/stdio/fileno.c @@ -1,4 +1,4 @@ -#include +#include #undef fileno int fileno(FILE *f) diff --git a/lib/crtdll/stdio/flsbuf.c b/lib/crtdll/stdio/flsbuf.c index 2a0feb6..cf2395b 100644 --- a/lib/crtdll/stdio/flsbuf.c +++ b/lib/crtdll/stdio/flsbuf.c @@ -1,88 +1,75 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include + int cntcr(char *bufp, int bufsiz); int convert(char *endp, int bufsiz,int n); int _writecnv(int fn, void *buf, size_t bufsiz); -int -_flsbuf(int c, FILE *f) + +int _flsbuf(int c, FILE *f) { char *base; int n, rn; char c1; int size; - - if (!OPEN4WRITING(f)) { __set_errno (EINVAL); return EOF; } -// no file associated with buffer -// this is a memory stream - - if ( fileno(f) == -1 ) + // no file associated with buffer, this is a memory stream + if (fileno(f) == -1) { return c; + } /* if the buffer is not yet allocated, allocate it */ - if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) - { + if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) { size = 4096; - if ((f->_base = base = malloc (size)) == NULL) - { + if ((f->_base = base = malloc (size)) == NULL) { f->_flag |= _IONBF; f->_flag &= ~(_IOFBF|_IOLBF); - } - else - { + } else { f->_flag |= _IOMYBUF; f->_cnt = f->_bufsiz = size; f->_ptr = base; rn = 0; - if (f == stdout && isatty (fileno (stdout))) - f->_flag |= _IOLBF; + if (f == stdout && isatty (fileno (stdout))) { + f->_flag |= _IOLBF; + } } } - if (f->_flag & _IOLBF) - { + if (f->_flag & _IOLBF) { /* in line-buffering mode we get here on each character */ *f->_ptr++ = c; rn = f->_ptr - base; - if (c == '\n' || rn >= f->_bufsiz) - { + if (c == '\n' || rn >= f->_bufsiz) { /* time for real flush */ f->_ptr = base; f->_cnt = 0; - } - else - { + } else { /* we got here because _cnt is wrong, so fix it */ - /* Negative _cnt causes all output functions - to call _flsbuf for each character, thus realizing line-buffering */ + /* Negative _cnt causes all output functions to call */ + /* _flsbuf for each character, thus realizing line-buffering */ f->_cnt = -rn; return c; } - } - else if (f->_flag & _IONBF) - { + } else if (f->_flag & _IONBF) { c1 = c; rn = 1; base = &c1; - f->_cnt = 0; - } - else /* _IOFBF */ - { + f->_cnt = 0; + } else { /* _IOFBF */ rn = f->_ptr - base; f->_ptr = base; if ( (f->_flag & _IOAHEAD) == _IOAHEAD ) @@ -90,25 +77,17 @@ _flsbuf(int c, FILE *f) f->_cnt = f->_bufsiz; f->_flag &= ~_IOAHEAD; } - - - f->_flag &= ~_IODIRTY; - while (rn > 0) - { + while (rn > 0) { n = _write(fileno(f), base, rn); - if (n <= 0) - { + if (n <= 0) { f->_flag |= _IOERR; return EOF; } rn -= n; base += n; } - - - if ((f->_flag&(_IOLBF|_IONBF)) == 0) - { + if ((f->_flag&(_IOLBF|_IONBF)) == 0) { f->_cnt--; *f->_ptr++ = c; } @@ -117,37 +96,33 @@ _flsbuf(int c, FILE *f) wint_t _flswbuf(wchar_t c,FILE *fp) { - return (wint_t )_flsbuf((int)c,fp); -} + int result; + result = _flsbuf((int)c, fp); + if (result == EOF) + return WEOF; + return (wint_t)result; +} int _writecnv(int fn, void *buf, size_t siz) { char *bufp = (char *)buf; int bufsiz = siz; - - char *tmp; + char *tmp; int cr1 = 0; int cr2 = 0; - int n; - cr1 = cntcr(bufp,bufsiz); - tmp = malloc(cr1); memcpy(tmp,bufp+bufsiz-cr1,cr1); cr2 = cntcr(tmp,cr1); - convert(bufp,bufsiz-cr2,cr1-cr2); n = _write(fn, bufp, bufsiz + cr1); - convert(tmp,cr1,cr2); n += _write(fn, tmp, cr1 + cr2); free(tmp); return n; - - } int convert(char *endp, int bufsiz,int n) @@ -165,15 +140,17 @@ int convert(char *endp, int bufsiz,int n) } return n; } + int cntcr(char *bufp, int bufsiz) { int cr = 0; + while (bufsiz > 0) { - if (*bufp == '\n') + if (*bufp == '\n') { cr++; + } bufp++; bufsiz--; } - return cr; } diff --git a/lib/crtdll/stdio/fopen.c b/lib/crtdll/stdio/fopen.c index 9335cf2..b657438 100644 --- a/lib/crtdll/stdio/fopen.c +++ b/lib/crtdll/stdio/fopen.c @@ -1,10 +1,10 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include //might change fopen(file,mode) -> fsopen(file,mode,_SH_DENYNO); diff --git a/lib/crtdll/stdio/fprintf.c b/lib/crtdll/stdio/fprintf.c index 9ac7b6b..6c503de 100644 --- a/lib/crtdll/stdio/fprintf.c +++ b/lib/crtdll/stdio/fprintf.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include int fprintf(register FILE *iop, const char *fmt, ...) diff --git a/lib/crtdll/stdio/fputc.c b/lib/crtdll/stdio/fputc.c index c63635a..c05abe9 100644 --- a/lib/crtdll/stdio/fputc.c +++ b/lib/crtdll/stdio/fputc.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include int fputc(int c, FILE *fp) @@ -12,6 +12,6 @@ fputc(int c, FILE *fp) wint_t fputwc(wchar_t c, FILE *fp) { - return fputwc(c,fp); + return putwc(c,fp); } diff --git a/lib/crtdll/stdio/fputchar.c b/lib/crtdll/stdio/fputchar.c index 235a085..35799c1 100644 --- a/lib/crtdll/stdio/fputchar.c +++ b/lib/crtdll/stdio/fputchar.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int _fputchar (int c) { diff --git a/lib/crtdll/stdio/fputs.c b/lib/crtdll/stdio/fputs.c index d8fbfff..b47e65b 100644 --- a/lib/crtdll/stdio/fputs.c +++ b/lib/crtdll/stdio/fputs.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include #include int diff --git a/lib/crtdll/stdio/fputws.c b/lib/crtdll/stdio/fputws.c new file mode 100644 index 0000000..399ac41 --- /dev/null +++ b/lib/crtdll/stdio/fputws.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include +#include +#include +#include + +//int fputws(const wchar_t* wsOutput, FILE* fileWrite) +//int fputs(const char *s, FILE *f) + +int +fputws(const wchar_t* s, FILE* f) +{ + int r = 0; + int c; + int unbuffered; + wchar_t localbuf[BUFSIZ]; + + unbuffered = f->_flag & _IONBF; + if (unbuffered) + { + f->_flag &= ~_IONBF; + f->_ptr = f->_base = localbuf; + f->_bufsiz = BUFSIZ; + } + + while ((c = *s++)) + r = putwc(c, f); + + if (unbuffered) + { + fflush(f); + f->_flag |= _IONBF; + f->_base = NULL; + f->_bufsiz = 0; + f->_cnt = 0; + } + return(r); +} diff --git a/lib/crtdll/stdio/fread.c b/lib/crtdll/stdio/fread.c index c9f7238..79fc372 100644 --- a/lib/crtdll/stdio/fread.c +++ b/lib/crtdll/stdio/fread.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include // carriage return line feed conversion is done in filbuf and flsbuf diff --git a/lib/crtdll/stdio/freopen.c b/lib/crtdll/stdio/freopen.c index 13a60f1..717c858 100644 --- a/lib/crtdll/stdio/freopen.c +++ b/lib/crtdll/stdio/freopen.c @@ -1,15 +1,13 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include - -FILE * -freopen(const char *file, const char *mode, FILE *f) +FILE *freopen(const char *file, const char *mode, FILE *f) { int fd, rw, oflags=0; char tbchar; diff --git a/lib/crtdll/stdio/frlist.c b/lib/crtdll/stdio/frlist.c index 511d931..3396998 100644 --- a/lib/crtdll/stdio/frlist.c +++ b/lib/crtdll/stdio/frlist.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -//#include -#include +#include +//#include +#include static __file_rec __initial_file_rec = { diff --git a/lib/crtdll/stdio/fscanf.c b/lib/crtdll/stdio/fscanf.c index f8f33e7..1b23898 100644 --- a/lib/crtdll/stdio/fscanf.c +++ b/lib/crtdll/stdio/fscanf.c @@ -17,13 +17,13 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include +#include +#include +#include +#include +#include -int __vfscanf (FILE *s, const char *format, va_list argptr); /* Read formatted input from STREAM according to the format string FORMAT. */ /* VARARGS2 */ int fscanf(FILE *stream,const char *format, ...) @@ -57,4 +57,3 @@ fwscanf(FILE *stream, const wchar_t *fmt, ...) free(cf); return done; } - diff --git a/lib/crtdll/stdio/fseek.c b/lib/crtdll/stdio/fseek.c index 7392946..bdc2f41 100644 --- a/lib/crtdll/stdio/fseek.c +++ b/lib/crtdll/stdio/fseek.c @@ -2,11 +2,11 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include int fseek(FILE *f, long offset, int ptrname) @@ -38,7 +38,6 @@ int fseek(FILE *f, long offset, int ptrname) return 0; } } - p = lseek(fileno(f), offset, ptrname); f->_cnt = 0; @@ -52,5 +51,4 @@ int fseek(FILE *f, long offset, int ptrname) -1 : 0; } return p==-1 ? -1 : 0; - } diff --git a/lib/crtdll/stdio/fsetpos.c b/lib/crtdll/stdio/fsetpos.c index 718bb6e..ee040f7 100644 --- a/lib/crtdll/stdio/fsetpos.c +++ b/lib/crtdll/stdio/fsetpos.c @@ -1,10 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include -int -fsetpos(FILE *stream,const fpos_t *pos) +int fsetpos(FILE *stream,const fpos_t *pos) { if (stream && pos) { diff --git a/lib/crtdll/stdio/fsopen.c b/lib/crtdll/stdio/fsopen.c index 9c14819..c766adf 100644 --- a/lib/crtdll/stdio/fsopen.c +++ b/lib/crtdll/stdio/fsopen.c @@ -9,20 +9,20 @@ */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -FILE * __alloc_file(void); +FILE* __alloc_file(void); -FILE* _fsopen(const char *file, const char *mode, int shflag) +FILE* _fsopen(const char* file, const char* mode, int shflag) { - FILE *f; + FILE* f; int fd, rw, oflags = 0; char tbchar; @@ -64,19 +64,17 @@ FILE* _fsopen(const char *file, const char *mode, int shflag) else oflags |= (_fmode & (O_TEXT|O_BINARY)); - - if ( shflag == _SH_DENYNO ) - shf = _S_IREAD | _S_IWRITE; + shf = _S_IREAD | _S_IWRITE; else if( shflag == _SH_DENYRD ) - shf = _S_IWRITE; + shf = _S_IWRITE; else if( shflag == _SH_DENYRW ) - shf = 0; + shf = 0; else if( shflag == _SH_DENYWR ) - shf = _S_IREAD; + shf = _S_IREAD; else - shf = _S_IREAD | _S_IWRITE; - + shf = _S_IREAD | _S_IWRITE; + fd = _open(file, oflags, shf); if (fd < 0) return NULL; diff --git a/lib/crtdll/stdio/ftell.c b/lib/crtdll/stdio/ftell.c index deb4bbd..24e7968 100644 --- a/lib/crtdll/stdio/ftell.c +++ b/lib/crtdll/stdio/ftell.c @@ -1,16 +1,14 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -//#include -#include -//#include -#include -#include -#include + +#include +#include +#include #include +#include -long -ftell(FILE *f) +long ftell(FILE *f) { long tres; int adjust=0; @@ -23,7 +21,6 @@ ftell(FILE *f) if (f->_cnt < 0) f->_cnt = 0; - else if (f->_flag&_IOREAD) { adjust = - f->_cnt; @@ -33,9 +30,9 @@ ftell(FILE *f) if (f->_base && (f->_flag&_IONBF)==0) adjust = f->_ptr - f->_base; } - else return -1; + tres = lseek(fileno(f), 0L, SEEK_CUR); if (tres<0) return tres; @@ -43,5 +40,6 @@ ftell(FILE *f) //f->_cnt = f->_bufsiz - tres; //f->_ptr = f->_base + tres; + return tres; } diff --git a/lib/crtdll/stdio/fwalk.c b/lib/crtdll/stdio/fwalk.c index 11be7eb..ef747c1 100644 --- a/lib/crtdll/stdio/fwalk.c +++ b/lib/crtdll/stdio/fwalk.c @@ -1,18 +1,18 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include -// not exported by crtdll -__file_rec *__file_rec_list; -void -_fwalk(void (*func)(FILE *)) +// not exported by msvcrt or crtdll +__file_rec* __file_rec_list; + +void _fwalk(void (*func)(FILE*)) { - __file_rec *fr; - int i; - - for (fr=__file_rec_list; fr; fr=fr->next) - for (i=0; icount; i++) - if (fr->files[i]->_flag) - func(fr->files[i]); + __file_rec* fr; + int i; + + for (fr=__file_rec_list; fr; fr=fr->next) + for (i=0; icount; i++) + if (fr->files[i]->_flag) + func(fr->files[i]); } diff --git a/lib/crtdll/stdio/fwrite.c b/lib/crtdll/stdio/fwrite.c index 7796416..82d7a7b 100644 --- a/lib/crtdll/stdio/fwrite.c +++ b/lib/crtdll/stdio/fwrite.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if 0 size_t diff --git a/lib/crtdll/stdio/getc.c b/lib/crtdll/stdio/getc.c index fe87af3..0983fc3 100644 --- a/lib/crtdll/stdio/getc.c +++ b/lib/crtdll/stdio/getc.c @@ -1,8 +1,8 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include //getc can be a macro #undef getc @@ -25,7 +25,7 @@ int getc(FILE *fp) if(fp->_cnt > 0) { fp->_cnt--; - c = (int)*fp->_ptr++; + c = (int)(*fp->_ptr++ & 0377); } else { c = _filbuf(fp); diff --git a/lib/crtdll/stdio/getchar.c b/lib/crtdll/stdio/getchar.c index fe0f036..14392d2 100644 --- a/lib/crtdll/stdio/getchar.c +++ b/lib/crtdll/stdio/getchar.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #undef getchar int diff --git a/lib/crtdll/stdio/getenv.c b/lib/crtdll/stdio/getenv.c index 9188ddb..30a2f38 100644 --- a/lib/crtdll/stdio/getenv.c +++ b/lib/crtdll/stdio/getenv.c @@ -1,5 +1,5 @@ #include -#include +#include void *malloc(size_t size); diff --git a/lib/crtdll/stdio/gets.c b/lib/crtdll/stdio/gets.c index 4885714..5b879c7 100644 --- a/lib/crtdll/stdio/gets.c +++ b/lib/crtdll/stdio/gets.c @@ -8,10 +8,9 @@ * 28/12/98: Appropriated for Reactos */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -char * -gets(char *s) +char* gets(char* s) { int c; char *cs; diff --git a/lib/crtdll/stdio/getw.c b/lib/crtdll/stdio/getw.c index 54b93c5..7fb7594 100644 --- a/lib/crtdll/stdio/getw.c +++ b/lib/crtdll/stdio/getw.c @@ -16,18 +16,20 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include /* Read a word (int) from STREAM. */ -int -_getw(FILE *stream) +int _getw(FILE *stream) { int w; /* Is there a better way? */ - if (fread( &w, sizeof(w), 1, stream) != 1) + if (fread( &w, sizeof(w), 1, stream) != 1) { + // EOF is a legitimate integer value so users must + // check feof or ferror to verify an EOF return. return(EOF); + } return(w); } diff --git a/lib/crtdll/stdio/perror.c b/lib/crtdll/stdio/perror.c index fdde0bb..a959151 100644 --- a/lib/crtdll/stdio/perror.c +++ b/lib/crtdll/stdio/perror.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include #ifdef perror @@ -9,8 +9,7 @@ void perror(const char *s); #endif -void -perror(const char *s) +void perror(const char *s) { fprintf(stderr, "%s: %s\n", s, _strerror(NULL)); diff --git a/lib/crtdll/stdio/popen.c b/lib/crtdll/stdio/popen.c index 6ac7f68..c24c378 100644 --- a/lib/crtdll/stdio/popen.c +++ b/lib/crtdll/stdio/popen.c @@ -1,14 +1,14 @@ #include -#include -#include -#include -#include -#include -#include - -FILE * -_popen (const char *cm, const char *md) /* program name, pipe mode */ +#include +#include +#include +#include +#include +#include + + +FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */ { FILE *pf; HANDLE hReadPipe, hWritePipe; diff --git a/lib/crtdll/stdio/printf.c b/lib/crtdll/stdio/printf.c index 2e8a45b..36cd1ae 100644 --- a/lib/crtdll/stdio/printf.c +++ b/lib/crtdll/stdio/printf.c @@ -16,9 +16,9 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include +#include +#include +#include /* Write formatted output to stdout from the format string FORMAT. */ /* VARARGS1 */ diff --git a/lib/crtdll/stdio/putc.c b/lib/crtdll/stdio/putc.c index 0764d07..8cc187b 100644 --- a/lib/crtdll/stdio/putc.c +++ b/lib/crtdll/stdio/putc.c @@ -1,18 +1,17 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include -#include -#include -#include +#include +#include +#include +#include // putc can be a macro #undef putc +#undef putwc -int putc(int c, FILE *fp) +int putc(int c, FILE* fp) { - -// valid stream macro should check that fp -// is dword aligned +// valid stream macro should check that fp is dword aligned if (!__validfp (fp)) { __set_errno(EINVAL); return -1; @@ -36,7 +35,9 @@ int putc(int c, FILE *fp) return EOF; } -wint_t putwc(wchar_t c, FILE *fp) +//wint_t putwc(wint_t c, FILE* fp) +//int putwc(wchar_t c, FILE* fp) +int putwc(wint_t c, FILE* fp) { // might check on multi bytes if text mode diff --git a/lib/crtdll/stdio/putchar.c b/lib/crtdll/stdio/putchar.c index ce2b083..4cd83f8 100644 --- a/lib/crtdll/stdio/putchar.c +++ b/lib/crtdll/stdio/putchar.c @@ -8,7 +8,7 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include +#include #undef putc #undef putchar diff --git a/lib/crtdll/stdio/puts.c b/lib/crtdll/stdio/puts.c index 11d6eb6..008a6f5 100644 --- a/lib/crtdll/stdio/puts.c +++ b/lib/crtdll/stdio/puts.c @@ -1,17 +1,18 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include #include -#include +#include +#include +#include #undef putchar -int -puts(const char *s) + + +int puts(const char *s) { - - int c; - while ((c = *s++)) - putchar(c); - return putchar('\n'); + int c; + + while ((c = *s++)) + putchar(c); + return putchar('\n'); } diff --git a/lib/crtdll/stdio/putw.c b/lib/crtdll/stdio/putw.c index 5b8227a..9495126 100644 --- a/lib/crtdll/stdio/putw.c +++ b/lib/crtdll/stdio/putw.c @@ -1,28 +1,27 @@ /* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. + * This file is part of the GNU C Library. + * + * The GNU C Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The GNU C Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU C Library; see the file COPYING.LIB. If + * not, write to the Free Software Foundation, Inc., 675 Mass Ave, + * Cambridge, MA 02139, USA. */ -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - - -#include +#include /* Write the word (int) W to STREAM. */ -int -_putw(int w,FILE *stream) +int _putw(int w,FILE *stream) { /* Is there a better way? */ if (fwrite( &w, sizeof(w), 1, stream) < 1) diff --git a/lib/crtdll/stdio/remove.c b/lib/crtdll/stdio/remove.c index 8fc77bd..56f913f 100644 --- a/lib/crtdll/stdio/remove.c +++ b/lib/crtdll/stdio/remove.c @@ -1,9 +1,9 @@ #include + int remove(const char *fn) { if (!DeleteFileA(fn)) return -1; return 0; } - diff --git a/lib/crtdll/stdio/rename.c b/lib/crtdll/stdio/rename.c index 14eb401..9baaf8e 100644 --- a/lib/crtdll/stdio/rename.c +++ b/lib/crtdll/stdio/rename.c @@ -1,16 +1,15 @@ #include -#include -#include +#include +#include int rename(const char *old_, const char *new_) { if ( old_ == NULL || new_ == NULL ) return -1; + if ( !MoveFileA(old_,new_) ) return -1; return 0; } - - diff --git a/lib/crtdll/stdio/rewind.c b/lib/crtdll/stdio/rewind.c index 099b6b7..013e2fc 100644 --- a/lib/crtdll/stdio/rewind.c +++ b/lib/crtdll/stdio/rewind.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include void rewind(FILE *f) @@ -12,5 +12,4 @@ void rewind(FILE *f) f->_cnt = 0; f->_ptr = f->_base; f->_flag &= ~(_IOERR|_IOEOF|_IOAHEAD); - } diff --git a/lib/crtdll/stdio/rmtmp.c b/lib/crtdll/stdio/rmtmp.c index 18d0fe4..6989447 100644 --- a/lib/crtdll/stdio/rmtmp.c +++ b/lib/crtdll/stdio/rmtmp.c @@ -9,9 +9,9 @@ * NOTE Not tested. */ -#include -#include -#include +#include +#include +#include #ifndef F_OK #define F_OK 0x01 diff --git a/lib/crtdll/stdio/scanf.c b/lib/crtdll/stdio/scanf.c index 9d44102..10d7c42 100644 --- a/lib/crtdll/stdio/scanf.c +++ b/lib/crtdll/stdio/scanf.c @@ -17,9 +17,9 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include -#include -#include +#include +#include +#include /* The function `vscanf' is not defined in ISO C. Therefore we must @@ -48,8 +48,6 @@ int scanf (const char *format, ...) return done; } - - int wscanf(const wchar_t *fmt, ...) { @@ -66,7 +64,6 @@ wscanf(const wchar_t *fmt, ...) done = VSCANF (f, arg); va_end (arg); free(f); + return done; } - - diff --git a/lib/crtdll/stdio/setbuf.c b/lib/crtdll/stdio/setbuf.c index f8a6e1d..a112ae3 100644 --- a/lib/crtdll/stdio/setbuf.c +++ b/lib/crtdll/stdio/setbuf.c @@ -1,10 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include -void -setbuf(FILE *f, char *buf) +void setbuf(FILE *f, char *buf) { if (buf) setvbuf(f, buf, _IOFBF, BUFSIZ); diff --git a/lib/crtdll/stdio/setbuffe.c b/lib/crtdll/stdio/setbuffe.c index 5fb09f2..d694b4d 100644 --- a/lib/crtdll/stdio/setbuffe.c +++ b/lib/crtdll/stdio/setbuffe.c @@ -1,7 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -//#include -#include -#include +//#include +#include +#include void setbuffer(FILE *f, void *buf, int size) { diff --git a/lib/crtdll/stdio/setlineb.c b/lib/crtdll/stdio/setlineb.c index e8dcb04..a46de66 100644 --- a/lib/crtdll/stdio/setlineb.c +++ b/lib/crtdll/stdio/setlineb.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include // not exported diff --git a/lib/crtdll/stdio/setvbuf.c b/lib/crtdll/stdio/setvbuf.c index 2f095e3..2b1d074 100644 --- a/lib/crtdll/stdio/setvbuf.c +++ b/lib/crtdll/stdio/setvbuf.c @@ -1,11 +1,11 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include int setvbuf(FILE *f, char *buf, int type, size_t len) diff --git a/lib/crtdll/stdio/sprintf.c b/lib/crtdll/stdio/sprintf.c index 855bc55..8a27c85 100644 --- a/lib/crtdll/stdio/sprintf.c +++ b/lib/crtdll/stdio/sprintf.c @@ -18,11 +18,11 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include +#include +#include +#include #include -#include +#include #undef sprintf #undef wsprintf diff --git a/lib/crtdll/stdio/sscanf.c b/lib/crtdll/stdio/sscanf.c index a81dde4..c0ccbb3 100644 --- a/lib/crtdll/stdio/sscanf.c +++ b/lib/crtdll/stdio/sscanf.c @@ -16,14 +16,13 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include +#include +#include +#include +#include +#include -int __vsscanf (const char *s,const char *format,va_list arg); - /* Read formatted input from S, according to the format string FORMAT. */ /* VARARGS2 */ int sscanf (const char *s,const char *format, ...) @@ -38,17 +37,7 @@ int sscanf (const char *s,const char *format, ...) return done; } -#ifdef USE_IN_LIBIO -# undef _IO_sscanf -/* This is for libg++. */ -strong_alias (sscanf, _IO_sscanf) -#endif - - - - -int -swscanf(const wchar_t *str, const wchar_t *fmt, ...) +int swscanf(const wchar_t *str, const wchar_t *fmt, ...) { va_list arg; int done; @@ -71,9 +60,6 @@ swscanf(const wchar_t *str, const wchar_t *fmt, ...) va_end (arg); free(f); - return done; - + return done; } - - diff --git a/lib/crtdll/stdio/stdhnd.c b/lib/crtdll/stdio/stdhnd.c index c37e1e3..c4fc04d 100644 --- a/lib/crtdll/stdio/stdhnd.c +++ b/lib/crtdll/stdio/stdhnd.c @@ -1,9 +1,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -//#include - - +#include +#include FILE _iob[5] = { diff --git a/lib/crtdll/stdio/stdiohk.c b/lib/crtdll/stdio/stdiohk.c index 83092aa..a808c37 100644 --- a/lib/crtdll/stdio/stdiohk.c +++ b/lib/crtdll/stdio/stdiohk.c @@ -1,6 +1,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include static void fcloseall_helper(FILE *f) diff --git a/lib/crtdll/stdio/tempnam.c b/lib/crtdll/stdio/tempnam.c index efa4ade..574dc4f 100644 --- a/lib/crtdll/stdio/tempnam.c +++ b/lib/crtdll/stdio/tempnam.c @@ -1,21 +1,27 @@ #include -#include -#include +#include +#include char *_tempnam(const char *dir,const char *prefix ) { - char *TempFileName = malloc(MAX_PATH); - char *d; - if ( dir == NULL ) - d = getenv("TMP"); - else - d = (char *)dir; + char *TempFileName = malloc(MAX_PATH); + char *d; - if ( GetTempFileNameA(d, prefix, 0, TempFileName ) == 0 ) { - free(TempFileName); - return NULL; - } - - return TempFileName; + if ( dir == NULL ) + d = getenv("TMP"); + else + d = (char *)dir; + +#ifdef _MSVCRT_LIB_ // TODO: check on difference? + if (GetTempFileNameA(d, prefix, 1, TempFileName) == 0) { +#else// TODO: FIXME: review which is correct + if (GetTempFileNameA(d, prefix, 0, TempFileName) == 0) { +#endif /*_MSVCRT_LIB_*/ + + free(TempFileName); + return NULL; + } + + return TempFileName; } diff --git a/lib/crtdll/stdio/tmpfile.c b/lib/crtdll/stdio/tmpfile.c index 22e3696..1e1c116 100644 --- a/lib/crtdll/stdio/tmpfile.c +++ b/lib/crtdll/stdio/tmpfile.c @@ -2,22 +2,17 @@ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -//#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#if 0 -#ifndef __dj_include_stdio_h_ -#define _name_to_remove _tmpfname -#endif -#endif +#include +#include +#include +#include +#include +//#include +#include +#include +#include + FILE * __alloc_file(void); diff --git a/lib/crtdll/stdio/tmpnam.c b/lib/crtdll/stdio/tmpnam.c index a3ce21d..88de936 100644 --- a/lib/crtdll/stdio/tmpnam.c +++ b/lib/crtdll/stdio/tmpnam.c @@ -1,15 +1,16 @@ #include -#include -#include - +#include +#include char * tmpnam(char *s) { char PathName[MAX_PATH]; static char static_buf[MAX_PATH]; - GetTempPath(MAX_PATH,PathName); + + GetTempPathA(MAX_PATH, PathName); GetTempFileNameA(PathName, "ARI",007,static_buf); strcpy(s,static_buf); - return s; + + return s; } diff --git a/lib/crtdll/stdio/ungetc.c b/lib/crtdll/stdio/ungetc.c index 99ef471..759a068 100644 --- a/lib/crtdll/stdio/ungetc.c +++ b/lib/crtdll/stdio/ungetc.c @@ -1,14 +1,13 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include -int -ungetc(int c, FILE *f) -{ +int ungetc(int c, FILE *f) +{ if (!__validfp (f) || !OPEN4READING(f)) { __set_errno (EINVAL); return EOF; @@ -16,8 +15,6 @@ ungetc(int c, FILE *f) if (c == EOF ) return EOF; - - if ( f->_ptr == NULL || f->_base == NULL) return EOF; @@ -52,8 +49,6 @@ ungetwc(wchar_t c, FILE *f) if (c == (wchar_t)EOF ) return EOF; - - if ( f->_ptr == NULL || f->_base == NULL) return EOF; diff --git a/lib/crtdll/stdio/vfprintf.c b/lib/crtdll/stdio/vfprintf.c index 394cd74..796b4a8 100644 --- a/lib/crtdll/stdio/vfprintf.c +++ b/lib/crtdll/stdio/vfprintf.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include int _isnanl(double x); int _isinfl(double x); @@ -55,12 +55,12 @@ vfprintf(FILE *f, const char *fmt, va_list ap) #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #define ZEROPAD 1 /* pad with zero */ diff --git a/lib/crtdll/stdio/vfscanf.c b/lib/crtdll/stdio/vfscanf.c index a420885..0b357d3 100644 --- a/lib/crtdll/stdio/vfscanf.c +++ b/lib/crtdll/stdio/vfscanf.c @@ -17,17 +17,17 @@ Boston, MA 02111-1307, USA. */ -#include +#include #include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include /* The internal entry points for `strtoX' take an extra flag argument saying whether or not to parse locale-dependent number grouping. */ @@ -48,7 +48,7 @@ unsigned long int __strtoul_internal (const char *__nptr, char **__endptr, int /* Those are flags in the conversion format. */ # define LONG 0x001 /* l: long or double */ -# define LONGDBL 0x002 /* L: long long or long double */ +# define LONGDBL 0x002 /* L: LONGLONG or long double */ # define SHORT 0x004 /* h: short */ # define SUPPRESS 0x008 /* *: suppress assignment */ # define POINTER 0x010 /* weird %p pointer (`fake hex') */ @@ -320,7 +320,7 @@ int __vfscanf (FILE *s, const char *format, va_list argptr) break; case 'q': case 'L': - /* double's are long double's, and int's are long long int's. */ + /* double's are long double's, and int's are LONGLONG int's. */ if (flags & TYPEMOD) /* Signal illegal format element. */ conv_error (); diff --git a/lib/crtdll/stdio/vfwprint.c b/lib/crtdll/stdio/vfwprint.c index 31c60b1..522ec12 100644 --- a/lib/crtdll/stdio/vfwprint.c +++ b/lib/crtdll/stdio/vfwprint.c @@ -1,15 +1,16 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include #include -#include -#include +#include +#include int _isnanl(double x); int _isinfl(double x); int _isnan(double x); int _isinf(double x); -extern int putwc (wchar_t wc, FILE* fileWrite); +int putwc(wint_t wc, FILE* fileWrite); +//wint_t putwc (wint_t wc, FILE* fileWrite); int __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list argp); @@ -58,12 +59,12 @@ vfwprintf(FILE *f, const wchar_t *fmt, va_list ap) #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #define ZEROPAD 1 /* pad with zero */ diff --git a/lib/crtdll/stdio/vprintf.c b/lib/crtdll/stdio/vprintf.c index 780d960..f724749 100644 --- a/lib/crtdll/stdio/vprintf.c +++ b/lib/crtdll/stdio/vprintf.c @@ -16,10 +16,10 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #undef __OPTIMIZE__ /* Avoid inline `vprintf' function. */ -#include -#include +#include +#include #undef vprintf #undef vwprintf diff --git a/lib/crtdll/stdio/vscanf.c b/lib/crtdll/stdio/vscanf.c index f7abe38..4c6b796 100644 --- a/lib/crtdll/stdio/vscanf.c +++ b/lib/crtdll/stdio/vscanf.c @@ -16,21 +16,19 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include +#include +#include +#include +#include -int __vfscanf (FILE *s, const char *format, va_list argptr); #undef vscanf /* Read formatted input from stdin according to the format string in FORMAT, using the argument list in ARG. */ -int -__vscanf (const char *format, va_list arg) +int __vscanf (const char *format, va_list arg) { - return __vfscanf (stdin, format, arg); + return __vfscanf(stdin, format, arg); } -//weak_alias (__vscanf, vscanf) diff --git a/lib/crtdll/stdio/vsprintf.c b/lib/crtdll/stdio/vsprintf.c index 52e899e..75bfb1d 100644 --- a/lib/crtdll/stdio/vsprintf.c +++ b/lib/crtdll/stdio/vsprintf.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include #include -#include +#include int vsprintf(char *str, const char *fmt, va_list ap) diff --git a/lib/crtdll/stdio/vsscanf.c b/lib/crtdll/stdio/vsscanf.c index e5f9719..920ff13 100644 --- a/lib/crtdll/stdio/vsscanf.c +++ b/lib/crtdll/stdio/vsscanf.c @@ -16,20 +16,18 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #undef vsscanf -int __vfscanf (FILE *s, const char *format, va_list argptr); - /* Read formatted input from S according to the format string FORMAT, using the argument list in ARG. */ -int -__vsscanf (const char *s,const char *format,va_list arg) +int __vsscanf(const char *s,const char *format,va_list arg) { FILE f; @@ -41,18 +39,12 @@ __vsscanf (const char *s,const char *format,va_list arg) memset ((void *) &f, 0, sizeof (f)); - - f._flag = _IOREAD; f._ptr = (char *)s; f._base = (char *)s; f._bufsiz = strlen(s); f._cnt = f._bufsiz; - return __vfscanf (&f, format, arg); } - -//weak_alias (__vsscanf, vsscanf) - diff --git a/lib/crtdll/stdlib/_exit.c b/lib/crtdll/stdlib/_exit.c index 2f6cef3..c67e0cf 100644 --- a/lib/crtdll/stdlib/_exit.c +++ b/lib/crtdll/stdlib/_exit.c @@ -1,8 +1,8 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include struct __atexit *__atexit_ptr = 0; diff --git a/lib/crtdll/stdlib/abort.c b/lib/crtdll/stdlib/abort.c index 3c33587..b76a227 100644 --- a/lib/crtdll/stdlib/abort.c +++ b/lib/crtdll/stdlib/abort.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include char *msg ="Abort\n\r"; diff --git a/lib/crtdll/stdlib/abs.c b/lib/crtdll/stdlib/abs.c index 2863888..5680b25 100644 --- a/lib/crtdll/stdlib/abs.c +++ b/lib/crtdll/stdlib/abs.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include +#include int abs(int j) diff --git a/lib/crtdll/stdlib/alloca.c b/lib/crtdll/stdlib/alloca.c new file mode 100644 index 0000000..cfbcc91 --- /dev/null +++ b/lib/crtdll/stdlib/alloca.c @@ -0,0 +1,68 @@ +#include +#include + + +#undef alloca +void *alloca(size_t s) +{ + register unsigned int as = s; + +// alloca(0) should not return the stack pointer + if ( s == 0 ) + return NULL; + + + if ( (s & 0xfffffffc) != 0 ) + as += 4; + + as &= 0xfffffffc; + + __asm__ __volatile__( + "mov %0, %%edx \n" +// "popl %%ebp \n" + "leave \n" + "popl %%ecx \n" + "subl %%edx, %%esp \n" + "movl %%esp, %%eax \n" + "addl $20, %%eax \n"//4 bytes + 16 bytes = arguments + "push %%ecx \n" + "ret \n" + : + :"g" ( as) + ); + + + return NULL; +} + +void *_alloca(size_t s) +{ + register unsigned int as = s; + +// alloca(0) should not return the stack pointer + if ( s == 0 ) + return NULL; + + + if ( (s & 0xfffffffc) != 0 ) + as += 4; + + as &= 0xfffffffc; + + __asm__ __volatile__( + "mov %0, %%edx \n" +// "popl %%ebp \n" + "leave \n" + "popl %%ecx \n" + "subl %%edx, %%esp \n" + "movl %%esp, %%eax \n" + "addl $20, %%eax \n"//4 bytes + 16 bytes = arguments + "push %%ecx \n" + "ret \n" + : + :"g" ( as) + ); + + + return NULL; +} diff --git a/lib/crtdll/stdlib/atexit.c b/lib/crtdll/stdlib/atexit.c index 462fa07..fd80fde 100644 --- a/lib/crtdll/stdlib/atexit.c +++ b/lib/crtdll/stdlib/atexit.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int atexit(void (*a)(void)) diff --git a/lib/crtdll/stdlib/atof.c b/lib/crtdll/stdlib/atof.c index 2b93d8c..8497148 100644 --- a/lib/crtdll/stdlib/atof.c +++ b/lib/crtdll/stdlib/atof.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include double atof(const char *ascii) diff --git a/lib/crtdll/stdlib/atoi.c b/lib/crtdll/stdlib/atoi.c index 1d19cf0..c6b95e3 100644 --- a/lib/crtdll/stdlib/atoi.c +++ b/lib/crtdll/stdlib/atoi.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include int atoi(const char *str) diff --git a/lib/crtdll/stdlib/atol.c b/lib/crtdll/stdlib/atol.c index 0360505..3cac430 100644 --- a/lib/crtdll/stdlib/atol.c +++ b/lib/crtdll/stdlib/atol.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include long atol(const char *str) diff --git a/lib/crtdll/stdlib/atold.c b/lib/crtdll/stdlib/atold.c index 1bcaeeb..c9b5116 100644 --- a/lib/crtdll/stdlib/atold.c +++ b/lib/crtdll/stdlib/atold.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include long double _atold(const char *ascii) diff --git a/lib/crtdll/stdlib/bsearch.c b/lib/crtdll/stdlib/bsearch.c index a36e43f..7c3d9ed 100644 --- a/lib/crtdll/stdlib/bsearch.c +++ b/lib/crtdll/stdlib/bsearch.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include void * bsearch(const void *key, const void *base0, size_t nelem, diff --git a/lib/crtdll/stdlib/calloc.c b/lib/crtdll/stdlib/calloc.c index 7325ed6..07aa4cf 100644 --- a/lib/crtdll/stdlib/calloc.c +++ b/lib/crtdll/stdlib/calloc.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include void * calloc(size_t size, size_t nelem) diff --git a/lib/crtdll/stdlib/div.c b/lib/crtdll/stdlib/div.c index be64654..833e6a3 100644 --- a/lib/crtdll/stdlib/div.c +++ b/lib/crtdll/stdlib/div.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include div_t div(int num, int denom) diff --git a/lib/crtdll/stdlib/ecvt.c b/lib/crtdll/stdlib/ecvt.c index 56c4489..18d0090 100644 --- a/lib/crtdll/stdlib/ecvt.c +++ b/lib/crtdll/stdlib/ecvt.c @@ -1,6 +1,6 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include char *ecvtbuf (double, int, int *, int *, char *); diff --git a/lib/crtdll/stdlib/ecvtbuf.c b/lib/crtdll/stdlib/ecvtbuf.c index e391e20..1d0f65f 100644 --- a/lib/crtdll/stdlib/ecvtbuf.c +++ b/lib/crtdll/stdlib/ecvtbuf.c @@ -1,10 +1,10 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -// #include +#include +#include +#include +#include +#include +// #include void __ecvround (char *, char *, const char *, int *); diff --git a/lib/crtdll/stdlib/errno.c b/lib/crtdll/stdlib/errno.c index b2bfaa6..ce1faba 100644 --- a/lib/crtdll/stdlib/errno.c +++ b/lib/crtdll/stdlib/errno.c @@ -1,5 +1,5 @@ #include -#include +#include #undef errno int errno; diff --git a/lib/crtdll/stdlib/fcvt.c b/lib/crtdll/stdlib/fcvt.c index ebe5552..8e4a3ed 100644 --- a/lib/crtdll/stdlib/fcvt.c +++ b/lib/crtdll/stdlib/fcvt.c @@ -1,6 +1,6 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include char *fcvtbuf (double, int, int *, int *, char *); diff --git a/lib/crtdll/stdlib/fcvtbuf.c b/lib/crtdll/stdlib/fcvtbuf.c index 4f9d137..2bf85aa 100644 --- a/lib/crtdll/stdlib/fcvtbuf.c +++ b/lib/crtdll/stdlib/fcvtbuf.c @@ -1,10 +1,10 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include -#include -// #include +#include +#include +#include +#include +#include +// #include void __ecvround (char *, char *, const char *, int *); char *ecvtbuf (double, int, int *, int *, char *); diff --git a/lib/crtdll/stdlib/fullpath.c b/lib/crtdll/stdlib/fullpath.c index cf43e3e..246cadf 100644 --- a/lib/crtdll/stdlib/fullpath.c +++ b/lib/crtdll/stdlib/fullpath.c @@ -7,26 +7,21 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include #include +#include #undef fullpath -char *fullpath( char *absPath, const char *relPath, size_t maxLength ) +char *fullpath(char *absPath, const char *relPath, size_t maxLength) { return _fullpath(absPath,relPath,maxLength ); } -char *_fullpath( char *absPath, const char *relPath, size_t maxLength ) +char* _fullpath(char* absPath, const char* relPath, size_t maxLength) { - + char* lpFilePart; - char *lpFilePart; - if ( GetFullPathName(relPath,maxLength,absPath,&lpFilePart) == 0 ) + if (GetFullPathNameA(relPath,maxLength,absPath,&lpFilePart) == 0) return NULL; return absPath; } - - - - diff --git a/lib/crtdll/stdlib/gcvt.c b/lib/crtdll/stdlib/gcvt.c index f32157a..3a0b621 100644 --- a/lib/crtdll/stdlib/gcvt.c +++ b/lib/crtdll/stdlib/gcvt.c @@ -1,7 +1,7 @@ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include +#include +#include +#include char * _gcvt (double value, int ndigits, char *buf) diff --git a/lib/crtdll/stdlib/itoa.c b/lib/crtdll/stdlib/itoa.c index 087c8b4..3a465d3 100644 --- a/lib/crtdll/stdlib/itoa.c +++ b/lib/crtdll/stdlib/itoa.c @@ -9,12 +9,13 @@ * 1998: Added ltoa Boudewijn Dekker */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -char * -itoa(int value, char *string, int radix) +#include +#include +#include + + +char* _itoa(int value, char* string, int radix) { char tmp[33]; char *tp = tmp; @@ -56,9 +57,7 @@ itoa(int value, char *string, int radix) return string; } - -char * -ltoa(long value, char *string, int radix) +char* _ltoa(long value, char* string, int radix) { char tmp[33]; char *tp = tmp; @@ -100,8 +99,7 @@ ltoa(long value, char *string, int radix) return string; } -char * -_ultoa(unsigned long value, char *string, int radix) +char* _ultoa(unsigned long value, char* string, int radix) { char tmp[33]; char *tp = tmp; @@ -115,7 +113,6 @@ _ultoa(unsigned long value, char *string, int radix) return 0; } - while (v || tp == tmp) { i = v % radix; @@ -130,7 +127,6 @@ _ultoa(unsigned long value, char *string, int radix) string = (char *)malloc((tp-tmp)+1); sp = string; - while (tp > tmp) *sp++ = *--tp; *sp = 0; diff --git a/lib/crtdll/stdlib/itow.c b/lib/crtdll/stdlib/itow.c index 4a159aa..730a6fb 100644 --- a/lib/crtdll/stdlib/itow.c +++ b/lib/crtdll/stdlib/itow.c @@ -11,167 +11,137 @@ * 2000: derived from ./itoa.c by ea */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -wchar_t * -_itow (int value, wchar_t *string, int radix) -{ - wchar_t tmp [33]; - wchar_t * tp = tmp; - int i; - unsigned int v; - int sign; - wchar_t * sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = ((radix == 10) && (value < 0)); - if (sign) - { - v = -value; - } - else - { - v = (unsigned) value; - } - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - { - *tp++ = i+ (wchar_t) '0'; - } - else - { - *tp++ = i + (wchar_t) 'a' - 10; - } - } - - if (string == 0) - { - string = (wchar_t *) malloc((tp-tmp) + (sign + 1) * sizeof(wchar_t)); - } - sp = string; - - if (sign) - { - *sp++ = (wchar_t) '-'; - } - while (tp > tmp) - { - *sp++ = *--tp; - } - *sp = (wchar_t) 0; - return string; -} +#include +#include +#include -wchar_t * -_ltow (long value, wchar_t *string, int radix) +wchar_t* _itow(int value, wchar_t* string, int radix) { - wchar_t tmp [33]; - wchar_t * tp = tmp; - long int i; - unsigned long int v; - int sign; - wchar_t * sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = ((radix == 10) && (value < 0)); - if (sign) - { - v = -value; - } - else - { - v = (unsigned long) value; - } - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - { - *tp++ = i + (wchar_t) '0'; - } - else - { - *tp++ = i + (wchar_t) 'a' - 10; - } - } - - if (string == 0) - { - string = (wchar_t *) malloc((tp - tmp) + (sign + 1) * sizeof(wchar_t)); - } - sp = string; - - if (sign) - { - *sp++ = (wchar_t) '-'; - } - while (tp > tmp) - { - *sp++ = *--tp; - } - *sp = (wchar_t) 0; - return string; + wchar_t tmp [33]; + wchar_t * tp = tmp; + int i; + unsigned int v; + int sign; + wchar_t * sp; + + if (radix > 36 || radix <= 1) + { + __set_errno(EDOM); + return 0; + } + + sign = ((radix == 10) && (value < 0)); + if (sign) { + v = -value; + } else { + v = (unsigned) value; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i+ (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { + string = (wchar_t *) malloc((tp-tmp) + (sign + 1) * sizeof(wchar_t)); + } + sp = string; + + if (sign) { + *sp++ = (wchar_t) '-'; + } + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; } -wchar_t * -_ultow (unsigned long value, wchar_t *string, int radix) +wchar_t* _ltow(long value, wchar_t* string, int radix) { - wchar_t tmp [33]; - wchar_t * tp = tmp; - long int i; - unsigned long int v = value; - wchar_t * sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - { - *tp++ = i + (wchar_t) '0'; - } - else - { - *tp++ = i + (wchar_t) 'a' - 10; - } - } - - if (string == 0) - { - string = (wchar_t *) malloc((tp - tmp) + sizeof(wchar_t)); - } - sp = string; - - - while (tp > tmp) - { - *sp++ = *--tp; - } - *sp = (wchar_t) 0; - return string; + wchar_t tmp [33]; + wchar_t * tp = tmp; + long int i; + unsigned long int v; + int sign; + wchar_t * sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + + sign = ((radix == 10) && (value < 0)); + if (sign) { + v = -value; + } else { + v = (unsigned long) value; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { + string = (wchar_t *) malloc((tp - tmp) + (sign + 1) * sizeof(wchar_t)); + } + sp = string; + + if (sign) { + *sp++ = (wchar_t) '-'; + } + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; } - -/* EOF */ +wchar_t* _ultow(unsigned long value, wchar_t* string, int radix) +{ + wchar_t tmp [33]; + wchar_t * tp = tmp; + long int i; + unsigned long int v = value; + wchar_t * sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { +#ifdef _MSVCRT_LIB_ // TODO: check on difference? + string = (wchar_t *)malloc(((tp-tmp)+1)*sizeof(wchar_t)); +#else // TODO: FIXME: review which is correct + string = (wchar_t *) malloc((tp - tmp) + sizeof(wchar_t)); +#endif /*_MSVCRT_LIB_*/ + } + sp = string; + + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; +} diff --git a/lib/crtdll/stdlib/labs.c b/lib/crtdll/stdlib/labs.c index b1c4fa2..87b69a3 100644 --- a/lib/crtdll/stdlib/labs.c +++ b/lib/crtdll/stdlib/labs.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include +#include long labs(long j) diff --git a/lib/crtdll/stdlib/ldiv.c b/lib/crtdll/stdlib/ldiv.c index 26cbfbb..a3b121b 100644 --- a/lib/crtdll/stdlib/ldiv.c +++ b/lib/crtdll/stdlib/ldiv.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include ldiv_t ldiv(long num, long denom) diff --git a/lib/crtdll/stdlib/llabs.c b/lib/crtdll/stdlib/llabs.c index fc6580a..83ba4ef 100644 --- a/lib/crtdll/stdlib/llabs.c +++ b/lib/crtdll/stdlib/llabs.c @@ -1,6 +1,6 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include long long llabs(long long j) diff --git a/lib/crtdll/stdlib/lldiv.c b/lib/crtdll/stdlib/lldiv.c index 2a0e3f5..75f065b 100644 --- a/lib/crtdll/stdlib/lldiv.c +++ b/lib/crtdll/stdlib/lldiv.c @@ -1,6 +1,6 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include lldiv_t lldiv(long long num, long long denom) diff --git a/lib/crtdll/stdlib/makepath.c b/lib/crtdll/stdlib/makepath.c index ebc59aa..da9e543 100644 --- a/lib/crtdll/stdlib/makepath.c +++ b/lib/crtdll/stdlib/makepath.c @@ -1,33 +1,29 @@ /* $Id$ */ -#include -#include +#include +#include void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext) { int dir_len; - if ((drive != NULL) && (*drive)) - { + if ((drive != NULL) && (*drive)) { strcpy(path, drive); strcat(path, ":"); + } else { + (*path)=0; } - else - (*path)=0; - if (dir != NULL) - { + if (dir != NULL) { strcat(path, dir); dir_len = strlen(dir); if (dir_len && *(dir + dir_len - 1) != '\\') strcat(path, "\\"); } - if (fname != NULL) - { + if (fname != NULL) { strcat(path, fname); - if (ext != NULL && *ext != 0) - { + if (ext != NULL && *ext != 0) { if (*ext != '.') strcat(path, "."); strcat(path, ext); diff --git a/lib/crtdll/stdlib/malloc.c b/lib/crtdll/stdlib/malloc.c index 116e38c..50db1d4 100644 --- a/lib/crtdll/stdlib/malloc.c +++ b/lib/crtdll/stdlib/malloc.c @@ -1,5 +1,5 @@ #include -#include +#include void* malloc(size_t _size) @@ -21,67 +21,3 @@ void* realloc(void* _ptr, size_t _size) { return(HeapReAlloc(GetProcessHeap(),0,_ptr,_size)); } -#undef alloca -void *alloca(size_t s) -{ - register unsigned int as = s; - -// alloca(0) should not return the stack pointer - if ( s == 0 ) - return NULL; - - - if ( (s & 0xfffffffc) != 0 ) - as += 4; - - as &= 0xfffffffc; - - __asm__ __volatile__( - "mov %0, %%edx \n" -// "popl %%ebp \n" - "leave \n" - "popl %%ecx \n" - "subl %%edx, %%esp \n" - "movl %%esp, %%eax \n" - "addl $20, %%eax \n"//4 bytes + 16 bytes = arguments - "push %%ecx \n" - "ret \n" - : - :"g" ( as) - ); - - - return NULL; -} - -void *_alloca(size_t s) -{ - register unsigned int as = s; - -// alloca(0) should not return the stack pointer - if ( s == 0 ) - return NULL; - - - if ( (s & 0xfffffffc) != 0 ) - as += 4; - - as &= 0xfffffffc; - - __asm__ __volatile__( - "mov %0, %%edx \n" -// "popl %%ebp \n" - "leave \n" - "popl %%ecx \n" - "subl %%edx, %%esp \n" - "movl %%esp, %%eax \n" - "addl $20, %%eax \n"//4 bytes + 16 bytes = arguments - "push %%ecx \n" - "ret \n" - : - :"g" ( as) - ); - - - return NULL; -} diff --git a/lib/crtdll/stdlib/mbstow.c b/lib/crtdll/stdlib/mbstow.c deleted file mode 100644 index f97c19e..0000000 --- a/lib/crtdll/stdlib/mbstow.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - - -int mblen (const char* mbs, size_t sizeString) -{ - return 0; -} - -size_t mbstowcs (wchar_t* wcaDest, const char* mbsConvert, size_t size) -{ - return 0; -} - -int mbtowc (wchar_t* wcDest, const char* mbConvert, size_t size) -{ - return 0; -} diff --git a/lib/crtdll/stdlib/mbstowcs.c b/lib/crtdll/stdlib/mbstowcs.c index bb459dc..6e0f558 100644 --- a/lib/crtdll/stdlib/mbstowcs.c +++ b/lib/crtdll/stdlib/mbstowcs.c @@ -9,4 +9,3 @@ int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) { return 0; } - diff --git a/lib/crtdll/stdlib/obsol.c b/lib/crtdll/stdlib/obsol.c index c5aec4e..a57e878 100644 --- a/lib/crtdll/stdlib/obsol.c +++ b/lib/crtdll/stdlib/obsol.c @@ -1,10 +1,14 @@ #include -#include +#include #undef _cpumode unsigned char _cpumode = 0; unsigned char *_cpumode_dll = &_cpumode; +WINBOOL STDCALL Beep(DWORD dwFreq, DWORD dwDuration); +VOID STDCALL Sleep(DWORD dwMilliseconds); +UINT STDCALL SetErrorMode(UINT uMode); + void _seterrormode(int nMode) { SetErrorMode(nMode); diff --git a/lib/crtdll/stdlib/putenv.c b/lib/crtdll/stdlib/putenv.c index cc91ccc..0d43f8c 100644 --- a/lib/crtdll/stdlib/putenv.c +++ b/lib/crtdll/stdlib/putenv.c @@ -1,11 +1,10 @@ #include -#include -#include +#include +#include -int -putenv(const char *val) +int putenv(const char *val) { char buffer[1024]; @@ -22,9 +21,3 @@ putenv(const char *val) return SetEnvironmentVariableA(buffer,epos+1); } - - - - - - diff --git a/lib/crtdll/stdlib/qsort.c b/lib/crtdll/stdlib/qsort.c index f2be7c5..09f5816 100644 --- a/lib/crtdll/stdlib/qsort.c +++ b/lib/crtdll/stdlib/qsort.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include /*- * Copyright (c) 1980, 1983 The Regents of the University of California. diff --git a/lib/crtdll/stdlib/rand.c b/lib/crtdll/stdlib/rand.c index 78912a2..74761b7 100644 --- a/lib/crtdll/stdlib/rand.c +++ b/lib/crtdll/stdlib/rand.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include static unsigned long long next = 0; diff --git a/lib/crtdll/stdlib/rot.c b/lib/crtdll/stdlib/rot.c index 7a67cb6..c25ffd5 100644 --- a/lib/crtdll/stdlib/rot.c +++ b/lib/crtdll/stdlib/rot.c @@ -8,7 +8,8 @@ * 03/04/99: Created */ -#include +#include +#include unsigned int _rotl( unsigned int value, int shift ) { diff --git a/lib/crtdll/stdlib/senv.c b/lib/crtdll/stdlib/senv.c index 66bf91e..b87dcb6 100644 --- a/lib/crtdll/stdlib/senv.c +++ b/lib/crtdll/stdlib/senv.c @@ -1,14 +1,20 @@ -#include #include -#include +#include +#include + +#define NDEBUG +#include + void _searchenv(const char *file,const char *var,char *path ) { char *env = getenv(var); - char *x; char *y; char *FilePart; + + DPRINT("_searchenv()\n"); + x = strchr(env,'='); if ( x != NULL ) { *x = 0; @@ -24,5 +30,4 @@ void _searchenv(const char *file,const char *var,char *path ) y = strchr(env,';'); } return; - } diff --git a/lib/crtdll/stdlib/splitp.c b/lib/crtdll/stdlib/splitp.c index 9388ea0..9d69349 100644 --- a/lib/crtdll/stdlib/splitp.c +++ b/lib/crtdll/stdlib/splitp.c @@ -1,5 +1,6 @@ -#include -#include +#include +#include + void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ext ) { @@ -44,4 +45,3 @@ void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ex *(fname+(tmp_ext-path))=0; } } - diff --git a/lib/crtdll/stdlib/strtod.c b/lib/crtdll/stdlib/strtod.c index 289752b..433ea38 100644 --- a/lib/crtdll/stdlib/strtod.c +++ b/lib/crtdll/stdlib/strtod.c @@ -1,7 +1,7 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include + +#include double diff --git a/lib/crtdll/stdlib/strtol.c b/lib/crtdll/stdlib/strtol.c index cbe7e18..1d32150 100644 --- a/lib/crtdll/stdlib/strtol.c +++ b/lib/crtdll/stdlib/strtol.c @@ -1,9 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include -#include -#include -#include +#include +#include +#include + long strtol(const char *nptr, char **endptr, int base) diff --git a/lib/crtdll/stdlib/strtold.c b/lib/crtdll/stdlib/strtold.c index d38d025..2cdc6ec 100644 --- a/lib/crtdll/stdlib/strtold.c +++ b/lib/crtdll/stdlib/strtold.c @@ -1,12 +1,16 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -//#include +#include +#include +//#include static double powten[] = { - 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L + 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L, +#ifdef __GNUC__ 1e512L, 1e512L*1e512L, 1e2048L, 1e4096L +#else + 1e256L, 1e256L, 1e256L, 1e256L +#endif }; long double diff --git a/lib/crtdll/stdlib/strtoll.c b/lib/crtdll/stdlib/strtoll.c index 237aeac..b609e79 100644 --- a/lib/crtdll/stdlib/strtoll.c +++ b/lib/crtdll/stdlib/strtoll.c @@ -1,10 +1,10 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include -#include -#include -//#include +#include +#include +#include +//#include /* constants used in Solaris */ #define LLONG_MIN -9223372036854775807L-1L diff --git a/lib/crtdll/stdlib/strtoul.c b/lib/crtdll/stdlib/strtoul.c index ce4b432..7e275da 100644 --- a/lib/crtdll/stdlib/strtoul.c +++ b/lib/crtdll/stdlib/strtoul.c @@ -1,10 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include -#include -#include -#include - +#include +#include +#include /* * Convert a string to an unsigned long integer. diff --git a/lib/crtdll/stdlib/strtoull.c b/lib/crtdll/stdlib/strtoull.c index d94845e..ec9f852 100644 --- a/lib/crtdll/stdlib/strtoull.c +++ b/lib/crtdll/stdlib/strtoull.c @@ -1,10 +1,10 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include -#include -#include -//#include +#include +#include +#include +//#include /* * Convert a string to an unsigned long integer. diff --git a/lib/crtdll/stdlib/swab.c b/lib/crtdll/stdlib/swab.c index 0126c59..ec106ac 100644 --- a/lib/crtdll/stdlib/swab.c +++ b/lib/crtdll/stdlib/swab.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include void _swab (const char* caFrom, char* caTo, size_t sizeToCopy) { diff --git a/lib/crtdll/stdlib/wcstom.c b/lib/crtdll/stdlib/wcstom.c index 9533eb2..462bcf9 100644 --- a/lib/crtdll/stdlib/wcstom.c +++ b/lib/crtdll/stdlib/wcstom.c @@ -1,4 +1,4 @@ -#include +#include size_t wcstombs (char* mbsDest, const wchar_t* wsConvert, size_t size) { diff --git a/lib/crtdll/stdlib/wcstomb.c b/lib/crtdll/stdlib/wcstomb.c index 832672a..c5e6492 100644 --- a/lib/crtdll/stdlib/wcstomb.c +++ b/lib/crtdll/stdlib/wcstomb.c @@ -16,12 +16,12 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #ifndef EILSEQ #define EILSEQ EINVAL diff --git a/lib/crtdll/stdlib/wcstombs.c b/lib/crtdll/stdlib/wcstombs.c index 32fb7a0..01f59f6 100644 --- a/lib/crtdll/stdlib/wcstombs.c +++ b/lib/crtdll/stdlib/wcstombs.c @@ -16,11 +16,11 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include +#include -#include -#include +#include +#include #ifndef EILSEQ #define EILSEQ EINVAL @@ -39,10 +39,12 @@ static const unsigned char encoding_byte[] = /* We don't need the state really because we don't have shift states to maintain between calls to this function. */ -static mbstate_t internal; +typedef int mbstate_t; +static mbstate_t mbstate_internal; -extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ +mbstate_t __no_r_state; /* Now defined in wcstombs.c. */ +//extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ size_t __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps); @@ -77,7 +79,7 @@ __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps) const wchar_t *run = *src; if (ps == NULL) - ps = &internal; + ps = &mbstate_internal; if (dst == NULL) /* The LEN parameter has to be ignored if we don't actually write @@ -149,4 +151,4 @@ __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps) return written; } -//weak_alias (__wcsrtombs, wcsrtombs) \ No newline at end of file +//weak_alias (__wcsrtombs, wcsrtombs) diff --git a/lib/crtdll/string/memccpy.c b/lib/crtdll/string/memccpy.c index ba13fa4..42fd26b 100644 --- a/lib/crtdll/string/memccpy.c +++ b/lib/crtdll/string/memccpy.c @@ -1,4 +1,4 @@ -#include +#include void * diff --git a/lib/crtdll/string/memchr.c b/lib/crtdll/string/memchr.c index cb0589f..fd21697 100644 --- a/lib/crtdll/string/memchr.c +++ b/lib/crtdll/string/memchr.c @@ -1,8 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include -#include - void * memchr(const void *s, int c, size_t n) { diff --git a/lib/crtdll/string/memcmp.c b/lib/crtdll/string/memcmp.c index ed5b9ae..997be7a 100644 --- a/lib/crtdll/string/memcmp.c +++ b/lib/crtdll/string/memcmp.c @@ -1,17 +1,15 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -int -memcmp(const void *s1, const void *s2, size_t n) -{ - if (n != 0) - { - const unsigned char *p1 = s1, *p2 = s2; - do { - if (*p1++ != *p2++) - return (*--p1 - *--p2); - } while (--n != 0); - } - return 0; +int memcmp(const void *s1, const void *s2, size_t n) +{ + if (n != 0) { + const unsigned char *p1 = s1, *p2 = s2; + do { + if (*p1++ != *p2++) + return (*--p1 - *--p2); + } while (--n != 0); + } + return 0; } diff --git a/lib/crtdll/string/memcpy.c b/lib/crtdll/string/memcpy.c index 7a1f7f4..7b2dd74 100644 --- a/lib/crtdll/string/memcpy.c +++ b/lib/crtdll/string/memcpy.c @@ -1,12 +1,12 @@ -#include +#include + /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ -void * -memcpy (void *to, const void *from, size_t count) +void* memcpy(void* to, const void* from, size_t count) { - register char *f = (char *)from; - register char *t = (char *)to; + register char* f = (char*)from; + register char* t = (char*)to; register int i = count; while (i-- > 0) diff --git a/lib/crtdll/string/memicmp.c b/lib/crtdll/string/memicmp.c index e95d771..ed76603 100644 --- a/lib/crtdll/string/memicmp.c +++ b/lib/crtdll/string/memicmp.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _memicmp(const void *s1, const void *s2, size_t n) diff --git a/lib/crtdll/string/memmove.c b/lib/crtdll/string/memmove.c index 3315e10..a3d3726 100644 --- a/lib/crtdll/string/memmove.c +++ b/lib/crtdll/string/memmove.c @@ -1,4 +1,4 @@ -#include +#include void * memmove(void *dest,const void *src,size_t count) diff --git a/lib/crtdll/string/memset.c b/lib/crtdll/string/memset.c index 286ff5d..01164bf 100644 --- a/lib/crtdll/string/memset.c +++ b/lib/crtdll/string/memset.c @@ -1,10 +1,11 @@ -#include +#include -void * memset(void *src,int val,size_t count) + +void* memset(void* src, int val, size_t count) { - char *char_src = (char *)src; + char* char_src = (char*)src; - while(count>0) { + while (count>0) { *char_src = val; char_src++; count--; diff --git a/lib/crtdll/string/str_old.c b/lib/crtdll/string/str_old.c index 7f959b5..7205514 100644 --- a/lib/crtdll/string/str_old.c +++ b/lib/crtdll/string/str_old.c @@ -25,8 +25,8 @@ * */ -#include -#include +#include +#include int strcasecmp (const char* sz1, const char* sz2) diff --git a/lib/crtdll/string/strcat.c b/lib/crtdll/string/strcat.c index fd09547..9f8a8ac 100644 --- a/lib/crtdll/string/strcat.c +++ b/lib/crtdll/string/strcat.c @@ -1,12 +1,12 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -char * -strcat(char *s, const char *append) + +char* strcat(char* s, const char* append) { - char *save = s; + char* save = s; - for (; *s; ++s); - while ((*s++ = *append++)); - return save; + for (; *s; ++s); + while ((*s++ = *append++)); + return save; } diff --git a/lib/crtdll/string/strchr.c b/lib/crtdll/string/strchr.c index 4489403..2e739a8 100644 --- a/lib/crtdll/string/strchr.c +++ b/lib/crtdll/string/strchr.c @@ -1,10 +1,8 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include - -char *strchr(const char *s, int c); - char *strchr(const char *s, int c) { char cc = c; diff --git a/lib/crtdll/string/strcmp.c b/lib/crtdll/string/strcmp.c index 3f8c76e..52d3448 100644 --- a/lib/crtdll/string/strcmp.c +++ b/lib/crtdll/string/strcmp.c @@ -1,8 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -int -strcmp(const char *s1, const char *s2) + +int strcmp(const char* s1, const char* s2) { while (*s1 == *s2) { @@ -11,5 +11,5 @@ strcmp(const char *s1, const char *s2) s1++; s2++; } - return *(unsigned const char *)s1 - *(unsigned const char *)(s2); + return *(unsigned const char*)s1 - *(unsigned const char*)(s2); } diff --git a/lib/crtdll/string/strcoll.c b/lib/crtdll/string/strcoll.c index 07f5e24..81e27d6 100644 --- a/lib/crtdll/string/strcoll.c +++ b/lib/crtdll/string/strcoll.c @@ -1,28 +1,30 @@ #include -#include +#include + /* Compare S1 and S2, returning less than, equal to or greater than zero if the collated form of S1 is lexicographically less than, equal to or greater than the collated form of S2. */ #if 1 -int strcoll (const char* s1, const char* s2) +int strcoll(const char* s1, const char* s2) { - return strcmp(s1,s2); + return strcmp(s1, s2); } -int _stricoll (const char* s1, const char* s2) +int _stricoll(const char* s1, const char* s2) { - return _stricmp(s1,s2); + return _stricmp(s1, s2); } + #else -int strcoll (const char *s1,const char *s2) +int strcoll (const char* s1,const char* s2) { - int ret; - ret = CompareStringA(LOCALE_USER_DEFAULT,0,s1,strlen(s1),s2,strlen(s2)); - if (ret == 0) - return 0; - else - return ret - 2; - return 0; + int ret; + ret = CompareStringA(LOCALE_USER_DEFAULT,0,s1,strlen(s1),s2,strlen(s2)); + if (ret == 0) + return 0; + else + return ret - 2; + return 0; } #endif diff --git a/lib/crtdll/string/strcpy.c b/lib/crtdll/string/strcpy.c index cf77c54..902254f 100644 --- a/lib/crtdll/string/strcpy.c +++ b/lib/crtdll/string/strcpy.c @@ -1,5 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -char* strcpy(char *to, const char *from); +#include + +#pragma function(strcpy) char* strcpy(char *to, const char *from) { diff --git a/lib/crtdll/string/strcspn.c b/lib/crtdll/string/strcspn.c index 430182d..db77bb7 100644 --- a/lib/crtdll/string/strcspn.c +++ b/lib/crtdll/string/strcspn.c @@ -1,8 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -size_t -strcspn(const char *s1, const char *s2) +size_t strcspn(const char *s1, const char *s2) { const char *p, *spanp; char c, sc; diff --git a/lib/crtdll/string/strdup.c b/lib/crtdll/string/strdup.c index 3214e4e..a84de36 100644 --- a/lib/crtdll/string/strdup.c +++ b/lib/crtdll/string/strdup.c @@ -1,7 +1,7 @@ - /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include + char *_strdup(const char *_s) { diff --git a/lib/crtdll/string/strerror.c b/lib/crtdll/string/strerror.c index 7fad6fb..6187e5f 100644 --- a/lib/crtdll/string/strerror.c +++ b/lib/crtdll/string/strerror.c @@ -1,8 +1,8 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include char __syserr00[] = "No Error"; diff --git a/lib/crtdll/string/stricmp.c b/lib/crtdll/string/stricmp.c index 913ceef..de15d0f 100644 --- a/lib/crtdll/string/stricmp.c +++ b/lib/crtdll/string/stricmp.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _stricmp(const char *s1, const char *s2) diff --git a/lib/crtdll/string/strlen.c b/lib/crtdll/string/strlen.c index c68a3dd..a2995f8 100644 --- a/lib/crtdll/string/strlen.c +++ b/lib/crtdll/string/strlen.c @@ -1,10 +1,10 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include -size_t -strlen(const char *str) + +size_t strlen(const char* str) { - const char *s; + const char* s; if (str == 0) return 0; diff --git a/lib/crtdll/string/strlwr.c b/lib/crtdll/string/strlwr.c index 9a11967..131ec3f 100644 --- a/lib/crtdll/string/strlwr.c +++ b/lib/crtdll/string/strlwr.c @@ -8,8 +8,8 @@ * Copyright 1997 Uwe Bonnes */ -#include -#include +#include +#include char * _strlwr(char *x) { diff --git a/lib/crtdll/string/strncat.c b/lib/crtdll/string/strncat.c index d3803fe..be963b4 100644 --- a/lib/crtdll/string/strncat.c +++ b/lib/crtdll/string/strncat.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include char * strncat(char *dst, const char *src, size_t n) diff --git a/lib/crtdll/string/strncmp.c b/lib/crtdll/string/strncmp.c index 0f2950e..6a2352d 100644 --- a/lib/crtdll/string/strncmp.c +++ b/lib/crtdll/string/strncmp.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include int diff --git a/lib/crtdll/string/strncpy.c b/lib/crtdll/string/strncpy.c index 428a235..6981589 100644 --- a/lib/crtdll/string/strncpy.c +++ b/lib/crtdll/string/strncpy.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include char * strncpy(char *dst, const char *src, size_t n) diff --git a/lib/crtdll/string/strnicmp.c b/lib/crtdll/string/strnicmp.c index 30563e9..b19a8a8 100644 --- a/lib/crtdll/string/strnicmp.c +++ b/lib/crtdll/string/strnicmp.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _strnicmp(const char *s1, const char *s2, size_t n) { diff --git a/lib/crtdll/string/strnlen.c b/lib/crtdll/string/strnlen.c index 6b92fb3..ba113d0 100644 --- a/lib/crtdll/string/strnlen.c +++ b/lib/crtdll/string/strnlen.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -#include +#include size_t strnlen(const char *str, size_t count) diff --git a/lib/crtdll/string/strpbrk.c b/lib/crtdll/string/strpbrk.c index c2968ae..c4837fc 100644 --- a/lib/crtdll/string/strpbrk.c +++ b/lib/crtdll/string/strpbrk.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include char * diff --git a/lib/crtdll/string/strrchr.c b/lib/crtdll/string/strrchr.c index 688d6bf..64be5cd 100644 --- a/lib/crtdll/string/strrchr.c +++ b/lib/crtdll/string/strrchr.c @@ -1,7 +1,6 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -//#include +#include char * strrchr(const char *s, int c) diff --git a/lib/crtdll/string/strrev.c b/lib/crtdll/string/strrev.c index 757ab08..d36b7a3 100644 --- a/lib/crtdll/string/strrev.c +++ b/lib/crtdll/string/strrev.c @@ -1,6 +1,6 @@ -#include +#include -char * _strrev(char *s) +char * _strrev(char *s) { char *e; char a; diff --git a/lib/crtdll/string/strset.c b/lib/crtdll/string/strset.c index 009ddc2..56fc314 100644 --- a/lib/crtdll/string/strset.c +++ b/lib/crtdll/string/strset.c @@ -1,5 +1,6 @@ -#include -#include +#include +#include +#include char* _strnset (char* szToFill, int szFill, size_t sizeMaxFill) { diff --git a/lib/crtdll/string/strspn.c b/lib/crtdll/string/strspn.c index d6e234d..f01e1bf 100644 --- a/lib/crtdll/string/strspn.c +++ b/lib/crtdll/string/strspn.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include size_t strspn(const char *s1, const char *s2) diff --git a/lib/crtdll/string/strspnp.c b/lib/crtdll/string/strspnp.c index bbb1e3b..41f8be6 100644 --- a/lib/crtdll/string/strspnp.c +++ b/lib/crtdll/string/strspnp.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include char * strspnp(const char *s1, const char *s2) diff --git a/lib/crtdll/string/strstr.c b/lib/crtdll/string/strstr.c index e62eeb0..4f23e4f 100644 --- a/lib/crtdll/string/strstr.c +++ b/lib/crtdll/string/strstr.c @@ -1,9 +1,8 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -//#include +#include -char * -strstr(const char *s, const char *find) + +char *strstr(const char *s, const char *find) { char c, sc; size_t len; diff --git a/lib/crtdll/string/strtok.c b/lib/crtdll/string/strtok.c index 62b0fdc..1ddb50d 100644 --- a/lib/crtdll/string/strtok.c +++ b/lib/crtdll/string/strtok.c @@ -1,8 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -char * -strtok(char *s, const char *delim) +char* strtok(char *s, const char *delim) { const char *spanp; int c, sc; diff --git a/lib/crtdll/string/strtoul.c b/lib/crtdll/string/strtoul.c index 5a007e4..e966dff 100644 --- a/lib/crtdll/string/strtoul.c +++ b/lib/crtdll/string/strtoul.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include unsigned long strtoul(const char *cp,char **endp,unsigned int base) { diff --git a/lib/crtdll/string/strupr.c b/lib/crtdll/string/strupr.c index 4cb0af4..21b17f4 100644 --- a/lib/crtdll/string/strupr.c +++ b/lib/crtdll/string/strupr.c @@ -9,8 +9,8 @@ */ -#include -#include +#include +#include char *_strupr(char *x) { diff --git a/lib/crtdll/string/strxfrm.c b/lib/crtdll/string/strxfrm.c index b23687c..ce76f99 100644 --- a/lib/crtdll/string/strxfrm.c +++ b/lib/crtdll/string/strxfrm.c @@ -1,18 +1,17 @@ #include -#include +#include #if 1 size_t strxfrm( char *dest, const char *src, size_t n ) { + strncpy(dest, src, n); + return (strlen(dest)); } #else size_t strxfrm( char *dest, const char *src, size_t n ) { - - int ret = LCMapStringA(LOCALE_USER_DEFAULT,LCMAP_LOWERCASE, - src, strlen(src), - dest, strlen(dest) ); - + int ret = LCMapStringA(LOCALE_USER_DEFAULT,LCMAP_LOWERCASE, + src, strlen(src), dest, strlen(dest)); if ( ret == 0 ) return -1; diff --git a/lib/crtdll/sys_stat/fstat.c b/lib/crtdll/sys_stat/fstat.c index 96a1e6c..8ed4a8f 100644 --- a/lib/crtdll/sys_stat/fstat.c +++ b/lib/crtdll/sys_stat/fstat.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/crtdll/sys/fstat.c @@ -7,48 +8,45 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -int -_fstat(int fd, struct stat *statbuf) +int _fstat(int fd, struct stat* statbuf) { - - BY_HANDLE_FILE_INFORMATION FileInformation; + BY_HANDLE_FILE_INFORMATION FileInformation; - if (!statbuf) - { - __set_errno(EINVAL); - return -1; + if (!statbuf) { + __set_errno(EINVAL); + return -1; } - if ( !GetFileInformationByHandle(_get_osfhandle(fd),&FileInformation) ) { - __set_errno (EBADF); - return -1; - } - statbuf->st_ctime = FileTimeToUnixTime( &FileInformation.ftCreationTime,NULL); - statbuf->st_atime = FileTimeToUnixTime( &FileInformation.ftLastAccessTime,NULL); - statbuf->st_mtime = FileTimeToUnixTime( &FileInformation.ftLastWriteTime,NULL); - if (statbuf->st_atime ==0) - statbuf->st_atime = statbuf->st_mtime; - if (statbuf->st_ctime ==0) - statbuf->st_ctime = statbuf->st_mtime; + if (!GetFileInformationByHandle(_get_osfhandle(fd),&FileInformation)) { + __set_errno (EBADF); + return -1; + } + statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL); + statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL); + statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL); + if (statbuf->st_atime ==0) + statbuf->st_atime = statbuf->st_mtime; + if (statbuf->st_ctime ==0) + statbuf->st_ctime = statbuf->st_mtime; - statbuf->st_dev = FileInformation.dwVolumeSerialNumber; - statbuf->st_size = FileInformation.nFileSizeLow; - statbuf->st_nlink = FileInformation.nNumberOfLinks; - statbuf->st_mode = S_IREAD; - if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - statbuf->st_mode |= S_IFDIR | S_IEXEC; - else - statbuf->st_mode |= S_IFREG; - if ( !(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - statbuf->st_mode |= S_IWRITE; - return 0; + statbuf->st_dev = FileInformation.dwVolumeSerialNumber; + statbuf->st_size = FileInformation.nFileSizeLow; + statbuf->st_nlink = FileInformation.nNumberOfLinks; + statbuf->st_mode = S_IREAD; + if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + statbuf->st_mode |= S_IFDIR | S_IEXEC; + else + statbuf->st_mode |= S_IFREG; + if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + statbuf->st_mode |= S_IWRITE; + return 0; } diff --git a/lib/crtdll/sys_stat/ftime.c b/lib/crtdll/sys_stat/ftime.c index c78ad44..6b2dd6c 100644 --- a/lib/crtdll/sys_stat/ftime.c +++ b/lib/crtdll/sys_stat/ftime.c @@ -16,32 +16,31 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + + // crtdll has void return type instead of int -void -_ftime (timebuf) - struct timeb *timebuf; +void _ftime(struct timeb* timebuf) { - int save = errno; - struct tm *tp; - - __set_errno (0); - if (time (&timebuf->time) == (time_t) -1 && errno != 0) - return; - timebuf->millitm = 0; - tp = localtime(&timebuf->time); - if (tp == NULL) + int save = errno; + struct tm* tp; + + __set_errno (0); + if (time (&timebuf->time) == (time_t) -1 && errno != 0) + return; + timebuf->millitm = 0; + tp = localtime(&timebuf->time); + if (tp == NULL) + return; + + timebuf->_timezone = tp->tm_gmtoff / 60; + timebuf->dstflag = tp->tm_isdst; + + free(tp); + __set_errno(save); return; - - timebuf->_timezone = tp->tm_gmtoff / 60; - timebuf->dstflag = tp->tm_isdst; - - free(tp); - __set_errno (save); - return; } - diff --git a/lib/crtdll/sys_stat/futime.c b/lib/crtdll/sys_stat/futime.c index cde6bfb..a1a269c 100644 --- a/lib/crtdll/sys_stat/futime.c +++ b/lib/crtdll/sys_stat/futime.c @@ -1,39 +1,40 @@ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -int _futime (int nHandle, struct _utimbuf *pTimes) + +int _futime(int nHandle, struct _utimbuf* pTimes) { - FILETIME LastAccessTime; - FILETIME LastWriteTime; - - // check for stdin / stdout handles ?? - if ( nHandle == -1 ) { - __set_errno(EBADF); - return -1; - } - - if ( pTimes == NULL ) { - pTimes = alloca(sizeof(struct _utimbuf)); - time(&pTimes->actime); - time(&pTimes->modtime); - } - - if ( pTimes->actime < pTimes->modtime ) { - __set_errno(EINVAL); - return -1; - } - - UnixTimeToFileTime(pTimes->actime,&LastAccessTime,0); - UnixTimeToFileTime(pTimes->modtime,&LastWriteTime,0); - if ( !SetFileTime(_get_osfhandle(nHandle),NULL, &LastAccessTime, &LastWriteTime) ) { - __set_errno(EBADF); - return -1; - } + FILETIME LastAccessTime; + FILETIME LastWriteTime; + + // check for stdin / stdout handles ?? + if (nHandle == -1) { + __set_errno(EBADF); + return -1; + } + + if (pTimes == NULL) { + pTimes = alloca(sizeof(struct _utimbuf)); + time(&pTimes->actime); + time(&pTimes->modtime); + } + + if (pTimes->actime < pTimes->modtime) { + __set_errno(EINVAL); + return -1; + } + + UnixTimeToFileTime(pTimes->actime, &LastAccessTime, 0); + UnixTimeToFileTime(pTimes->modtime, &LastWriteTime, 0); + if (!SetFileTime(_get_osfhandle(nHandle), NULL, &LastAccessTime, &LastWriteTime)) { + __set_errno(EBADF); + return -1; + } - return 0; + return 0; } diff --git a/lib/crtdll/sys_stat/stat.c b/lib/crtdll/sys_stat/stat.c index f12d4b1..a6e9d72 100644 --- a/lib/crtdll/sys_stat/stat.c +++ b/lib/crtdll/sys_stat/stat.c @@ -1,55 +1,51 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -int _stat( const char *path, struct stat *buffer ) +int _stat(const char* path, struct stat* buffer) { - WIN32_FIND_DATA wfd; - HANDLE fh; - fh = FindFirstFile (path,&wfd); - if ( fh == INVALID_HANDLE_VALUE ) - { - __set_errno(ENOFILE); - return -1; - } - if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - int fd = _open(path,_O_RDONLY); - int ret; - - ret = fstat(fd,buffer); - _close(fd); + HANDLE fh; + WIN32_FIND_DATA wfd; - return ret; - } - buffer->st_ctime = FileTimeToUnixTime( &wfd.ftCreationTime,NULL); - buffer->st_atime = FileTimeToUnixTime( &wfd.ftLastAccessTime,NULL); - buffer->st_mtime = FileTimeToUnixTime( &wfd.ftLastWriteTime,NULL); + fh = FindFirstFile(path, &wfd); + if (fh == INVALID_HANDLE_VALUE) { + __set_errno(ENOFILE); + return -1; + } + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + int fd = _open(path, _O_RDONLY); + int ret; + ret = fstat(fd, buffer); + _close(fd); + return ret; + } + buffer->st_ctime = FileTimeToUnixTime(&wfd.ftCreationTime,NULL); + buffer->st_atime = FileTimeToUnixTime(&wfd.ftLastAccessTime,NULL); + buffer->st_mtime = FileTimeToUnixTime(&wfd.ftLastWriteTime,NULL); - if (buffer->st_atime ==0) - buffer->st_atime = buffer->st_mtime; - if (buffer->st_ctime ==0) - buffer->st_ctime = buffer->st_mtime; + if (buffer->st_atime ==0) + buffer->st_atime = buffer->st_mtime; + if (buffer->st_ctime ==0) + buffer->st_ctime = buffer->st_mtime; - buffer->st_mode = S_IREAD; - if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - buffer->st_mode |= S_IFDIR; - else - buffer->st_mode |= S_IFREG; - if ( ! (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - buffer->st_mode |= S_IWRITE | S_IEXEC; + buffer->st_mode = S_IREAD; + if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + buffer->st_mode |= S_IFDIR; + else + buffer->st_mode |= S_IFREG; + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + buffer->st_mode |= S_IWRITE | S_IEXEC; - buffer->st_size = wfd.nFileSizeLow; - buffer->st_nlink = 1; - if (FindNextFile(fh,&wfd)) - { - __set_errno(ENOFILE); - FindClose(fh); - return -1; - } - return 0; + buffer->st_size = wfd.nFileSizeLow; + buffer->st_nlink = 1; + if (FindNextFile(fh, &wfd)) { + __set_errno(ENOFILE); + FindClose(fh); + return -1; + } + return 0; } diff --git a/lib/crtdll/sys_stat/systime.c b/lib/crtdll/sys_stat/systime.c index 2289ad4..d168a4f 100644 --- a/lib/crtdll/sys_stat/systime.c +++ b/lib/crtdll/sys_stat/systime.c @@ -1,67 +1,66 @@ #include -#include +#include int month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31}; -unsigned int _getsystime(struct tm *tp) + +unsigned int _getsystime(struct tm* tp) { - SYSTEMTIME Time; - TIME_ZONE_INFORMATION TimeZoneInformation; - DWORD TimeZoneId; - int i; + SYSTEMTIME Time; + TIME_ZONE_INFORMATION TimeZoneInformation; + DWORD TimeZoneId; + int i; + + GetLocalTime(&Time); - GetLocalTime(&Time); + tp->tm_year = Time.wYear - 1900; + tp->tm_mon = Time.wMonth - 1; + tp->tm_wday = Time.wDayOfWeek; + tp->tm_mday = Time.wDay; + tp->tm_hour = Time.wHour; + tp->tm_min = Time.wMinute; + tp->tm_sec = Time.wSecond; - tp->tm_year = Time.wYear - 1900; - tp->tm_mon = Time.wMonth - 1; - tp->tm_wday = Time.wDayOfWeek; - tp->tm_mday = Time.wDay; - tp->tm_hour = Time.wHour; - tp->tm_min = Time.wMinute; - tp->tm_sec = Time.wSecond; + tp->tm_isdst = -1; - tp->tm_isdst = -1; + //FIXME GetTimeZoneInformation currently not in kernel32 - //FIXME GetTimeZoneInformation currently not in kernel32 + //TimeZoneId = GetTimeZoneInformation(&TimeZoneInformation ); + //if ( TimeZoneId == TIME_ZONE_ID_DAYLIGHT ) { + // tp->tm_isdst = 1; + //} + //else + // tp->tm_isdst = 0; - //TimeZoneId = GetTimeZoneInformation(&TimeZoneInformation ); - //if ( TimeZoneId == TIME_ZONE_ID_DAYLIGHT ) { - // tp->tm_isdst = 1; - //} - //else - // tp->tm_isdst = 0; - - - - if ( tp->tm_year%4 == 0 ) { - if (tp->tm_year%100 != 0 ) - tp->tm_yday = 1; - else if ( (tp->tm_year-100)%1000 == 0 ) - tp->tm_yday = 1; - } + if (tp->tm_year % 4 == 0) { + if (tp->tm_year % 100 != 0) + tp->tm_yday = 1; + else if ((tp->tm_year-100) % 1000 == 0) + tp->tm_yday = 1; + } - for(i=0;i<=tp->tm_mon;i++) - tp->tm_yday += month[i]; - - return Time.wMilliseconds; + for (i = 0; i <= tp->tm_mon; i++) + tp->tm_yday += month[i]; + + return Time.wMilliseconds; } -unsigned int _setsystime(struct tm *tp, unsigned int ms) +unsigned int _setsystime(struct tm* tp, unsigned int ms) { - SYSTEMTIME Time; + SYSTEMTIME Time; - Time.wYear = tp->tm_year + 1900; - Time.wMonth = tp->tm_mon + 1; - Time.wDayOfWeek = tp->tm_wday; - Time.wDay = tp->tm_mday; - Time.wHour = tp->tm_hour; - Time.wMinute = tp->tm_min; - Time.wSecond = tp->tm_sec; - Time.wMilliseconds = ms; + Time.wYear = tp->tm_year + 1900; + Time.wMonth = tp->tm_mon + 1; + Time.wDayOfWeek = tp->tm_wday; + Time.wDay = tp->tm_mday; + Time.wHour = tp->tm_hour; + Time.wMinute = tp->tm_min; + Time.wSecond = tp->tm_sec; + Time.wMilliseconds = ms; - if ( !SetLocalTime(&Time)) - return -1; + if (!SetLocalTime(&Time)) + return -1; - return 0; + return 0; } diff --git a/lib/crtdll/tchar/strdec.c b/lib/crtdll/tchar/strdec.c index 05cbf98..05bd76a 100644 --- a/lib/crtdll/tchar/strdec.c +++ b/lib/crtdll/tchar/strdec.c @@ -1,4 +1,4 @@ -#include +#include char * _strdec(const char *str1, const char *str2) { diff --git a/lib/crtdll/tchar/strinc.c b/lib/crtdll/tchar/strinc.c index bb1b49f..35f4d5d 100644 --- a/lib/crtdll/tchar/strinc.c +++ b/lib/crtdll/tchar/strinc.c @@ -1,4 +1,4 @@ -#include +#include char * _strinc(const char *str) { diff --git a/lib/crtdll/tchar/strncnt.c b/lib/crtdll/tchar/strncnt.c index b47cc20..2c56f8f 100644 --- a/lib/crtdll/tchar/strncnt.c +++ b/lib/crtdll/tchar/strncnt.c @@ -1,6 +1,5 @@ -#include -#include -#include +#include +#include size_t _strncnt( const char *str, size_t max) { diff --git a/lib/crtdll/tchar/strnextc.c b/lib/crtdll/tchar/strnextc.c index b1c0585..8a2918f 100644 --- a/lib/crtdll/tchar/strnextc.c +++ b/lib/crtdll/tchar/strnextc.c @@ -1,4 +1,4 @@ -#include +#include int _strnextc(const char *str) { diff --git a/lib/crtdll/tchar/strninc.c b/lib/crtdll/tchar/strninc.c index 75f279b..de776d2 100644 --- a/lib/crtdll/tchar/strninc.c +++ b/lib/crtdll/tchar/strninc.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include char * _strninc(const char *str, size_t inc) { diff --git a/lib/crtdll/tchar/strspnp.c b/lib/crtdll/tchar/strspnp.c index 3656740..75c888c 100644 --- a/lib/crtdll/tchar/strspnp.c +++ b/lib/crtdll/tchar/strspnp.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include char * _strspnp( const char * str1, const char * str2) diff --git a/lib/crtdll/time/clock.c b/lib/crtdll/time/clock.c index 4fcda91..3b7745a 100644 --- a/lib/crtdll/time/clock.c +++ b/lib/crtdll/time/clock.c @@ -9,23 +9,21 @@ */ #include -#include -#include +#include +#include VOID STDCALL GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime ); clock_t clock ( void ) { - FILETIME CreationTime; - FILETIME ExitTime; - FILETIME KernelTime; - FILETIME UserTime; - - DWORD Remainder; + FILETIME CreationTime; + FILETIME ExitTime; + FILETIME KernelTime; + FILETIME UserTime; + DWORD Remainder; - if ( !GetProcessTimes(GetCurrentProcess(),&CreationTime,&ExitTime,&KernelTime,&UserTime ) ) - return -1; - + if (!GetProcessTimes(GetCurrentProcess(),&CreationTime,&ExitTime,&KernelTime,&UserTime)) + return -1; - return FileTimeToUnixTime( &KernelTime,&Remainder ) + FileTimeToUnixTime( &UserTime,&Remainder ); + return FileTimeToUnixTime(&KernelTime,&Remainder) + FileTimeToUnixTime(&UserTime,&Remainder); } diff --git a/lib/crtdll/time/ctime.c b/lib/crtdll/time/ctime.c index 9f33c97..ef5c117 100644 --- a/lib/crtdll/time/ctime.c +++ b/lib/crtdll/time/ctime.c @@ -29,33 +29,33 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90"; -#endif /* LIBC_SCCS and not lint */ - /* ** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). ** POSIX-style TZ environment variable handling from Guy Harris ** (guy@auspex.com). */ - - - -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include "tzfile.h" -#include +#include #include "posixrul.h" + +#ifdef __cplusplus +#define CPP_CONST const +#else +#define CPP_CONST +#endif + #define P(s) s #define alloc_size_t size_t #define qsort_size_t size_t @@ -84,8 +84,10 @@ static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90"; ** manual page of what this "time zone abbreviation" means (doing this so ** that tzname[0] has the "normal" length of three characters). */ -int _daylight_dll; -int _timezone_dll; + +void _set_daylight_export(int); +void _set_timezone_export(int); + static char WILDABBR[] = " "; @@ -135,36 +137,36 @@ struct rule { /* ** Prototypes for static functions. */ - +#if 0 static long detzcode P((const char * codep)); static const char * getzname P((const char * strp)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); +static const char * getnum P((const char * strp, int * nump, int min, int max)); static const char * getsecs P((const char * strp, long * secsp)); static const char * getoffset P((const char * strp, long * offsetp)); static const char * getrule P((const char * strp, struct rule * rulep)); static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp)); +static void gmtsub P((const time_t * timep, long offset, struct tm * tmp)); +static void localsub P((const time_t * timep, long offset, struct tm * tmp)); static void normalize P((int * tensptr, int * unitsptr, int base)); static void settzname P((void)); -static time_t time1 P((struct tm * tmp, void (* funcp)(const time_t * const, const long, struct tm * const), - long offset)); -static time_t time2 P((struct tm *tmp, void (* funcp)(const time_t * const, const long, struct tm * const), - long offset, int * okayp)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); +static time_t time1 P((struct tm * tmp, void (* funcp)(const time_t * CPP_CONST, const long, struct tm * CPP_CONST), long offset)); +static time_t time2 P((struct tm *tmp, void (* funcp)(const time_t * CPP_CONST, const long, struct tm * CPP_CONST), long offset, int * okayp)); +static void timesub P((const time_t * timep, long offset, const struct state * sp, struct tm * tmp)); +static int tmcomp P((const struct tm * atmp, const struct tm * btmp)); +static time_t transtime P((time_t janfirst, int year, const struct rule * rulep, long offset)); static int tzload P((const char * name, struct state * sp)); -static int tzparse P((const char * name, struct state * sp, - int lastditch)); +static int tzparse P((const char * name, struct state * sp, int lastditch)); static void tzsetwall(void); +#else + +static const char * getnum(const char * strp, int * CPP_CONST nump, const int min, const int max); +static void timesub(const time_t * CPP_CONST timep, const long offset, const struct state * CPP_CONST sp, struct tm * CPP_CONST tmp); +static time_t transtime(const time_t janfirst, const int year, const struct rule * CPP_CONST rulep, const long offset); +static void tzsetwall(void); + +#endif + #ifdef ALL_STATE static struct state *lclptr; static struct state *gmtptr; @@ -186,7 +188,7 @@ char * _tzname[2] = { }; static long -detzcode(const char * const codep) +detzcode(const char * CPP_CONST codep) { long result; int i; @@ -200,7 +202,7 @@ detzcode(const char * const codep) static void settzname(void) { - const struct state * const sp = lclptr; + const struct state * CPP_CONST sp = lclptr; int i; _tzname[0] = WILDABBR; @@ -214,17 +216,22 @@ settzname(void) #endif /* defined ALL_STATE */ for (i = 0; i < sp->typecnt; ++i) { - register const struct ttinfo * const ttisp = &sp->ttis[i]; + register const struct ttinfo * CPP_CONST ttisp = &sp->ttis[i]; _tzname[ttisp->tt_isdst] = (char *)&sp->chars[ttisp->tt_abbrind]; #if 0 - if (ttisp->tt_isdst) - _daylight = 1; - if (i == 0 || !ttisp->tt_isdst) - _timezone_dll = -(ttisp->tt_gmtoff); - if (i == 0 || ttisp->tt_isdst) + if (ttisp->tt_isdst) { + //_daylight = 1; + _set_daylight_export(1); + } + if (i == 0 || !ttisp->tt_isdst) { + //_timezone_dll = -(ttisp->tt_gmtoff); + _set_timezone_export(-(ttisp->tt_gmtoff)); + } + if (i == 0 || ttisp->tt_isdst) { _altzone = -(ttisp->tt_gmtoff); + } #endif } /* @@ -232,7 +239,7 @@ settzname(void) */ for (i = 0; i < sp->timecnt; ++i) { - const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]]; + const struct ttinfo * CPP_CONST ttisp = &sp->ttis[sp->types[i]]; _tzname[ttisp->tt_isdst] = (char *)&sp->chars[ttisp->tt_abbrind]; } @@ -260,7 +267,7 @@ tzdir(void) } static int -tzload(const char *name, struct state * const sp) +tzload(const char *name, struct state * CPP_CONST sp) { const char * p; int i; @@ -419,7 +426,7 @@ getzname(const char *strp) */ static const char * -getnum(const char *strp, int * const nump, const int min, const int max) +getnum(const char *strp, int * CPP_CONST nump, const int min, const int max) { char c; int num; @@ -449,7 +456,7 @@ getnum(const char *strp, int * const nump, const int min, const int max) */ static const char * -getsecs(const char *strp, long * const secsp) +getsecs(const char *strp, long * CPP_CONST secsp) { int num; @@ -484,7 +491,7 @@ getsecs(const char *strp, long * const secsp) */ static const char * -getoffset(const char *strp, long * const offsetp) +getoffset(const char *strp, long * CPP_CONST offsetp) { int neg; @@ -513,7 +520,7 @@ getoffset(const char *strp, long * const offsetp) */ static const char * -getrule(const char *strp, struct rule * const rulep) +getrule(const char *strp, struct rule * CPP_CONST rulep) { if (*strp == 'J') { @@ -575,7 +582,7 @@ getrule(const char *strp, struct rule * const rulep) */ static time_t -transtime(const time_t janfirst, const int year, const struct rule * const rulep, const long offset) +transtime(const time_t janfirst, const int year, const struct rule * CPP_CONST rulep, const long offset) { int leapyear; time_t value=0; @@ -667,7 +674,7 @@ transtime(const time_t janfirst, const int year, const struct rule * const rulep */ static int -tzparse(const char *name, struct state * const sp, const int lastditch) +tzparse(const char *name, struct state * CPP_CONST sp, const int lastditch) { const char * stdname; const char * dstname=0; @@ -891,7 +898,7 @@ tzparse(const char *name, struct state * const sp, const int lastditch) } static void -gmtload(struct state * const sp) +gmtload(struct state * CPP_CONST sp) { if (tzload(GMT, sp) != 0) (void) tzparse(GMT, sp, TRUE); @@ -968,7 +975,7 @@ tzsetwall(void) /*ARGSUSED*/ static void -localsub(const time_t * const timep, const long offset, struct tm * const tmp) +localsub(const time_t * CPP_CONST timep, const long offset, struct tm * CPP_CONST tmp) { const struct state * sp; const struct ttinfo * ttisp; @@ -1016,7 +1023,7 @@ localsub(const time_t * const timep, const long offset, struct tm * const tmp) } struct tm * -localtime(const time_t * const timep) +localtime(const time_t * CPP_CONST timep) { static struct tm tm; @@ -1029,7 +1036,7 @@ localtime(const time_t * const timep) */ static void -gmtsub(const time_t * const timep, const long offset, struct tm * const tmp) +gmtsub(const time_t * CPP_CONST timep, const long offset, struct tm * CPP_CONST tmp) { if (!gmt_is_set) { @@ -1063,7 +1070,7 @@ gmtsub(const time_t * const timep, const long offset, struct tm * const tmp) } struct tm * -gmtime(const time_t * const timep) +gmtime(const time_t * CPP_CONST timep) { static struct tm tm; @@ -1072,7 +1079,7 @@ gmtime(const time_t * const timep) } static void -timesub(const time_t * const timep, const long offset, const struct state * const sp, struct tm * const tmp) +timesub(const time_t * CPP_CONST timep, const long offset, const struct state * CPP_CONST sp, struct tm * CPP_CONST tmp) { const struct lsinfo * lp; long days; @@ -1192,7 +1199,7 @@ asctime(const struct tm *timeptr) } char * -ctime(const time_t * const timep) +ctime(const time_t * CPP_CONST timep) { return asctime(localtime(timep)); } @@ -1211,7 +1218,7 @@ ctime(const time_t * const timep) #endif /* !defined WRONG */ static void -normalize(int * const tensptr, int * const unitsptr, const int base) +normalize(int * CPP_CONST tensptr, int * CPP_CONST unitsptr, const int base) { if (*unitsptr >= base) { @@ -1231,7 +1238,7 @@ normalize(int * const tensptr, int * const unitsptr, const int base) } static int -tmcomp(const struct tm * const atmp, const struct tm * const btmp) +tmcomp(const struct tm * CPP_CONST atmp, const struct tm * CPP_CONST btmp) { int result; @@ -1245,7 +1252,7 @@ tmcomp(const struct tm * const atmp, const struct tm * const btmp) } static time_t -time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct tm *), const long offset, int * const okayp) +time2(struct tm *tmp, void (*const funcp)(const time_t * CPP_CONST, const long, struct tm *), const long offset, int * CPP_CONST okayp) { const struct state * sp; int dir; @@ -1295,7 +1302,12 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct ** If time_t is signed, then 0 is the median value, ** if time_t is unsigned, then 1 << bits is median. */ +#ifdef _MSVCRT_LIB_ + t = (time_t) ((1 << bits) - 1); +#else // TODO: FIXME: review which is correct t = (time_t) 1 << bits; +#endif /*_MSVCRT_LIB_*/ + for ( ; ; ) { (*funcp)(&t, offset, &mytm); @@ -1357,7 +1369,7 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct } static time_t -time1(struct tm * const tmp, void (*const funcp)(const time_t * const, const long, struct tm *), const long offset) +time1(struct tm * CPP_CONST tmp, void (*const funcp)(const time_t * CPP_CONST, const long, struct tm *), const long offset) { time_t t; const struct state * sp; @@ -1407,7 +1419,3 @@ mktime(struct tm * tmp) { return time1(tmp, localsub, 0L); } - - - - diff --git a/lib/crtdll/time/difftime.c b/lib/crtdll/time/difftime.c index 97d6b59..87f4005 100644 --- a/lib/crtdll/time/difftime.c +++ b/lib/crtdll/time/difftime.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include double difftime(time_t time1, time_t time0) diff --git a/lib/crtdll/time/strdate.c b/lib/crtdll/time/strdate.c index ca9b013..ac3680a 100644 --- a/lib/crtdll/time/strdate.c +++ b/lib/crtdll/time/strdate.c @@ -7,14 +7,14 @@ * UPDATE HISTORY: * 28/12/98: Created */ -#include -#include -#include -#include +#include +#include +#include +#include + char *_strdate( const char *datestr ) { - time_t t; struct tm *d; char *dt = (char *)datestr; diff --git a/lib/crtdll/time/strftime.c b/lib/crtdll/time/strftime.c index c5c65df..5c83edf 100644 --- a/lib/crtdll/time/strftime.c +++ b/lib/crtdll/time/strftime.c @@ -1,32 +1,33 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include -#include -#include +#include +#include +#include +#include + #define TM_YEAR_BASE 1900 -static const char *afmt[] = { +static const char* afmt[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", }; -static const char *Afmt[] = { +static const char* Afmt[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", }; -static const char *bfmt[] = { +static const char* bfmt[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", }; -static const char *Bfmt[] = { +static const char* Bfmt[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; static size_t gsize; -static char *pt; +static char* pt; + -static int -_add(const char *str) +static int _add(const char* str) { for (;; ++pt, --gsize) { @@ -37,11 +38,10 @@ _add(const char *str) } } -static int -_conv(int n, int digits, char pad) +static int _conv(int n, int digits, char pad) { static char buf[10]; - char *p; + char* p; for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) *p-- = n % 10 + '0'; @@ -50,16 +50,14 @@ _conv(int n, int digits, char pad) return _add(++p); } -static size_t -_fmt(const char *format, const struct tm *t) +static size_t _fmt(const char* format, const struct tm* t) { for (; *format; ++format) { if (*format == '%') { - if (*(format+1) == '#' ) {format++;} + if (*(format+1) == '#') {format++;} - switch(*++format) - { + switch(*++format) { case '\0': --format; break; @@ -113,8 +111,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'I': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, '0')) + if (!_conv(t->tm_hour % 12 ? t->tm_hour % 12 : 12, 2, '0')) return 0; continue; case 'j': @@ -126,8 +123,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'l': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, ' ')) + if (!_conv(t->tm_hour % 12 ? t->tm_hour % 12 : 12, 2, ' ')) return 0; continue; case 'M': @@ -168,14 +164,11 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'U': - if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, - 2, '0')) + if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, 2, '0')) return 0; continue; case 'W': - if (!_conv((t->tm_yday + 7 - - (t->tm_wday ? (t->tm_wday - 1) : 6)) - / 7, 2, '0')) + if (!_conv((t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, 2, '0')) return 0; continue; case 'w': @@ -187,8 +180,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'y': - if (!_conv((t->tm_year + TM_YEAR_BASE) - % 100, 2, '0')) + if (!_conv((t->tm_year + TM_YEAR_BASE) % 100, 2, '0')) return 0; continue; case 'Y': @@ -230,32 +222,30 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *t) return 0; } -size_t -wcsftime(wchar_t *s, size_t maxsize, const wchar_t *format, const struct tm *t) +size_t wcsftime(wchar_t* s, size_t maxsize, const wchar_t* format, const struct tm* t) { - char *x; - char *f; + char* x; + char* f; int i,j; x = malloc(maxsize); j = wcslen(format); f = malloc(j+1); - for(i=0;i -#include -#include -#include +#include +#include +#include +#include + char *_strtime(char* buf) { diff --git a/lib/crtdll/time/time.c b/lib/crtdll/time/time.c index 3a49372..f7019fb 100644 --- a/lib/crtdll/time/time.c +++ b/lib/crtdll/time/time.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/time.c + * FILE: lib/crtdll/time/time.c * PURPOSE: Get system time * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -16,18 +16,22 @@ */ #include -#include -#include +#include +#include + VOID STDCALL GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime ); -time_t -time(time_t *t) +time_t time(time_t* t) { FILETIME SystemTime; DWORD Remainder; + time_t tt; GetSystemTimeAsFileTime(&SystemTime); - return FileTimeToUnixTime( &SystemTime,&Remainder ); + tt = FileTimeToUnixTime( &SystemTime,&Remainder ); + if (t) + *t = tt; + return tt; } /*********************************************************************** diff --git a/lib/crtdll/time/tz_vars.c b/lib/crtdll/time/tz_vars.c new file mode 100644 index 0000000..3ccf177 --- /dev/null +++ b/lib/crtdll/time/tz_vars.c @@ -0,0 +1,21 @@ +#include +#include +#include + + +int _daylight_dll; +int _timezone_dll; + + +void _set_daylight_export(int value) +{ + _daylight_dll = value; +} + +void _set_timezone_export(int value) +{ + _timezone_dll = value; +} + + + diff --git a/lib/crtdll/wchar/.cvsignore b/lib/crtdll/wchar/.cvsignore index bd0e3df..5761abc 100644 --- a/lib/crtdll/wchar/.cvsignore +++ b/lib/crtdll/wchar/.cvsignore @@ -1,3 +1 @@ -*.d *.o -*.sym diff --git a/lib/crtdll/wchar/wcscat.c b/lib/crtdll/wchar/wcscat.c deleted file mode 100644 index dc2a39e..0000000 --- a/lib/crtdll/wchar/wcscat.c +++ /dev/null @@ -1,19 +0,0 @@ - - -#include - -wchar_t * wcscat(wchar_t * dest,const wchar_t * src) -{ - - wchar_t *d = dest; - for (; *dest !=0; dest++); - while (*src != 0) - { - *dest = *src; - dest++; - src++; - } - *dest = 0; - return d; -} - diff --git a/lib/crtdll/wchar/wcschr.c b/lib/crtdll/wchar/wcschr.c deleted file mode 100644 index 5bbd959..0000000 --- a/lib/crtdll/wchar/wcschr.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - -#include - -wchar_t* wcschr(const wchar_t* str, wchar_t ch) -{ - while ((*str)!=0) - { - if ((*str)==ch) - { - return((wchar_t *)str); - } - str++; - } - return(NULL); -} diff --git a/lib/crtdll/wchar/wcscmp.c b/lib/crtdll/wchar/wcscmp.c deleted file mode 100644 index ab25af4..0000000 --- a/lib/crtdll/wchar/wcscmp.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - -#include - -int wcscmp(const wchar_t* cs,const wchar_t * ct) -{ - while (*cs == *ct) - { - if (*cs == 0) - return 0; - cs++; - ct++; - } - return *cs - *ct; - -} diff --git a/lib/crtdll/wchar/wcscoll.c b/lib/crtdll/wchar/wcscoll.c index 98a65d7..6a5278f 100644 --- a/lib/crtdll/wchar/wcscoll.c +++ b/lib/crtdll/wchar/wcscoll.c @@ -1,6 +1,5 @@ - -#include +#include int wcscoll(const wchar_t *a1,const wchar_t *a2) { diff --git a/lib/crtdll/wchar/wcscpy.c b/lib/crtdll/wchar/wcscpy.c deleted file mode 100644 index 44f71f0..0000000 --- a/lib/crtdll/wchar/wcscpy.c +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - -#include - -wchar_t * wcscpy(wchar_t * str1,const wchar_t * str2) -{ - wchar_t *save = str1; - - for (; (*str1 = *str2); ++str2, ++str1); - return save; -} diff --git a/lib/crtdll/wchar/wcscspn.c b/lib/crtdll/wchar/wcscspn.c deleted file mode 100644 index 2c3f2d2..0000000 --- a/lib/crtdll/wchar/wcscspn.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -size_t wcscspn(const wchar_t *str,const wchar_t *reject) -{ - wchar_t *s; - wchar_t *t; - s=(wchar_t *)str; - do { - t=(wchar_t *)reject; - while (*t) { - if (*t==*s) - break; - t++; - } - if (*t) - break; - s++; - } while (*s); - return s-str; /* nr of wchars */ -} diff --git a/lib/crtdll/wchar/wcsdup.c b/lib/crtdll/wchar/wcsdup.c deleted file mode 100644 index 6d9f216..0000000 --- a/lib/crtdll/wchar/wcsdup.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - - -wchar_t *_wcsdup(const wchar_t *ptr) -{ - wchar_t *dup; - dup = malloc((wcslen(ptr) + 1)*sizeof(wchar_t)); - if( dup == NULL ) { - __set_errno(ENOMEM); - return NULL; - } - wcscpy(dup,ptr); - return dup; -} - - - diff --git a/lib/crtdll/wchar/wcsftime.c b/lib/crtdll/wchar/wcsftime.c deleted file mode 100644 index 4e402b5..0000000 --- a/lib/crtdll/wchar/wcsftime.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -size_t wcsftime(wchar_t *str, size_t len, const wchar_t *fmt, const struct tm *tp ) -{ - return 0; -} \ No newline at end of file diff --git a/lib/crtdll/wchar/wcsicmp.c b/lib/crtdll/wchar/wcsicmp.c deleted file mode 100644 index 1cfaf8e..0000000 --- a/lib/crtdll/wchar/wcsicmp.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - -#include - -int _wcsicmp(const wchar_t* cs,const wchar_t * ct) -{ - while (towlower(*cs) == towlower(*ct)) - { - if (*cs == 0) - return 0; - cs++; - ct++; - } - return towlower(*cs) - towlower(*ct); - -} diff --git a/lib/crtdll/wchar/wcslen.c b/lib/crtdll/wchar/wcslen.c index df294b8..e7471bd 100644 --- a/lib/crtdll/wchar/wcslen.c +++ b/lib/crtdll/wchar/wcslen.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include size_t wcslen(const wchar_t * s) @@ -17,7 +17,3 @@ size_t wstrlen(const wchar_t *s) { return wcslen(s); } - - - - diff --git a/lib/crtdll/wchar/wcslwr.c b/lib/crtdll/wchar/wcslwr.c deleted file mode 100644 index 0dcf2da..0000000 --- a/lib/crtdll/wchar/wcslwr.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * The C RunTime DLL - * - * Implements C run-time functionality as known from UNIX. - * - * Copyright 1996,1998 Marcus Meissner - * Copyright 1996 Jukka Iivonen - * Copyright 1997 Uwe Bonnes - */ - -#include - -wchar_t * _wcslwr(wchar_t *x) -{ - wchar_t *y=x; - - while (*y) { - *y=towlower(*y); - y++; - } - return x; -} diff --git a/lib/crtdll/wchar/wcsncat.c b/lib/crtdll/wchar/wcsncat.c deleted file mode 100644 index 85d0d81..0000000 --- a/lib/crtdll/wchar/wcsncat.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include - -wchar_t *wcsncat(wchar_t *dst, const wchar_t *src, size_t n) -{ - if (n != 0) - { - wchar_t *d = dst; - const wchar_t *s = src; - - while (*d != 0) - d++; - do { - if ((*d = *s++) == 0) - break; - d++; - } while (--n != 0); - *d = 0; - } - return dst; -} diff --git a/lib/crtdll/wchar/wcsncmp.c b/lib/crtdll/wchar/wcsncmp.c deleted file mode 100644 index 6341f46..0000000 --- a/lib/crtdll/wchar/wcsncmp.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -int wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t count) -{ - while ((*cs) == (*ct) && count > 0) - { - if (*cs == 0) - return 0; - cs++; - ct++; - count--; - } - return (*cs) - (*ct); - -} - diff --git a/lib/crtdll/wchar/wcsncpy.c b/lib/crtdll/wchar/wcsncpy.c deleted file mode 100644 index 9cad913..0000000 --- a/lib/crtdll/wchar/wcsncpy.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -wchar_t * wcsncpy(wchar_t * dest,const wchar_t *src,size_t count) -{ - int i; - - for (i=0;i - -int _wcsnicmp (const wchar_t *cs, const wchar_t *ct, size_t count) -{ - if (count == 0) - return 0; - do { - if (towupper(*cs) != towupper(*ct++)) - return towupper(*cs) - towupper(*--ct); - if (*cs++ == 0) - break; - } while (--count != 0); - return 0; -} diff --git a/lib/crtdll/wchar/wcsnlen.c b/lib/crtdll/wchar/wcsnlen.c deleted file mode 100644 index dc5796c..0000000 --- a/lib/crtdll/wchar/wcsnlen.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -size_t _wcsnlen(const wchar_t * s, size_t count) -{ - - unsigned int len=0; - - while(s[len]!=0 && len < count) { - len++; - }; - return len; -} diff --git a/lib/crtdll/wchar/wcspbrk.c b/lib/crtdll/wchar/wcspbrk.c deleted file mode 100644 index ccef388..0000000 --- a/lib/crtdll/wchar/wcspbrk.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2) -{ - const wchar_t *scanp; - int c, sc; - - while ((c = *s1++) != 0) - { - for (scanp = s2; (sc = *scanp++) != 0;) - if (sc == c) { - return (wchar_t *)(--s1); - } - } - return 0; -} diff --git a/lib/crtdll/wchar/wcsrchr.c b/lib/crtdll/wchar/wcsrchr.c deleted file mode 100644 index 8568d96..0000000 --- a/lib/crtdll/wchar/wcsrchr.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -wchar_t* wcsrchr(const wchar_t* str, wchar_t ch) -{ - - wchar_t *sp=(wchar_t *)0; - while (*str != 0) - { - if (*str == ch) - sp = (wchar_t *)str; - str++; - } - if (ch == 0) - sp = (wchar_t *)str; - return sp; -} diff --git a/lib/crtdll/wchar/wcsrev.c b/lib/crtdll/wchar/wcsrev.c deleted file mode 100644 index 695f0de..0000000 --- a/lib/crtdll/wchar/wcsrev.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -wchar_t * _wcsrev(wchar_t *s) -{ - wchar_t *e; - wchar_t a; - e=s; - while (*e) - e++; - while (s - -wchar_t* _wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill) -{ - wchar_t *t = wsToFill; - int i = 0; - while( *wsToFill != 0 && i < sizeMaxFill) - { - *wsToFill = wcFill; - wsToFill++; - i++; - - } - return t; -} - -wchar_t* _wcsset (wchar_t* wsToFill, wchar_t wcFill) -{ - wchar_t *t = wsToFill; - while( *wsToFill != 0 ) - { - *wsToFill = wcFill; - wsToFill++; - - } - return t; -} diff --git a/lib/crtdll/wchar/wcsspn.c b/lib/crtdll/wchar/wcsspn.c deleted file mode 100644 index 5ae0df0..0000000 --- a/lib/crtdll/wchar/wcsspn.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -size_t wcsspn(const wchar_t *str,const wchar_t *accept) -{ - wchar_t *s; - wchar_t *t; - s=(wchar_t *)str; - do { - t=(wchar_t *)accept; - while (*t) { - if (*t==*s) - break; - t++; - } - if (!*t) - break; - s++; - } while (*s); - return s-str; /* nr of wchars */ -} diff --git a/lib/crtdll/wchar/wcsstr.c b/lib/crtdll/wchar/wcsstr.c deleted file mode 100644 index ebe638f..0000000 --- a/lib/crtdll/wchar/wcsstr.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -wchar_t *wcsstr(const wchar_t *s,const wchar_t *b) -{ - wchar_t *x; - wchar_t *y; - wchar_t *c; - x=(wchar_t *)s; - while (*x) { - if (*x==*b) { - y=x; - c=(wchar_t *)b; - while (*y && *c && *y==*c) { - c++; - y++; - } - if (!*c) - return x; - } - x++; - } - return NULL; -} diff --git a/lib/crtdll/wchar/wcstod.c b/lib/crtdll/wchar/wcstod.c index ffef827..52786fc 100644 --- a/lib/crtdll/wchar/wcstod.c +++ b/lib/crtdll/wchar/wcstod.c @@ -1,9 +1,9 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include -double wcstod(const wchar_t *s, wchar_t **sret) +double wcstod(const wchar_t* s, wchar_t** sret) { long double r; /* result */ int e; /* exponent */ diff --git a/lib/crtdll/wchar/wcstok.c b/lib/crtdll/wchar/wcstok.c index 3afd717..9b33b6b 100644 --- a/lib/crtdll/wchar/wcstok.c +++ b/lib/crtdll/wchar/wcstok.c @@ -1,4 +1,4 @@ -#include +#include wchar_t *wcstok(wchar_t *s, const wchar_t *ct) { @@ -7,7 +7,6 @@ wchar_t *wcstok(wchar_t *s, const wchar_t *ct) wchar_t *tok; static wchar_t *last; - if (s == NULL && (s = last) == NULL) return (NULL); @@ -19,12 +18,12 @@ wchar_t *wcstok(wchar_t *s, const wchar_t *ct) s++; for (spanp = ct; (sc = *spanp) != 0;spanp++) { if (c == sc) - goto cont; + goto cont; } if (c == 0) { /* no non-ctiter characters */ last = NULL; - return (NULL); + return (NULL); } tok = s - 2; @@ -33,7 +32,6 @@ wchar_t *wcstok(wchar_t *s, const wchar_t *ct) * Note that ct must have one NUL; we stop if we see that, too. */ for (;;) { - c = *s; s+=2; spanp = ct; @@ -48,7 +46,6 @@ wchar_t *wcstok(wchar_t *s, const wchar_t *ct) } spanp+=2; } while (sc != 0); - } /* NOTREACHED */ } diff --git a/lib/crtdll/wchar/wcstol.c b/lib/crtdll/wchar/wcstol.c index 5a5ae97..fa95e96 100644 --- a/lib/crtdll/wchar/wcstol.c +++ b/lib/crtdll/wchar/wcstol.c @@ -1,12 +1,12 @@ -#include +#include -long wcstol(const wchar_t *cp,wchar_t **endp,int base) +long wcstol(const wchar_t* cp, wchar_t** endp, int base) { - long result = 0,value; + long result = 0, value; int sign = 1; - if ( *cp == L'-' ) { + if (*cp == L'-') { sign = -1; cp++; } @@ -28,14 +28,13 @@ long wcstol(const wchar_t *cp,wchar_t **endp,int base) cp++; } if (endp) - *endp = (wchar_t *)cp; + *endp = (wchar_t*)cp; return result * sign; } - -unsigned long wcstoul(const wchar_t *cp,wchar_t **endp,int base) +unsigned long wcstoul(const wchar_t* cp, wchar_t** endp, int base) { - unsigned long result = 0,value; + unsigned long result = 0, value; if (!base) { base = 10; @@ -54,7 +53,6 @@ unsigned long wcstoul(const wchar_t *cp,wchar_t **endp,int base) cp++; } if (endp) - *endp = (wchar_t *)cp; + *endp = (wchar_t*)cp; return result; } - diff --git a/lib/crtdll/wchar/wcstombs.c b/lib/crtdll/wchar/wcstombs.c index f660411..7479632 100644 --- a/lib/crtdll/wchar/wcstombs.c +++ b/lib/crtdll/wchar/wcstombs.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include size_t wcstombs( char *dst, const wchar_t *src, size_t len ) { diff --git a/lib/crtdll/wchar/wcsupr.c b/lib/crtdll/wchar/wcsupr.c deleted file mode 100644 index 438b5a9..0000000 --- a/lib/crtdll/wchar/wcsupr.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -wchar_t *_wcsupr(wchar_t *x) -{ - wchar_t *y=x; - - while (*y) { - *y=towupper(*y); - y++; - } - return x; -} diff --git a/lib/crtdll/wchar/wcsxfrm.c b/lib/crtdll/wchar/wcsxfrm.c deleted file mode 100644 index 91ae8e6..0000000 --- a/lib/crtdll/wchar/wcsxfrm.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -size_t wcsxfrm(wchar_t *dst,const wchar_t *src, size_t n) -{ - size_t r = 0; - int c; - - if (n != 0) { - while ((c = *src++) != 0) - { - r++; - if (--n == 0) - { - while (*src++ != 0) - r++; - break; - } - *dst++ = c; - } - *dst = 0; - } - return r; -} diff --git a/lib/crtdll/wchar/wtoi.c b/lib/crtdll/wchar/wtoi.c index 6aeb3d1..721f979 100644 --- a/lib/crtdll/wchar/wtoi.c +++ b/lib/crtdll/wchar/wtoi.c @@ -1,11 +1,12 @@ -#include +#include -int _wtoi( const wchar_t *str ) + +int _wtoi(const wchar_t* str) { return (int)wcstol(str, 0, 10); } -long _wtol( const wchar_t *str ) +long _wtol(const wchar_t* str) { return (int)wcstol(str, 0, 10); } diff --git a/lib/fmifs/.cvsignore b/lib/fmifs/.cvsignore index 3ad077f..933a473 100644 --- a/lib/fmifs/.cvsignore +++ b/lib/fmifs/.cvsignore @@ -1,3 +1,7 @@ fmifs.coff fmifs.dll -fmifs.nostrip.dll \ No newline at end of file +fmifs.nostrip.dll +fmifs.sym +*.o +*.obj +*.d diff --git a/lib/fmifs/makefile b/lib/fmifs/makefile index 95797d2..0e887a7 100644 --- a/lib/fmifs/makefile +++ b/lib/fmifs/makefile @@ -8,6 +8,10 @@ TARGET_NAME = fmifs TARGET_BASE = 0x76df0000 +TARGET_CFLAGS = -fno-builtin + +TARGET_LFLAGS = -nostdlib -nostartfiles + TARGET_SDKLIBS = ntdll.a kernel32.a TARGET_OBJECTS = \ diff --git a/lib/gdi32/.cvsignore b/lib/gdi32/.cvsignore index 22801be..765c9c8 100644 --- a/lib/gdi32/.cvsignore +++ b/lib/gdi32/.cvsignore @@ -1,3 +1,5 @@ gdi32.coff +gdi32.sym gdi32.dll -gdi32.nostrip.dll \ No newline at end of file +gdi32.nostrip.dll +*.o diff --git a/lib/gdi32/main/.cvsignore b/lib/gdi32/main/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/gdi32/main/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/gdi32/makefile b/lib/gdi32/makefile index 894abe5..bf1fe50 100644 --- a/lib/gdi32/makefile +++ b/lib/gdi32/makefile @@ -8,6 +8,14 @@ TARGET_NAME = gdi32 TARGET_BASE = 0x77ed0000 +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin + +TARGET_LFLAGS = -nostartfiles -nostdlib + TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a TARGET_OBJECTS = $(TARGET_NAME).o diff --git a/lib/gdi32/misc/.cvsignore b/lib/gdi32/misc/.cvsignore index 63c24b8..397312b 100644 --- a/lib/gdi32/misc/.cvsignore +++ b/lib/gdi32/misc/.cvsignore @@ -1 +1,2 @@ -win32k.c \ No newline at end of file +win32k.c +*.o diff --git a/lib/gdi32/misc/stubs.c b/lib/gdi32/misc/stubs.c index 5454fa5..8c52686 100644 --- a/lib/gdi32/misc/stubs.c +++ b/lib/gdi32/misc/stubs.c @@ -1050,19 +1050,6 @@ RestoreDC( } - -UINT -STDCALL -RealizePalette( - HDC a0 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - - BOOL STDCALL RoundRect( @@ -1145,20 +1132,6 @@ SetMetaRgn( -HPALETTE -STDCALL -SelectPalette( - HDC a0, - HPALETTE a1, - BOOL a2 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - - COLORREF STDCALL SetBkColor( @@ -1477,12 +1450,12 @@ EnumEnhMetaFile( } - -UINT -STDCALL + +UINT +STDCALL GetEnhMetaFileBits( - HENHMETAFILE a0, - UINT a1, + HENHMETAFILE a0, + UINT a1, LPBYTE a2 ) { @@ -1491,9 +1464,9 @@ GetEnhMetaFileBits( } - -UINT -STDCALL + +UINT +STDCALL GetEnhMetaFileHeader( HENHMETAFILE a0, UINT a1, @@ -1505,9 +1478,9 @@ GetEnhMetaFileHeader( } - -UINT -STDCALL + +UINT +STDCALL GetEnhMetaFilePaletteEntries( HENHMETAFILE a0, UINT a1, @@ -1519,9 +1492,9 @@ GetEnhMetaFilePaletteEntries( } - -UINT -STDCALL + +UINT +STDCALL GetEnhMetaFilePixelFormat( HENHMETAFILE a0, DWORD a1, @@ -1533,14 +1506,14 @@ GetEnhMetaFilePixelFormat( } - -UINT -STDCALL + +UINT +STDCALL GetWinMetaFileBits( HENHMETAFILE a0, - UINT a1, - LPBYTE a2, - INT a3, + UINT a1, + LPBYTE a2, + INT a3, HDC a4 ) { @@ -1549,12 +1522,12 @@ GetWinMetaFileBits( } - -BOOL -STDCALL + +BOOL +STDCALL PlayEnhMetaFile( - HDC a0, - HENHMETAFILE a1, + HDC a0, + HENHMETAFILE a1, CONST RECT *a2 ) { @@ -1563,13 +1536,13 @@ PlayEnhMetaFile( } - -BOOL -STDCALL + +BOOL +STDCALL PlayEnhMetaFileRecord( HDC a0, - LPHANDLETABLE a1, - CONST ENHMETARECORD *a2, + LPHANDLETABLE a1, + CONST ENHMETARECORD *a2, UINT a3 ) { @@ -1578,11 +1551,11 @@ PlayEnhMetaFileRecord( } - -HENHMETAFILE -STDCALL + +HENHMETAFILE +STDCALL SetEnhMetaFileBits( - UINT a0, + UINT a0, CONST BYTE *a1 ) { @@ -1591,13 +1564,13 @@ SetEnhMetaFileBits( } - -HENHMETAFILE -STDCALL + +HENHMETAFILE +STDCALL SetWinMetaFileBits( - UINT a0, - CONST BYTE *a1, - HDC a2, + UINT a0, + CONST BYTE *a1, + HDC a2, // CONST METAFILEPICT *a3 PVOID a3 ) @@ -1607,12 +1580,12 @@ SetWinMetaFileBits( } - -BOOL -STDCALL + +BOOL +STDCALL GdiComment( - HDC a0, - UINT a1, + HDC a0, + UINT a1, CONST BYTE *a2 ) { @@ -1621,15 +1594,15 @@ GdiComment( } - -BOOL -STDCALL + +BOOL +STDCALL AngleArc( - HDC hdc, - int a1, - int a2, - DWORD a3, - FLOAT a4, + HDC hdc, + int a1, + int a2, + DWORD a3, + FLOAT a4, FLOAT a5 ) { @@ -1638,13 +1611,13 @@ AngleArc( } - -BOOL -STDCALL + +BOOL +STDCALL PolyPolyline( - HDC hdc, - CONST POINT *a1, - CONST DWORD *a2, + HDC hdc, + CONST POINT *a1, + CONST DWORD *a2, DWORD a3 ) { @@ -1653,9 +1626,9 @@ PolyPolyline( } - -BOOL -STDCALL + +BOOL +STDCALL GetWorldTransform( HDC hdc, LPXFORM a1 @@ -1666,11 +1639,11 @@ GetWorldTransform( } - -BOOL -STDCALL + +BOOL +STDCALL SetWorldTransform( - HDC a0, + HDC a0, CONST XFORM *a1 ) { @@ -1679,12 +1652,12 @@ SetWorldTransform( } - -BOOL -STDCALL + +BOOL +STDCALL ModifyWorldTransform( HDC a0, - CONST XFORM *a1, + CONST XFORM *a1, DWORD a2 ) { @@ -1693,12 +1666,12 @@ ModifyWorldTransform( } - -BOOL -STDCALL + +BOOL +STDCALL CombineTransform( - LPXFORM a0, - CONST XFORM *a1, + LPXFORM a0, + CONST XFORM *a1, CONST XFORM *a2 ) { @@ -1707,13 +1680,13 @@ CombineTransform( } - -UINT -STDCALL + +UINT +STDCALL GetDIBColorTable( - HDC hdc, - UINT a1, - UINT a2, + HDC hdc, + UINT a1, + UINT a2, RGBQUAD *a3 ) { @@ -1722,13 +1695,13 @@ GetDIBColorTable( } - -UINT -STDCALL + +UINT +STDCALL SetDIBColorTable( - HDC hdc, - UINT a1, - UINT a2, + HDC hdc, + UINT a1, + UINT a2, CONST RGBQUAD *a3 ) { @@ -1737,11 +1710,11 @@ SetDIBColorTable( } - -BOOL -STDCALL + +BOOL +STDCALL SetColorAdjustment( - HDC hdc, + HDC hdc, CONST COLORADJUSTMENT *a1 ) { @@ -1750,11 +1723,11 @@ SetColorAdjustment( } - -BOOL -STDCALL + +BOOL +STDCALL GetColorAdjustment( - HDC hdc, + HDC hdc, LPCOLORADJUSTMENT a1 ) { @@ -1763,9 +1736,9 @@ GetColorAdjustment( } - -HPALETTE -STDCALL + +HPALETTE +STDCALL CreateHalftonePalette( HDC hdc ) @@ -1776,8 +1749,8 @@ CreateHalftonePalette( -int -STDCALL +int +STDCALL EndDoc( HDC hdc ) @@ -1787,9 +1760,9 @@ EndDoc( } - -int -STDCALL + +int +STDCALL StartPage( HDC hdc ) @@ -1799,9 +1772,9 @@ StartPage( } - -int -STDCALL + +int +STDCALL EndPage( HDC hdc ) @@ -1811,9 +1784,9 @@ EndPage( } - -int -STDCALL + +int +STDCALL AbortDoc( HDC hdc ) @@ -1823,11 +1796,11 @@ AbortDoc( } - -int -STDCALL + +int +STDCALL SetAbortProc( - HDC hdc, + HDC hdc, ABORTPROC a1 ) { @@ -1836,9 +1809,9 @@ SetAbortProc( } - -BOOL -STDCALL + +BOOL +STDCALL AbortPath( HDC hdc ) @@ -1848,18 +1821,18 @@ AbortPath( } - -BOOL -STDCALL + +BOOL +STDCALL ArcTo( - HDC hdc, - int a1, - int a2, - int a3, - int a4, - int a5, + HDC hdc, + int a1, + int a2, + int a3, + int a4, + int a5, int a6, - int a7, + int a7, int a8 ) { @@ -1868,9 +1841,9 @@ ArcTo( } - -BOOL -STDCALL + +BOOL +STDCALL BeginPath( HDC hdc ) @@ -1880,9 +1853,9 @@ BeginPath( } - -BOOL -STDCALL + +BOOL +STDCALL CloseFigure( HDC hdc ) @@ -1892,9 +1865,9 @@ CloseFigure( } - -BOOL -STDCALL + +BOOL +STDCALL EndPath( HDC hdc ) @@ -1904,9 +1877,9 @@ EndPath( } - -BOOL -STDCALL + +BOOL +STDCALL FillPath( HDC hdc ) @@ -1916,9 +1889,9 @@ FillPath( } - -BOOL -STDCALL + +BOOL +STDCALL FlattenPath( HDC hdc ) @@ -1928,13 +1901,13 @@ FlattenPath( } - -int -STDCALL + +int +STDCALL GetPath( - HDC hdc, - LPPOINT a1, - LPBYTE a2, + HDC hdc, + LPPOINT a1, + LPBYTE a2, int a3 ) { @@ -1943,9 +1916,9 @@ GetPath( } - -HRGN -STDCALL + +HRGN +STDCALL PathToRegion( HDC hdc ) @@ -1955,13 +1928,13 @@ PathToRegion( } - -BOOL -STDCALL + +BOOL +STDCALL PolyDraw( - HDC hdc, - CONST POINT *a1, - CONST BYTE *a2, + HDC hdc, + CONST POINT *a1, + CONST BYTE *a2, int a3 ) { @@ -1970,11 +1943,11 @@ PolyDraw( } - -BOOL -STDCALL + +BOOL +STDCALL SelectClipPath( - HDC hdc, + HDC hdc, int a1 ) { @@ -1983,11 +1956,11 @@ SelectClipPath( } - -int -STDCALL + +int +STDCALL SetArcDirection( - HDC hdc, + HDC hdc, int a1 ) { @@ -1996,12 +1969,12 @@ SetArcDirection( } - -BOOL -STDCALL + +BOOL +STDCALL SetMiterLimit( - HDC hdc, - FLOAT a1, + HDC hdc, + FLOAT a1, PFLOAT a2 ) { @@ -2010,9 +1983,9 @@ SetMiterLimit( } - -BOOL -STDCALL + +BOOL +STDCALL StrokeAndFillPath( HDC hdc ) @@ -2022,9 +1995,9 @@ StrokeAndFillPath( } - -BOOL -STDCALL + +BOOL +STDCALL StrokePath( HDC hdc ) @@ -2034,9 +2007,9 @@ StrokePath( } - -BOOL -STDCALL + +BOOL +STDCALL WidenPath( HDC hdc ) @@ -2046,14 +2019,14 @@ WidenPath( } - -HPEN -STDCALL + +HPEN +STDCALL ExtCreatePen( - DWORD a0, - DWORD a1, - CONST LOGBRUSH *a2, - DWORD a3, + DWORD a0, + DWORD a1, + CONST LOGBRUSH *a2, + DWORD a3, CONST DWORD *a4 ) { @@ -2062,11 +2035,11 @@ ExtCreatePen( } - -BOOL -STDCALL + +BOOL +STDCALL GetMiterLimit( - HDC hdc, + HDC hdc, PFLOAT a1 ) { @@ -2075,9 +2048,9 @@ GetMiterLimit( } - -int -STDCALL + +int +STDCALL GetArcDirection( HDC hdc ) @@ -2087,7 +2060,7 @@ GetArcDirection( } - + HRGN STDCALL CreatePolygonRgn( @@ -2683,7 +2656,7 @@ wglSwapLayerBuffers( } -/* === AFTER THIS POINT I GUESS... ========= +/* === AFTER THIS POINT I GUESS... ========= * (based on stack size in Norlander's .def) * === WHERE ARE THEY DEFINED? ============= */ diff --git a/lib/gdi32/objects/.cvsignore b/lib/gdi32/objects/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/gdi32/objects/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/gdi32/objects/dc.c b/lib/gdi32/objects/dc.c index 13195c5..47d2dba 100644 --- a/lib/gdi32/objects/dc.c +++ b/lib/gdi32/objects/dc.c @@ -175,3 +175,26 @@ DeleteObject( { return W32kDeleteObject(a0); } + +HPALETTE +STDCALL +SelectPalette( + HDC a0, + HPALETTE a1, + BOOL a2 + ) +{ + return W32kSelectPalette( a0, a1,a2 ); +} + +UINT +STDCALL +RealizePalette( + HDC a0 + ) +{ + return W32kRealizePalette( a0 ); +} + + + diff --git a/lib/gdi32/objects/region.c b/lib/gdi32/objects/region.c index 69e288c..49c5143 100644 --- a/lib/gdi32/objects/region.c +++ b/lib/gdi32/objects/region.c @@ -56,7 +56,7 @@ CreateRectRgnIndirect( CONST RECT *a0 ) { - return W32kCreateRectRgnIndirect(a0); + return W32kCreateRectRgnIndirect((RECT *)a0); } diff --git a/lib/gdi32/objects/text.c b/lib/gdi32/objects/text.c index 4ab5acd..b0e9390 100644 --- a/lib/gdi32/objects/text.c +++ b/lib/gdi32/objects/text.c @@ -3,6 +3,7 @@ #endif #undef WIN32_LEAN_AND_MEAN +#include #include #include #include @@ -202,7 +203,6 @@ CreateFontA( ANSI_STRING StringA; UNICODE_STRING StringU; HFONT ret; - LOGFONT tlf; RtlInitAnsiString(&StringA, (LPSTR)Face); RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE); diff --git a/lib/kernel32/.cvsignore b/lib/kernel32/.cvsignore index 031332b..f16a880 100644 --- a/lib/kernel32/.cvsignore +++ b/lib/kernel32/.cvsignore @@ -1,9 +1,11 @@ kernel32.a kernel32.dll kernel32.nostrip.dll +kernel32.sym kernel32.lib kernel32.coff base.tmp junk.tmp temp.exp - +*.o +*.bin diff --git a/lib/kernel32/MSG00409.bin b/lib/kernel32/MSG00409.bin new file mode 100644 index 0000000000000000000000000000000000000000..5ca7b783a1032ceda40e0fbe6cacc3716f39b70a GIT binary patch literal 292 zcmXBPKMMhI9LMnwHh%^Yi^<w$uuk#shPy3GOfU4H)sb+NL^z5q|~E*+}SQ2!c9vfI>SE8Ick~( zX-@_vxlC+^)JlH#WK)}UL^la~|(uJC!CSB -#include +#include -#include typedef LONG (STDCALL *LPTOP_LEVEL_EXCEPTION_FILTER)( struct _EXCEPTION_POINTERS *ExceptionInfo diff --git a/lib/kernel32/file/backup.c b/lib/kernel32/file/backup.c index aa050fc..591142e 100644 --- a/lib/kernel32/file/backup.c +++ b/lib/kernel32/file/backup.c @@ -10,14 +10,7 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include -#include - -#include -#include +#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/cnotify.c b/lib/kernel32/file/cnotify.c index 15338ca..7c065b0 100644 --- a/lib/kernel32/file/cnotify.c +++ b/lib/kernel32/file/cnotify.c @@ -9,7 +9,7 @@ * Created 01/11/98 */ -#include +#include WINBOOL STDCALL diff --git a/lib/kernel32/file/copy.c b/lib/kernel32/file/copy.c index 9f3c139..52f5ffb 100644 --- a/lib/kernel32/file/copy.c +++ b/lib/kernel32/file/copy.c @@ -12,18 +12,183 @@ /* INCLUDES ****************************************************************/ -#include -#include +#include #define NDEBUG #include -#include -#define LPPROGRESS_ROUTINE void* +/* FUNCTIONS ****************************************************************/ -/* FUNCTIONS ****************************************************************/ +static NTSTATUS +CopyLoop ( + HANDLE FileHandleSource, + HANDLE FileHandleDest, + LARGE_INTEGER SourceFileSize, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + WINBOOL *pbCancel, + WINBOOL *KeepDest + ) +{ + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatusBlock; + UCHAR *lpBuffer = NULL; + ULONG RegionSize = 0x10000; + LARGE_INTEGER BytesCopied; + DWORD CallbackReason; + DWORD ProgressResult; + WINBOOL EndOfFileFound; + + *KeepDest = FALSE; + errCode = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID *)&lpBuffer, + 2, + &RegionSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); + + if (NT_SUCCESS(errCode)) + { + BytesCopied.QuadPart = 0; + EndOfFileFound = FALSE; + CallbackReason = CALLBACK_STREAM_SWITCH; + while (! EndOfFileFound && + NT_SUCCESS(errCode) && + (NULL == pbCancel || ! *pbCancel)) + { + if (NULL != lpProgressRoutine) + { + ProgressResult = (*lpProgressRoutine)(SourceFileSize, + BytesCopied, + SourceFileSize, + BytesCopied, + 0, + CallbackReason, + FileHandleSource, + FileHandleDest, + lpData); + switch (ProgressResult) + { + case PROGRESS_CANCEL: + DPRINT("Progress callback requested cancel\n"); + errCode = STATUS_REQUEST_ABORTED; + break; + case PROGRESS_STOP: + DPRINT("Progress callback requested stop\n"); + errCode = STATUS_REQUEST_ABORTED; + *KeepDest = TRUE; + break; + case PROGRESS_QUIET: + lpProgressRoutine = NULL; + break; + case PROGRESS_CONTINUE: + default: + break; + } + CallbackReason = CALLBACK_CHUNK_FINISHED; + } + if (NT_SUCCESS(errCode)) + { + errCode = NtReadFile(FileHandleSource, + NULL, + NULL, + NULL, + (PIO_STATUS_BLOCK)&IoStatusBlock, + lpBuffer, + RegionSize, + NULL, + NULL); + if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel)) + { + errCode = NtWriteFile(FileHandleDest, + NULL, + NULL, + NULL, + (PIO_STATUS_BLOCK)&IoStatusBlock, + lpBuffer, + IoStatusBlock.Information, + NULL, + NULL); + if (NT_SUCCESS(errCode)) + { + BytesCopied.QuadPart += IoStatusBlock.Information; + } + else + { + DPRINT("Error 0x%08x reading writing to dest\n", errCode); + } + } + else if (!NT_SUCCESS(errCode)) + { + if (STATUS_END_OF_FILE == errCode) + { + EndOfFileFound = TRUE; + errCode = STATUS_SUCCESS; + } + else + { + DPRINT("Error 0x%08x reading from source\n", errCode); + } + } + } + } + + if (! EndOfFileFound && (NULL != pbCancel && *pbCancel)) + { + DPRINT("User requested cancel\n"); + errCode = STATUS_REQUEST_ABORTED; + } + + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID *)&lpBuffer, + &RegionSize, + MEM_RELEASE); + } + else + { + DPRINT("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize); + } + + return errCode; +} + +static NTSTATUS +SetLastWriteTime( + HANDLE FileHandle, + TIME LastWriteTime + ) +{ + NTSTATUS errCode = STATUS_SUCCESS; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileBasic; + + errCode = NtQueryInformationFile (FileHandle, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + DPRINT("Error 0x%08x obtaining FileBasicInformation\n", errCode); + } + else + { + FileBasic.LastWriteTime = LastWriteTime; + errCode = NtSetInformationFile (FileHandle, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + DPRINT("Error 0x%0x setting LastWriteTime\n", errCode); + } + } + + return errCode; +} WINBOOL STDCALL @@ -36,15 +201,15 @@ CopyFileExW ( DWORD dwCopyFlags ) { - NTSTATUS errCode = 0; + NTSTATUS errCode; HANDLE FileHandleSource, FileHandleDest; IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION FileStandard; FILE_BASIC_INFORMATION FileBasic; - FILE_POSITION_INFORMATION FilePosition; - UCHAR *lpBuffer = NULL; - ULONG RegionSize = 0x1000000; - BOOL bCancel = FALSE; + FILE_DISPOSITION_INFORMATION FileDispInfo; + WINBOOL RC = FALSE; + WINBOOL KeepDestOnError = FALSE; + DWORD SystemError; FileHandleSource = CreateFileW(lpExistingFileName, GENERIC_READ, @@ -53,137 +218,87 @@ CopyFileExW ( OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, NULL); - if (FileHandleSource == NULL) - { - return(FALSE); - } - - errCode = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock, - &FileStandard, - sizeof(FILE_STANDARD_INFORMATION), - FileStandardInformation); - if (!NT_SUCCESS(errCode)) - { - NtClose(FileHandleSource); - SetLastErrorByStatus(errCode); - return FALSE; - } - - errCode = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock,&FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - NtClose(FileHandleSource); - SetLastErrorByStatus(errCode); - return FALSE; - } - - FileHandleDest = CreateFileW(lpNewFileName, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS, - FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING, - NULL); - if (FileHandleDest == NULL) - { - return(FALSE); - } - - FilePosition.CurrentByteOffset.QuadPart = 0; - - errCode = NtSetInformationFile(FileHandleSource, - &IoStatusBlock, - &FilePosition, - sizeof(FILE_POSITION_INFORMATION), - FilePositionInformation); - if (!NT_SUCCESS(errCode)) - { - NtClose(FileHandleSource); - NtClose(FileHandleDest); - SetLastErrorByStatus(errCode); - return FALSE; - } - - errCode = NtSetInformationFile(FileHandleDest, - &IoStatusBlock, - &FilePosition, - sizeof(FILE_POSITION_INFORMATION), - FilePositionInformation); - if (!NT_SUCCESS(errCode)) + if (INVALID_HANDLE_VALUE != FileHandleSource) { + errCode = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock, + &FileStandard, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(errCode)) + { + DPRINT("Status 0x%08x obtaining FileStandardInformation for source\n", errCode); + SetLastErrorByStatus(errCode); + } + else + { + errCode = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock,&FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + DPRINT("Status 0x%08x obtaining FileBasicInformation for source\n", errCode); + SetLastErrorByStatus(errCode); + } + else + { + FileHandleDest = CreateFileW(lpNewFileName, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS, + FileBasic.FileAttributes, + NULL); + if (INVALID_HANDLE_VALUE != FileHandleDest) + { + errCode = CopyLoop(FileHandleSource, + FileHandleDest, + FileStandard.EndOfFile, + lpProgressRoutine, + lpData, + pbCancel, + &KeepDestOnError); + if (!NT_SUCCESS(errCode)) + { + SetLastErrorByStatus(errCode); + } + else + { + errCode = SetLastWriteTime(FileHandleDest, + FileBasic.LastWriteTime); + if (!NT_SUCCESS(errCode)) + { + SetLastErrorByStatus(errCode); + } + else + { + RC = TRUE; + } + } + NtClose(FileHandleDest); + if (! RC && ! KeepDestOnError) + { + SystemError = GetLastError(); + SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL); + DeleteFileW(lpNewFileName); + SetLastError(SystemError); + } + } + else + { + DPRINT("Error %d during opening of dest file\n", GetLastError()); + } + } + } NtClose(FileHandleSource); - NtClose(FileHandleDest); - SetLastErrorByStatus(errCode); - return FALSE; } - - errCode = NtAllocateVirtualMemory(NtCurrentProcess(), - (PVOID *)&lpBuffer, - 2, - &RegionSize, - MEM_RESERVE | MEM_COMMIT, - PAGE_READWRITE); - - if (!NT_SUCCESS(errCode)) + else { - NtClose(FileHandleSource); - NtClose(FileHandleDest); - SetLastErrorByStatus(errCode); - return FALSE; + DPRINT("Error %d during opening of source file\n", GetLastError()); } - do { - errCode = NtReadFile(FileHandleSource, - NULL, - NULL, - NULL, - (PIO_STATUS_BLOCK)&IoStatusBlock, - lpBuffer, - RegionSize, - NULL, - NULL); - if (pbCancel != NULL) - bCancel = *pbCancel; - - if (!NT_SUCCESS(errCode) || bCancel) - { - NtFreeVirtualMemory(NtCurrentProcess(), - (PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE); - NtClose(FileHandleSource); - NtClose(FileHandleDest); - if ( errCode == STATUS_END_OF_FILE ) - break; - else - return FALSE; - } - - errCode = NtWriteFile(FileHandleDest, - NULL, - lpProgressRoutine, - lpData, - (PIO_STATUS_BLOCK)&IoStatusBlock, - lpBuffer, - IoStatusBlock.Information, - NULL, - NULL); - - if (!NT_SUCCESS(errCode)) - { - NtFreeVirtualMemory(NtCurrentProcess(), - (PVOID *)&lpBuffer, - &RegionSize, - MEM_RELEASE); - NtClose(FileHandleSource); - NtClose(FileHandleDest); - return FALSE; - } - - } while ( TRUE ); - return TRUE; + return RC; } diff --git a/lib/kernel32/file/create.c b/lib/kernel32/file/create.c index 1466ae8..c6ca94e 100644 --- a/lib/kernel32/file/create.c +++ b/lib/kernel32/file/create.c @@ -15,15 +15,10 @@ /* INCLUDES *****************************************************************/ -#include -/* please FIXME: ddk/ntddk.h should be enough */ -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ @@ -255,6 +250,7 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName, break; default: + break; } return FileHandle; diff --git a/lib/kernel32/file/curdir.c b/lib/kernel32/file/curdir.c index 31b64a2..3f092ec 100644 --- a/lib/kernel32/file/curdir.c +++ b/lib/kernel32/file/curdir.c @@ -11,13 +11,10 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include +#include #define NDEBUG #include -#include /* GLOBAL VARIABLES **********************************************************/ diff --git a/lib/kernel32/file/delete.c b/lib/kernel32/file/delete.c index d427186..2568d2b 100644 --- a/lib/kernel32/file/delete.c +++ b/lib/kernel32/file/delete.c @@ -11,13 +11,10 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/deviceio.c b/lib/kernel32/file/deviceio.c index 79f5c34..0a9863d 100644 --- a/lib/kernel32/file/deviceio.c +++ b/lib/kernel32/file/deviceio.c @@ -9,13 +9,11 @@ * Created 01/11/98 */ -#include -#include +#include #define NDEBUG //#define DBG #include -#include WINBOOL diff --git a/lib/kernel32/file/dir.c b/lib/kernel32/file/dir.c index 269efe7..8736996 100644 --- a/lib/kernel32/file/dir.c +++ b/lib/kernel32/file/dir.c @@ -15,15 +15,10 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS *****************************************************************/ @@ -138,6 +133,13 @@ CreateDirectoryExW ( DPRINT ("lpTemplateDirectory %S lpNewDirectory %S lpSecurityAttributes %p\n", lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes); + + // Can't create empty directory + if(lpNewDirectory == NULL || *lpNewDirectory == 0) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0) { diff --git a/lib/kernel32/file/dosdev.c b/lib/kernel32/file/dosdev.c index 414a736..2bc8712 100644 --- a/lib/kernel32/file/dosdev.c +++ b/lib/kernel32/file/dosdev.c @@ -9,8 +9,7 @@ * Created 01/11/98 */ -#include -#include +#include WINBOOL diff --git a/lib/kernel32/file/file.c b/lib/kernel32/file/file.c index 7d0e41d..79061ad 100644 --- a/lib/kernel32/file/file.c +++ b/lib/kernel32/file/file.c @@ -12,16 +12,10 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include +#include #define NDEBUG #include -#include - -#define LPPROGRESS_ROUTINE void* /* GLOBALS ******************************************************************/ @@ -411,10 +405,14 @@ GetCompressedFileSizeW(LPCWSTR lpFileName, { CloseHandle(hFile); SetLastErrorByStatus(errCode); - return 0; + return INVALID_FILE_SIZE; } CloseHandle(hFile); - return 0; + + if(lpFileSizeHigh) + *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart; + + return FileCompression.CompressedFileSize.u.LowPart; } @@ -607,6 +605,11 @@ SetFileAttributesW(LPCWSTR lpFileName, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + DPRINT("SetFileAttributes CreateFileW failed with code %d\n", GetLastError()); + return FALSE; + } errCode = NtQueryInformationFile(hFile, &IoStatusBlock, @@ -616,6 +619,7 @@ SetFileAttributesW(LPCWSTR lpFileName, if (!NT_SUCCESS(errCode)) { CloseHandle(hFile); + DPRINT("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", errCode); SetLastErrorByStatus(errCode); return FALSE; } @@ -628,6 +632,7 @@ SetFileAttributesW(LPCWSTR lpFileName, if (!NT_SUCCESS(errCode)) { CloseHandle(hFile); + DPRINT("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", errCode); SetLastErrorByStatus(errCode); return FALSE; } diff --git a/lib/kernel32/file/find.c b/lib/kernel32/file/find.c index 8b47b75..455e51b 100644 --- a/lib/kernel32/file/find.c +++ b/lib/kernel32/file/find.c @@ -11,13 +11,10 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include +#include #define NDEBUG #include -#include /* TYPES ********************************************************************/ diff --git a/lib/kernel32/file/iocompl.c b/lib/kernel32/file/iocompl.c index 3d06b40..c452eb2 100644 --- a/lib/kernel32/file/iocompl.c +++ b/lib/kernel32/file/iocompl.c @@ -9,9 +9,7 @@ * Created 01/11/98 */ -#include -#include -#include +#include #include @@ -138,4 +136,21 @@ FileIOCompletionRoutine( } +BOOL STDCALL +CancelIo(HANDLE hFile) +{ + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + Status = NtCancelIoFile(hFile, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); +} + /* EOF */ diff --git a/lib/kernel32/file/lfile.c b/lib/kernel32/file/lfile.c index 4dd4acd..6b83cf7 100644 --- a/lib/kernel32/file/lfile.c +++ b/lib/kernel32/file/lfile.c @@ -9,10 +9,7 @@ * Created 01/11/98 */ -#undef WIN32_LEAN_AND_MEAN -#include -#include -#include +#include long diff --git a/lib/kernel32/file/lock.c b/lib/kernel32/file/lock.c index 4ec38d1..62d100a 100644 --- a/lib/kernel32/file/lock.c +++ b/lib/kernel32/file/lock.c @@ -14,14 +14,10 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include -#include +#include -//#define NDEBUG +#define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/mailslot.c b/lib/kernel32/file/mailslot.c index e429cc6..8483f64 100644 --- a/lib/kernel32/file/mailslot.c +++ b/lib/kernel32/file/mailslot.c @@ -10,12 +10,10 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include +#include +#define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/move.c b/lib/kernel32/file/move.c index 635ddae..defa6c4 100644 --- a/lib/kernel32/file/move.c +++ b/lib/kernel32/file/move.c @@ -11,12 +11,11 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include +#include #define NDEBUG #include +#include #define FILE_RENAME_SIZE MAX_PATH +sizeof(FILE_RENAME_INFORMATION) @@ -45,6 +44,24 @@ MoveFileExA ( DWORD dwFlags ) { + return MoveFileWithProgressA (lpExistingFileName, + lpNewFileName, + NULL, + NULL, + dwFlags); +} + + +WINBOOL +STDCALL +MoveFileWithProgressA ( + LPCSTR lpExistingFileName, + LPCSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + DWORD dwFlags + ) +{ UNICODE_STRING ExistingFileNameU; UNICODE_STRING NewFileNameU; ANSI_STRING ExistingFileName; @@ -77,9 +94,11 @@ MoveFileExA ( TRUE); } - Result = MoveFileExW (ExistingFileNameU.Buffer, - NewFileNameU.Buffer, - dwFlags); + Result = MoveFileWithProgressW (ExistingFileNameU.Buffer, + NewFileNameU.Buffer, + lpProgressRoutine, + lpData, + dwFlags); RtlFreeHeap (RtlGetProcessHeap (), 0, @@ -113,11 +132,158 @@ MoveFileExW ( DWORD dwFlags ) { + return MoveFileWithProgressW (lpExistingFileName, + lpNewFileName, + NULL, + NULL, + dwFlags); +} + + +static WINBOOL +AdjustFileAttributes ( + LPCWSTR ExistingFileName, + LPCWSTR NewFileName + ) +{ + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION ExistingInfo, + NewInfo; + HANDLE hFile; + DWORD Attributes; + NTSTATUS errCode; + WINBOOL Result = FALSE; + + hFile = CreateFileW (ExistingFileName, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (INVALID_HANDLE_VALUE != hFile) + { + errCode = NtQueryInformationFile (hFile, + &IoStatusBlock, + &ExistingInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (NT_SUCCESS (errCode)) + { + if (0 != (ExistingInfo.FileAttributes & FILE_ATTRIBUTE_READONLY)) + { + Attributes = ExistingInfo.FileAttributes; + ExistingInfo.FileAttributes &= ~ FILE_ATTRIBUTE_READONLY; + if (0 == (ExistingInfo.FileAttributes & + (FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_ARCHIVE))) + { + ExistingInfo.FileAttributes |= FILE_ATTRIBUTE_NORMAL; + } + errCode = NtSetInformationFile (hFile, + &IoStatusBlock, + &ExistingInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + DPRINT("Removing READONLY attribute from source failed with status 0x%08x\n", errCode); + } + ExistingInfo.FileAttributes = Attributes; + } + CloseHandle(hFile); + + if (NT_SUCCESS(errCode)) + { + hFile = CreateFileW (NewFileName, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (INVALID_HANDLE_VALUE != hFile) + { + errCode = NtQueryInformationFile(hFile, + &IoStatusBlock, + &NewInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (NT_SUCCESS(errCode)) + { + NewInfo.FileAttributes = (NewInfo.FileAttributes & + ~ (FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_NORMAL)) | + (ExistingInfo.FileAttributes & + (FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_NORMAL)) | + FILE_ATTRIBUTE_ARCHIVE; + NewInfo.CreationTime = ExistingInfo.CreationTime; + NewInfo.LastAccessTime = ExistingInfo.LastAccessTime; + NewInfo.LastWriteTime = ExistingInfo.LastWriteTime; + errCode = NtSetInformationFile (hFile, + &IoStatusBlock, + &NewInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (NT_SUCCESS(errCode)) + { + Result = TRUE; + } + else + { + DPRINT("Setting attributes on dest file failed with status 0x%08x\n", errCode); + } + } + else + { + DPRINT("Obtaining attributes from dest file failed with status 0x%08x\n", errCode); + } + CloseHandle(hFile); + } + else + { + DPRINT("Opening dest file to set attributes failed with code %d\n", GetLastError()); + } + } + } + else + { + DPRINT("Obtaining attributes from source file failed with status 0x%08x\n", errCode); + CloseHandle(hFile); + } + } + else + { + DPRINT("Opening source file to obtain attributes failed with code %d\n", GetLastError()); + } + + return Result; +} + + +WINBOOL +STDCALL +MoveFileWithProgressW ( + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + DWORD dwFlags + ) +{ HANDLE hFile = NULL; IO_STATUS_BLOCK IoStatusBlock; FILE_RENAME_INFORMATION *FileRename; USHORT Buffer[FILE_RENAME_SIZE]; - NTSTATUS errCode; + NTSTATUS errCode; + DWORD err; + WINBOOL Result; hFile = CreateFileW (lpExistingFileName, GENERIC_ALL, @@ -137,21 +303,63 @@ MoveFileExW ( memcpy (FileRename->FileName, lpNewFileName, min(FileRename->FileNameLength, MAX_PATH)); - + errCode = NtSetInformationFile (hFile, &IoStatusBlock, FileRename, FILE_RENAME_SIZE, FileRenameInformation); CloseHandle(hFile); - if (!NT_SUCCESS(errCode)) + if (NT_SUCCESS(errCode)) + { + Result = TRUE; + } + /* FIXME file rename not yet implemented in all FSDs so it will always + * fail, even when the move is to the same device + */ +#if 0 + else if (STATUS_NOT_SAME_DEVICE == errCode && + MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED)) +#else + else +#endif { - if (CopyFileW (lpExistingFileName, - lpNewFileName, - FileRename->Replace)) - DeleteFileW (lpExistingFileName); + Result = CopyFileExW (lpExistingFileName, + lpNewFileName, + lpProgressRoutine, + lpData, + NULL, + FileRename->Replace ? 0 : COPY_FILE_FAIL_IF_EXISTS) && + AdjustFileAttributes(lpExistingFileName, lpNewFileName) && + DeleteFileW (lpExistingFileName); + if (! Result) + { + /* Delete of the existing file failed so the + * existing file is still there. Clean up the + * new file (if possible) + */ + err = GetLastError(); + if (! SetFileAttributesW (lpNewFileName, FILE_ATTRIBUTE_NORMAL)) + { + DPRINT("Removing possible READONLY attrib from new file failed with code %d\n", GetLastError()); + } + if (! DeleteFileW (lpNewFileName)) + { + DPRINT("Deleting new file during cleanup failed with code %d\n", GetLastError()); + } + SetLastError (err); + } } - return TRUE; + /* See FIXME above */ +#if 0 + else + { + SetLastErrorByStatus (errCode); + Result = FALSE; + } +#endif + + return Result; } /* EOF */ diff --git a/lib/kernel32/file/npipe.c b/lib/kernel32/file/npipe.c index b3cf709..3fc0fe8 100644 --- a/lib/kernel32/file/npipe.c +++ b/lib/kernel32/file/npipe.c @@ -10,16 +10,10 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include -//#include -//#include -#include -#include - -//#define NDEBUG +#include + + +#define NDEBUG #include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/pipe.c b/lib/kernel32/file/pipe.c index 4ff0c88..59bf40b 100644 --- a/lib/kernel32/file/pipe.c +++ b/lib/kernel32/file/pipe.c @@ -10,9 +10,9 @@ /* INCLUDES *****************************************************************/ -#include -#include +#include +#define NDEBUG #include /* GLOBALS ******************************************************************/ diff --git a/lib/kernel32/file/rw.c b/lib/kernel32/file/rw.c index 7e43803..3742a0d 100644 --- a/lib/kernel32/file/rw.c +++ b/lib/kernel32/file/rw.c @@ -11,14 +11,10 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/tape.c b/lib/kernel32/file/tape.c index 372d07e..c3c14b4 100644 --- a/lib/kernel32/file/tape.c +++ b/lib/kernel32/file/tape.c @@ -12,14 +12,10 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/file/volume.c b/lib/kernel32/file/volume.c index 1852032..654d48c 100644 --- a/lib/kernel32/file/volume.c +++ b/lib/kernel32/file/volume.c @@ -19,29 +19,29 @@ * Copyright 1996 Alexandre Julliard */ -#include -#include -#include +#include #define NDEBUG #include -#include #define MAX_DOS_DRIVES 26 -HANDLE InternalOpenDirW(PWCHAR DirName, BOOLEAN Write) -{ - UNICODE_STRING NtPathU; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS errCode; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE hFile; - if (!RtlDosPathNameToNtPathName_U ((LPWSTR)DirName, - &NtPathU, - NULL, - NULL)) +static HANDLE +InternalOpenDirW(LPCWSTR DirName, + BOOLEAN Write) +{ + UNICODE_STRING NtPathU; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; + + if (!RtlDosPathNameToNtPathName_U((LPWSTR)DirName, + &NtPathU, + NULL, + NULL)) { DPRINT("Invalid path\n"); SetLastError(ERROR_BAD_PATHNAME); @@ -76,6 +76,7 @@ HANDLE InternalOpenDirW(PWCHAR DirName, BOOLEAN Write) return hFile; } + DWORD STDCALL GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer) @@ -222,12 +223,12 @@ GetDiskFreeSpaceW( GetCurrentDirectoryW (MAX_PATH, RootPathName); RootPathName[3] = 0; } - - if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW((PWCHAR)lpRootPathName, FALSE))) + + hFile = InternalOpenDirW(lpRootPathName, FALSE); + if (INVALID_HANDLE_VALUE == hFile) { - return FALSE; + return FALSE; } - errCode = NtQueryVolumeInformationFile(hFile, &IoStatusBlock, @@ -321,8 +322,9 @@ GetDiskFreeSpaceExW( GetCurrentDirectoryW (MAX_PATH, RootPathName); RootPathName[3] = 0; } - - if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW(lpDirectoryName, FALSE))) + + hFile = InternalOpenDirW(lpDirectoryName, FALSE); + if (INVALID_HANDLE_VALUE == hFile) { return FALSE; } @@ -555,11 +557,11 @@ GetVolumeInformationW( DPRINT("FileFsVolume %p\n", FileFsVolume); DPRINT("FileFsAttribute %p\n", FileFsAttribute); - hFile = InternalOpenDirW(lpRootPathName, FALSE); - if (hFile == INVALID_HANDLE_VALUE) - { - return FALSE; - } + hFile = InternalOpenDirW(lpRootPathName, FALSE); + if (hFile == INVALID_HANDLE_VALUE) + { + return FALSE; + } DPRINT("hFile: %x\n", hFile); errCode = NtQueryVolumeInformationFile(hFile, @@ -677,8 +679,9 @@ SetVolumeLabelW(LPCWSTR lpRootPathName, LabelInfo->VolumeLabelLength = LabelLength; wcscpy(LabelInfo->VolumeLabel, lpVolumeName); - - if (INVALID_HANDLE_VALUE == (hFile = InternalOpenDirW(lpRootPathName, TRUE))) + + hFile = InternalOpenDirW(lpRootPathName, TRUE); + if (INVALID_HANDLE_VALUE == hFile) { return FALSE; } diff --git a/lib/kernel32/k32.h b/lib/kernel32/k32.h new file mode 100755 index 0000000..018d32a --- /dev/null +++ b/lib/kernel32/k32.h @@ -0,0 +1,26 @@ +#define NTOS_MODE_USER +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/lib/kernel32/kernel32.def b/lib/kernel32/kernel32.def index 1401368..eaa0e93 100644 --- a/lib/kernel32/kernel32.def +++ b/lib/kernel32/kernel32.def @@ -36,6 +36,7 @@ AddConsoleAliasA@12 AddConsoleAliasW@12 AllocConsole@0 AreFileApisANSI@0 +AttachConsole@4 BackupRead@28 BackupSeek@24 BackupWrite@28 @@ -98,6 +99,7 @@ CreateSemaphoreA@16 CreateSemaphoreW@16 CreateTapePartition@16 CreateThread@24 +CreateToolhelp32Snapshot@8 CreateVirtualBuffer@12 CreateWaitableTimerA@12 CreateWaitableTimerW@12 @@ -227,7 +229,9 @@ GetConsoleHardwareState@12 GetConsoleInputWaitHandle@0 GetConsoleMode@8 GetConsoleOutputCP@0 +GetConsoleProcessList@8 GetConsoleScreenBufferInfo@8 +GetConsoleSelectionInfo@4 GetConsoleTitleA@8 GetConsoleTitleW@8 GetCurrencyFormatA@24 @@ -259,6 +263,8 @@ GetExitCodeThread@8 GetFiberData@0 GetFileAttributesA@4 GetFileAttributesW@4 +GetFileAttributesExA +GetFileAttributesExW GetFileInformationByHandle@8 GetFileSize@8 GetFileTime@16 @@ -382,6 +388,10 @@ GlobalUnWire@4 GlobalUnfix@4 GlobalUnlock@4 GlobalWire@4 +Heap32First@12 +Heap32ListFirst@8 +Heap32ListNext@8 +Heap32Next@4 HeapAlloc@12 HeapCompact@8 HeapCreate@12 @@ -444,10 +454,16 @@ LockFileEx@24 LockResource@4 MapViewOfFile@20 MapViewOfFileEx@24 +Module32First@8 +Module32FirstW@8 +Module32Next@8 +Module32NextW@8 MoveFileA@8 MoveFileExA@12 +MoveFileWithProgressA@20 MoveFileExW@12 MoveFileW@8 +MoveFileWithProgressW@20 MulDiv@12 MultiByteToWideChar@24 OpenConsoleW@16 @@ -472,6 +488,10 @@ PeekNamedPipe@24 PostQueuedCompletionStatus@16 PrepareTape@12 ProcessIdToSessionId@8 +Process32First@8 +Process32FirstW@8 +Process32Next@8 +Process32NextW@8 PulseEvent@4 PurgeComm@8 QueryDosDeviceA@12 @@ -566,6 +586,7 @@ SetLocaleInfoW@12 SetMailslotInfo@8 SetNamedPipeHandleState@16 SetPriorityClass@8 +SetProcessAffinityMask@8 SetProcessShutdownParameters@8 SetProcessWorkingSetSize@12 SetStdHandle@8 @@ -598,10 +619,13 @@ SystemTimeToFileTime@8 SystemTimeToTzSpecificLocalTime@12 TerminateProcess@8 TerminateThread@8 +Thread32First@8 +Thread32Next@8 TlsAlloc@0 TlsFree@4 TlsGetValue@4 TlsSetValue@8 +Toolhelp32ReadProcessMemory@20 TransactNamedPipe@28 TransmitCommChar@8 TrimVirtualBuffer@4 diff --git a/lib/kernel32/kernel32.edf b/lib/kernel32/kernel32.edf index b0b69ba..f1b0355 100644 --- a/lib/kernel32/kernel32.edf +++ b/lib/kernel32/kernel32.edf @@ -40,6 +40,7 @@ AddConsoleAliasA=AddConsoleAliasA@12 AddConsoleAliasW=AddConsoleAliasW@12 AllocConsole=AllocConsole@0 AreFileApisANSI=AreFileApisANSI@0 +AttachConsole=AttachConsole@4 BackupRead=BackupRead@28 BackupSeek=BackupSeek@24 BackupWrite=BackupWrite@28 @@ -53,6 +54,7 @@ BuildCommDCBAndTimeoutsW=BuildCommDCBAndTimeoutsW@12 BuildCommDCBW=BuildCommDCBW@8 CallNamedPipeA=CallNamedPipeA@28 CallNamedPipeW=CallNamedPipeW@28 +CancelIo=CancelIo@4 CancelWaitableTimer=CancelWaitableTimer@4 ClearCommBreak=ClearCommBreak@4 ClearCommError=ClearCommError@12 @@ -101,6 +103,7 @@ CreateSemaphoreA=CreateSemaphoreA@16 CreateSemaphoreW=CreateSemaphoreW@16 CreateTapePartition=CreateTapePartition@16 CreateThread=CreateThread@24 +CreateToolhelp32Snapshot=CreateToolhelp32Snapshot@8 CreateVirtualBuffer=CreateVirtualBuffer@12 CreateWaitableTimerA=CreateWaitableTimerA@12 CreateWaitableTimerW=CreateWaitableTimerW@12 @@ -230,7 +233,9 @@ GetConsoleHardwareState=GetConsoleHardwareState@12 GetConsoleInputWaitHandle=GetConsoleInputWaitHandle@0 GetConsoleMode=GetConsoleMode@8 GetConsoleOutputCP=GetConsoleOutputCP@0 +GetConsoleProcessList=GetConsoleProcessList@8 GetConsoleScreenBufferInfo=GetConsoleScreenBufferInfo@8 +GetConsoleSelectionInfo=GetConsoleSelectionInfo@4 GetConsoleTitleA=GetConsoleTitleA@8 GetConsoleTitleW=GetConsoleTitleW@8 GetCurrencyFormatA=GetCurrencyFormatA@24 @@ -263,6 +268,8 @@ GetExitCodeThread=GetExitCodeThread@8 GetFiberData=GetFiberData@0 GetFileAttributesA=GetFileAttributesA@4 GetFileAttributesW=GetFileAttributesW@4 +GetFileAttributesExA=GetFileAttributesExA@12 +GetFileAttributesExW=GetFileAttributesExW@12 GetFileInformationByHandle=GetFileInformationByHandle@8 GetFileSize=GetFileSize@8 GetFileTime=GetFileTime@16 @@ -386,6 +393,10 @@ GlobalUnWire=GlobalUnWire@4 GlobalUnfix=GlobalUnfix@4 GlobalUnlock=GlobalUnlock@4 GlobalWire=GlobalWire@4 +Heap32First=Heap32First@12 +Heap32ListFirst=Heap32ListFirst@8 +Heap32ListNext=Heap32ListNext@8 +Heap32Next=Heap32Next@4 HeapAlloc=NTDLL.RtlAllocateHeap HeapCompact=HeapCompact@8 HeapCreate=HeapCreate@12 @@ -448,10 +459,16 @@ LockFileEx=LockFileEx@24 LockResource=LockResource@4 MapViewOfFile=MapViewOfFile@20 MapViewOfFileEx=MapViewOfFileEx@24 +Module32First=Module32First@8 +Module32FirstW=Module32FirstW@8 +Module32Next=Module32Next@8 +Module32NextW=Module32NextW@8 MoveFileA=MoveFileA@8 MoveFileExA=MoveFileExA@12 +MoveFileWithProgressA=MoveFileWithProgressA@20 MoveFileExW=MoveFileExW@12 MoveFileW=MoveFileW@8 +MoveFileWithProgressW=MoveFileWithProgressW@20 MulDiv=MulDiv@12 MultiByteToWideChar=MultiByteToWideChar@24 OpenConsoleW=OpenConsoleW@16 @@ -476,6 +493,10 @@ PeekNamedPipe=PeekNamedPipe@24 PostQueuedCompletionStatus=PostQueuedCompletionStatus@16 PrepareTape=PrepareTape@12 ProcessIdToSessionId=ProcessIdToSessionId@8 +Process32First=Process32First@8 +Process32FirstW=Process32FirstW@8 +Process32Next=Process32Next@8 +Process32NextW=Process32NextW@8 PulseEvent=PulseEvent@4 PurgeComm=PurgeComm@8 QueryDosDeviceA=QueryDosDeviceA@12 @@ -570,6 +591,7 @@ SetLocaleInfoW=SetLocaleInfoW@12 SetMailslotInfo=SetMailslotInfo@8 SetNamedPipeHandleState=SetNamedPipeHandleState@16 SetPriorityClass=SetPriorityClass@8 +SetProcessAffinityMask=SetProcessAffinityMask@8 SetProcessShutdownParameters=SetProcessShutdownParameters@8 SetProcessWorkingSetSize=SetProcessWorkingSetSize@12 SetStdHandle=SetStdHandle@8 @@ -602,10 +624,13 @@ SystemTimeToFileTime=SystemTimeToFileTime@8 SystemTimeToTzSpecificLocalTime=SystemTimeToTzSpecificLocalTime@12 TerminateProcess=TerminateProcess@8 TerminateThread=TerminateThread@8 +Thread32First=Thread32First@8 +Thread32Next=Thread32Next@8 TlsAlloc=TlsAlloc@0 TlsFree=TlsFree@4 TlsGetValue=TlsGetValue@4 TlsSetValue=TlsSetValue@8 +Toolhelp32ReadProcessMemory=Toolhelp32ReadProcessMemory@20 TransactNamedPipe=TransactNamedPipe@28 TransmitCommChar=TransmitCommChar@8 TrimVirtualBuffer=TrimVirtualBuffer@4 diff --git a/lib/kernel32/kernel32.mc b/lib/kernel32/kernel32.mc new file mode 100644 index 0000000..68ea166 --- /dev/null +++ b/lib/kernel32/kernel32.mc @@ -0,0 +1,5358 @@ +; +; kernel32.mc MESSAGE resources for kernel32.dll +; + +MessageIdTypedef=ULONG + +SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS + Informational=0x1:STATUS_SEVERITY_INFORMATIONAL + Warning=0x2:STATUS_SEVERITY_WARNING + Error=0x3:STATUS_SEVERITY_ERROR + ) + +FacilityNames=(System=0x0:FACILITY_SYSTEM + Runtime=0x2:FACILITY_RUNTIME + Stubs=0x3:FACILITY_STUBS + Io=0x4:FACILITY_IO_ERROR_CODE + ) + +LanguageNames=(English=0x409:MSG00409) + +; +; message definitions +; + +MessageId=0x00 +Severity=Success +Facility=System +SymbolicName=ERROR_SUCCESS +Language=English +ERROR_SUCCESS - The operation completed successfully. +. + +MessageId=0x01 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FUNCTION +Language=English +ERROR_INVALID_FUNCTION - Incorrect function. +. + +MessageId=0x02 +Severity=Success +Facility=System +SymbolicName=ERROR_FILE_NOT_FOUND +Language=English +ERROR_FILE_NOT_FOUND - The system cannot find the file specified. +. + +MessageId=0x03 +Severity=Success +Facility=System +SymbolicName=ERROR_PATH_NOT_FOUND +Language=English +ERROR_PATH_NOT_FOUND - The system cannot find the path specified. +. + +MessageId=0x04 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_OPEN_FILES +Language=English +ERROR_TOO_MANY_OPEN_FILES - The system cannot open the file. +. + +MessageId=0x05 +Severity=Success +Facility=System +SymbolicName=ERROR_ACCESS_DENIED +Language=English +ERROR_ACCESS_DENIED - Access is denied. +. + +MessageId=0x06 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_HANDLE +Language=English +ERROR_INVALID_HANDLE - The handle is invalid. +. + +MessageId=0x07 +Severity=Success +Facility=System +SymbolicName=ERROR_ARENA_TRASHED +Language=English +ERROR_ARENA_TRASHED - The storage control blocks were destroyed. +. + +MessageId=0x08 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_ENOUGH_MEMORY +Language=English +ERROR_NOT_ENOUGH_MEMORY - Not enough storage is available to process this command. +. + +MessageId=0x09 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_BLOCK +Language=English +ERROR_INVALID_BLOCK - The storage control block address is invalid. +. + +MessageId=0x0A +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_ENVIRONMENT +Language=English +ERROR_BAD_ENVIRONMENT - The environment is incorrect. +. + +MessageId=0x0B +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_FORMAT +Language=English +ERROR_BAD_FORMAT - An attempt was made to load a program with an incorrect format. +. + +MessageId=0x0C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ACCESS +Language=English +ERROR_INVALID_ACCESS - The access code is invalid. +. + +MessageId=0x0D +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DATA +Language=English +ERROR_INVALID_DATA - The data is invalid. +. + +MessageId=0x0E +Severity=Success +Facility=System +SymbolicName=ERROR_OUTOFMEMORY +Language=English +ERROR_OUTOFMEMORY - Not enough storage is available to complete this operation. +. + +MessageId=0x0F +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DRIVE +Language=English +ERROR_INVALID_DRIVE - The system cannot find the drive specified. +. + +MessageId=0x10 +Severity=Success +Facility=System +SymbolicName=ERROR_CURRENT_DIRECTORY +Language=English +ERROR_CURRENT_DIRECTORY - The directory cannot be removed. +. + +MessageId=0x11 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_SAME_DEVICE +Language=English +ERROR_NOT_SAME_DEVICE - The system cannot move the file to a different disk drive. +. + +MessageId=0x12 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_MORE_FILES +Language=English +ERROR_NO_MORE_FILES - There are no more files. +. + +MessageId=0x13 +Severity=Success +Facility=System +SymbolicName=ERROR_WRITE_PROTECT +Language=English +ERROR_WRITE_PROTECT - The media is write protected. +. + +MessageId=0x14 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_UNIT +Language=English +ERROR_BAD_UNIT - The system cannot find the device specified. +. + +MessageId=0x15 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_READY +Language=English +ERROR_NOT_READY - The device is not ready. +. + +MessageId=0x16 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_COMMAND +Language=English +ERROR_BAD_COMMAND - The device does not recognize the command. +. + +MessageId=0x17 +Severity=Success +Facility=System +SymbolicName=ERROR_CRC +Language=English +ERROR_CRC - Data error (cyclic redundancy check). +. + +MessageId=0x18 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_LENGTH +Language=English +ERROR_BAD_LENGTH - The program issued a command but the command length is incorrect. +. + +MessageId=0x19 +Severity=Success +Facility=System +SymbolicName=ERROR_SEEK +Language=English +ERROR_SEEK - The drive cannot locate a specific area or track on the disk. +. + +MessageId=0x1A +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_DOS_DISK +Language=English +ERROR_NOT_DOS_DISK - The specified disk or diskette cannot be accessed. +. + +MessageId=0x1B +Severity=Success +Facility=System +SymbolicName=ERROR_SECTOR_NOT_FOUND +Language=English +ERROR_SECTOR_NOT_FOUND - The drive cannot find the sector requested. +. + +MessageId=0x1C +Severity=Success +Facility=System +SymbolicName=ERROR_OUT_OF_PAPER +Language=English +ERROR_OUT_OF_PAPER - The printer is out of paper. +. + +MessageId=0x1D +Severity=Success +Facility=System +SymbolicName=ERROR_WRITE_FAULT +Language=English +ERROR_WRITE_FAULT - The system cannot write to the specified device. +. + +MessageId=0x1E +Severity=Success +Facility=System +SymbolicName=ERROR_READ_FAULT +Language=English +ERROR_READ_FAULT - The system cannot read from the specified device. +. + +MessageId=0x1F +Severity=Success +Facility=System +SymbolicName=ERROR_GEN_FAILURE +Language=English +ERROR_GEN_FAILURE - A device attached to the system is not functioning. +. + +MessageId=0x20 +Severity=Success +Facility=System +SymbolicName=ERROR_SHARING_VIOLATION +Language=English +ERROR_SHARING_VIOLATION - The process cannot access the file because it is being used by another process. +. + +MessageId=0x21 +Severity=Success +Facility=System +SymbolicName=ERROR_LOCK_VIOLATION +Language=English +ERROR_LOCK_VIOLATION - The process cannot access the file because another process has locked a portion of the file. +. + +MessageId=0x22 +Severity=Success +Facility=System +SymbolicName=ERROR_WRONG_DISK +Language=English +ERROR_WRONG_DISK +. + +MessageId=0x24 +Severity=Success +Facility=System +SymbolicName=ERROR_SHARING_BUFFER_EXCEEDED +Language=English +ERROR_SHARING_BUFFER_EXCEEDED +. + +MessageId=0x26 +Severity=Success +Facility=System +SymbolicName=ERROR_HANDLE_EOF +Language=English +ERROR_HANDLE_EOF - Too many files opened for sharing. +. + +MessageId=0x27 +Severity=Success +Facility=System +SymbolicName=ERROR_HANDLE_DISK_FULL +Language=English +ERROR_HANDLE_DISK_FULL +. + +MessageId=0x32 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_SUPPORTED +Language=English +ERROR_NOT_SUPPORTED - Reached the end of the file. +. + +MessageId=0x33 +Severity=Success +Facility=System +SymbolicName=ERROR_REM_NOT_LIST +Language=English +ERROR_REM_NOT_LIST - The disk is full. +. + +MessageId=0x34 +Severity=Success +Facility=System +SymbolicName=ERROR_DUP_NAME +Language=English +ERROR_DUP_NAME +. + +MessageId=0x35 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_NETPATH +Language=English +ERROR_BAD_NETPATH +. + +MessageId=0x36 +Severity=Success +Facility=System +SymbolicName=ERROR_NETWORK_BUSY +Language=English +ERROR_NETWORK_BUSY +. + +MessageId=0x37 +Severity=Success +Facility=System +SymbolicName=ERROR_DEV_NOT_EXIST +Language=English +ERROR_DEV_NOT_EXIST +. + +MessageId=0x38 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_CMDS +Language=English +ERROR_TOO_MANY_CMDS +. + +MessageId=0x39 +Severity=Success +Facility=System +SymbolicName=ERROR_ADAP_HDW_ERR +Language=English +ERROR_ADAP_HDW_ERR +. + +MessageId=0x3A +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_NET_RESP +Language=English +ERROR_BAD_NET_RESP +. + +MessageId=0x3B +Severity=Success +Facility=System +SymbolicName=ERROR_UNEXP_NET_ERR +Language=English +ERROR_UNEXP_NET_ERR +. + +MessageId=0x3C +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_REM_ADAP +Language=English +ERROR_BAD_REM_ADAP +. + +MessageId=0x3D +Severity=Success +Facility=System +SymbolicName=ERROR_PRINTQ_FULL +Language=English +ERROR_PRINTQ_FULL +. + +MessageId=0x3E +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SPOOL_SPACE +Language=English +ERROR_NO_SPOOL_SPACE - The network request is not supported. +. + +MessageId=0x3F +Severity=Success +Facility=System +SymbolicName=ERROR_PRINT_CANCELLED +Language=English +ERROR_PRINT_CANCELLED - The remote computer is not available. +. + +MessageId=0x40 +Severity=Success +Facility=System +SymbolicName=ERROR_NETNAME_DELETED +Language=English +ERROR_NETNAME_DELETED - A duplicate name exists on the network. +. + +MessageId=0x41 +Severity=Success +Facility=System +SymbolicName=ERROR_NETWORK_ACCESS_DENIED +Language=English +ERROR_NETWORK_ACCESS_DENIED - The network path was not found. +. + +MessageId=0x42 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_DEV_TYPE +Language=English +ERROR_BAD_DEV_TYPE - The network is busy. +. + +MessageId=0x43 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_NET_NAME +Language=English +ERROR_BAD_NET_NAME - The specified network resource or device is no longer available. +. + +MessageId=0x44 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_NAMES +Language=English +ERROR_TOO_MANY_NAMES - The network BIOS command limit has been reached. +. + +MessageId=0x45 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_SESS +Language=English +ERROR_TOO_MANY_SESS - A network adapter hardware error occurred. +. + +MessageId=0x46 +Severity=Success +Facility=System +SymbolicName=ERROR_SHARING_PAUSED +Language=English +ERROR_SHARING_PAUSED - The specified server cannot perform the requested operation. +. + +MessageId=0x47 +Severity=Success +Facility=System +SymbolicName=ERROR_REQ_NOT_ACCEP +Language=English +ERROR_REQ_NOT_ACCEP - An unexpected network error occurred. +. + +MessageId=0x48 +Severity=Success +Facility=System +SymbolicName=ERROR_REDIR_PAUSED +Language=English +ERROR_REDIR_PAUSED - The remote adapter is not compatible. +. + +MessageId=0x50 +Severity=Success +Facility=System +SymbolicName=ERROR_FILE_EXISTS +Language=English +ERROR_FILE_EXISTS - The printer queue is full. +. + +MessageId=0x52 +Severity=Success +Facility=System +SymbolicName=ERROR_CANNOT_MAKE +Language=English +ERROR_CANNOT_MAKE - Space to store the file waiting to be printed is not available on the server. +. + +MessageId=0x53 +Severity=Success +Facility=System +SymbolicName=ERROR_FAIL_I24 +Language=English +ERROR_FAIL_I24 - Your file waiting to be printed was deleted. +. + +MessageId=0x54 +Severity=Success +Facility=System +SymbolicName=ERROR_OUT_OF_STRUCTURES +Language=English +ERROR_OUT_OF_STRUCTURES - The specified network name is no longer available. +. + +MessageId=0x55 +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_ASSIGNED +Language=English +ERROR_ALREADY_ASSIGNED - Network access is denied. +. + +MessageId=0x56 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PASSWORD +Language=English +ERROR_INVALID_PASSWORD - The network resource type is not correct. +. + +MessageId=0x57 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PARAMETER +Language=English +ERROR_INVALID_PARAMETER - The network name cannot be found. +. + +MessageId=0x58 +Severity=Success +Facility=System +SymbolicName=ERROR_NET_WRITE_FAULT +Language=English +ERROR_NET_WRITE_FAULT - The name limit for the local computer network adapter card was exceeded. +. + +MessageId=0x59 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_PROC_SLOTS +Language=English +ERROR_NO_PROC_SLOTS - The network BIOS session limit was exceeded. +. + +MessageId=0x64 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_SEMAPHORES +Language=English +ERROR_TOO_MANY_SEMAPHORES - The remote server has been paused or is in the process of being started. +. + +MessageId=0x65 +Severity=Success +Facility=System +SymbolicName=ERROR_EXCL_SEM_ALREADY_OWNED +Language=English +ERROR_EXCL_SEM_ALREADY_OWNED - No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept. +. + +MessageId=0x66 +Severity=Success +Facility=System +SymbolicName=ERROR_SEM_IS_SET +Language=English +ERROR_SEM_IS_SET - The specified printer or disk device has been paused. +. + +MessageId=0x67 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_SEM_REQUESTS +Language=English +ERROR_TOO_MANY_SEM_REQUESTS +. + +MessageId=0x68 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_AT_INTERRUPT_TIME +Language=English +ERROR_INVALID_AT_INTERRUPT_TIME +. + +MessageId=0x69 +Severity=Success +Facility=System +SymbolicName=ERROR_SEM_OWNER_DIED +Language=English +ERROR_SEM_OWNER_DIED +. + +MessageId=0x6A +Severity=Success +Facility=System +SymbolicName=ERROR_SEM_USER_LIMIT +Language=English +ERROR_SEM_USER_LIMIT +. + +MessageId=0x6B +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_CHANGE +Language=English +ERROR_DISK_CHANGE +. + +MessageId=0x6C +Severity=Success +Facility=System +SymbolicName=ERROR_DRIVE_LOCKED +Language=English +ERROR_DRIVE_LOCKED +. + +MessageId=0x6D +Severity=Success +Facility=System +SymbolicName=ERROR_BROKEN_PIPE +Language=English +ERROR_BROKEN_PIPE +. + +MessageId=0x6E +Severity=Success +Facility=System +SymbolicName=ERROR_OPEN_FAILED +Language=English +ERROR_OPEN_FAILED - The file exists. +. + +MessageId=0x6F +Severity=Success +Facility=System +SymbolicName=ERROR_BUFFER_OVERFLOW +Language=English +ERROR_BUFFER_OVERFLOW +. + +MessageId=0x70 +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_FULL +Language=English +ERROR_DISK_FULL - The directory or file cannot be created. +. + +MessageId=0x71 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_MORE_SEARCH_HANDLES +Language=English +ERROR_NO_MORE_SEARCH_HANDLES - Fail on INT 24. +. + +MessageId=0x72 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_TARGET_HANDLE +Language=English +ERROR_INVALID_TARGET_HANDLE - Storage to process this request is not available. +. + +MessageId=0x75 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_CATEGORY +Language=English +ERROR_INVALID_CATEGORY - The local device name is already in use. +. + +MessageId=0x76 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_VERIFY_SWITCH +Language=English +ERROR_INVALID_VERIFY_SWITCH - The specified network password is not correct. +. + +MessageId=0x77 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_DRIVER_LEVEL +Language=English +ERROR_BAD_DRIVER_LEVEL - The parameter is incorrect. +. + +MessageId=0x78 +Severity=Success +Facility=System +SymbolicName=ERROR_CALL_NOT_IMPLEMENTED +Language=English +ERROR_CALL_NOT_IMPLEMENTED - A write fault occurred on the network. +. + +MessageId=0x79 +Severity=Success +Facility=System +SymbolicName=ERROR_SEM_TIMEOUT +Language=English +ERROR_SEM_TIMEOUT - The system cannot start another process at this time. +. + +MessageId=0x7A +Severity=Success +Facility=System +SymbolicName=ERROR_INSUFFICIENT_BUFFER +Language=English +ERROR_INSUFFICIENT_BUFFER +. + +MessageId=0x7B +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_NAME +Language=English +ERROR_INVALID_NAME +. + +MessageId=0x7C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_LEVEL +Language=English +ERROR_INVALID_LEVEL +. + +MessageId=0x7D +Severity=Success +Facility=System +SymbolicName=ERROR_NO_VOLUME_LABEL +Language=English +ERROR_NO_VOLUME_LABEL +. + +MessageId=0x7E +Severity=Success +Facility=System +SymbolicName=ERROR_MOD_NOT_FOUND +Language=English +ERROR_MOD_NOT_FOUND +. + +MessageId=0x7F +Severity=Success +Facility=System +SymbolicName=ERROR_PROC_NOT_FOUND +Language=English +ERROR_PROC_NOT_FOUND +. + +MessageId=0x80 +Severity=Success +Facility=System +SymbolicName=ERROR_WAIT_NO_CHILDREN +Language=English +ERROR_WAIT_NO_CHILDREN +. + +MessageId=0x81 +Severity=Success +Facility=System +SymbolicName=ERROR_CHILD_NOT_COMPLETE +Language=English +ERROR_CHILD_NOT_COMPLETE +. + +MessageId=0x82 +Severity=Success +Facility=System +SymbolicName=ERROR_DIRECT_ACCESS_HANDLE +Language=English +ERROR_DIRECT_ACCESS_HANDLE +. + +MessageId=0x83 +Severity=Success +Facility=System +SymbolicName=ERROR_NEGATIVE_SEEK +Language=English +ERROR_NEGATIVE_SEEK +. + +MessageId=0x84 +Severity=Success +Facility=System +SymbolicName=ERROR_SEEK_ON_DEVICE +Language=English +ERROR_SEEK_ON_DEVICE - Cannot create another system semaphore. +. + +MessageId=0x85 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_JOIN_TARGET +Language=English +ERROR_IS_JOIN_TARGET - The exclusive semaphore is owned by another process. +. + +MessageId=0x86 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_JOINED +Language=English +ERROR_IS_JOINED - The semaphore is set and cannot be closed. +. + +MessageId=0x87 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_SUBSTED +Language=English +ERROR_IS_SUBSTED - The semaphore cannot be set again. +. + +MessageId=0x88 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_JOINED +Language=English +ERROR_NOT_JOINED - Cannot request exclusive semaphores at interrupt time. +. + +MessageId=0x89 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_SUBSTED +Language=English +ERROR_NOT_SUBSTED - The previous ownership of this semaphore has ended. +. + +MessageId=0x8A +Severity=Success +Facility=System +SymbolicName=ERROR_JOIN_TO_JOIN +Language=English +ERROR_JOIN_TO_JOIN +. + +MessageId=0x8B +Severity=Success +Facility=System +SymbolicName=ERROR_SUBST_TO_SUBST +Language=English +ERROR_SUBST_TO_SUBST - The program stopped because an alternate diskette was not inserted. +. + +MessageId=0x8C +Severity=Success +Facility=System +SymbolicName=ERROR_JOIN_TO_SUBST +Language=English +ERROR_JOIN_TO_SUBST - The disk is in use or locked by +another process. +. + +MessageId=0x8D +Severity=Success +Facility=System +SymbolicName=ERROR_SUBST_TO_JOIN +Language=English +ERROR_SUBST_TO_JOIN - The pipe has been ended. +. + +MessageId=0x8E +Severity=Success +Facility=System +SymbolicName=ERROR_BUSY_DRIVE +Language=English +ERROR_BUSY_DRIVE - The system cannot open the +device or file specified. +. + +MessageId=0x8F +Severity=Success +Facility=System +SymbolicName=ERROR_SAME_DRIVE +Language=English +ERROR_SAME_DRIVE - The file name is too long. +. + +MessageId=0x90 +Severity=Success +Facility=System +SymbolicName=ERROR_DIR_NOT_ROOT +Language=English +ERROR_DIR_NOT_ROOT - There is not enough space on the disk. +. + +MessageId=0x91 +Severity=Success +Facility=System +SymbolicName=ERROR_DIR_NOT_EMPTY +Language=English +ERROR_DIR_NOT_EMPTY - No more internal file identifiers available. +. + +MessageId=0x92 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_SUBST_PATH +Language=English +ERROR_IS_SUBST_PATH - The target internal file identifier is incorrect. +. + +MessageId=0x93 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_JOIN_PATH +Language=English +ERROR_IS_JOIN_PATH +. + +MessageId=0x94 +Severity=Success +Facility=System +SymbolicName=ERROR_PATH_BUSY +Language=English +ERROR_PATH_BUSY +. + +MessageId=0x95 +Severity=Success +Facility=System +SymbolicName=ERROR_IS_SUBST_TARGET +Language=English +ERROR_IS_SUBST_TARGET - The IOCTL call made by the application program is not correct. +. + +MessageId=0x96 +Severity=Success +Facility=System +SymbolicName=ERROR_SYSTEM_TRACE +Language=English +ERROR_SYSTEM_TRACE - The verify-on-write switch parameter value is not correct. +. + +MessageId=0x97 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EVENT_COUNT +Language=English +ERROR_INVALID_EVENT_COUNT - The system does not support the command requested. +. + +MessageId=0x98 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_MUXWAITERS +Language=English +ERROR_TOO_MANY_MUXWAITERS - This function is not supported on this system. +. + +MessageId=0x99 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_LIST_FORMAT +Language=English +ERROR_INVALID_LIST_FORMAT - The semaphore timeout period has expired. +. + +MessageId=0x9A +Severity=Success +Facility=System +SymbolicName=ERROR_LABEL_TOO_LONG +Language=English +ERROR_LABEL_TOO_LONG - The data area passed to a system call is too small. +. + +MessageId=0x9B +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_TCBS +Language=English +ERROR_TOO_MANY_TCBS - The filename, directory name, or volume label syntax is incorrect. +. + +MessageId=0x9C +Severity=Success +Facility=System +SymbolicName=ERROR_SIGNAL_REFUSED +Language=English +ERROR_SIGNAL_REFUSED - The system call level is not correct. +. + +MessageId=0x9D +Severity=Success +Facility=System +SymbolicName=ERROR_DISCARDED +Language=English +ERROR_DISCARDED - The disk has no volume label. +. + +MessageId=0x9E +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_LOCKED +Language=English +ERROR_NOT_LOCKED - The specified module could not be found. +. + +MessageId=0x9F +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_THREADID_ADDR +Language=English +ERROR_BAD_THREADID_ADDR - The specified procedure could not be found. +. + +MessageId=0xA0 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_ARGUMENTS +Language=English +ERROR_BAD_ARGUMENTS - There are no child processes to wait for. +. + +MessageId=0xA1 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_PATHNAME +Language=English +ERROR_BAD_PATHNAME +. + +MessageId=0xA2 +Severity=Success +Facility=System +SymbolicName=ERROR_SIGNAL_PENDING +Language=English +ERROR_SIGNAL_PENDING - Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. +. + +MessageId=0xA4 +Severity=Success +Facility=System +SymbolicName=ERROR_MAX_THRDS_REACHED +Language=English +ERROR_MAX_THRDS_REACHED - An attempt was made to move the file pointer before the beginning of the file. +. + +MessageId=0xA7 +Severity=Success +Facility=System +SymbolicName=ERROR_LOCK_FAILED +Language=English +ERROR_LOCK_FAILED - The file pointer cannot be set on the specified device or file. +. + +MessageId=0xAA +Severity=Success +Facility=System +SymbolicName=ERROR_BUSY +Language=English +ERROR_BUSY - A JOIN or SUBST command cannot be used for a drive that contains previously joined drives. +. + +MessageId=0xAD +Severity=Success +Facility=System +SymbolicName=ERROR_CANCEL_VIOLATION +Language=English +ERROR_CANCEL_VIOLATION - An attempt was made to use a JOIN or SUBST command on a drive that has already been joined. +. + +MessageId=0xAE +Severity=Success +Facility=System +SymbolicName=ERROR_ATOMIC_LOCKS_NOT_SUPPORTED +Language=English +ERROR_ATOMIC_LOCKS_NOT_SUPPORTED - An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted. +. + +MessageId=0xB4 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SEGMENT_NUMBER +Language=English +ERROR_INVALID_SEGMENT_NUMBER - The system tried to delete the JOIN of a drive that is not joined. +. + +MessageId=0xB6 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ORDINAL +Language=English +ERROR_INVALID_ORDINAL - The system tried to delete the substitution of a drive that is not substituted. +. + +MessageId=0xB7 +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_EXISTS +Language=English +ERROR_ALREADY_EXISTS - The system tried to join a drive to a directory on a joined drive. +. + +MessageId=0xBA +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FLAG_NUMBER +Language=English +ERROR_INVALID_FLAG_NUMBER - The system tried to substitute a drive to a directory on a substituted drive. +. + +MessageId=0xBB +Severity=Success +Facility=System +SymbolicName=ERROR_SEM_NOT_FOUND +Language=English +ERROR_SEM_NOT_FOUND - The system tried to join a drive to a directory on a substituted drive. +. + +MessageId=0xBC +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_STARTING_CODESEG +Language=English +ERROR_INVALID_STARTING_CODESEG - The system tried to SUBST a drive to a directory on a joined drive. +. + +MessageId=0xBD +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_STACKSEG +Language=English +ERROR_INVALID_STACKSEG - The system cannot perform a JOIN or SUBST at this time. +. + +MessageId=0xBE +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MODULETYPE +Language=English +ERROR_INVALID_MODULETYPE - The system cannot join or substitute a drive to or for a directory on the same drive. +. + +MessageId=0xBF +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EXE_SIGNATURE +Language=English +ERROR_INVALID_EXE_SIGNATURE - The directory is not a subdirectory of the root directory. +. + +MessageId=0xC0 +Severity=Success +Facility=System +SymbolicName=ERROR_EXE_MARKED_INVALID +Language=English +ERROR_EXE_MARKED_INVALID - The directory is not empty. +. + +MessageId=0xC1 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_EXE_FORMAT +Language=English +ERROR_BAD_EXE_FORMAT - The path specified is being used in a substitute. +. + +MessageId=0xC2 +Severity=Success +Facility=System +SymbolicName=ERROR_ITERATED_DATA_EXCEEDS_64k +Language=English +ERROR_ITERATED_DATA_EXCEEDS_64k - Not enough resources are available to process this command. +. + +MessageId=0xC3 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MINALLOCSIZE +Language=English +ERROR_INVALID_MINALLOCSIZE - The path specified cannot be used at this time. +. + +MessageId=0xC4 +Severity=Success +Facility=System +SymbolicName=ERROR_DYNLINK_FROM_INVALID_RING +Language=English +ERROR_DYNLINK_FROM_INVALID_RING - An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute. +. + +MessageId=0xC5 +Severity=Success +Facility=System +SymbolicName=ERROR_IOPL_NOT_ENABLED +Language=English +ERROR_IOPL_NOT_ENABLED - System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. +. + +MessageId=0xC6 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SEGDPL +Language=English +ERROR_INVALID_SEGDPL - The number of specified semaphore events for DosMuxSemWait is not correct. +. + +MessageId=0xC7 +Severity=Success +Facility=System +SymbolicName=ERROR_AUTODATASEG_EXCEEDS_64k +Language=English +ERROR_AUTODATASEG_EXCEEDS_64k - DosMuxSemWait did not execute; too many semaphores are already set. +. + +MessageId=0xC8 +Severity=Success +Facility=System +SymbolicName=ERROR_RING2SEG_MUST_BE_MOVABLE +Language=English +ERROR_RING2SEG_MUST_BE_MOVABLE - The DosMuxSemWait list is not correct. +. + +MessageId=0xC9 +Severity=Success +Facility=System +SymbolicName=ERROR_RELOC_CHAIN_XEEDS_SEGLIM +Language=English +ERROR_RELOC_CHAIN_XEEDS_SEGLIM - The volume label you entered exceeds the label character +limit of the target file system. +. + +MessageId=0xCA +Severity=Success +Facility=System +SymbolicName=ERROR_INFLOOP_IN_RELOC_CHAIN +Language=English +ERROR_INFLOOP_IN_RELOC_CHAIN - Cannot create another thread. +. + +MessageId=0xCB +Severity=Success +Facility=System +SymbolicName=ERROR_ENVVAR_NOT_FOUND +Language=English +ERROR_ENVVAR_NOT_FOUND - The recipient process has refused the signal. +. + +MessageId=0xCD +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SIGNAL_SENT +Language=English +ERROR_NO_SIGNAL_SENT - The segment is already discarded and cannot be locked. +. + +MessageId=0xCE +Severity=Success +Facility=System +SymbolicName=ERROR_FILENAME_EXCED_RANGE +Language=English +ERROR_FILENAME_EXCED_RANGE - The segment is already unlocked. +. + +MessageId=0xCF +Severity=Success +Facility=System +SymbolicName=ERROR_RING2_STACK_IN_USE +Language=English +ERROR_RING2_STACK_IN_USE - The address for the thread ID is not correct. +. + +MessageId=0xD0 +Severity=Success +Facility=System +SymbolicName=ERROR_META_EXPANSION_TOO_LONG +Language=English +ERROR_META_EXPANSION_TOO_LONG - The argument string passed to DosExecPgm is not correct. +. + +MessageId=0xD1 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SIGNAL_NUMBER +Language=English +ERROR_INVALID_SIGNAL_NUMBER - The specified path is invalid. +. + +MessageId=0xD2 +Severity=Success +Facility=System +SymbolicName=ERROR_THREAD_1_INACTIVE +Language=English +ERROR_THREAD_1_INACTIVE - A signal is already pending. +. + +MessageId=0xD4 +Severity=Success +Facility=System +SymbolicName=ERROR_LOCKED +Language=English +ERROR_LOCKED +. + +MessageId=0xD6 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_MODULES +Language=English +ERROR_TOO_MANY_MODULES - No more threads can be created in the system. +. + +MessageId=0xD7 +Severity=Success +Facility=System +SymbolicName=ERROR_NESTING_NOT_ALLOWED +Language=English +ERROR_NESTING_NOT_ALLOWED +. + +MessageId=0xE6 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_PIPE +Language=English +ERROR_BAD_PIPE +. + +MessageId=0xE7 +Severity=Success +Facility=System +SymbolicName=ERROR_PIPE_BUSY +Language=English +ERROR_PIPE_BUSY - Unable to lock a region of a file. +. + +MessageId=0xE8 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_DATA +Language=English +ERROR_NO_DATA +. + +MessageId=0xE9 +Severity=Success +Facility=System +SymbolicName=ERROR_PIPE_NOT_CONNECTED +Language=English +ERROR_PIPE_NOT_CONNECTED +. + +MessageId=0xEA +Severity=Success +Facility=System +SymbolicName=ERROR_MORE_DATA +Language=English +ERROR_MORE_DATA - The requested resource is in use. +. + +MessageId=0xF0 +Severity=Success +Facility=System +SymbolicName=ERROR_VC_DISCONNECTED +Language=English +ERROR_VC_DISCONNECTED +. + +MessageId=0xFE +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EA_NAME +Language=English +ERROR_INVALID_EA_NAME +. + +MessageId=0xFF +Severity=Success +Facility=System +SymbolicName=ERROR_EA_LIST_INCONSISTENT +Language=English +ERROR_EA_LIST_INCONSISTENT - A lock request was not outstanding for the supplied cancel region. +. + +MessageId=0x103 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_MORE_ITEMS +Language=English +ERROR_NO_MORE_ITEMS - The file system does not support atomic changes to the lock type. +. + +MessageId=0x10A +Severity=Success +Facility=System +SymbolicName=ERROR_CANNOT_COPY +Language=English +ERROR_CANNOT_COPY +. + +MessageId=0x10B +Severity=Success +Facility=System +SymbolicName=ERROR_DIRECTORY +Language=English +ERROR_DIRECTORY +. + +MessageId=0x113 +Severity=Success +Facility=System +SymbolicName=ERROR_EAS_DIDNT_FIT +Language=English +ERROR_EAS_DIDNT_FIT +. + +MessageId=0x114 +Severity=Success +Facility=System +SymbolicName=ERROR_EA_FILE_CORRUPT +Language=English +ERROR_EA_FILE_CORRUPT +. + +MessageId=0x115 +Severity=Success +Facility=System +SymbolicName=ERROR_EA_TABLE_FULL +Language=English +ERROR_EA_TABLE_FULL +. + +MessageId=0x116 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EA_HANDLE +Language=English +ERROR_INVALID_EA_HANDLE - The system detected a segment number that was not correct. +. + +MessageId=0x11A +Severity=Success +Facility=System +SymbolicName=ERROR_EAS_NOT_SUPPORTED +Language=English +ERROR_EAS_NOT_SUPPORTED +. + +MessageId=0x120 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_OWNER +Language=English +ERROR_NOT_OWNER +. + +MessageId=0x12A +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_POSTS +Language=English +ERROR_TOO_MANY_POSTS - Cannot create a file when that file already exists. +. + +MessageId=0x12B +Severity=Success +Facility=System +SymbolicName=ERROR_PARTIAL_COPY +Language=English +ERROR_PARTIAL_COPY +. + +MessageId=0x13D +Severity=Success +Facility=System +SymbolicName=ERROR_MR_MID_NOT_FOUND +Language=English +ERROR_MR_MID_NOT_FOUND +. + +MessageId=0x1E7 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ADDRESS +Language=English +ERROR_INVALID_ADDRESS - The flag passed is not correct. +. + +MessageId=0x216 +Severity=Success +Facility=System +SymbolicName=ERROR_ARITHMETIC_OVERFLOW +Language=English +ERROR_ARITHMETIC_OVERFLOW - The specified system semaphore name was not found. +. + +MessageId=0x217 +Severity=Success +Facility=System +SymbolicName=ERROR_PIPE_CONNECTED +Language=English +ERROR_PIPE_CONNECTED +. + +MessageId=0x218 +Severity=Success +Facility=System +SymbolicName=ERROR_PIPE_LISTENING +Language=English +ERROR_PIPE_LISTENING +. + +MessageId=0x3E2 +Severity=Success +Facility=System +SymbolicName=ERROR_EA_ACCESS_DENIED +Language=English +ERROR_EA_ACCESS_DENIED +. + +MessageId=0x3E3 +Severity=Success +Facility=System +SymbolicName=ERROR_OPERATION_ABORTED +Language=English +ERROR_OPERATION_ABORTED +. + +MessageId=0x3E4 +Severity=Success +Facility=System +SymbolicName=ERROR_IO_INCOMPLETE +Language=English +ERROR_IO_INCOMPLETE +. + +MessageId=0x3E5 +Severity=Success +Facility=System +SymbolicName=ERROR_IO_PENDING +Language=English +ERROR_IO_PENDING +. + +MessageId=0x3E6 +Severity=Success +Facility=System +SymbolicName=ERROR_NOACCESS +Language=English +ERROR_NOACCESS +. + +MessageId=0x3E7 +Severity=Success +Facility=System +SymbolicName=ERROR_SWAPERROR +Language=English +ERROR_SWAPERROR +. + +MessageId=0x3E9 +Severity=Success +Facility=System +SymbolicName=ERROR_STACK_OVERFLOW +Language=English +ERROR_STACK_OVERFLOW - The operating system cannot run this application program. +. + +MessageId=0x3EA +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MESSAGE +Language=English +ERROR_INVALID_MESSAGE - The operating system is not presently configured to run this application. +. + +MessageId=0x3EB +Severity=Success +Facility=System +SymbolicName=ERROR_CAN_NOT_COMPLETE +Language=English +ERROR_CAN_NOT_COMPLETE +. + +MessageId=0x3EC +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FLAGS +Language=English +ERROR_INVALID_FLAGS - The operating system cannot run this application program. +. + +MessageId=0x3ED +Severity=Success +Facility=System +SymbolicName=ERROR_UNRECOGNIZED_VOLUME +Language=English +ERROR_UNRECOGNIZED_VOLUME - The code segment cannot be greater than or equal to 64K. +. + +MessageId=0x3EE +Severity=Success +Facility=System +SymbolicName=ERROR_FILE_INVALID +Language=English +ERROR_FILE_INVALID +. + +MessageId=0x3EF +Severity=Success +Facility=System +SymbolicName=ERROR_FULLSCREEN_MODE +Language=English +ERROR_FULLSCREEN_MODE +. + +MessageId=0x3F0 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_TOKEN +Language=English +ERROR_NO_TOKEN - The system could not find the environment +option that was entered. +. + +MessageId=0x3F1 +Severity=Success +Facility=System +SymbolicName=ERROR_BADDB +Language=English +ERROR_BADDB +. + +MessageId=0x3F2 +Severity=Success +Facility=System +SymbolicName=ERROR_BADKEY +Language=English +ERROR_BADKEY - No process in the command subtree has a +signal handler. +. + +MessageId=0x3F3 +Severity=Success +Facility=System +SymbolicName=ERROR_CANTOPEN +Language=English +ERROR_CANTOPEN - The filename or extension is too long. +. + +MessageId=0x3F4 +Severity=Success +Facility=System +SymbolicName=ERROR_CANTREAD +Language=English +ERROR_CANTREAD - The ring 2 stack is in use. +. + +MessageId=0x3F5 +Severity=Success +Facility=System +SymbolicName=ERROR_CANTWRITE +Language=English +ERROR_CANTWRITE - The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified. +. + +MessageId=0x3F6 +Severity=Success +Facility=System +SymbolicName=ERROR_REGISTRY_RECOVERED +Language=English +ERROR_REGISTRY_RECOVERED - The signal being posted is not correct. +. + +MessageId=0x3F7 +Severity=Success +Facility=System +SymbolicName=ERROR_REGISTRY_CORRUPT +Language=English +ERROR_REGISTRY_CORRUPT - The signal handler cannot be set. +. + +MessageId=0x3F8 +Severity=Success +Facility=System +SymbolicName=ERROR_REGISTRY_IO_FAILED +Language=English +ERROR_REGISTRY_IO_FAILED +. + +MessageId=0x3F9 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_REGISTRY_FILE +Language=English +ERROR_NOT_REGISTRY_FILE - The segment is locked and cannot be reallocated. +. + +MessageId=0x3FA +Severity=Success +Facility=System +SymbolicName=ERROR_KEY_DELETED +Language=English +ERROR_KEY_DELETED +. + +MessageId=0x3FB +Severity=Success +Facility=System +SymbolicName=ERROR_NO_LOG_SPACE +Language=English +ERROR_NO_LOG_SPACE - Too many dynamic-link modules are attached to this program or dynamic-link module. +. + +MessageId=0x3FC +Severity=Success +Facility=System +SymbolicName=ERROR_KEY_HAS_CHILDREN +Language=English +ERROR_KEY_HAS_CHILDREN - Cannot nest calls to LoadModule. +. + +MessageId=0x3FD +Severity=Success +Facility=System +SymbolicName=ERROR_CHILD_MUST_BE_VOLATILE +Language=English +ERROR_CHILD_MUST_BE_VOLATILE +. + +MessageId=0x3FE +Severity=Success +Facility=System +SymbolicName=ERROR_NOTIFY_ENUM_DIR +Language=English +ERROR_NOTIFY_ENUM_DIR +. + +MessageId=0x41B +Severity=Success +Facility=System +SymbolicName=ERROR_DEPENDENT_SERVICES_RUNNING +Language=English +ERROR_DEPENDENT_SERVICES_RUNNING +. + +MessageId=0x41C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SERVICE_CONTROL +Language=English +ERROR_INVALID_SERVICE_CONTROL +. + +MessageId=0x41D +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_REQUEST_TIMEOUT +Language=English +ERROR_SERVICE_REQUEST_TIMEOUT +. + +MessageId=0x41E +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_NO_THREAD +Language=English +ERROR_SERVICE_NO_THREAD +. + +MessageId=0x41F +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_DATABASE_LOCKED +Language=English +ERROR_SERVICE_DATABASE_LOCKED +. + +MessageId=0x420 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_ALREADY_RUNNING +Language=English +ERROR_SERVICE_ALREADY_RUNNING +. + +MessageId=0x421 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SERVICE_ACCOUNT +Language=English +ERROR_INVALID_SERVICE_ACCOUNT +. + +MessageId=0x422 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_DISABLED +Language=English +ERROR_SERVICE_DISABLED +. + +MessageId=0x423 +Severity=Success +Facility=System +SymbolicName=ERROR_CIRCULAR_DEPENDENCY +Language=English +ERROR_CIRCULAR_DEPENDENCY +. + +MessageId=0x424 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_DOES_NOT_EXIST +Language=English +ERROR_SERVICE_DOES_NOT_EXIST +. + +MessageId=0x425 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_CANNOT_ACCEPT_CTRL +Language=English +ERROR_SERVICE_CANNOT_ACCEPT_CTRL +. + +MessageId=0x426 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_NOT_ACTIVE +Language=English +ERROR_SERVICE_NOT_ACTIVE +. + +MessageId=0x427 +Severity=Success +Facility=System +SymbolicName=ERROR_FAILED_SERVICE_CONTROLLER_CONNECT +Language=English +ERROR_FAILED_SERVICE_CONTROLLER_CONNECT - The pipe state is invalid. +. + +MessageId=0x428 +Severity=Success +Facility=System +SymbolicName=ERROR_EXCEPTION_IN_SERVICE +Language=English +ERROR_EXCEPTION_IN_SERVICE - All pipe instances are busy. +. + +MessageId=0x429 +Severity=Success +Facility=System +SymbolicName=ERROR_DATABASE_DOES_NOT_EXIST +Language=English +ERROR_DATABASE_DOES_NOT_EXIST - The pipe is being closed. +. + +MessageId=0x42A +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_SPECIFIC_ERROR +Language=English +ERROR_SERVICE_SPECIFIC_ERROR - No process is on the other end of the pipe. +. + +MessageId=0x42B +Severity=Success +Facility=System +SymbolicName=ERROR_PROCESS_ABORTED +Language=English +ERROR_PROCESS_ABORTED - More data is available. +. + +MessageId=0x42C +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_DEPENDENCY_FAIL +Language=English +ERROR_SERVICE_DEPENDENCY_FAIL +. + +MessageId=0x42D +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_LOGON_FAILED +Language=English +ERROR_SERVICE_LOGON_FAILED +. + +MessageId=0x42E +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_START_HANG +Language=English +ERROR_SERVICE_START_HANG +. + +MessageId=0x42F +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SERVICE_LOCK +Language=English +ERROR_INVALID_SERVICE_LOCK +. + +MessageId=0x430 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_MARKED_FOR_DELETE +Language=English +ERROR_SERVICE_MARKED_FOR_DELETE +. + +MessageId=0x431 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_EXISTS +Language=English +ERROR_SERVICE_EXISTS - The session was canceled. +. + +MessageId=0x432 +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_RUNNING_LKG +Language=English +ERROR_ALREADY_RUNNING_LKG +. + +MessageId=0x433 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_DEPENDENCY_DELETED +Language=English +ERROR_SERVICE_DEPENDENCY_DELETED +. + +MessageId=0x434 +Severity=Success +Facility=System +SymbolicName=ERROR_BOOT_ALREADY_ACCEPTED +Language=English +ERROR_BOOT_ALREADY_ACCEPTED +. + +MessageId=0x435 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_NEVER_STARTED +Language=English +ERROR_SERVICE_NEVER_STARTED +. + +MessageId=0x436 +Severity=Success +Facility=System +SymbolicName=ERROR_DUPLICATE_SERVICE_NAME +Language=English +ERROR_DUPLICATE_SERVICE_NAME +. + +MessageId=0x44C +Severity=Success +Facility=System +SymbolicName=ERROR_END_OF_MEDIA +Language=English +ERROR_END_OF_MEDIA +. + +MessageId=0x44D +Severity=Success +Facility=System +SymbolicName=ERROR_FILEMARK_DETECTED +Language=English +ERROR_FILEMARK_DETECTED +. + +MessageId=0x44E +Severity=Success +Facility=System +SymbolicName=ERROR_BEGINNING_OF_MEDIA +Language=English +ERROR_BEGINNING_OF_MEDIA +. + +MessageId=0x44F +Severity=Success +Facility=System +SymbolicName=ERROR_SETMARK_DETECTED +Language=English +ERROR_SETMARK_DETECTED +. + +MessageId=0x450 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_DATA_DETECTED +Language=English +ERROR_NO_DATA_DETECTED +. + +MessageId=0x451 +Severity=Success +Facility=System +SymbolicName=ERROR_PARTITION_FAILURE +Language=English +ERROR_PARTITION_FAILURE +. + +MessageId=0x452 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_BLOCK_LENGTH +Language=English +ERROR_INVALID_BLOCK_LENGTH +. + +MessageId=0x453 +Severity=Success +Facility=System +SymbolicName=ERROR_DEVICE_NOT_PARTITIONED +Language=English +ERROR_DEVICE_NOT_PARTITIONED +. + +MessageId=0x454 +Severity=Success +Facility=System +SymbolicName=ERROR_UNABLE_TO_LOCK_MEDIA +Language=English +ERROR_UNABLE_TO_LOCK_MEDIA - The specified extended attribute name was invalid. +. + +MessageId=0x455 +Severity=Success +Facility=System +SymbolicName=ERROR_UNABLE_TO_UNLOAD_MEDIA +Language=English +ERROR_UNABLE_TO_UNLOAD_MEDIA - The extended attributes are inconsistent. +. + +MessageId=0x456 +Severity=Success +Facility=System +SymbolicName=ERROR_MEDIA_CHANGED +Language=English +ERROR_MEDIA_CHANGED +. + +MessageId=0x457 +Severity=Success +Facility=System +SymbolicName=ERROR_BUS_RESET +Language=English +ERROR_BUS_RESET +. + +MessageId=0x458 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_MEDIA_IN_DRIVE +Language=English +ERROR_NO_MEDIA_IN_DRIVE - The wait operation timed out. +. + +MessageId=0x459 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_UNICODE_TRANSLATION +Language=English +ERROR_NO_UNICODE_TRANSLATION - No more data is available. +. + +MessageId=0x45A +Severity=Success +Facility=System +SymbolicName=ERROR_DLL_INIT_FAILED +Language=English +ERROR_DLL_INIT_FAILED +. + +MessageId=0x45B +Severity=Success +Facility=System +SymbolicName=ERROR_SHUTDOWN_IN_PROGRESS +Language=English +ERROR_SHUTDOWN_IN_PROGRESS +. + +MessageId=0x45C +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SHUTDOWN_IN_PROGRESS +Language=English +ERROR_NO_SHUTDOWN_IN_PROGRESS +. + +MessageId=0x45D +Severity=Success +Facility=System +SymbolicName=ERROR_IO_DEVICE +Language=English +ERROR_IO_DEVICE +. + +MessageId=0x45E +Severity=Success +Facility=System +SymbolicName=ERROR_SERIAL_NO_DEVICE +Language=English +ERROR_SERIAL_NO_DEVICE +. + +MessageId=0x45F +Severity=Success +Facility=System +SymbolicName=ERROR_IRQ_BUSY +Language=English +ERROR_IRQ_BUSY +. + +MessageId=0x460 +Severity=Success +Facility=System +SymbolicName=ERROR_MORE_WRITES +Language=English +ERROR_MORE_WRITES - The copy functions cannot be used. +. + +MessageId=0x461 +Severity=Success +Facility=System +SymbolicName=ERROR_COUNTER_TIMEOUT +Language=English +ERROR_COUNTER_TIMEOUT - The directory name is invalid. +. + +MessageId=0x462 +Severity=Success +Facility=System +SymbolicName=ERROR_FLOPPY_ID_MARK_NOT_FOUND +Language=English +ERROR_FLOPPY_ID_MARK_NOT_FOUND +. + +MessageId=0x463 +Severity=Success +Facility=System +SymbolicName=ERROR_FLOPPY_WRONG_CYLINDER +Language=English +ERROR_FLOPPY_WRONG_CYLINDER +. + +MessageId=0x464 +Severity=Success +Facility=System +SymbolicName=ERROR_FLOPPY_UNKNOWN_ERROR +Language=English +ERROR_FLOPPY_UNKNOWN_ERROR +. + +MessageId=0x465 +Severity=Success +Facility=System +SymbolicName=ERROR_FLOPPY_BAD_REGISTERS +Language=English +ERROR_FLOPPY_BAD_REGISTERS +. + +MessageId=0x466 +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_RECALIBRATE_FAILED +Language=English +ERROR_DISK_RECALIBRATE_FAILED +. + +MessageId=0x467 +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_OPERATION_FAILED +Language=English +ERROR_DISK_OPERATION_FAILED +. + +MessageId=0x468 +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_RESET_FAILED +Language=English +ERROR_DISK_RESET_FAILED +. + +MessageId=0x469 +Severity=Success +Facility=System +SymbolicName=ERROR_EOM_OVERFLOW +Language=English +ERROR_EOM_OVERFLOW - The extended attributes did not fit in the buffer. +. + +MessageId=0x46A +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_ENOUGH_SERVER_MEMORY +Language=English +ERROR_NOT_ENOUGH_SERVER_MEMORY - The extended attribute file on the mounted file system is corrupt. +. + +MessageId=0x46B +Severity=Success +Facility=System +SymbolicName=ERROR_POSSIBLE_DEADLOCK +Language=English +ERROR_POSSIBLE_DEADLOCK - The extended attribute table file is full. +. + +MessageId=0x46C +Severity=Success +Facility=System +SymbolicName=ERROR_MAPPED_ALIGNMENT +Language=English +ERROR_MAPPED_ALIGNMENT - The specified extended attribute handle is invalid. +. + +MessageId=0x474 +Severity=Success +Facility=System +SymbolicName=ERROR_SET_POWER_STATE_VETOED +Language=English +ERROR_SET_POWER_STATE_VETOED +. + +MessageId=0x475 +Severity=Success +Facility=System +SymbolicName=ERROR_SET_POWER_STATE_FAILED +Language=English +ERROR_SET_POWER_STATE_FAILED +. + +MessageId=0x476 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_LINKS +Language=English +ERROR_TOO_MANY_LINKS +. + +MessageId=0x47E +Severity=Success +Facility=System +SymbolicName=ERROR_OLD_WIN_VERSION +Language=English +ERROR_OLD_WIN_VERSION - The mounted file system does not support extended attributes. +. + +MessageId=0x47F +Severity=Success +Facility=System +SymbolicName=ERROR_APP_WRONG_OS +Language=English +ERROR_APP_WRONG_OS +. + +MessageId=0x480 +Severity=Success +Facility=System +SymbolicName=ERROR_SINGLE_INSTANCE_APP +Language=English +ERROR_SINGLE_INSTANCE_APP +. + +MessageId=0x481 +Severity=Success +Facility=System +SymbolicName=ERROR_RMODE_APP +Language=English +ERROR_RMODE_APP +. + +MessageId=0x482 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DLL +Language=English +ERROR_INVALID_DLL +. + +MessageId=0x483 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_ASSOCIATION +Language=English +ERROR_NO_ASSOCIATION +. + +MessageId=0x484 +Severity=Success +Facility=System +SymbolicName=ERROR_DDE_FAIL +Language=English +ERROR_DDE_FAIL - Attempt to release mutex not owned by caller. +. + +MessageId=0x485 +Severity=Success +Facility=System +SymbolicName=ERROR_DLL_NOT_FOUND +Language=English +ERROR_DLL_NOT_FOUND +. + +MessageId=0x4B0 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_DEVICE +Language=English +ERROR_BAD_DEVICE +. + +MessageId=0x4B1 +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_UNAVAIL +Language=English +ERROR_CONNECTION_UNAVAIL +. + +MessageId=0x4B2 +Severity=Success +Facility=System +SymbolicName=ERROR_DEVICE_ALREADY_REMEMBERED +Language=English +ERROR_DEVICE_ALREADY_REMEMBERED +. + +MessageId=0x4B3 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_NET_OR_BAD_PATH +Language=English +ERROR_NO_NET_OR_BAD_PATH +. + +MessageId=0x4B4 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_PROVIDER +Language=English +ERROR_BAD_PROVIDER +. + +MessageId=0x4B5 +Severity=Success +Facility=System +SymbolicName=ERROR_CANNOT_OPEN_PROFILE +Language=English +ERROR_CANNOT_OPEN_PROFILE +. + +MessageId=0x4B6 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_PROFILE +Language=English +ERROR_BAD_PROFILE +. + +MessageId=0x4B7 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_CONTAINER +Language=English +ERROR_NOT_CONTAINER +. + +MessageId=0x4B8 +Severity=Success +Facility=System +SymbolicName=ERROR_EXTENDED_ERROR +Language=English +ERROR_EXTENDED_ERROR - Too many posts were made to a semaphore. +. + +MessageId=0x4B9 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_GROUPNAME +Language=English +ERROR_INVALID_GROUPNAME - Only part of a ReadProcessMemory or WriteProcessMemory request was completed. +. + +MessageId=0x4BA +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_COMPUTERNAME +Language=English +ERROR_INVALID_COMPUTERNAME - The oplock request is denied. +. + +MessageId=0x4BB +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EVENTNAME +Language=English +ERROR_INVALID_EVENTNAME - An invalid oplock acknowledgment was received by the system. +. + +MessageId=0x4BC +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DOMAINNAME +Language=English +ERROR_INVALID_DOMAINNAME +. + +MessageId=0x4BD +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SERVICENAME +Language=English +ERROR_INVALID_SERVICENAME +. + +MessageId=0x4BE +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_NETNAME +Language=English +ERROR_INVALID_NETNAME +. + +MessageId=0x4BF +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SHARENAME +Language=English +ERROR_INVALID_SHARENAME +. + +MessageId=0x4C0 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PASSWORDNAME +Language=English +ERROR_INVALID_PASSWORDNAME +. + +MessageId=0x4C1 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MESSAGENAME +Language=English +ERROR_INVALID_MESSAGENAME +. + +MessageId=0x4C2 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MESSAGEDEST +Language=English +ERROR_INVALID_MESSAGEDEST +. + +MessageId=0x4C3 +Severity=Success +Facility=System +SymbolicName=ERROR_SESSION_CREDENTIAL_CONFLICT +Language=English +ERROR_SESSION_CREDENTIAL_CONFLICT +. + +MessageId=0x4C4 +Severity=Success +Facility=System +SymbolicName=ERROR_REMOTE_SESSION_LIMIT_EXCEEDED +Language=English +ERROR_REMOTE_SESSION_LIMIT_EXCEEDED +. + +MessageId=0x4C5 +Severity=Success +Facility=System +SymbolicName=ERROR_DUP_DOMAINNAME +Language=English +ERROR_DUP_DOMAINNAME +. + +MessageId=0x4C6 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_NETWORK +Language=English +ERROR_NO_NETWORK +. + +MessageId=0x4C7 +Severity=Success +Facility=System +SymbolicName=ERROR_CANCELLED +Language=English +ERROR_CANCELLED +. + +MessageId=0x4C8 +Severity=Success +Facility=System +SymbolicName=ERROR_USER_MAPPED_FILE +Language=English +ERROR_USER_MAPPED_FILE +. + +MessageId=0x4C9 +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_REFUSED +Language=English +ERROR_CONNECTION_REFUSED +. + +MessageId=0x4CA +Severity=Success +Facility=System +SymbolicName=ERROR_GRACEFUL_DISCONNECT +Language=English +ERROR_GRACEFUL_DISCONNECT +. + +MessageId=0x4CB +Severity=Success +Facility=System +SymbolicName=ERROR_ADDRESS_ALREADY_ASSOCIATED +Language=English +ERROR_ADDRESS_ALREADY_ASSOCIATED +. + +MessageId=0x4CC +Severity=Success +Facility=System +SymbolicName=ERROR_ADDRESS_NOT_ASSOCIATED +Language=English +ERROR_ADDRESS_NOT_ASSOCIATED +. + +MessageId=0x4CD +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_INVALID +Language=English +ERROR_CONNECTION_INVALID +. + +MessageId=0x4CE +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_ACTIVE +Language=English +ERROR_CONNECTION_ACTIVE +. + +MessageId=0x4CF +Severity=Success +Facility=System +SymbolicName=ERROR_NETWORK_UNREACHABLE +Language=English +ERROR_NETWORK_UNREACHABLE +. + +MessageId=0x4D0 +Severity=Success +Facility=System +SymbolicName=ERROR_HOST_UNREACHABLE +Language=English +ERROR_HOST_UNREACHABLE +. + +MessageId=0x4D1 +Severity=Success +Facility=System +SymbolicName=ERROR_PROTOCOL_UNREACHABLE +Language=English +ERROR_PROTOCOL_UNREACHABLE +. + +MessageId=0x4D2 +Severity=Success +Facility=System +SymbolicName=ERROR_PORT_UNREACHABLE +Language=English +ERROR_PORT_UNREACHABLE +. + +MessageId=0x4D3 +Severity=Success +Facility=System +SymbolicName=ERROR_REQUEST_ABORTED +Language=English +ERROR_REQUEST_ABORTED +. + +MessageId=0x4D4 +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_ABORTED +Language=English +ERROR_CONNECTION_ABORTED +. + +MessageId=0x4D5 +Severity=Success +Facility=System +SymbolicName=ERROR_RETRY +Language=English +ERROR_RETRY +. + +MessageId=0x4D6 +Severity=Success +Facility=System +SymbolicName=ERROR_CONNECTION_COUNT_LIMIT +Language=English +ERROR_CONNECTION_COUNT_LIMIT +. + +MessageId=0x4D7 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGIN_TIME_RESTRICTION +Language=English +ERROR_LOGIN_TIME_RESTRICTION +. + +MessageId=0x4D8 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGIN_WKSTA_RESTRICTION +Language=English +ERROR_LOGIN_WKSTA_RESTRICTION +. + +MessageId=0x4D9 +Severity=Success +Facility=System +SymbolicName=ERROR_INCORRECT_ADDRESS +Language=English +ERROR_INCORRECT_ADDRESS +. + +MessageId=0x4DA +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_REGISTERED +Language=English +ERROR_ALREADY_REGISTERED +. + +MessageId=0x4DB +Severity=Success +Facility=System +SymbolicName=ERROR_SERVICE_NOT_FOUND +Language=English +ERROR_SERVICE_NOT_FOUND +. + +MessageId=0x4DC +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_AUTHENTICATED +Language=English +ERROR_NOT_AUTHENTICATED +. + +MessageId=0x4DD +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_LOGGED_ON +Language=English +ERROR_NOT_LOGGED_ON +. + +MessageId=0x4DE +Severity=Success +Facility=System +SymbolicName=ERROR_CONTINUE +Language=English +ERROR_CONTINUE +. + +MessageId=0x4DF +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_INITIALIZED +Language=English +ERROR_ALREADY_INITIALIZED +. + +MessageId=0x4E0 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_MORE_DEVICES +Language=English +ERROR_NO_MORE_DEVICES +. + +MessageId=0x514 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_ALL_ASSIGNED +Language=English +ERROR_NOT_ALL_ASSIGNED +. + +MessageId=0x515 +Severity=Success +Facility=System +SymbolicName=ERROR_SOME_NOT_MAPPED +Language=English +ERROR_SOME_NOT_MAPPED +. + +MessageId=0x516 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_QUOTAS_FOR_ACCOUNT +Language=English +ERROR_NO_QUOTAS_FOR_ACCOUNT +. + +MessageId=0x517 +Severity=Success +Facility=System +SymbolicName=ERROR_LOCAL_USER_SESSION_KEY +Language=English +ERROR_LOCAL_USER_SESSION_KEY +. + +MessageId=0x518 +Severity=Success +Facility=System +SymbolicName=ERROR_NULL_LM_PASSWORD +Language=English +ERROR_NULL_LM_PASSWORD +. + +MessageId=0x519 +Severity=Success +Facility=System +SymbolicName=ERROR_UNKNOWN_REVISION +Language=English +ERROR_UNKNOWN_REVISION +. + +MessageId=0x51A +Severity=Success +Facility=System +SymbolicName=ERROR_REVISION_MISMATCH +Language=English +ERROR_REVISION_MISMATCH +. + +MessageId=0x51B +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_OWNER +Language=English +ERROR_INVALID_OWNER +. + +MessageId=0x51C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PRIMARY_GROUP +Language=English +ERROR_INVALID_PRIMARY_GROUP +. + +MessageId=0x51D +Severity=Success +Facility=System +SymbolicName=ERROR_NO_IMPERSONATION_TOKEN +Language=English +ERROR_NO_IMPERSONATION_TOKEN +. + +MessageId=0x51E +Severity=Success +Facility=System +SymbolicName=ERROR_CANT_DISABLE_MANDATORY +Language=English +ERROR_CANT_DISABLE_MANDATORY +. + +MessageId=0x51F +Severity=Success +Facility=System +SymbolicName=ERROR_NO_LOGON_SERVERS +Language=English +ERROR_NO_LOGON_SERVERS +. + +MessageId=0x520 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_LOGON_SESSION +Language=English +ERROR_NO_SUCH_LOGON_SESSION +. + +MessageId=0x521 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_PRIVILEGE +Language=English +ERROR_NO_SUCH_PRIVILEGE +. + +MessageId=0x522 +Severity=Success +Facility=System +SymbolicName=ERROR_PRIVILEGE_NOT_HELD +Language=English +ERROR_PRIVILEGE_NOT_HELD +. + +MessageId=0x523 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ACCOUNT_NAME +Language=English +ERROR_INVALID_ACCOUNT_NAME +. + +MessageId=0x524 +Severity=Success +Facility=System +SymbolicName=ERROR_USER_EXISTS +Language=English +ERROR_USER_EXISTS +. + +MessageId=0x525 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_USER +Language=English +ERROR_NO_SUCH_USER +. + +MessageId=0x526 +Severity=Success +Facility=System +SymbolicName=ERROR_GROUP_EXISTS +Language=English +ERROR_GROUP_EXISTS +. + +MessageId=0x527 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_GROUP +Language=English +ERROR_NO_SUCH_GROUP +. + +MessageId=0x528 +Severity=Success +Facility=System +SymbolicName=ERROR_MEMBER_IN_GROUP +Language=English +ERROR_MEMBER_IN_GROUP +. + +MessageId=0x529 +Severity=Success +Facility=System +SymbolicName=ERROR_MEMBER_NOT_IN_GROUP +Language=English +ERROR_MEMBER_NOT_IN_GROUP +. + +MessageId=0x52A +Severity=Success +Facility=System +SymbolicName=ERROR_LAST_ADMIN +Language=English +ERROR_LAST_ADMIN +. + +MessageId=0x52B +Severity=Success +Facility=System +SymbolicName=ERROR_WRONG_PASSWORD +Language=English +ERROR_WRONG_PASSWORD +. + +MessageId=0x52C +Severity=Success +Facility=System +SymbolicName=ERROR_ILL_FORMED_PASSWORD +Language=English +ERROR_ILL_FORMED_PASSWORD +. + +MessageId=0x52D +Severity=Success +Facility=System +SymbolicName=ERROR_PASSWORD_RESTRICTION +Language=English +ERROR_PASSWORD_RESTRICTION +. + +MessageId=0x52E +Severity=Success +Facility=System +SymbolicName=ERROR_LOGON_FAILURE +Language=English +ERROR_LOGON_FAILURE +. + +MessageId=0x52F +Severity=Success +Facility=System +SymbolicName=ERROR_ACCOUNT_RESTRICTION +Language=English +ERROR_ACCOUNT_RESTRICTION +. + +MessageId=0x530 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_LOGON_HOURS +Language=English +ERROR_INVALID_LOGON_HOURS +. + +MessageId=0x531 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_WORKSTATION +Language=English +ERROR_INVALID_WORKSTATION +. + +MessageId=0x532 +Severity=Success +Facility=System +SymbolicName=ERROR_PASSWORD_EXPIRED +Language=English +ERROR_PASSWORD_EXPIRED +. + +MessageId=0x533 +Severity=Success +Facility=System +SymbolicName=ERROR_ACCOUNT_DISABLED +Language=English +ERROR_ACCOUNT_DISABLED +. + +MessageId=0x534 +Severity=Success +Facility=System +SymbolicName=ERROR_NONE_MAPPED +Language=English +ERROR_NONE_MAPPED +. + +MessageId=0x535 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_LUIDS_REQUESTED +Language=English +ERROR_TOO_MANY_LUIDS_REQUESTED +. + +MessageId=0x536 +Severity=Success +Facility=System +SymbolicName=ERROR_LUIDS_EXHAUSTED +Language=English +ERROR_LUIDS_EXHAUSTED +. + +MessageId=0x537 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SUB_AUTHORITY +Language=English +ERROR_INVALID_SUB_AUTHORITY +. + +MessageId=0x538 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ACL +Language=English +ERROR_INVALID_ACL +. + +MessageId=0x539 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SID +Language=English +ERROR_INVALID_SID +. + +MessageId=0x53A +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SECURITY_DESCR +Language=English +ERROR_INVALID_SECURITY_DESCR +. + +MessageId=0x53C +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_INHERITANCE_ACL +Language=English +ERROR_BAD_INHERITANCE_ACL +. + +MessageId=0x53D +Severity=Success +Facility=System +SymbolicName=ERROR_SERVER_DISABLED +Language=English +ERROR_SERVER_DISABLED +. + +MessageId=0x53E +Severity=Success +Facility=System +SymbolicName=ERROR_SERVER_NOT_DISABLED +Language=English +ERROR_SERVER_NOT_DISABLED +. + +MessageId=0x53F +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ID_AUTHORITY +Language=English +ERROR_INVALID_ID_AUTHORITY +. + +MessageId=0x540 +Severity=Success +Facility=System +SymbolicName=ERROR_ALLOTTED_SPACE_EXCEEDED +Language=English +ERROR_ALLOTTED_SPACE_EXCEEDED +. + +MessageId=0x541 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_GROUP_ATTRIBUTES +Language=English +ERROR_INVALID_GROUP_ATTRIBUTES +. + +MessageId=0x542 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_IMPERSONATION_LEVEL +Language=English +ERROR_BAD_IMPERSONATION_LEVEL +. + +MessageId=0x543 +Severity=Success +Facility=System +SymbolicName=ERROR_CANT_OPEN_ANONYMOUS +Language=English +ERROR_CANT_OPEN_ANONYMOUS +. + +MessageId=0x544 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_VALIDATION_CLASS +Language=English +ERROR_BAD_VALIDATION_CLASS +. + +MessageId=0x545 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_TOKEN_TYPE +Language=English +ERROR_BAD_TOKEN_TYPE +. + +MessageId=0x546 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SECURITY_ON_OBJECT +Language=English +ERROR_NO_SECURITY_ON_OBJECT +. + +MessageId=0x547 +Severity=Success +Facility=System +SymbolicName=ERROR_CANT_ACCESS_DOMAIN_INFO +Language=English +ERROR_CANT_ACCESS_DOMAIN_INFO +. + +MessageId=0x548 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SERVER_STATE +Language=English +ERROR_INVALID_SERVER_STATE +. + +MessageId=0x549 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DOMAIN_STATE +Language=English +ERROR_INVALID_DOMAIN_STATE +. + +MessageId=0x54A +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DOMAIN_ROLE +Language=English +ERROR_INVALID_DOMAIN_ROLE +. + +MessageId=0x54B +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_DOMAIN +Language=English +ERROR_NO_SUCH_DOMAIN +. + +MessageId=0x54C +Severity=Success +Facility=System +SymbolicName=ERROR_DOMAIN_EXISTS +Language=English +ERROR_DOMAIN_EXISTS +. + +MessageId=0x54D +Severity=Success +Facility=System +SymbolicName=ERROR_DOMAIN_LIMIT_EXCEEDED +Language=English +ERROR_DOMAIN_LIMIT_EXCEEDED +. + +MessageId=0x54E +Severity=Success +Facility=System +SymbolicName=ERROR_INTERNAL_DB_CORRUPTION +Language=English +ERROR_INTERNAL_DB_CORRUPTION +. + +MessageId=0x54F +Severity=Success +Facility=System +SymbolicName=ERROR_INTERNAL_ERROR +Language=English +ERROR_INTERNAL_ERROR +. + +MessageId=0x550 +Severity=Success +Facility=System +SymbolicName=ERROR_GENERIC_NOT_MAPPED +Language=English +ERROR_GENERIC_NOT_MAPPED +. + +MessageId=0x551 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_DESCRIPTOR_FORMAT +Language=English +ERROR_BAD_DESCRIPTOR_FORMAT +. + +MessageId=0x552 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_LOGON_PROCESS +Language=English +ERROR_NOT_LOGON_PROCESS +. + +MessageId=0x553 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGON_SESSION_EXISTS +Language=English +ERROR_LOGON_SESSION_EXISTS +. + +MessageId=0x554 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_PACKAGE +Language=English +ERROR_NO_SUCH_PACKAGE +. + +MessageId=0x555 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_LOGON_SESSION_STATE +Language=English +ERROR_BAD_LOGON_SESSION_STATE +. + +MessageId=0x556 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGON_SESSION_COLLISION +Language=English +ERROR_LOGON_SESSION_COLLISION +. + +MessageId=0x557 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_LOGON_TYPE +Language=English +ERROR_INVALID_LOGON_TYPE +. + +MessageId=0x558 +Severity=Success +Facility=System +SymbolicName=ERROR_CANNOT_IMPERSONATE +Language=English +ERROR_CANNOT_IMPERSONATE +. + +MessageId=0x559 +Severity=Success +Facility=System +SymbolicName=ERROR_RXACT_INVALID_STATE +Language=English +ERROR_RXACT_INVALID_STATE +. + +MessageId=0x55A +Severity=Success +Facility=System +SymbolicName=ERROR_RXACT_COMMIT_FAILURE +Language=English +ERROR_RXACT_COMMIT_FAILURE +. + +MessageId=0x55B +Severity=Success +Facility=System +SymbolicName=ERROR_SPECIAL_ACCOUNT +Language=English +ERROR_SPECIAL_ACCOUNT +. + +MessageId=0x55C +Severity=Success +Facility=System +SymbolicName=ERROR_SPECIAL_GROUP +Language=English +ERROR_SPECIAL_GROUP +. + +MessageId=0x55D +Severity=Success +Facility=System +SymbolicName=ERROR_SPECIAL_USER +Language=English +ERROR_SPECIAL_USER +. + +MessageId=0x55E +Severity=Success +Facility=System +SymbolicName=ERROR_MEMBERS_PRIMARY_GROUP +Language=English +ERROR_MEMBERS_PRIMARY_GROUP +. + +MessageId=0x55F +Severity=Success +Facility=System +SymbolicName=ERROR_TOKEN_ALREADY_IN_USE +Language=English +ERROR_TOKEN_ALREADY_IN_USE +. + +MessageId=0x560 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_ALIAS +Language=English +ERROR_NO_SUCH_ALIAS +. + +MessageId=0x561 +Severity=Success +Facility=System +SymbolicName=ERROR_MEMBER_NOT_IN_ALIAS +Language=English +ERROR_MEMBER_NOT_IN_ALIAS +. + +MessageId=0x562 +Severity=Success +Facility=System +SymbolicName=ERROR_MEMBER_IN_ALIAS +Language=English +ERROR_MEMBER_IN_ALIAS +. + +MessageId=0x563 +Severity=Success +Facility=System +SymbolicName=ERROR_ALIAS_EXISTS +Language=English +ERROR_ALIAS_EXISTS +. + +MessageId=0x564 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGON_NOT_GRANTED +Language=English +ERROR_LOGON_NOT_GRANTED +. + +MessageId=0x565 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_SECRETS +Language=English +ERROR_TOO_MANY_SECRETS +. + +MessageId=0x566 +Severity=Success +Facility=System +SymbolicName=ERROR_SECRET_TOO_LONG +Language=English +ERROR_SECRET_TOO_LONG +. + +MessageId=0x567 +Severity=Success +Facility=System +SymbolicName=ERROR_INTERNAL_DB_ERROR +Language=English +ERROR_INTERNAL_DB_ERROR +. + +MessageId=0x568 +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_CONTEXT_IDS +Language=English +ERROR_TOO_MANY_CONTEXT_IDS +. + +MessageId=0x569 +Severity=Success +Facility=System +SymbolicName=ERROR_LOGON_TYPE_NOT_GRANTED +Language=English +ERROR_LOGON_TYPE_NOT_GRANTED +. + +MessageId=0x56A +Severity=Success +Facility=System +SymbolicName=ERROR_NT_CROSS_ENCRYPTION_REQUIRED +Language=English +ERROR_NT_CROSS_ENCRYPTION_REQUIRED +. + +MessageId=0x56B +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SUCH_MEMBER +Language=English +ERROR_NO_SUCH_MEMBER +. + +MessageId=0x56C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MEMBER +Language=English +ERROR_INVALID_MEMBER +. + +MessageId=0x56D +Severity=Success +Facility=System +SymbolicName=ERROR_TOO_MANY_SIDS +Language=English +ERROR_TOO_MANY_SIDS +. + +MessageId=0x56E +Severity=Success +Facility=System +SymbolicName=ERROR_LM_CROSS_ENCRYPTION_REQUIRED +Language=English +ERROR_LM_CROSS_ENCRYPTION_REQUIRED +. + +MessageId=0x56F +Severity=Success +Facility=System +SymbolicName=ERROR_NO_INHERITANCE +Language=English +ERROR_NO_INHERITANCE +. + +MessageId=0x570 +Severity=Success +Facility=System +SymbolicName=ERROR_FILE_CORRUPT +Language=English +ERROR_FILE_CORRUPT +. + +MessageId=0x571 +Severity=Success +Facility=System +SymbolicName=ERROR_DISK_CORRUPT +Language=English +ERROR_DISK_CORRUPT +. + +MessageId=0x572 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_USER_SESSION_KEY +Language=English +ERROR_NO_USER_SESSION_KEY +. + +MessageId=0x573 +Severity=Success +Facility=System +SymbolicName=ERROR_LICENSE_QUOTA_EXCEEDED +Language=English +ERROR_LICENSE_QUOTA_EXCEEDED +. + +MessageId=0x578 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_WINDOW_HANDLE +Language=English +ERROR_INVALID_WINDOW_HANDLE +. + +MessageId=0x579 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MENU_HANDLE +Language=English +ERROR_INVALID_MENU_HANDLE +. + +MessageId=0x57A +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_CURSOR_HANDLE +Language=English +ERROR_INVALID_CURSOR_HANDLE +. + +MessageId=0x57B +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ACCEL_HANDLE +Language=English +ERROR_INVALID_ACCEL_HANDLE +. + +MessageId=0x57C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_HOOK_HANDLE +Language=English +ERROR_INVALID_HOOK_HANDLE +. + +MessageId=0x57D +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DWP_HANDLE +Language=English +ERROR_INVALID_DWP_HANDLE +. + +MessageId=0x57E +Severity=Success +Facility=System +SymbolicName=ERROR_TLW_WITH_WSCHILD +Language=English +ERROR_TLW_WITH_WSCHILD +. + +MessageId=0x57F +Severity=Success +Facility=System +SymbolicName=ERROR_CANNOT_FIND_WND_CLASS +Language=English +ERROR_CANNOT_FIND_WND_CLASS +. + +MessageId=0x580 +Severity=Success +Facility=System +SymbolicName=ERROR_WINDOW_OF_OTHER_THREAD +Language=English +ERROR_WINDOW_OF_OTHER_THREAD +. + +MessageId=0x581 +Severity=Success +Facility=System +SymbolicName=ERROR_HOTKEY_ALREADY_REGISTERED +Language=English +ERROR_HOTKEY_ALREADY_REGISTERED +. + +MessageId=0x582 +Severity=Success +Facility=System +SymbolicName=ERROR_CLASS_ALREADY_EXISTS +Language=English +ERROR_CLASS_ALREADY_EXISTS +. + +MessageId=0x583 +Severity=Success +Facility=System +SymbolicName=ERROR_CLASS_DOES_NOT_EXIST +Language=English +ERROR_CLASS_DOES_NOT_EXIST +. + +MessageId=0x584 +Severity=Success +Facility=System +SymbolicName=ERROR_CLASS_HAS_WINDOWS +Language=English +ERROR_CLASS_HAS_WINDOWS +. + +MessageId=0x585 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_INDEX +Language=English +ERROR_INVALID_INDEX +. + +MessageId=0x586 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ICON_HANDLE +Language=English +ERROR_INVALID_ICON_HANDLE +. + +MessageId=0x587 +Severity=Success +Facility=System +SymbolicName=ERROR_PRIVATE_DIALOG_INDEX +Language=English +ERROR_PRIVATE_DIALOG_INDEX +. + +MessageId=0x588 +Severity=Success +Facility=System +SymbolicName=ERROR_LISTBOX_ID_NOT_FOUND +Language=English +ERROR_LISTBOX_ID_NOT_FOUND +. + +MessageId=0x589 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_WILDCARD_CHARACTERS +Language=English +ERROR_NO_WILDCARD_CHARACTERS +. + +MessageId=0x58A +Severity=Success +Facility=System +SymbolicName=ERROR_CLIPBOARD_NOT_OPEN +Language=English +ERROR_CLIPBOARD_NOT_OPEN +. + +MessageId=0x58B +Severity=Success +Facility=System +SymbolicName=ERROR_HOTKEY_NOT_REGISTERED +Language=English +ERROR_HOTKEY_NOT_REGISTERED +. + +MessageId=0x58C +Severity=Success +Facility=System +SymbolicName=ERROR_WINDOW_NOT_DIALOG +Language=English +ERROR_WINDOW_NOT_DIALOG +. + +MessageId=0x58D +Severity=Success +Facility=System +SymbolicName=ERROR_CONTROL_ID_NOT_FOUND +Language=English +ERROR_CONTROL_ID_NOT_FOUND +. + +MessageId=0x58E +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_COMBOBOX_MESSAGE +Language=English +ERROR_INVALID_COMBOBOX_MESSAGE +. + +MessageId=0x58F +Severity=Success +Facility=System +SymbolicName=ERROR_WINDOW_NOT_COMBOBOX +Language=English +ERROR_WINDOW_NOT_COMBOBOX +. + +MessageId=0x590 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_EDIT_HEIGHT +Language=English +ERROR_INVALID_EDIT_HEIGHT +. + +MessageId=0x591 +Severity=Success +Facility=System +SymbolicName=ERROR_DC_NOT_FOUND +Language=English +ERROR_DC_NOT_FOUND +. + +MessageId=0x592 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_HOOK_FILTER +Language=English +ERROR_INVALID_HOOK_FILTER +. + +MessageId=0x593 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FILTER_PROC +Language=English +ERROR_INVALID_FILTER_PROC +. + +MessageId=0x594 +Severity=Success +Facility=System +SymbolicName=ERROR_HOOK_NEEDS_HMOD +Language=English +ERROR_HOOK_NEEDS_HMOD +. + +MessageId=0x595 +Severity=Success +Facility=System +SymbolicName=ERROR_GLOBAL_ONLY_HOOK +Language=English +ERROR_GLOBAL_ONLY_HOOK +. + +MessageId=0x596 +Severity=Success +Facility=System +SymbolicName=ERROR_JOURNAL_HOOK_SET +Language=English +ERROR_JOURNAL_HOOK_SET +. + +MessageId=0x597 +Severity=Success +Facility=System +SymbolicName=ERROR_HOOK_NOT_INSTALLED +Language=English +ERROR_HOOK_NOT_INSTALLED +. + +MessageId=0x598 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_LB_MESSAGE +Language=English +ERROR_INVALID_LB_MESSAGE +. + +MessageId=0x599 +Severity=Success +Facility=System +SymbolicName=ERROR_SETCOUNT_ON_BAD_LB +Language=English +ERROR_SETCOUNT_ON_BAD_LB +. + +MessageId=0x59A +Severity=Success +Facility=System +SymbolicName=ERROR_LB_WITHOUT_TABSTOPS +Language=English +ERROR_LB_WITHOUT_TABSTOPS +. + +MessageId=0x59B +Severity=Success +Facility=System +SymbolicName=ERROR_DESTROY_OBJECT_OF_OTHER_THREAD +Language=English +ERROR_DESTROY_OBJECT_OF_OTHER_THREAD +. + +MessageId=0x59C +Severity=Success +Facility=System +SymbolicName=ERROR_CHILD_WINDOW_MENU +Language=English +ERROR_CHILD_WINDOW_MENU +. + +MessageId=0x59D +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SYSTEM_MENU +Language=English +ERROR_NO_SYSTEM_MENU +. + +MessageId=0x59E +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_MSGBOX_STYLE +Language=English +ERROR_INVALID_MSGBOX_STYLE +. + +MessageId=0x59F +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SPI_VALUE +Language=English +ERROR_INVALID_SPI_VALUE +. + +MessageId=0x5A0 +Severity=Success +Facility=System +SymbolicName=ERROR_SCREEN_ALREADY_LOCKED +Language=English +ERROR_SCREEN_ALREADY_LOCKED +. + +MessageId=0x5A1 +Severity=Success +Facility=System +SymbolicName=ERROR_HWNDS_HAVE_DIFF_PARENT +Language=English +ERROR_HWNDS_HAVE_DIFF_PARENT +. + +MessageId=0x5A2 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_CHILD_WINDOW +Language=English +ERROR_NOT_CHILD_WINDOW +. + +MessageId=0x5A3 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_GW_COMMAND +Language=English +ERROR_INVALID_GW_COMMAND +. + +MessageId=0x5A4 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_THREAD_ID +Language=English +ERROR_INVALID_THREAD_ID +. + +MessageId=0x5A5 +Severity=Success +Facility=System +SymbolicName=ERROR_NON_MDICHILD_WINDOW +Language=English +ERROR_NON_MDICHILD_WINDOW +. + +MessageId=0x5A6 +Severity=Success +Facility=System +SymbolicName=ERROR_POPUP_ALREADY_ACTIVE +Language=English +ERROR_POPUP_ALREADY_ACTIVE +. + +MessageId=0x5A7 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SCROLLBARS +Language=English +ERROR_NO_SCROLLBARS +. + +MessageId=0x5A8 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SCROLLBAR_RANGE +Language=English +ERROR_INVALID_SCROLLBAR_RANGE +. + +MessageId=0x5A9 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SHOWWIN_COMMAND +Language=English +ERROR_INVALID_SHOWWIN_COMMAND +. + +MessageId=0x5AA +Severity=Success +Facility=System +SymbolicName=ERROR_NO_SYSTEM_RESOURCES +Language=English +ERROR_NO_SYSTEM_RESOURCES +. + +MessageId=0x5AB +Severity=Success +Facility=System +SymbolicName=ERROR_NONPAGED_SYSTEM_RESOURCES +Language=English +ERROR_NONPAGED_SYSTEM_RESOURCES +. + +MessageId=0x5AC +Severity=Success +Facility=System +SymbolicName=ERROR_PAGED_SYSTEM_RESOURCES +Language=English +ERROR_PAGED_SYSTEM_RESOURCES +. + +MessageId=0x5AD +Severity=Success +Facility=System +SymbolicName=ERROR_WORKING_SET_QUOTA +Language=English +ERROR_WORKING_SET_QUOTA - Attempt to access invalid address. +. + +MessageId=0x5AE +Severity=Success +Facility=System +SymbolicName=ERROR_PAGEFILE_QUOTA +Language=English +ERROR_PAGEFILE_QUOTA +. + +MessageId=0x5AF +Severity=Success +Facility=System +SymbolicName=ERROR_COMMITMENT_LIMIT +Language=English +ERROR_COMMITMENT_LIMIT +. + +MessageId=0x5B0 +Severity=Success +Facility=System +SymbolicName=ERROR_MENU_ITEM_NOT_FOUND +Language=English +ERROR_MENU_ITEM_NOT_FOUND +. + +MessageId=0x5DC +Severity=Success +Facility=System +SymbolicName=ERROR_EVENTLOG_FILE_CORRUPT +Language=English +ERROR_EVENTLOG_FILE_CORRUPT +. + +MessageId=0x5DD +Severity=Success +Facility=System +SymbolicName=ERROR_EVENTLOG_CANT_START +Language=English +ERROR_EVENTLOG_CANT_START +. + +MessageId=0x5DE +Severity=Success +Facility=System +SymbolicName=ERROR_LOG_FILE_FULL +Language=English +ERROR_LOG_FILE_FULL +. + +MessageId=0x5DF +Severity=Success +Facility=System +SymbolicName=ERROR_EVENTLOG_FILE_CHANGED +Language=English +ERROR_EVENTLOG_FILE_CHANGED +. + +MessageId=0x6A4 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_STRING_BINDING +Language=English +RPC_S_INVALID_STRING_BINDING +. + +MessageId=0x6A5 +Severity=Success +Facility=System +SymbolicName=RPC_S_WRONG_KIND_OF_BINDING +Language=English +RPC_S_WRONG_KIND_OF_BINDING +. + +MessageId=0x6A6 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_BINDING +Language=English +RPC_S_INVALID_BINDING +. + +MessageId=0x6A7 +Severity=Success +Facility=System +SymbolicName=RPC_S_PROTSEQ_NOT_SUPPORTED +Language=English +RPC_S_PROTSEQ_NOT_SUPPORTED +. + +MessageId=0x6A8 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_RPC_PROTSEQ +Language=English +RPC_S_INVALID_RPC_PROTSEQ +. + +MessageId=0x6A9 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_STRING_UUID +Language=English +RPC_S_INVALID_STRING_UUID +. + +MessageId=0x6AA +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_ENDPOINT_FORMAT +Language=English +RPC_S_INVALID_ENDPOINT_FORMAT +. + +MessageId=0x6AB +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_NET_ADDR +Language=English +RPC_S_INVALID_NET_ADDR +. + +MessageId=0x6AC +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_ENDPOINT_FOUND +Language=English +RPC_S_NO_ENDPOINT_FOUND +. + +MessageId=0x6AD +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_TIMEOUT +Language=English +RPC_S_INVALID_TIMEOUT +. + +MessageId=0x6AE +Severity=Success +Facility=System +SymbolicName=RPC_S_OBJECT_NOT_FOUND +Language=English +RPC_S_OBJECT_NOT_FOUND +. + +MessageId=0x6AF +Severity=Success +Facility=System +SymbolicName=RPC_S_ALREADY_REGISTERED +Language=English +RPC_S_ALREADY_REGISTERED +. + +MessageId=0x6B0 +Severity=Success +Facility=System +SymbolicName=RPC_S_TYPE_ALREADY_REGISTERED +Language=English +RPC_S_TYPE_ALREADY_REGISTERED +. + +MessageId=0x6B1 +Severity=Success +Facility=System +SymbolicName=RPC_S_ALREADY_LISTENING +Language=English +RPC_S_ALREADY_LISTENING +. + +MessageId=0x6B2 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_PROTSEQS_REGISTERED +Language=English +RPC_S_NO_PROTSEQS_REGISTERED +. + +MessageId=0x6B3 +Severity=Success +Facility=System +SymbolicName=RPC_S_NOT_LISTENING +Language=English +RPC_S_NOT_LISTENING +. + +MessageId=0x6B4 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_MGR_TYPE +Language=English +RPC_S_UNKNOWN_MGR_TYPE +. + +MessageId=0x6B5 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_IF +Language=English +RPC_S_UNKNOWN_IF +. + +MessageId=0x6B6 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_BINDINGS +Language=English +RPC_S_NO_BINDINGS +. + +MessageId=0x6B7 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_PROTSEQS +Language=English +RPC_S_NO_PROTSEQS +. + +MessageId=0x6B8 +Severity=Success +Facility=System +SymbolicName=RPC_S_CANT_CREATE_ENDPOINT +Language=English +RPC_S_CANT_CREATE_ENDPOINT +. + +MessageId=0x6B9 +Severity=Success +Facility=System +SymbolicName=RPC_S_OUT_OF_RESOURCES +Language=English +RPC_S_OUT_OF_RESOURCES +. + +MessageId=0x6BA +Severity=Success +Facility=System +SymbolicName=RPC_S_SERVER_UNAVAILABLE +Language=English +RPC_S_SERVER_UNAVAILABLE +. + +MessageId=0x6BB +Severity=Success +Facility=System +SymbolicName=RPC_S_SERVER_TOO_BUSY +Language=English +RPC_S_SERVER_TOO_BUSY +. + +MessageId=0x6BC +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_NETWORK_OPTIONS +Language=English +RPC_S_INVALID_NETWORK_OPTIONS +. + +MessageId=0x6BD +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_CALL_ACTIVE +Language=English +RPC_S_NO_CALL_ACTIVE +. + +MessageId=0x6BE +Severity=Success +Facility=System +SymbolicName=RPC_S_CALL_FAILED +Language=English +RPC_S_CALL_FAILED +. + +MessageId=0x6BF +Severity=Success +Facility=System +SymbolicName=RPC_S_CALL_FAILED_DNE +Language=English +RPC_S_CALL_FAILED_DNE +. + +MessageId=0x6C0 +Severity=Success +Facility=System +SymbolicName=RPC_S_PROTOCOL_ERROR +Language=English +RPC_S_PROTOCOL_ERROR +. + +MessageId=0x6C2 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNSUPPORTED_TRANS_SYN +Language=English +RPC_S_UNSUPPORTED_TRANS_SYN +. + +MessageId=0x6C4 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNSUPPORTED_TYPE +Language=English +RPC_S_UNSUPPORTED_TYPE +. + +MessageId=0x6C5 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_TAG +Language=English +RPC_S_INVALID_TAG +. + +MessageId=0x6C6 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_BOUND +Language=English +RPC_S_INVALID_BOUND +. + +MessageId=0x6C7 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_ENTRY_NAME +Language=English +RPC_S_NO_ENTRY_NAME +. + +MessageId=0x6C8 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_NAME_SYNTAX +Language=English +RPC_S_INVALID_NAME_SYNTAX +. + +MessageId=0x6C9 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNSUPPORTED_NAME_SYNTAX +Language=English +RPC_S_UNSUPPORTED_NAME_SYNTAX +. + +MessageId=0x6CB +Severity=Success +Facility=System +SymbolicName=RPC_S_UUID_NO_ADDRESS +Language=English +RPC_S_UUID_NO_ADDRESS +. + +MessageId=0x6CC +Severity=Success +Facility=System +SymbolicName=RPC_S_DUPLICATE_ENDPOINT +Language=English +RPC_S_DUPLICATE_ENDPOINT +. + +MessageId=0x6CD +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_AUTHN_TYPE +Language=English +RPC_S_UNKNOWN_AUTHN_TYPE +. + +MessageId=0x6CE +Severity=Success +Facility=System +SymbolicName=RPC_S_MAX_CALLS_TOO_SMALL +Language=English +RPC_S_MAX_CALLS_TOO_SMALL - Arithmetic result exceeded 32 bits. +. + +MessageId=0x6CF +Severity=Success +Facility=System +SymbolicName=RPC_S_STRING_TOO_LONG +Language=English +RPC_S_STRING_TOO_LONG - There is a process on other end of the pipe. +. + +MessageId=0x6D0 +Severity=Success +Facility=System +SymbolicName=RPC_S_PROTSEQ_NOT_FOUND +Language=English +RPC_S_PROTSEQ_NOT_FOUND - Waiting for a process to open the other end of the pipe. +. + +MessageId=0x6D1 +Severity=Success +Facility=System +SymbolicName=RPC_S_PROCNUM_OUT_OF_RANGE +Language=English +RPC_S_PROCNUM_OUT_OF_RANGE +. + +MessageId=0x6D2 +Severity=Success +Facility=System +SymbolicName=RPC_S_BINDING_HAS_NO_AUTH +Language=English +RPC_S_BINDING_HAS_NO_AUTH +. + +MessageId=0x6D3 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_AUTHN_SERVICE +Language=English +RPC_S_UNKNOWN_AUTHN_SERVICE +. + +MessageId=0x6D4 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_AUTHN_LEVEL +Language=English +RPC_S_UNKNOWN_AUTHN_LEVEL +. + +MessageId=0x6D5 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_AUTH_IDENTITY +Language=English +RPC_S_INVALID_AUTH_IDENTITY +. + +MessageId=0x6D6 +Severity=Success +Facility=System +SymbolicName=RPC_S_UNKNOWN_AUTHZ_SERVICE +Language=English +RPC_S_UNKNOWN_AUTHZ_SERVICE +. + +MessageId=0x6D7 +Severity=Success +Facility=System +SymbolicName=EPT_S_INVALID_ENTRY +Language=English +EPT_S_INVALID_ENTRY +. + +MessageId=0x6D8 +Severity=Success +Facility=System +SymbolicName=EPT_S_CANT_PERFORM_OP +Language=English +EPT_S_CANT_PERFORM_OP +. + +MessageId=0x6D9 +Severity=Success +Facility=System +SymbolicName=EPT_S_NOT_REGISTERED +Language=English +EPT_S_NOT_REGISTERED +. + +MessageId=0x6DA +Severity=Success +Facility=System +SymbolicName=RPC_S_NOTHING_TO_EXPORT +Language=English +RPC_S_NOTHING_TO_EXPORT +. + +MessageId=0x6DB +Severity=Success +Facility=System +SymbolicName=RPC_S_INCOMPLETE_NAME +Language=English +RPC_S_INCOMPLETE_NAME +. + +MessageId=0x6DC +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_VERS_OPTION +Language=English +RPC_S_INVALID_VERS_OPTION +. + +MessageId=0x6DD +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_MORE_MEMBERS +Language=English +RPC_S_NO_MORE_MEMBERS +. + +MessageId=0x6DE +Severity=Success +Facility=System +SymbolicName=RPC_S_NOT_ALL_OBJS_UNEXPORTED +Language=English +RPC_S_NOT_ALL_OBJS_UNEXPORTED +. + +MessageId=0x6DF +Severity=Success +Facility=System +SymbolicName=RPC_S_INTERFACE_NOT_FOUND +Language=English +RPC_S_INTERFACE_NOT_FOUND +. + +MessageId=0x6E0 +Severity=Success +Facility=System +SymbolicName=RPC_S_ENTRY_ALREADY_EXISTS +Language=English +RPC_S_ENTRY_ALREADY_EXISTS +. + +MessageId=0x6E1 +Severity=Success +Facility=System +SymbolicName=RPC_S_ENTRY_NOT_FOUND +Language=English +RPC_S_ENTRY_NOT_FOUND +. + +MessageId=0x6E2 +Severity=Success +Facility=System +SymbolicName=RPC_S_NAME_SERVICE_UNAVAILABLE +Language=English +RPC_S_NAME_SERVICE_UNAVAILABLE +. + +MessageId=0x6E3 +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_NAF_ID +Language=English +RPC_S_INVALID_NAF_ID +. + +MessageId=0x6E4 +Severity=Success +Facility=System +SymbolicName=RPC_S_CANNOT_SUPPORT +Language=English +RPC_S_CANNOT_SUPPORT +. + +MessageId=0x6E5 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_CONTEXT_AVAILABLE +Language=English +RPC_S_NO_CONTEXT_AVAILABLE +. + +MessageId=0x6E6 +Severity=Success +Facility=System +SymbolicName=RPC_S_INTERNAL_ERROR +Language=English +RPC_S_INTERNAL_ERROR +. + +MessageId=0x6E7 +Severity=Success +Facility=System +SymbolicName=RPC_S_ZERO_DIVIDE +Language=English +RPC_S_ZERO_DIVIDE +. + +MessageId=0x6E8 +Severity=Success +Facility=System +SymbolicName=RPC_S_ADDRESS_ERROR +Language=English +RPC_S_ADDRESS_ERROR +. + +MessageId=0x6E9 +Severity=Success +Facility=System +SymbolicName=RPC_S_FP_DIV_ZERO +Language=English +RPC_S_FP_DIV_ZERO +. + +MessageId=0x6EA +Severity=Success +Facility=System +SymbolicName=RPC_S_FP_UNDERFLOW +Language=English +RPC_S_FP_UNDERFLOW +. + +MessageId=0x6EB +Severity=Success +Facility=System +SymbolicName=RPC_S_FP_OVERFLOW +Language=English +RPC_S_FP_OVERFLOW +. + +MessageId=0x6EC +Severity=Success +Facility=System +SymbolicName=RPC_X_NO_MORE_ENTRIES +Language=English +RPC_X_NO_MORE_ENTRIES +. + +MessageId=0x6ED +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_CHAR_TRANS_OPEN_FAIL +Language=English +RPC_X_SS_CHAR_TRANS_OPEN_FAIL +. + +MessageId=0x6EE +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_CHAR_TRANS_SHORT_FILE +Language=English +RPC_X_SS_CHAR_TRANS_SHORT_FILE +. + +MessageId=0x6EF +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_IN_NULL_CONTEXT +Language=English +RPC_X_SS_IN_NULL_CONTEXT +. + +MessageId=0x6F1 +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_CONTEXT_DAMAGED +Language=English +RPC_X_SS_CONTEXT_DAMAGED +. + +MessageId=0x6F2 +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_HANDLES_MISMATCH +Language=English +RPC_X_SS_HANDLES_MISMATCH +. + +MessageId=0x6F3 +Severity=Success +Facility=System +SymbolicName=RPC_X_SS_CANNOT_GET_CALL_HANDLE +Language=English +RPC_X_SS_CANNOT_GET_CALL_HANDLE +. + +MessageId=0x6F4 +Severity=Success +Facility=System +SymbolicName=RPC_X_NULL_REF_POINTER +Language=English +RPC_X_NULL_REF_POINTER +. + +MessageId=0x6F5 +Severity=Success +Facility=System +SymbolicName=RPC_X_ENUM_VALUE_OUT_OF_RANGE +Language=English +RPC_X_ENUM_VALUE_OUT_OF_RANGE +. + +MessageId=0x6F6 +Severity=Success +Facility=System +SymbolicName=RPC_X_BYTE_COUNT_TOO_SMALL +Language=English +RPC_X_BYTE_COUNT_TOO_SMALL +. + +MessageId=0x6F7 +Severity=Success +Facility=System +SymbolicName=RPC_X_BAD_STUB_DATA +Language=English +RPC_X_BAD_STUB_DATA +. + +MessageId=0x6F8 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_USER_BUFFER +Language=English +ERROR_INVALID_USER_BUFFER +. + +MessageId=0x6F9 +Severity=Success +Facility=System +SymbolicName=ERROR_UNRECOGNIZED_MEDIA +Language=English +ERROR_UNRECOGNIZED_MEDIA +. + +MessageId=0x6FA +Severity=Success +Facility=System +SymbolicName=ERROR_NO_TRUST_LSA_SECRET +Language=English +ERROR_NO_TRUST_LSA_SECRET +. + +MessageId=0x6FB +Severity=Success +Facility=System +SymbolicName=ERROR_NO_TRUST_SAM_ACCOUNT +Language=English +ERROR_NO_TRUST_SAM_ACCOUNT +. + +MessageId=0x6FC +Severity=Success +Facility=System +SymbolicName=ERROR_TRUSTED_DOMAIN_FAILURE +Language=English +ERROR_TRUSTED_DOMAIN_FAILURE +. + +MessageId=0x6FD +Severity=Success +Facility=System +SymbolicName=ERROR_TRUSTED_RELATIONSHIP_FAILURE +Language=English +ERROR_TRUSTED_RELATIONSHIP_FAILURE +. + +MessageId=0x6FE +Severity=Success +Facility=System +SymbolicName=ERROR_TRUST_FAILURE +Language=English +ERROR_TRUST_FAILURE +. + +MessageId=0x6FF +Severity=Success +Facility=System +SymbolicName=RPC_S_CALL_IN_PROGRESS +Language=English +RPC_S_CALL_IN_PROGRESS +. + +MessageId=0x700 +Severity=Success +Facility=System +SymbolicName=ERROR_NETLOGON_NOT_STARTED +Language=English +ERROR_NETLOGON_NOT_STARTED +. + +MessageId=0x701 +Severity=Success +Facility=System +SymbolicName=ERROR_ACCOUNT_EXPIRED +Language=English +ERROR_ACCOUNT_EXPIRED +. + +MessageId=0x702 +Severity=Success +Facility=System +SymbolicName=ERROR_REDIRECTOR_HAS_OPEN_HANDLES +Language=English +ERROR_REDIRECTOR_HAS_OPEN_HANDLES +. + +MessageId=0x703 +Severity=Success +Facility=System +SymbolicName=ERROR_PRINTER_DRIVER_ALREADY_INSTALLED +Language=English +ERROR_PRINTER_DRIVER_ALREADY_INSTALLED +. + +MessageId=0x704 +Severity=Success +Facility=System +SymbolicName=ERROR_UNKNOWN_PORT +Language=English +ERROR_UNKNOWN_PORT +. + +MessageId=0x705 +Severity=Success +Facility=System +SymbolicName=ERROR_UNKNOWN_PRINTER_DRIVER +Language=English +ERROR_UNKNOWN_PRINTER_DRIVER +. + +MessageId=0x706 +Severity=Success +Facility=System +SymbolicName=ERROR_UNKNOWN_PRINTPROCESSOR +Language=English +ERROR_UNKNOWN_PRINTPROCESSOR +. + +MessageId=0x707 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_SEPARATOR_FILE +Language=English +ERROR_INVALID_SEPARATOR_FILE +. + +MessageId=0x708 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PRIORITY +Language=English +ERROR_INVALID_PRIORITY +. + +MessageId=0x709 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PRINTER_NAME +Language=English +ERROR_INVALID_PRINTER_NAME +. + +MessageId=0x70A +Severity=Success +Facility=System +SymbolicName=ERROR_PRINTER_ALREADY_EXISTS +Language=English +ERROR_PRINTER_ALREADY_EXISTS +. + +MessageId=0x70B +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PRINTER_COMMAND +Language=English +ERROR_INVALID_PRINTER_COMMAND +. + +MessageId=0x70C +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_DATATYPE +Language=English +ERROR_INVALID_DATATYPE +. + +MessageId=0x70D +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_ENVIRONMENT +Language=English +ERROR_INVALID_ENVIRONMENT +. + +MessageId=0x70E +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_MORE_BINDINGS +Language=English +RPC_S_NO_MORE_BINDINGS +. + +MessageId=0x70F +Severity=Success +Facility=System +SymbolicName=ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT +Language=English +ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT +. + +MessageId=0x710 +Severity=Success +Facility=System +SymbolicName=ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT +Language=English +ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT +. + +MessageId=0x711 +Severity=Success +Facility=System +SymbolicName=ERROR_NOLOGON_SERVER_TRUST_ACCOUNT +Language=English +ERROR_NOLOGON_SERVER_TRUST_ACCOUNT +. + +MessageId=0x712 +Severity=Success +Facility=System +SymbolicName=ERROR_DOMAIN_TRUST_INCONSISTENT +Language=English +ERROR_DOMAIN_TRUST_INCONSISTENT +. + +MessageId=0x713 +Severity=Success +Facility=System +SymbolicName=ERROR_SERVER_HAS_OPEN_HANDLES +Language=English +ERROR_SERVER_HAS_OPEN_HANDLES +. + +MessageId=0x714 +Severity=Success +Facility=System +SymbolicName=ERROR_RESOURCE_DATA_NOT_FOUND +Language=English +ERROR_RESOURCE_DATA_NOT_FOUND +. + +MessageId=0x715 +Severity=Success +Facility=System +SymbolicName=ERROR_RESOURCE_TYPE_NOT_FOUND +Language=English +ERROR_RESOURCE_TYPE_NOT_FOUND +. + +MessageId=0x716 +Severity=Success +Facility=System +SymbolicName=ERROR_RESOURCE_NAME_NOT_FOUND +Language=English +ERROR_RESOURCE_NAME_NOT_FOUND +. + +MessageId=0x717 +Severity=Success +Facility=System +SymbolicName=ERROR_RESOURCE_LANG_NOT_FOUND +Language=English +ERROR_RESOURCE_LANG_NOT_FOUND +. + +MessageId=0x718 +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_ENOUGH_QUOTA +Language=English +ERROR_NOT_ENOUGH_QUOTA +. + +MessageId=0x719 +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_INTERFACES +Language=English +RPC_S_NO_INTERFACES +. + +MessageId=0x71A +Severity=Success +Facility=System +SymbolicName=RPC_S_CALL_CANCELLED +Language=English +RPC_S_CALL_CANCELLED +. + +MessageId=0x71B +Severity=Success +Facility=System +SymbolicName=RPC_S_BINDING_INCOMPLETE +Language=English +RPC_S_BINDING_INCOMPLETE +. + +MessageId=0x71C +Severity=Success +Facility=System +SymbolicName=RPC_S_COMM_FAILURE +Language=English +RPC_S_COMM_FAILURE +. + +MessageId=0x71D +Severity=Success +Facility=System +SymbolicName=RPC_S_UNSUPPORTED_AUTHN_LEVEL +Language=English +RPC_S_UNSUPPORTED_AUTHN_LEVEL +. + +MessageId=0x71E +Severity=Success +Facility=System +SymbolicName=RPC_S_NO_PRINC_NAME +Language=English +RPC_S_NO_PRINC_NAME +. + +MessageId=0x71F +Severity=Success +Facility=System +SymbolicName=RPC_S_NOT_RPC_ERROR +Language=English +RPC_S_NOT_RPC_ERROR +. + +MessageId=0x720 +Severity=Success +Facility=System +SymbolicName=RPC_S_UUID_LOCAL_ONLY +Language=English +RPC_S_UUID_LOCAL_ONLY +. + +MessageId=0x721 +Severity=Success +Facility=System +SymbolicName=RPC_S_SEC_PKG_ERROR +Language=English +RPC_S_SEC_PKG_ERROR +. + +MessageId=0x722 +Severity=Success +Facility=System +SymbolicName=RPC_S_NOT_CANCELLED +Language=English +RPC_S_NOT_CANCELLED +. + +MessageId=0x723 +Severity=Success +Facility=System +SymbolicName=RPC_X_INVALID_ES_ACTION +Language=English +RPC_X_INVALID_ES_ACTION +. + +MessageId=0x724 +Severity=Success +Facility=System +SymbolicName=RPC_X_WRONG_ES_VERSION +Language=English +RPC_X_WRONG_ES_VERSION +. + +MessageId=0x725 +Severity=Success +Facility=System +SymbolicName=RPC_X_WRONG_STUB_VERSION +Language=English +RPC_X_WRONG_STUB_VERSION +. + +MessageId=0x726 +Severity=Success +Facility=System +SymbolicName=RPC_X_INVALID_PIPE_OBJECT +Language=English +RPC_X_INVALID_PIPE_OBJECT +. + +MessageId=0x727 +Severity=Success +Facility=System +SymbolicName=RPC_X_WRONG_PIPE_ORDER +Language=English +RPC_X_WRONG_PIPE_ORDER +. + +MessageId=0x728 +Severity=Success +Facility=System +SymbolicName=RPC_X_WRONG_PIPE_VERSION +Language=English +RPC_X_WRONG_PIPE_VERSION +. + +MessageId=0x76A +Severity=Success +Facility=System +SymbolicName=RPC_S_GROUP_MEMBER_NOT_FOUND +Language=English +RPC_S_GROUP_MEMBER_NOT_FOUND +. + +MessageId=0x76B +Severity=Success +Facility=System +SymbolicName=EPT_S_CANT_CREATE +Language=English +EPT_S_CANT_CREATE +. + +MessageId=0x76C +Severity=Success +Facility=System +SymbolicName=RPC_S_INVALID_OBJECT +Language=English +RPC_S_INVALID_OBJECT +. + +MessageId=0x76D +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_TIME +Language=English +ERROR_INVALID_TIME +. + +MessageId=0x76E +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FORM_NAME +Language=English +ERROR_INVALID_FORM_NAME +. + +MessageId=0x76F +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_FORM_SIZE +Language=English +ERROR_INVALID_FORM_SIZE +. + +MessageId=0x770 +Severity=Success +Facility=System +SymbolicName=ERROR_ALREADY_WAITING +Language=English +ERROR_ALREADY_WAITING +. + +MessageId=0x771 +Severity=Success +Facility=System +SymbolicName=ERROR_PRINTER_DELETED +Language=English +ERROR_PRINTER_DELETED +. + +MessageId=0x772 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PRINTER_STATE +Language=English +ERROR_INVALID_PRINTER_STATE +. + +MessageId=0x773 +Severity=Success +Facility=System +SymbolicName=ERROR_PASSWORD_MUST_CHANGE +Language=English +ERROR_PASSWORD_MUST_CHANGE +. + +MessageId=0x774 +Severity=Success +Facility=System +SymbolicName=ERROR_DOMAIN_CONTROLLER_NOT_FOUND +Language=English +ERROR_DOMAIN_CONTROLLER_NOT_FOUND +. + +MessageId=0x775 +Severity=Success +Facility=System +SymbolicName=ERROR_ACCOUNT_LOCKED_OUT +Language=English +ERROR_ACCOUNT_LOCKED_OUT +. + +MessageId=0x776 +Severity=Success +Facility=System +SymbolicName=OR_INVALID_OXID +Language=English +OR_INVALID_OXID +. + +MessageId=0x777 +Severity=Success +Facility=System +SymbolicName=OR_INVALID_OID +Language=English +OR_INVALID_OID +. + +MessageId=0x778 +Severity=Success +Facility=System +SymbolicName=OR_INVALID_SET +Language=English +OR_INVALID_SET +. + +MessageId=0x779 +Severity=Success +Facility=System +SymbolicName=RPC_S_SEND_INCOMPLETE +Language=English +RPC_S_SEND_INCOMPLETE +. + +MessageId=0x7D0 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_PIXEL_FORMAT +Language=English +ERROR_INVALID_PIXEL_FORMAT +. + +MessageId=0x7D1 +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_DRIVER +Language=English +ERROR_BAD_DRIVER +. + +MessageId=0x7D2 +Severity=Success +Facility=System +SymbolicName=ERROR_INVALID_WINDOW_STYLE +Language=English +ERROR_INVALID_WINDOW_STYLE +. + +MessageId=0x7D3 +Severity=Success +Facility=System +SymbolicName=ERROR_METAFILE_NOT_SUPPORTED +Language=English +ERROR_METAFILE_NOT_SUPPORTED +. + +MessageId=0x7D4 +Severity=Success +Facility=System +SymbolicName=ERROR_TRANSFORM_NOT_SUPPORTED +Language=English +ERROR_TRANSFORM_NOT_SUPPORTED +. + +MessageId=0x7D5 +Severity=Success +Facility=System +SymbolicName=ERROR_CLIPPING_NOT_SUPPORTED +Language=English +ERROR_CLIPPING_NOT_SUPPORTED +. + +MessageId=0x89A +Severity=Success +Facility=System +SymbolicName=ERROR_BAD_USERNAME +Language=English +ERROR_BAD_USERNAME +. + +MessageId=0x8CA +Severity=Success +Facility=System +SymbolicName=ERROR_NOT_CONNECTED +Language=English +ERROR_NOT_CONNECTED +. + +MessageId=0x961 +Severity=Success +Facility=System +SymbolicName=ERROR_OPEN_FILES +Language=English +ERROR_OPEN_FILES +. + +MessageId=0x962 +Severity=Success +Facility=System +SymbolicName=ERROR_ACTIVE_CONNECTIONS +Language=English +ERROR_ACTIVE_CONNECTIONS +. + +MessageId=0x964 +Severity=Success +Facility=System +SymbolicName=ERROR_DEVICE_IN_USE +Language=English +ERROR_DEVICE_IN_USE +. + +MessageId=0xBB8 +Severity=Success +Facility=System +SymbolicName=ERROR_UNKNOWN_PRINT_MONITOR +Language=English +ERROR_UNKNOWN_PRINT_MONITOR +. + +MessageId=0xBB9 +Severity=Success +Facility=System +SymbolicName=ERROR_PRINTER_DRIVER_IN_USE +Language=English +ERROR_PRINTER_DRIVER_IN_USE +. + +MessageId=0xBBA +Severity=Success +Facility=System +SymbolicName=ERROR_SPOOL_FILE_NOT_FOUND +Language=English +ERROR_SPOOL_FILE_NOT_FOUND +. + +MessageId=0xBBB +Severity=Success +Facility=System +SymbolicName=ERROR_SPL_NO_STARTDOC +Language=English +ERROR_SPL_NO_STARTDOC +. + +MessageId=0xBBC +Severity=Success +Facility=System +SymbolicName=ERROR_SPL_NO_ADDJOB +Language=English +ERROR_SPL_NO_ADDJOB +. + +MessageId=0xBBD +Severity=Success +Facility=System +SymbolicName=ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED +Language=English +ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED +. + +MessageId=0xBBE +Severity=Success +Facility=System +SymbolicName=ERROR_PRINT_MONITOR_ALREADY_INSTALLED +Language=English +ERROR_PRINT_MONITOR_ALREADY_INSTALLED +. + +MessageId=0xFA0 +Severity=Success +Facility=System +SymbolicName=ERROR_WINS_INTERNAL +Language=English +ERROR_WINS_INTERNAL +. + +MessageId=0xFA1 +Severity=Success +Facility=System +SymbolicName=ERROR_CAN_NOT_DEL_LOCAL_WINS +Language=English +ERROR_CAN_NOT_DEL_LOCAL_WINS +. + +MessageId=0xFA2 +Severity=Success +Facility=System +SymbolicName=ERROR_STATIC_INIT +Language=English +ERROR_STATIC_INIT +. + +MessageId=0xFA3 +Severity=Success +Facility=System +SymbolicName=ERROR_INC_BACKUP +Language=English +ERROR_INC_BACKUP +. + +MessageId=0xFA4 +Severity=Success +Facility=System +SymbolicName=ERROR_FULL_BACKUP +Language=English +ERROR_FULL_BACKUP +. + +MessageId=0xFA5 +Severity=Success +Facility=System +SymbolicName=ERROR_REC_NON_EXISTENT +Language=English +ERROR_REC_NON_EXISTENT +. + +MessageId=0xFA6 +Severity=Success +Facility=System +SymbolicName=ERROR_RPL_NOT_ALLOWED +Language=English +ERROR_RPL_NOT_ALLOWED +. + +MessageId=0x17E6 +Severity=Success +Facility=System +SymbolicName=ERROR_NO_BROWSER_SERVERS_FOUND +Language=English +ERROR_NO_BROWSER_SERVERS_FOUND +. + +; EOF diff --git a/lib/kernel32/kernel32.rc b/lib/kernel32/kernel32.rc index 78588bb..bdc2e3f 100644 --- a/lib/kernel32/kernel32.rc +++ b/lib/kernel32/kernel32.rc @@ -1,6 +1,7 @@ #include #include + LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO @@ -36,3 +37,5 @@ BEGIN END END + +#include "errcodes.rc" diff --git a/lib/kernel32/makefile b/lib/kernel32/makefile index 0753d54..c783173 100644 --- a/lib/kernel32/makefile +++ b/lib/kernel32/makefile @@ -8,7 +8,7 @@ TARGET_NAME = kernel32 TARGET_BASE = 0x77f00000 -TARGET_CFLAGS = -DKERNEL32_BASE=$(TARGET_DLLBASE) +TARGET_CFLAGS = -DKERNEL32_BASE=$(TARGET_DLLBASE) -I./ TARGET_LFLAGS = -nostartfiles @@ -16,6 +16,8 @@ TARGET_SDKLIBS = ntdll.a TARGET_GCCLIBS = gcc +TARGET_PCH = k32.h + TARGET_OBJECTS = $(TARGET_NAME).o TARGET_CLEAN = except/*.o file/*.o mem/*.o misc/*.o nls/*.o \ @@ -26,14 +28,21 @@ include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk +depends: + make -f errormsg.mak + +.PHONY: depends SYNCH_OBJECTS = synch/critical.o synch/event.o synch/intrlck.o synch/mutex.o \ synch/sem.o synch/timer.o synch/wait.o MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o \ - misc/dllmain.o misc/comm.o \ - misc/console.o misc/time.o misc/stubs.o misc/ldr.o misc/res.o \ - misc/debug.o misc/sysinfo.o misc/profile.o + misc/dllmain.o misc/comm.o misc/errormsg.o \ + misc/console.o misc/time.o misc/toolhelp.o \ + misc/stubs.o misc/ldr.o misc/res.o \ + misc/debug.o misc/sysinfo.o misc/profile.o \ + misc/mbchars.o misc/muldiv.o misc/getname.o \ + misc/perfcnt.o FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \ file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \ @@ -45,26 +54,43 @@ FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \ MEM_OBJECTS = mem/global.o mem/heap.o mem/isbad.o mem/local.o \ mem/procmem.o mem/section.o mem/virtual.o -NLS_OBJECTS = nls/codepage.o nls/cpmisc.o nls/cptable.o\ - nls/cp37.o nls/cp437.o nls/cp500.o nls/cp737.o nls/cp775.o nls/cp850.o nls/cp852.o nls/cp855.o nls/cp857.o\ - nls/cp860.o nls/cp861.o nls/cp863.o nls/cp865.o nls/cp866.o nls/cp869.o nls/cp875.o nls/cp1026.o\ - nls/cp1250.o nls/cp1251.o nls/cp1252.o nls/cp1253.o nls/cp1254.o nls/cp1255.o nls/cp1256.o nls/cp1257.o\ - nls/cp10000.o nls/cp10006.o nls/cp10007.o nls/cp10029.o nls/cp10079.o nls/cp10081.o\ - nls/lctable.o\ - nls/lcAFK.o nls/lcBEL.o nls/lcBGR.o nls/lcCAT.o nls/lcCSY.o nls/lcDAN.o\ - nls/lcDEA.o nls/lcDEC.o nls/lcDEL.o nls/lcDES.o nls/lcDEU.o\ - nls/lcELL.o\ - nls/lcENA.o nls/lcENB.o nls/lcENC.o nls/lcENG.o nls/lcENI.o nls/lcENJ.o nls/lcENL.o nls/lcENS.o nls/lcENT.o\ - nls/lcENU.o nls/lcENZ.o\ - nls/lcESA.o nls/lcESB.o nls/lcESC.o nls/lcESD.o nls/lcESE.o nls/lcESF.o nls/lcESG.o nls/lcESH.o nls/lcESI.o\ - nls/lcESL.o nls/lcESM.o nls/lcESN.o nls/lcESO.o nls/lcESP.o nls/lcESR.o nls/lcESS.o nls/lcESU.o nls/lcESV.o\ - nls/lcESY.o nls/lcESZ.o\ - nls/lcETI.o nls/lcEUQ.o nls/lcFIN.o nls/lcFOS.o\ - nls/lcFRA.o nls/lcFRB.o nls/lcFRC.o nls/lcFRL.o nls/lcFRS.o\ - nls/lcHRV.o nls/lcHUN.o nls/lcIND.o nls/lcISL.o nls/lcITA.o nls/lcITS.o nls/lcLTH.o nls/lcLVI.o nls/lcNLB.o\ - nls/lcNLD.o nls/lcNON.o nls/lcNOR.o nls/lcPLK.o nls/lcPTB.o nls/lcPTG.o nls/lcROM.o nls/lcRUS.o nls/lcSKY.o\ - nls/lcSLV.o nls/lcSQI.o nls/lcSRB.o nls/lcSRL.o nls/lcSVE.o nls/lcSVF.o nls/lcTRK.o nls/lcUKR.o\ - nls/locale.o nls/mbtowc.o nls/wctomb.o nls/ole2nls.o + +NLS_OBJECTS = nls/codepage.o nls/cpmisc.o \ + nls/cptable.o nls/lctable.o \ + nls/lcAFK.o nls/lcBEL.o nls/lcBGR.o nls/lcCAT.o \ + nls/lcCSY.o nls/lcDAN.o nls/lcDEA.o nls/lcDEC.o \ + nls/lcDEL.o nls/lcDES.o nls/lcDEU.o nls/lcELL.o \ + nls/lcENA.o nls/lcENB.o nls/lcENC.o nls/lcENG.o \ + nls/lcENI.o nls/lcENJ.o nls/lcENL.o nls/lcENS.o \ + nls/lcENT.o nls/lcENU.o nls/lcENZ.o nls/lcESA.o \ + nls/lcESB.o nls/lcESC.o nls/lcESD.o nls/lcESE.o \ + nls/lcESF.o nls/lcESG.o nls/lcESH.o nls/lcESI.o \ + nls/lcESL.o nls/lcESM.o nls/lcESN.o nls/lcESO.o \ + nls/lcESP.o nls/lcESR.o nls/lcESS.o nls/lcESU.o \ + nls/lcESV.o nls/lcESY.o nls/lcESZ.o nls/lcETI.o \ + nls/lcEUQ.o nls/lcFIN.o nls/lcFOS.o nls/lcFRA.o \ + nls/lcFRB.o nls/lcFRC.o nls/lcFRL.o nls/lcFRS.o \ + nls/lcHRV.o nls/lcHUN.o nls/lcIND.o nls/lcISL.o \ + nls/lcITA.o nls/lcITS.o nls/lcLTH.o nls/lcLVI.o \ + nls/lcNLB.o nls/lcNLD.o nls/lcNON.o nls/lcNOR.o \ + nls/lcPLK.o nls/lcPTB.o nls/lcPTG.o nls/lcROM.o \ + nls/lcRUS.o nls/lcSKY.o nls/lcSLV.o nls/lcSQI.o \ + nls/lcSRB.o nls/lcSRL.o nls/lcSVE.o nls/lcSVF.o \ + nls/lcTRK.o nls/lcUKR.o\ + nls/locale.o + +NLS_UNUSED_OBJECTS = nls/mbtowc.o nls/wctomb.o nls/ole2nls.o + +NLS_CP_OBJECTS = \ + nls/cp37.o nls/cp437.o nls/cp500.o nls/cp737.o nls/cp775.o \ + nls/cp850.o nls/cp852.o nls/cp855.o nls/cp857.o \ + nls/cp860.o nls/cp861.o nls/cp863.o nls/cp865.o \ + nls/cp866.o nls/cp869.o nls/cp875.o nls/cp1026.o \ + nls/cp1250.o nls/cp1251.o nls/cp1252.o nls/cp1253.o \ + nls/cp1254.o nls/cp1255.o nls/cp1256.o nls/cp1257.o \ + nls/cp10000.o nls/cp10006.o nls/cp10007.o \ + nls/cp10029.o nls/cp10079.o nls/cp10081.o + THREAD_OBJECTS = \ thread/fiber.o \ @@ -85,7 +111,10 @@ OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \ $(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \ $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) -$(TARGET_NAME).o: $(OBJECTS) +#$(NLS_OBJECTS) + + +$(TARGET_NAME).o: $(OBJECTS) errcodes.rc $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o %/TAGS: diff --git a/lib/kernel32/mem/global.c b/lib/kernel32/mem/global.c index 9fddbff..9f3f2f7 100644 --- a/lib/kernel32/mem/global.c +++ b/lib/kernel32/mem/global.c @@ -11,9 +11,7 @@ * NOTE: Only fixed memory is implemented!! */ -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/mem/heap.c b/lib/kernel32/mem/heap.c index 05c906c..bf77054 100644 --- a/lib/kernel32/mem/heap.c +++ b/lib/kernel32/mem/heap.c @@ -27,8 +27,7 @@ * Put the type definitions of the heap in a seperate header. Boudewijn Dekker */ -#include -#include +#include #define NDEBUG #include @@ -36,11 +35,11 @@ /********************************************************************* * HeapCreate -- KERNEL32 * *********************************************************************/ -HANDLE STDCALL HeapCreate(DWORD flags, DWORD minsize, DWORD maxsize) +HANDLE STDCALL HeapCreate(DWORD flags, DWORD dwInitialSize, DWORD dwMaximumSize) { - DPRINT("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, minsize, maxsize); - return(RtlCreateHeap(flags, NULL, maxsize, minsize, NULL, NULL)); + DPRINT("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, dwInitialSize, dwMaximumSize); + return(RtlCreateHeap(flags, NULL, dwMaximumSize, dwInitialSize, NULL, NULL)); } /********************************************************************* @@ -63,7 +62,7 @@ HANDLE WINAPI GetProcessHeap(VOID) /******************************************************************** * GetProcessHeaps -- KERNEL32 * ********************************************************************/ -DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles ) +DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles) { return(RtlGetProcessHeaps(maxheaps, phandles)); } diff --git a/lib/kernel32/mem/isbad.c b/lib/kernel32/mem/isbad.c index 3be0666..ec1afa8 100644 --- a/lib/kernel32/mem/isbad.c +++ b/lib/kernel32/mem/isbad.c @@ -5,7 +5,7 @@ * ReactOS Operating System * */ -#include +#include /* FIXME: Stubs. What is it for? */ UINT diff --git a/lib/kernel32/mem/local.c b/lib/kernel32/mem/local.c index c0a0391..0f42196 100644 --- a/lib/kernel32/mem/local.c +++ b/lib/kernel32/mem/local.c @@ -21,9 +21,7 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/mem/procmem.c b/lib/kernel32/mem/procmem.c index 3a2b0f8..00832cd 100644 --- a/lib/kernel32/mem/procmem.c +++ b/lib/kernel32/mem/procmem.c @@ -9,10 +9,7 @@ /* INCLUDES ******************************************************************/ - -#include -#include -#include +#include /* FUNCTIONS *****************************************************************/ WINBOOL diff --git a/lib/kernel32/mem/section.c b/lib/kernel32/mem/section.c index 42c8204..7eb800c 100644 --- a/lib/kernel32/mem/section.c +++ b/lib/kernel32/mem/section.c @@ -9,10 +9,9 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include +#include +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ @@ -82,6 +81,7 @@ CreateFileMappingW(HANDLE hFile, NTSTATUS Status; HANDLE SectionHandle; LARGE_INTEGER MaximumSize; + PLARGE_INTEGER MaximumSizePointer; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING UnicodeName; PSECURITY_DESCRIPTOR SecurityDescriptor; @@ -95,8 +95,16 @@ CreateFileMappingW(HANDLE hFile, SecurityDescriptor = NULL; } - MaximumSize.u.LowPart = dwMaximumSizeLow; - MaximumSize.u.HighPart = dwMaximumSizeHigh; + if ((dwMaximumSizeLow == 0) && (dwMaximumSizeHigh == 0)) + { + MaximumSizePointer = NULL; + } + else + { + MaximumSize.u.LowPart = dwMaximumSizeLow; + MaximumSize.u.HighPart = dwMaximumSizeHigh; + MaximumSizePointer = &MaximumSize; + } RtlInitUnicodeString(&UnicodeName, lpName); InitializeObjectAttributes(&ObjectAttributes, @@ -107,7 +115,7 @@ CreateFileMappingW(HANDLE hFile, Status = NtCreateSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes, - &MaximumSize, + MaximumSizePointer, flProtect, 0, hFile); diff --git a/lib/kernel32/mem/virtual.c b/lib/kernel32/mem/virtual.c index 1b5a52a..beded07 100644 --- a/lib/kernel32/mem/virtual.c +++ b/lib/kernel32/mem/virtual.c @@ -9,9 +9,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include +#include /* FUNCTIONS *****************************************************************/ diff --git a/lib/kernel32/misc/atom.c b/lib/kernel32/misc/atom.c index 64e59d4..6243f35 100644 --- a/lib/kernel32/misc/atom.c +++ b/lib/kernel32/misc/atom.c @@ -10,9 +10,7 @@ * Full rewrite 27/05/2001 */ -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/misc/comm.c b/lib/kernel32/misc/comm.c index 4ffd707..51b4adc 100644 --- a/lib/kernel32/misc/comm.c +++ b/lib/kernel32/misc/comm.c @@ -10,67 +10,733 @@ * UPDATE HISTORY: * Created 01/11/98 * RDD (30/09/2002) implemented many function bodies to call serial driver. + * KJK (11/02/2003) implemented BuildCommDCB & BuildCommDCBAndTimeouts */ -#include -#include -#include -#include -#include -#include +#include -//#define NDEBUG -#define DBG +#define NDEBUG #include -#include +/* BUILDCOMMDCB & BUILDCOMMDCBANDTIMEOUTS */ + +/* TYPES */ + +/* Pointer to a callback that handles a particular parameter */ +typedef BOOL (*COMMDCB_PARAM_CALLBACK) +( + DCB *, + COMMTIMEOUTS *, + BOOL *, + LPWSTR * +); + +/* Symbolic flag of any length */ +typedef struct _COMMDCB_PARAM_STRFLAG +{ + UNICODE_STRING String; + ULONG_PTR Value; +} COMMDCB_PARAM_STRFLAG; + +/* One char long symbolic flag */ +typedef struct _COMMDCB_PARAM_CHARFLAG +{ + WCHAR Char; + ULONG_PTR Value; +} COMMDCB_PARAM_CHARFLAG; + +/* MACROS */ +/* stupid Borland C++ requires this */ +#define _L(__S__) L ## __S__ + +/* Declare a parameter handler */ +#define COMMDCB_PARAM_HANDLER(__P__) \ + BOOL COMMDCB_ ## __P__ ## Param \ + ( \ + DCB * Dcb, \ + COMMTIMEOUTS * Timeouts, \ + BOOL * StopBitsSet, \ + LPWSTR * StrTail \ + ) + +/* UTILITIES */ +/* + Lookup a string flag and return its numerical value. The flags array must be + sorted - a dichotomycal search is performed +*/ +BOOL COMMDCB_LookupStrFlag +( + UNICODE_STRING * Flag, + COMMDCB_PARAM_STRFLAG * Flags, + int FlagCount, + ULONG_PTR * Value +) +{ + /* Lower and upper bound for dichotomycal search */ + int nLowerBound = 0; + int nUpperBound = FlagCount - 1; + + do + { + LONG nComparison; + /* pick the element in the middle of the area of interest as the pivot */ + int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2; + + /* compare the string with the pivot */ + nComparison = RtlCompareUnicodeString + ( + Flag, + &Flags[nCurFlag].String, + TRUE + ); + + /* string is equal */ + if(nComparison == 0) + { + /* return the flag's value */ + *Value = Flags[nCurFlag].Value; + + /* success */ + return TRUE; + } + /* string is less than */ + else if(nComparison < 0) + { + /* + restrict the search to the first half of the current slice, minus the pivot + */ + nUpperBound = nCurFlag - 1; + + /* fallthrough */ + } + /* string is greater than */ + else + { + /* + restrict the search to the second half of the current slice, minus the pivot + */ + nLowerBound = nCurFlag + 1; + + /* fallthrough */ + } + } + /* continue until the slice is empty */ + while(nLowerBound <= nUpperBound); + + /* string not found: failure */ + return FALSE; +} + +/* PARSERS */ +/* + Find the next character flag and return its numerical value. The flags array + must be sorted - a dichotomycal search is performed +*/ +BOOL COMMDCB_ParseCharFlag +( + LPWSTR * StrTail, + COMMDCB_PARAM_CHARFLAG * Flags, + int FlagCount, + ULONG_PTR * Value +) +{ + /* Lower and upper bound for dichotomycal search */ + int nLowerBound = 0; + int nUpperBound = FlagCount - 1; + /* get the first character as the flag */ + WCHAR wcFlag = (*StrTail)[0]; + + /* premature end of string, or the character is whitespace */ + if(!wcFlag || iswspace(wcFlag)) + /* failure */ + return FALSE; + + /* uppercase the character for case-insensitive search */ + wcFlag = towupper(wcFlag); + + /* skip the character flag */ + ++ (*StrTail); + + /* see COMMDCB_LookupStrFlag for a description of the algorithm */ + do + { + LONG nComparison; + int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2; + + nComparison = wcFlag - towupper(Flags[nCurFlag].Char); + + if(nComparison == 0) + { + *Value = Flags[nCurFlag].Value; + + return TRUE; + } + else if(nComparison < 0) + { + nUpperBound = nCurFlag - 1; + } + else + { + nLowerBound = nCurFlag + 1; + } + } + while(nUpperBound >= nLowerBound); + + /* flag not found: failure */ + return FALSE; +} + +/* + Find the next string flag and return its numerical value. The flags array must + be sorted - a dichotomycal search is performed +*/ +BOOL COMMDCB_ParseStrFlag +( + LPWSTR * StrTail, + COMMDCB_PARAM_STRFLAG * Flags, + int FlagCount, + ULONG_PTR * Value +) +{ + LPWSTR pwcNewTail = *StrTail; + UNICODE_STRING wstrFlag; + + /* scan the string until the first space character or the terminating null */ + while(pwcNewTail[0] && !iswspace(pwcNewTail[0])) + ++ pwcNewTail; + + /* string flag empty */ + if(pwcNewTail == *StrTail) + /* failure */ + return FALSE; + + /* build the UNICODE_STRING description of the string flag */ + wstrFlag.Buffer = *StrTail; + wstrFlag.Length = (pwcNewTail - *StrTail) * sizeof(WCHAR); + wstrFlag.MaximumLength = wstrFlag.Length; + + /* skip the string flag */ + *StrTail = pwcNewTail; + + /* lookup the string flag's value and return it */ + return COMMDCB_LookupStrFlag(&wstrFlag, Flags, FlagCount, Value); +} + +/* + Parse a boolean value in the symbolic form on/off +*/ +BOOL COMMDCB_ParseBool(LPWSTR * StrTail, BOOL * Value) +{ + BOOL bRetVal; + ULONG_PTR nValue; + static COMMDCB_PARAM_STRFLAG a_BoolFlags[] = + { + { UNICODE_STRING_INITIALIZER(L"off"), FALSE }, + { UNICODE_STRING_INITIALIZER(L"on"), TRUE } + }; + + /* try to recognize the next flag as a boolean */ + bRetVal = COMMDCB_ParseStrFlag + ( + StrTail, + a_BoolFlags, + sizeof(a_BoolFlags) / sizeof(a_BoolFlags[0]), + &nValue + ); + + /* failure */ + if(!bRetVal) return FALSE; + + /* success */ + *Value = nValue ? TRUE : FALSE; + return TRUE; +} + +/* + Parse a decimal integer +*/ +BOOL COMMDCB_ParseInt(LPWSTR * StrTail, DWORD * Value) +{ + LPWSTR pwcPrevTail = *StrTail; + DWORD nValue = wcstoul(*StrTail, StrTail, 10); + + /* no character was consumed: failure */ + if(pwcPrevTail == *StrTail) return FALSE; + + /* success */ + *Value = nValue; + return TRUE; +} + +/* PARAMETER HANDLERS */ +/* baud= */ +COMMDCB_PARAM_HANDLER(baud) +{ + DWORD nValue; + + (void)Timeouts; + + /* parse the baudrate */ + if(!COMMDCB_ParseInt(StrTail, &nValue)) + /* failure */ + return FALSE; + + switch(nValue) + { + /* documented abbreviations */ + case 11: Dcb->BaudRate = 110; break; + case 15: Dcb->BaudRate = 150; break; + case 30: Dcb->BaudRate = 300; break; + case 60: Dcb->BaudRate = 600; break; + case 12: Dcb->BaudRate = 1200; break; + case 24: Dcb->BaudRate = 2400; break; + case 48: Dcb->BaudRate = 4800; break; + case 96: Dcb->BaudRate = 9600; break; + case 19: Dcb->BaudRate = 19200; break; + /* literal value */ + default: Dcb->BaudRate = nValue; break; + } + + /* if the stop bits haven't been specified explicitely */ + if(!(*StopBitsSet)) + { + /* default the stop bits to 2 for 110 baud */ + if(Dcb->BaudRate == 110) Dcb->StopBits = TWOSTOPBITS; + /* else, default the stop bits to 1 */ + else Dcb->StopBits = ONESTOPBIT; + } + + /* success */ + return TRUE; +} + +/* data= */ +COMMDCB_PARAM_HANDLER(data) +{ + DWORD nValue; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the data bits */ + if(!COMMDCB_ParseInt(StrTail, &nValue)) + /* failure */ + return FALSE; + + /* value out of range: failure */ + if(nValue < 5 || nValue > 8) return FALSE; + + /* success */ + Dcb->ByteSize = nValue; + return TRUE; +} + +/* dtr= */ +COMMDCB_PARAM_HANDLER(dtr) +{ + BOOL bRetVal; + ULONG_PTR nValue; + static COMMDCB_PARAM_STRFLAG a_DTRFlags[] = + { + { UNICODE_STRING_INITIALIZER(L"hs"), DTR_CONTROL_HANDSHAKE }, + { UNICODE_STRING_INITIALIZER(L"off"), DTR_CONTROL_DISABLE }, + { UNICODE_STRING_INITIALIZER(L"on"), DTR_CONTROL_ENABLE } + }; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + bRetVal = COMMDCB_ParseStrFlag + ( + StrTail, + a_DTRFlags, + sizeof(a_DTRFlags) / sizeof(a_DTRFlags[0]), + &nValue + ); + + /* failure */ + if(!bRetVal) return FALSE; + + /* success */ + Dcb->fDtrControl = nValue; + return TRUE; +} + +/* idsr= */ +COMMDCB_PARAM_HANDLER(idsr) +{ + BOOL bValue; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + if(!COMMDCB_ParseBool(StrTail, &bValue)) + /* failure */ + return FALSE; + + /* success */ + Dcb->fDsrSensitivity = bValue; + return TRUE; +} + +/* octs= */ +COMMDCB_PARAM_HANDLER(octs) +{ + BOOL bValue; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + if(!COMMDCB_ParseBool(StrTail, &bValue)) + /* failure */ + return FALSE; + + /* success */ + Dcb->fOutxCtsFlow = bValue; + return TRUE; +} + +/* odsr= */ +COMMDCB_PARAM_HANDLER(odsr) +{ + BOOL bValue; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + if(!COMMDCB_ParseBool(StrTail, &bValue)) + /* failure */ + return FALSE; + + /* success */ + Dcb->fOutxDsrFlow = bValue; + return TRUE; +} + +/* parity= */ +COMMDCB_PARAM_HANDLER(parity) +{ + BOOL bRetVal; + ULONG_PTR nValue; + static COMMDCB_PARAM_CHARFLAG a_ParityFlags[] = + { + { L'e', EVENPARITY }, + { L'm', MARKPARITY }, + { L'n', NOPARITY }, + { L'o', ODDPARITY }, + { L's', SPACEPARITY } + }; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + bRetVal = COMMDCB_ParseCharFlag + ( + StrTail, + a_ParityFlags, + sizeof(a_ParityFlags) / sizeof(a_ParityFlags[0]), + &nValue + ); + + /* failure */ + if(!bRetVal) return FALSE; + + /* success */ + Dcb->Parity = nValue; + return TRUE; +} + +/* rts= */ +COMMDCB_PARAM_HANDLER(rts) +{ + DWORD nRetVal; + ULONG_PTR nValue; + static COMMDCB_PARAM_STRFLAG a_RTSFlags[] = + { + { UNICODE_STRING_INITIALIZER(L"hs"), RTS_CONTROL_HANDSHAKE }, + { UNICODE_STRING_INITIALIZER(L"off"), RTS_CONTROL_DISABLE }, + { UNICODE_STRING_INITIALIZER(L"on"), RTS_CONTROL_ENABLE }, + { UNICODE_STRING_INITIALIZER(L"tg"), RTS_CONTROL_TOGGLE } + }; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + nRetVal = COMMDCB_ParseStrFlag + ( + StrTail, + a_RTSFlags, + sizeof(a_RTSFlags) / sizeof(a_RTSFlags[0]), + &nValue + ); + + /* failure */ + if(!nRetVal) return FALSE; + + /* success */ + Dcb->fRtsControl = nValue; + return TRUE; +} + +/* stop= */ +COMMDCB_PARAM_HANDLER(stop) +{ + BOOL bRetVal; + ULONG_PTR nValue; + static COMMDCB_PARAM_STRFLAG a_StopFlags[] = + { + { UNICODE_STRING_INITIALIZER(L"1"), ONESTOPBIT }, + { UNICODE_STRING_INITIALIZER(L"1.5"), ONE5STOPBITS }, + { UNICODE_STRING_INITIALIZER(L"2"), TWOSTOPBITS } + }; + + (void)Timeouts; + + /* parse the flag */ + bRetVal = COMMDCB_ParseStrFlag + ( + StrTail, + a_StopFlags, + sizeof(a_StopFlags) / sizeof(a_StopFlags[0]), + &nValue + ); + + /* failure */ + if(!bRetVal) return FALSE; + + /* tell the baud= handler that the stop bits have been specified explicitely */ + *StopBitsSet = TRUE; + + /* success */ + Dcb->StopBits = nValue; + return TRUE; +} + +/* to= */ +COMMDCB_PARAM_HANDLER(to) +{ + BOOL bValue; + + (void)Dcb; + (void)StopBitsSet; + + /* parse the flag */ + if(!COMMDCB_ParseBool(StrTail, &bValue)) + /* failure */ + return FALSE; + + /* for BuildCommDCB(), Timeouts is NULL */ + if(Timeouts) + { + /* why? no idea. All values taken from Windows 2000 with experimentation */ + Timeouts->ReadIntervalTimeout = 0; + Timeouts->ReadTotalTimeoutMultiplier = 0; + Timeouts->ReadTotalTimeoutConstant = 0; + Timeouts->WriteTotalTimeoutMultiplier = 0; + + /* timeout */ + if(bValue) Timeouts->WriteTotalTimeoutConstant = 60000; + /* no timeout */ + else Timeouts->WriteTotalTimeoutConstant = 0; + } + + /* success */ + return TRUE; +} + +/* xon= */ +COMMDCB_PARAM_HANDLER(xon) +{ + BOOL bValue; + + (void)Timeouts; + (void)StopBitsSet; + + /* parse the flag */ + if(!COMMDCB_ParseBool(StrTail, &bValue)) + /* failure */ + return FALSE; + + /* XON/XOFF */ + if(bValue) Dcb->fInX = Dcb->fOutX = TRUE; + /* no XON/XOFF */ + else Dcb->fInX = Dcb->fOutX = FALSE; + + /* success */ + return TRUE; +} + +/* FUNCTIONS */ +#define COMMDCB_PARAM(__P__) \ + { \ + UNICODE_STRING_INITIALIZER(_L(#__P__)), \ + (ULONG_PTR)&COMMDCB_ ## __P__ ## Param \ + } WINBOOL STDCALL -BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB) +BuildCommDCBAndTimeoutsW +( + LPCWSTR lpDef, + LPDCB lpDCB, + LPCOMMTIMEOUTS lpCommTimeouts +) { - if (lpDCB == NULL) { - DPRINT("ERROR: BuildCommDCBA() - NULL DCB pointer\n"); - return FALSE; - } - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + /* tell the baud= handler that the stop bits should be defaulted */ + BOOL bStopBitsSet = FALSE; + + /* parameter validation */ + if(lpDCB->DCBlength != sizeof(DCB)) goto InvalidParam; + + /* set defaults */ + lpDCB->StopBits = ONESTOPBIT; + + /* + The documentation for MODE says that data= defaults to 7, but BuildCommDCB + doesn't seem to set it + */ + /* lpDCB->ByteSize = 7; */ + + /* skip COMx[n] */ + if + ( + lpDef[0] && + towupper(lpDef[0]) == L'C' && + lpDef[1] && + towupper(lpDef[1]) == L'O' && + lpDef[2] && + towupper(lpDef[2]) == L'M' + ) + { + DWORD nDummy; + + /* skip "COM" */ + lpDef += 3; + + /* premature end of string */ + if(!lpDef[0]) goto InvalidParam; + + /* skip "x" */ + if(!COMMDCB_ParseInt((LPWSTR *)&lpDef, &nDummy)) goto InvalidParam; + + /* skip ":" */ + if(lpDef[0] == L':') ++ lpDef; + } + + /* skip leading whitespace */ + while(lpDef[0] && iswspace(lpDef[0])) ++ lpDef; + + /* repeat until the end of the string */ + while(lpDef[0]) + { + static COMMDCB_PARAM_STRFLAG a_Params[] = + { + COMMDCB_PARAM(baud), + COMMDCB_PARAM(data), + COMMDCB_PARAM(dtr), + COMMDCB_PARAM(idsr), + COMMDCB_PARAM(octs), + COMMDCB_PARAM(odsr), + COMMDCB_PARAM(parity), + COMMDCB_PARAM(rts), + COMMDCB_PARAM(stop), + COMMDCB_PARAM(to), + COMMDCB_PARAM(xon) + }; + BOOL bRetVal; + COMMDCB_PARAM_CALLBACK pCallback; + UNICODE_STRING wstrParam; + LPWSTR pwcPrevTail = (LPWSTR)lpDef; + + /* get the parameter */ + while(lpDef[0] && lpDef[0] != L'=') ++ lpDef; + + /* premature end of string */ + if(!lpDef[0]) goto InvalidParam; + + /* build the parameter's UNICODE_STRING */ + wstrParam.Buffer = pwcPrevTail; + wstrParam.Length = (lpDef - pwcPrevTail) * sizeof(WCHAR); + wstrParam.MaximumLength = wstrParam.Length; + + /* skip the "=" */ + ++ lpDef; + + /* lookup the callback for the parameter */ + bRetVal = COMMDCB_LookupStrFlag + ( + &wstrParam, + a_Params, + sizeof(a_Params) / sizeof(a_Params[0]), + (ULONG_PTR *)&pCallback + ); + + /* invalid parameter */ + if(!bRetVal) goto InvalidParam; + + /* call the callback to parse the parameter's argument */ + if(!pCallback(lpDCB, lpCommTimeouts, &bStopBitsSet, (LPWSTR *)&lpDef)) + /* failure */ + goto InvalidParam; + + /* skip trailing whitespace */ + while(lpDef[0] && iswspace(lpDef[0])) ++ lpDef; + } + + /* success */ + return TRUE; + +InvalidParam: + /* failure */ + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } + WINBOOL STDCALL -BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB) +BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) { - if (lpDCB == NULL) { - DPRINT("ERROR: BuildCommDCBW() - NULL DCB pointer\n"); - return FALSE; - } - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + NTSTATUS nErrCode; + WINBOOL bRetVal; + ANSI_STRING strDef; + UNICODE_STRING wstrDef; + + RtlInitAnsiString(&strDef, (LPSTR)lpDef); + + nErrCode = RtlAnsiStringToUnicodeString(&wstrDef, &strDef, TRUE); + + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return FALSE; + } + + bRetVal = BuildCommDCBAndTimeoutsW(wstrDef.Buffer, lpDCB, lpCommTimeouts); + + RtlFreeUnicodeString(&wstrDef); + + return bRetVal; } WINBOOL STDCALL -BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) +BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB) { - if (lpDCB == NULL) { - DPRINT("ERROR: BuildCommDCBAndTimeoutsA() - NULL DCB pointer\n"); - return FALSE; - } - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + return BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL); } WINBOOL STDCALL -BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) +BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB) { - if (lpDCB == NULL) { - DPRINT("ERROR: BuildCommDCBAndTimeoutsW() - NULL DCB pointer\n"); - return FALSE; - } - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + return BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL); } WINBOOL diff --git a/lib/kernel32/misc/console.c b/lib/kernel32/misc/console.c index ab75193..bb2a5c0 100644 --- a/lib/kernel32/misc/console.c +++ b/lib/kernel32/misc/console.c @@ -13,18 +13,10 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include - -#include -#include +#include #define NDEBUG #include -#include /* GLOBALS *******************************************************************/ @@ -937,7 +929,7 @@ PeekConsoleInputA( LPDWORD lpNumberOfEventsRead ) { - PCSRSS_API_REQUEST Request; + PCSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; NTSTATUS Status; PVOID BufferBase; @@ -1118,8 +1110,55 @@ WriteConsoleInputA( LPDWORD lpNumberOfEventsWritten ) { -/* TO DO */ - return FALSE; + PCSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + PVOID BufferBase, BufferTargetBase; + NTSTATUS Status; + DWORD Size; + + if(lpBuffer == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + Size = nLength * sizeof(INPUT_RECORD); + + Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST)); + if(Request == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + CsrReleaseParameterBuffer(BufferBase); + return FALSE; + } + + Request->Type = CSRSS_WRITE_CONSOLE_INPUT; + Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput; + Request->Data.WriteConsoleInputRequest.Length = nLength; + Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase; + + Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); + if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); + return FALSE; + } + + if(lpNumberOfEventsWritten != NULL) + *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length; + + RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); + + return TRUE; } @@ -1155,8 +1194,62 @@ ReadConsoleOutputA( PSMALL_RECT lpReadRegion ) { -/* TO DO */ - return FALSE; + PCSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + PVOID BufferBase; + PVOID BufferTargetBase; + NTSTATUS Status; + DWORD Size, SizeX, SizeY; + + if(lpBuffer == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO); + + Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST)); + if(Request == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + CsrReleaseParameterBuffer(BufferBase); + return FALSE; + } + + Request->Type = CSRSS_READ_CONSOLE_OUTPUT; + Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput; + Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize; + Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord; + Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion; + Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase; + + Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); + if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus(Status); + RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); + return FALSE; + } + + SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1; + SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1; + + memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY); + *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion; + + RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); + + return TRUE; } @@ -1213,6 +1306,7 @@ WriteConsoleOutputA(HANDLE hConsoleOutput, sizeof(CSRSS_API_REQUEST)); if (Request == NULL) { + CsrReleaseParameterBuffer(BufferBase); SetLastError(ERROR_OUTOFMEMORY); return FALSE; } @@ -1229,6 +1323,7 @@ WriteConsoleOutputA(HANDLE hConsoleOutput, sizeof(CSRSS_API_REPLY)); if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { + CsrReleaseParameterBuffer(BufferBase); RtlFreeHeap(GetProcessHeap(), 0, Request); SetLastErrorByStatus(Status); return FALSE; @@ -1461,6 +1556,8 @@ WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, lpCharacter += Size; Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord; } + + RtlFreeHeap( GetProcessHeap(), 0, Request ); return TRUE; } @@ -1527,7 +1624,7 @@ WriteConsoleOutputAttribute( Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) ); if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) { - RtlFreeHeap( GetProcessHeap(), 0, Request ); + RtlFreeHeap( GetProcessHeap(), 0, Request ); SetLastErrorByStatus ( Status ); return FALSE; } @@ -1535,6 +1632,8 @@ WriteConsoleOutputAttribute( lpAttribute += Size; Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord; } + + RtlFreeHeap( GetProcessHeap(), 0, Request ); return TRUE; } @@ -1626,9 +1725,9 @@ GetNumberOfConsoleInputEvents( Request.Type = CSRSS_GET_NUM_INPUT_EVENTS; Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput; Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); - if(!NT_SUCCESS(Status) || !NT_SUCCESS(Reply.Status)) + if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { - SetLastErrorByStatus(Reply.Status); + SetLastErrorByStatus(Status); return FALSE; } @@ -1913,7 +2012,7 @@ WINBASEAPI BOOL WINAPI SetConsoleTextAttribute( - HANDLE hConsoleOutput, + HANDLE hConsoleOutput, WORD wAttributes ) { diff --git a/lib/kernel32/misc/debug.c b/lib/kernel32/misc/debug.c index 10a1faf..78e2279 100644 --- a/lib/kernel32/misc/debug.c +++ b/lib/kernel32/misc/debug.c @@ -9,12 +9,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include -#include +#include /* FUNCTIONS *****************************************************************/ diff --git a/lib/kernel32/misc/dllmain.c b/lib/kernel32/misc/dllmain.c index 0005813..25d0529 100644 --- a/lib/kernel32/misc/dllmain.c +++ b/lib/kernel32/misc/dllmain.c @@ -11,11 +11,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include +#include #define NDEBUG #include @@ -83,6 +79,8 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { + (void)lpReserved; + DPRINT("DllMain(hInst %x, ul_reason_for_call %d)\n", hInst, ul_reason_for_call); diff --git a/lib/kernel32/misc/env.c b/lib/kernel32/misc/env.c index 7375940..0e32c9e 100644 --- a/lib/kernel32/misc/env.c +++ b/lib/kernel32/misc/env.c @@ -9,15 +9,10 @@ * Created 01/11/98 */ -#include -#include -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ******************************************************************/ @@ -216,48 +211,185 @@ DWORD STDCALL GetVersion(VOID) { - DWORD Version = 0; - OSVERSIONINFO VersionInformation; - GetVersionExW(&VersionInformation); + PPEB pPeb = NtCurrentPeb(); + DWORD nVersion; - Version |= ( VersionInformation.dwMajorVersion << 8 ); - Version |= VersionInformation.dwMinorVersion; + nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion); - Version |= ( VersionInformation.dwPlatformId << 16 ); + /* behave consistently when posing as another operating system */ + /* build number */ + if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS) + nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16; + + /* non-NT platform flag */ + if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT) + nVersion |= 0x80000000; - return Version; + return nVersion; } WINBOOL STDCALL GetVersionExW( - LPOSVERSIONINFO lpVersionInformation + LPOSVERSIONINFOW lpVersionInformation ) { - lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - lpVersionInformation->dwMajorVersion = 4; - lpVersionInformation->dwMinorVersion = 0; - lpVersionInformation->dwBuildNumber = 12; - lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT; - lstrcpyW((WCHAR *)lpVersionInformation->szCSDVersion,L"Ariadne was here..."); - return TRUE; + PPEB pPeb = NtCurrentPeb(); + + /* TODO: move this into RtlGetVersion */ + switch(lpVersionInformation->dwOSVersionInfoSize) + { + case sizeof(OSVERSIONINFOEXW): + { + LPOSVERSIONINFOEXW lpVersionInformationEx = + (LPOSVERSIONINFOEXW)lpVersionInformation; + + lpVersionInformationEx->wServicePackMajor = pPeb->SPMajorVersion; + lpVersionInformationEx->wServicePackMinor = pPeb->SPMinorVersion; + /* TODO: read from the KUSER_SHARED_DATA */ + lpVersionInformationEx->wSuiteMask = 0; + /* TODO: call RtlGetNtProductType */ + lpVersionInformationEx->wProductType = 0; + /* ??? */ + lpVersionInformationEx->wReserved = 0; + /* fall through */ + } + + case sizeof(OSVERSIONINFOW): + { + lpVersionInformation->dwMajorVersion = pPeb->OSMajorVersion; + lpVersionInformation->dwMinorVersion = pPeb->OSMinorVersion; + lpVersionInformation->dwBuildNumber = pPeb->OSBuildNumber; + lpVersionInformation->dwPlatformId = pPeb->OSPlatformId; + + /* version string is "ReactOS x.y.z" */ + wcsncpy + ( + lpVersionInformation->szCSDVersion, + L"ReactOS " KERNEL_VERSION_STR, + sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) + ); + + /* null-terminate, just in case */ + lpVersionInformation->szCSDVersion + [ + sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) - 1 + ] = 0; + + break; + } + + default: + { + /* unknown version information revision */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + } + + return TRUE; } WINBOOL STDCALL GetVersionExA( - LPOSVERSIONINFO lpVersionInformation + LPOSVERSIONINFOA lpVersionInformation ) { - lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - lpVersionInformation->dwMajorVersion = 4; - lpVersionInformation->dwMinorVersion = 0; - lpVersionInformation->dwBuildNumber = 12; - lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT; - lstrcpyA((char *)lpVersionInformation->szCSDVersion,"ReactOs Pre-Alpha"); - return TRUE; + NTSTATUS nErrCode; + OSVERSIONINFOEXW oviVerInfo; + LPOSVERSIONINFOEXA lpVersionInformationEx; + + /* UNICODE_STRING descriptor of the Unicode version string */ + UNICODE_STRING wstrVerStr = + { + /* + gives extra work to RtlUnicodeStringToAnsiString, but spares us an + RtlInitUnicodeString round + */ + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) - + 1, + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]), + oviVerInfo.szCSDVersion + }; + + /* ANSI_STRING descriptor of the ANSI version string buffer */ + ANSI_STRING strVerStr = + { + 0, + sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion) * + sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion[0]) - + 1, + lpVersionInformation->szCSDVersion + }; + + switch(lpVersionInformation->dwOSVersionInfoSize) + { + case sizeof(OSVERSIONINFOEXA): + { + oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + break; + } + + case sizeof(OSVERSIONINFOA): + { + oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + break; + } + + default: + { + /* unknown version information revision */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + } + + if(!GetVersionExW((LPOSVERSIONINFOW)&oviVerInfo)) + return FALSE; + + /* null-terminate, just in case */ + oviVerInfo.szCSDVersion + [ + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) - + 1 + ] = 0; + + /* convert the version string */ + nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + SetLastErrorByStatus(nErrCode); + return FALSE; + } + + /* copy the fields */ + lpVersionInformation->dwMajorVersion = oviVerInfo.dwMajorVersion; + lpVersionInformation->dwMinorVersion = oviVerInfo.dwMinorVersion; + lpVersionInformation->dwBuildNumber = oviVerInfo.dwBuildNumber; + lpVersionInformation->dwPlatformId = oviVerInfo.dwPlatformId; + + if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOEXA)) + /* success */ + return TRUE; + + /* copy the extended fields */ + lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation; + lpVersionInformationEx->wServicePackMajor = oviVerInfo.wServicePackMajor; + lpVersionInformationEx->wServicePackMinor = oviVerInfo.wServicePackMinor; + lpVersionInformationEx->wSuiteMask = oviVerInfo.wSuiteMask; + lpVersionInformationEx->wProductType = oviVerInfo.wProductType; + lpVersionInformationEx->wReserved = oviVerInfo.wReserved; + + /* success */ + return TRUE; } @@ -365,7 +497,8 @@ FreeEnvironmentStringsW ( LPWSTR EnvironmentStrings ) { - return TRUE; + (void)EnvironmentStrings; + return TRUE; } diff --git a/lib/kernel32/misc/error.c b/lib/kernel32/misc/error.c index ca49750..31194ac 100644 --- a/lib/kernel32/misc/error.c +++ b/lib/kernel32/misc/error.c @@ -3,12 +3,11 @@ * reactos/lib/kernel32/misc/error.c * */ -#include -#include -// #define NDEBUG +#include + +#define NDEBUG #include -#include /* INTERNAL */ diff --git a/lib/kernel32/misc/errormsg.c b/lib/kernel32/misc/errormsg.c new file mode 100644 index 0000000..162f964 --- /dev/null +++ b/lib/kernel32/misc/errormsg.c @@ -0,0 +1,796 @@ +/* $Id$ + * + * reactos/lib/kernel32/misc/errormsg.c + * + */ +/* + * FormatMessage implementation + * + * Copyright 1996 Marcus Meissner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +// #define NDEBUG +#include +#include + +#define USE_WINE_PORT + +#ifdef USE_WINE_PORT + +//#define NDEBUG +//#include + +//#define DPRINTF DPRINT +//#define ERR DPRINT +//#define SetLastError(x) +//#define WARN DPRINT +#define TRACE DPRINT +#define FIXME DPRINT + +#define strlenW lstrlen +#define strlen lstrlen + +#define MAKEINTRESOURCE(i) (LPTSTR) ((DWORD) ((WORD) (i))) +//#define MAKEINTRESOURCEA(i) (LPTSTR) ((DWORD) ((WORD) (i))) +//#define MAKEINTRESOURCEW(i) (LPTSTR) ((DWORD) ((WORD) (i))) + +#define MAKEINTRESOURCEA(i) (LPSTR)((ULONG_PTR)((WORD)(i))) +#define MAKEINTRESOURCEW(i) (LPWSTR)((ULONG_PTR)((WORD)(i))) +//#define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE) + + + +int HEAP_strdupWtoA(HANDLE hHeap, int flags, LPWSTR lpSource) +{ + return 0; +} + +/* INTERNAL */ + +//#include "config.h" + +#include +#include + +//#include "windef.h" +//#include "winbase.h" +//#include "winerror.h" +//#include "winuser.h" +//#include "winnls.h" +//#include "wine/unicode.h" +//#include "heap.h" +//#include "wine/debug.h" + +//WINE_DEFAULT_DEBUG_CHANNEL(resource); + +typedef struct tagMESSAGE_RESOURCE_ENTRY { + WORD Length; + WORD Flags; + BYTE Text[1]; +} MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY; +#define MESSAGE_RESOURCE_UNICODE 0x0001 + +typedef struct tagMESSAGE_RESOURCE_BLOCK { + DWORD LowId; + DWORD HighId; + DWORD OffsetToEntries; +} MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK; + +typedef struct tagMESSAGE_RESOURCE_DATA { + DWORD NumberOfBlocks; + MESSAGE_RESOURCE_BLOCK Blocks[ 1 ]; +} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; + + +//#define RT_RCDATAA MAKEINTRESOURCEA(10) +//#define RT_RCDATAW MAKEINTRESOURCEW(10) +////#define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA) +//#define RT_MESSAGETABLEA MAKEINTRESOURCEA(11) +#define RT_MESSAGETABLEW MAKEINTRESOURCEW(11) +////#define RT_MESSAGETABLE WINELIB_NAME_AW(RT_MESSAGETABLE) + +/* Messages...used by FormatMessage32* (KERNEL32.something) + * + * They can be specified either directly or using a message ID and + * loading them from the resource. + * + * The resourcedata has following format: + * start: + * 0: DWORD nrofentries + * nrofentries * subentry: + * 0: DWORD firstentry + * 4: DWORD lastentry + * 8: DWORD offset from start to the stringentries + * + * (lastentry-firstentry) * stringentry: + * 0: WORD len (0 marks end) [ includes the 4 byte header length ] + * 2: WORD flags + * 4: CHAR[len-4] + * (stringentry i of a subentry refers to the ID 'firstentry+i') + * + * Yes, ANSI strings in win32 resources. Go figure. + */ + +/********************************************************************** + * load_messageA (internal) + */ +static INT load_messageA( HMODULE instance, UINT id, WORD lang, + LPSTR buffer, INT buflen ) +{ + HGLOBAL hmem; + HRSRC hrsrc; + PMESSAGE_RESOURCE_DATA mrd; + PMESSAGE_RESOURCE_BLOCK mrb; + PMESSAGE_RESOURCE_ENTRY mre; + int i,slen; + + //TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); + + /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ + hrsrc = FindResourceExW(instance,RT_MESSAGETABLEW,(LPWSTR)1,lang); + if (!hrsrc) return 0; + hmem = LoadResource( instance, hrsrc ); + if (!hmem) return 0; + + mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); + mre = NULL; + mrb = &(mrd->Blocks[0]); + for (i=mrd->NumberOfBlocks;i--;) { + if ((id>=mrb->LowId) && (id<=mrb->HighId)) { + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); + id -= mrb->LowId; + break; + } + mrb++; + } + if (!mre) + return 0; + for (i=id;i--;) { + if (!mre->Length) + return 0; + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+mre->Length); + } + slen=mre->Length; + //TRACE(" - strlen=%d\n",slen); + i = min(buflen - 1, slen); + if (buffer == NULL) + return slen; + if (i>0) { + if (mre->Flags & MESSAGE_RESOURCE_UNICODE) + WideCharToMultiByte( CP_ACP, 0, (LPWSTR)mre->Text, -1, buffer, i, NULL, NULL ); + else + lstrcpynA(buffer, (LPSTR)mre->Text, i); + buffer[i]=0; + } else { + if (buflen>1) { + buffer[0]=0; + return 0; + } + } + if (buffer) { + //TRACE("'%s' copied !\n", buffer); + TRACE("'%s'\n", buffer); + } + return i; +} + +#if 0 /* FIXME */ +/********************************************************************** + * load_messageW (internal) + */ +static INT load_messageW( HMODULE instance, UINT id, WORD lang, + LPWSTR buffer, INT buflen ) +{ + INT retval; + LPSTR buffer2 = NULL; + if (buffer && buflen) + buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen ); + retval = load_messageA(instance,id,lang,buffer2,buflen); + if (buffer) + { + if (retval) { + lstrcpynAtoW( buffer, buffer2, buflen ); + retval = strlenW( buffer ); + } + HeapFree( GetProcessHeap(), 0, buffer2 ); + } + return retval; +} +#endif + + +/*********************************************************************** + * FormatMessageA (KERNEL32.@) + * FIXME: missing wrap, + */ +DWORD WINAPI FormatMessageA( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPSTR lpBuffer, + DWORD nSize, + va_list* _args ) +{ + LPDWORD args=(LPDWORD)_args; +#if defined(__i386__) || defined(__sparc__) +/* This implementation is completely dependant on the format of the va_list on x86 CPUs */ + LPSTR target,t; + DWORD talloced; + LPSTR from,f; + DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK; + BOOL eos = FALSE; + INT bufsize; + HMODULE hmodule = (HMODULE)lpSource; + CHAR ch; + + //TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n", dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args); + if ((dwFlags & FORMAT_MESSAGE_FROM_STRING) + &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) + || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0; + + if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK) + FIXME("line wrapping (%lu) not supported.\n", width); + from = NULL; + if (dwFlags & FORMAT_MESSAGE_FROM_STRING) + { + from = HeapAlloc( GetProcessHeap(), 0, strlen((LPSTR)lpSource)+1 ); + strcpy( from, (LPSTR)lpSource ); + } + else { + bufsize = 0; + + if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) + { + bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + if ((!bufsize) && (!dwLanguageId)) { + bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NULL,100); + } + } + if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) && (!bufsize)) + { + hmodule = GetModuleHandleA("kernel32"); + bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + if ((!bufsize) && (!dwLanguageId)) { + bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NULL,100); + } + } + + if (!bufsize) { + SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND); + return 0; + } + + from = HeapAlloc( GetProcessHeap(), 0, bufsize + 1 ); + load_messageA(hmodule,dwMessageId,dwLanguageId,from,bufsize+1); + } + target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100); + t = target; + talloced= 100; + +#define ADD_TO_T(c) do { \ + *t++=c;\ + if (t-target == talloced) {\ + target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\ + t = target+talloced;\ + talloced*=2;\ + }\ +} while (0) + + if (from) { + f=from; + if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) { + while (*f && !eos) + ADD_TO_T(*f++); + } + else { + while (*f && !eos) { + if (*f=='%') { + int insertnr; + char *fmtstr,*x,*lastf; + DWORD *argliststart; + + fmtstr = NULL; + lastf = f; + f++; + if (!*f) { + ADD_TO_T('%'); + continue; + } + switch (*f) { + case '1':case '2':case '3':case '4':case '5': + case '6':case '7':case '8':case '9': + insertnr=*f-'0'; + switch (f[1]) { + case '0':case '1':case '2':case '3': + case '4':case '5':case '6':case '7': + case '8':case '9': + f++; + insertnr=insertnr*10+*f-'0'; + f++; + break; + default: + f++; + break; + } + if (*f=='!') { + f++; + if (NULL!=(x=strchr(f,'!'))) { + *x='\0'; + fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + sprintf(fmtstr,"%%%s",f); + f=x+1; + } else { + fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + sprintf(fmtstr,"%%%s",f); + f+=strlen(f); /*at \0*/ + } + } else { + if(!args) break; + fmtstr = HeapAlloc(GetProcessHeap(),0,3); + strcpy( fmtstr, "%s" ); + } + if (args) { + int sz; + LPSTR b; + + if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) + argliststart=args+insertnr-1; + else + argliststart=(*(DWORD**)args)+insertnr-1; + + /* FIXME: precision and width components are not handled correctly */ + if ( (strcmp(fmtstr, "%ls") == 0) || (strcmp(fmtstr,"%S") == 0) ) { + sz = WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, NULL, 0, NULL, NULL); + b = HeapAlloc(GetProcessHeap(), 0, sz); + WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, b, sz, NULL, NULL); + } else { + b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000); + /* CMF - This makes a BIG assumption about va_list */ + TRACE("A BIG assumption\n"); + //vsnprintf(b, sz, fmtstr, (va_list) argliststart); + } + for (x=b; *x; x++) ADD_TO_T(*x); + + HeapFree(GetProcessHeap(),0,b); + } else { + /* NULL args - copy formatstr + * (probably wrong) + */ + while ((lastf 0 && !MultiByteToWideChar( CP_ACP, 0, target, -1, lpBuffer, nSize )) + lpBuffer[nSize-1] = 0; + } + HeapFree(GetProcessHeap(),0,target); + if (from) HeapFree(GetProcessHeap(),0,from); + return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? + strlenW(*(LPWSTR*)lpBuffer): + strlenW(lpBuffer); +#else + return 0; +#endif /* __i386__ */ +} +#undef ADD_TO_T + + +#else + +/* EXPORTED */ + +DWORD +STDCALL +FormatMessageW( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPWSTR lpBuffer, + DWORD nSize, + va_list* Arguments) +{ + +// RtlFormatMessage + + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + + +DWORD +STDCALL +FormatMessageA( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPSTR lpBuffer, + DWORD nSize, + va_list* Arguments) +{ + HLOCAL pBuf = NULL; + //LPSTR pBuf = NULL; + +#define MAX_MSG_STR_LEN 200 + + if (lpBuffer != NULL) { + + if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) { + pBuf = LocalAlloc(LPTR, max(nSize, MAX_MSG_STR_LEN)); + if (pBuf == NULL) { + return 0; + } + *(LPSTR*)lpBuffer = pBuf; + } else { + pBuf = *(LPSTR*)lpBuffer; + } + + if (dwFlags & FORMAT_MESSAGE_FROM_STRING) { + } else { + } + +//FORMAT_MESSAGE_IGNORE_INSERTS +//FORMAT_MESSAGE_FROM_STRING +//FORMAT_MESSAGE_FROM_HMODULE +//FORMAT_MESSAGE_FROM_SYSTEM +//FORMAT_MESSAGE_ARGUMENT_ARRAY + + } +/* + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, + error, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (PTSTR)&msg, + 0, + NULL) + ) + */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + +#endif + +/* EOF */ diff --git a/lib/kernel32/misc/getname.c b/lib/kernel32/misc/getname.c new file mode 100644 index 0000000..f016af5 --- /dev/null +++ b/lib/kernel32/misc/getname.c @@ -0,0 +1,49 @@ +/* $Id$ + * + */ +#include + + +WINBOOL +STDCALL +GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize) +{ + WCHAR Name[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD Size = 0; + + /* + * FIXME: get the computer's name from the registry. + */ + lstrcpyW(Name, L"ROSHost"); /* <-- FIXME -- */ + Size = lstrlenW(Name) + 1; + if (Size > *nSize) { + *nSize = Size; + SetLastError(ERROR_BUFFER_OVERFLOW); + return FALSE; + } + lstrcpyW(lpBuffer, Name); + return TRUE; +} + + +WINBOOL +STDCALL +GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize) +{ + WCHAR Name[MAX_COMPUTERNAME_LENGTH + 1]; + int i; + + if (FALSE == GetComputerNameW(Name, nSize)) { + return FALSE; + } + +/* FIXME --> */ +/* Use UNICODE to ANSI */ + for (i = 0; Name[i]; ++i) { + lpBuffer[i] = (CHAR)Name[i]; + } + lpBuffer[i] = '\0'; +/* FIXME <-- */ + + return TRUE; +} diff --git a/lib/kernel32/misc/handle.c b/lib/kernel32/misc/handle.c index 2011d89..129b9b3 100644 --- a/lib/kernel32/misc/handle.c +++ b/lib/kernel32/misc/handle.c @@ -11,12 +11,10 @@ /* INCLUDES ******************************************************************/ -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS *****************************************************************/ @@ -64,11 +62,11 @@ WINBOOL STDCALL SetHandleInformation(HANDLE hObject, } if (dwMask & HANDLE_FLAG_INHERIT) { - HandleInfo.bInheritHandle = TRUE; + HandleInfo.bInheritHandle = dwFlags & HANDLE_FLAG_INHERIT; } if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE) { - HandleInfo.bProtectFromClose = TRUE; + HandleInfo.bProtectFromClose = dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE; } errCode = NtSetInformationObject(hObject, diff --git a/lib/kernel32/misc/ldr.c b/lib/kernel32/misc/ldr.c index 90f1ec4..b43550a 100644 --- a/lib/kernel32/misc/ldr.c +++ b/lib/kernel32/misc/ldr.c @@ -7,13 +7,10 @@ * AUTHOR : Boudewijn Dekker */ -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ @@ -59,6 +56,8 @@ LoadLibraryExA ( HINSTANCE hInst; NTSTATUS Status; + (void)hFile; + RtlInitAnsiString (&LibFileName, (LPSTR)lpLibFileName); @@ -111,6 +110,8 @@ LoadLibraryExW ( HINSTANCE hInst; NTSTATUS Status; + (void)hFile; + if ( lpLibFileName == NULL ) return NULL; diff --git a/lib/kernel32/misc/mbchars.c b/lib/kernel32/misc/mbchars.c new file mode 100644 index 0000000..32e5135 --- /dev/null +++ b/lib/kernel32/misc/mbchars.c @@ -0,0 +1,302 @@ +/* $Id$ + * + */ +#include + + +/********************************************************************** + * NAME PRIVATE + * IsInstalledCP@4 + * + * RETURN VALUE + * TRUE if CodePage is installed in the system. + */ +static +BOOL +STDCALL +IsInstalledCP(UINT CodePage) +{ + /* FIXME */ + return TRUE; +} + + +/********************************************************************** + * NAME EXPORTED + * MultiByteToWideChar@24 + * + * ARGUMENTS + * CodePage + * CP_ACP ANSI code page + * CP_MACCP Macintosh code page + * CP_OEMCP OEM code page + * (UINT) Any installed code page + * + * dwFlags + * MB_PRECOMPOSED + * MB_COMPOSITE + * MB_ERR_INVALID_CHARS + * MB_USEGLYPHCHARS + * + * lpMultiByteStr + * Input buffer; + * + * cchMultiByte + * Size of MultiByteStr, or -1 if MultiByteStr is + * NULL terminated; + * + * lpWideCharStr + * Output buffer; + * + * cchWideChar + * Size (in WCHAR unit) of WideCharStr, or 0 + * if the caller just wants to know how large + * WideCharStr should be for a successful + * conversion. + * + * RETURN VALUE + * 0 on error; otherwise the number of WCHAR written + * in the WideCharStr buffer. + * + * NOTE + * A raw converter for now. It assumes lpMultiByteStr is + * NEVER multi-byte (that is each input character is + * 8-bit ASCII) and is ALWAYS NULL terminated. + * FIXME-FIXME-FIXME-FIXME + */ +INT +STDCALL +MultiByteToWideChar( + UINT CodePage, + DWORD dwFlags, + LPCSTR lpMultiByteStr, + int cchMultiByte, + LPWSTR lpWideCharStr, + int cchWideChar) +{ + int InStringLength = 0; + PCHAR r; + PWCHAR w; + int cchConverted; + + /* + * Check the parameters. + */ + if (/* --- CODE PAGE --- */ + ( (CP_ACP != CodePage) + && (CP_MACCP != CodePage) + && (CP_OEMCP != CodePage) + && (FALSE == IsInstalledCP(CodePage)) ) + /* --- FLAGS --- */ + || (dwFlags & ~(MB_PRECOMPOSED | MB_COMPOSITE | + MB_ERR_INVALID_CHARS | MB_USEGLYPHCHARS)) + /* --- INPUT BUFFER --- */ + || (NULL == lpMultiByteStr) ) + { + SetLastError (ERROR_INVALID_PARAMETER); + return 0; + } + /* + * Compute the input buffer length. + */ + //if (-1 == cchMultiByte) + if (cchMultiByte < 0) + { + InStringLength = lstrlen(lpMultiByteStr) + 1; + } + else + { + InStringLength = cchMultiByte; + } + /* + * Does caller query for output + * buffer size? + */ + if (0 == cchWideChar) + { + //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success. + return InStringLength; + } + /* + * Is space provided for the translated + * string enough? + */ + if (cchWideChar < InStringLength) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + /* + * Raw 8- to 16-bit conversion. + */ + for (cchConverted = 0, + r = (PCHAR)lpMultiByteStr, + w = (PWCHAR)lpWideCharStr; + + cchConverted < InStringLength; + + r++, + w++, + cchConverted++) + { + *w = (WCHAR)*r; + } + /* + * Return how many characters we + * wrote in the output buffer. + */ + //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success. + return cchConverted; +} + + +/********************************************************************** + * NAME EXPORTED + * WideCharToMultiByte@32 + * + * Not yet implemented complete (without NLS so far) + * + * ARGUMENTS + * CodePage + * CP_ACP ANSI code page + * CP_MACCP Macintosh code page + * CP_OEMCP OEM code page + * CP_SYMBOL Symbol code page (42) + * CP_THREAD_ACP Current thread's ANSI code page + * CP_UTF7 Translate using UTF-7 + * CP_UTF8 Translate using UTF-8 + * (UINT) Any installed code page + * + * dwFlags + * WC_NO_BEST_FIT_CHARS + * WC_COMPOSITECHECK Convert composite characters to precomposed characters. + * WC_DISCARDNS Discard nonspacing characters during conversion. + * WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior. + * WC_DEFAULTCHAR Replace exceptions with the default character during conversion. + * + * lpWideCharStr + * Points to the wide-character string to be converted. + * + * cchWideChar + * Size (in WCHAR unit) of WideCharStr, or 0 + * if the caller just wants to know how large + * WideCharStr should be for a successful + * conversion. + * lpMultiByteStr + * Points to the buffer to receive the translated string. + * cchMultiByte + * Specifies the size in bytes of the buffer pointed to by the + * lpMultiByteStr parameter. If this value is zero, the function + * returns the number of bytes required for the buffer. + * lpDefaultChar + * Points to the character used if a wide character cannot be + * represented in the specified code page. If this parameter is + * NULL, a system default value is used. + FIXME: ignored + * lpUsedDefaultChar + * Points to a flag that indicates whether a default character was used. + * This parameter may be NULL. + FIXME: allways set to FALSE. + * + * + * + * RETURN VALUE + * 0 on error; otherwise the number of bytes written + * in the lpMultiByteStr buffer. Or the number of + * bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero. + * + * NOTE + * A raw converter for now. It just cuts off the upper 9 Bit. + * So the MBCS-string does not contain any LeadCharacters + * FIXME - FIXME - FIXME - FIXME + */ + +int +STDCALL +WideCharToMultiByte( + UINT CodePage, + DWORD dwFlags, + LPCWSTR lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cchMultiByte, + LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar + ) +{ + int wi, di; // wide counter, dbcs byte count + + /* + * Check the parameters. + */ + if ( /* --- CODE PAGE --- */ + ( (CP_ACP != CodePage) + && (CP_MACCP != CodePage) + && (CP_OEMCP != CodePage) + && (CP_SYMBOL != CodePage) + && (CP_THREAD_ACP != CodePage) + && (CP_UTF7 != CodePage) + && (CP_UTF8 != CodePage) + && (FALSE == IsInstalledCP (CodePage)) + ) + /* --- FLAGS --- */ + || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS + |*/ WC_COMPOSITECHECK + | WC_DISCARDNS + | WC_SEPCHARS + | WC_DEFAULTCHAR + ) + ) + /* --- INPUT BUFFER --- */ + || (NULL == lpWideCharStr) + ) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // for now, make no difference but only convert cut the characters to 7Bit + //if (cchWideChar == -1) // assume its a 0-terminated str + if (cchWideChar < 0) // assume its a 0-terminated str + { // and determine its length +// for (cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++) +// cchWideChar++; + for (cchWideChar = 0; lpWideCharStr[cchWideChar] != 0; cchWideChar++) { + } + cchWideChar++; // length includes the null terminator + } + + // user wants to determine needed space + if (cchMultiByte == 0) + { + //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success. + return cchWideChar; // FIXME: determine correct. + } + // the lpWideCharStr is cchWideChar characters long. + for (wi=0, di=0; wi127) ) + { + lpMultiByteStr[di]= + *lpUsedDefaultChar = TRUE; + + }*/ + // FIXME + // just cut off the upper 9 Bit, since vals>=128 mean LeadByte. + lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F; + } + // has MultiByte exceeded but Wide is still in the string? + if (wi < cchWideChar && di >= cchMultiByte) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + // else return # of bytes wirtten to MBCSbuffer (di) + //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success. + // FIXME: move that elsewhere + if (lpUsedDefaultChar != NULL) *lpUsedDefaultChar = FALSE; + return di; +} + +/* EOF */ diff --git a/lib/kernel32/misc/muldiv.c b/lib/kernel32/misc/muldiv.c new file mode 100644 index 0000000..3b9a559 --- /dev/null +++ b/lib/kernel32/misc/muldiv.c @@ -0,0 +1,61 @@ +/* $Id$ + * + */ +#include + + +/*********************************************************************** + * MulDiv (KERNEL32.@) + * RETURNS + * Result of multiplication and division + * -1: Overflow occurred or Divisor was 0 + */ + +//FIXME! move to correct file +INT STDCALL MulDiv( + INT nMultiplicand, + INT nMultiplier, + INT nDivisor) +{ +#if SIZEOF_LONG_LONG >= 8 + long long ret; + + if (!nDivisor) return -1; + + /* We want to deal with a positive divisor to simplify the logic. */ + if (nDivisor < 0) + { + nMultiplicand = - nMultiplicand; + nDivisor = -nDivisor; + } + + /* If the result is positive, we "add" to round. else, we subtract to round. */ + if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) || + ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) ) + ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor; + else + ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor; + + if ((ret > 2147483647) || (ret < -2147483647)) return -1; + return ret; +#else + if (!nDivisor) return -1; + + /* We want to deal with a positive divisor to simplify the logic. */ + if (nDivisor < 0) + { + nMultiplicand = - nMultiplicand; + nDivisor = -nDivisor; + } + + /* If the result is positive, we "add" to round. else, we subtract to round. */ + if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) || + ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) ) + return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor; + + return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor; + +#endif +} + + diff --git a/lib/kernel32/misc/perfcnt.c b/lib/kernel32/misc/perfcnt.c new file mode 100644 index 0000000..c8bdaa4 --- /dev/null +++ b/lib/kernel32/misc/perfcnt.c @@ -0,0 +1,84 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ */ +/* + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/misc/perfcnt.c + * PURPOSE: Performance counter + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + + +/* FUNCTIONS ****************************************************************/ + +WINBOOL STDCALL +QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) +{ + LARGE_INTEGER Frequency; + NTSTATUS Status; + + Status = NtQueryPerformanceCounter(lpPerformanceCount, + &Frequency); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + if (Frequency.QuadPart == 0ULL) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return(FALSE); + } + + return(TRUE); +} + + +WINBOOL STDCALL +QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) +{ + LARGE_INTEGER Count; + NTSTATUS Status; + + Status = NtQueryPerformanceCounter(&Count, + lpFrequency); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + if (lpFrequency->QuadPart == 0ULL) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return(FALSE); + } + + return(TRUE); +} + +/* EOF */ diff --git a/lib/kernel32/misc/profile.c b/lib/kernel32/misc/profile.c index 99c8e1d..a03f443 100644 --- a/lib/kernel32/misc/profile.c +++ b/lib/kernel32/misc/profile.c @@ -10,11 +10,7 @@ * Created 01/11/98 */ -#include -#include -#include -#include -//#include +#include /* FUNCTIONS *****************************************************************/ diff --git a/lib/kernel32/misc/res.c b/lib/kernel32/misc/res.c index 80bbda1..f603ef0 100644 --- a/lib/kernel32/misc/res.c +++ b/lib/kernel32/misc/res.c @@ -7,11 +7,10 @@ * AUTHOR : ??? */ -#include -#include -#include +#include + +#define NDEBUG #include -#include HRSRC diff --git a/lib/kernel32/misc/stubs.c b/lib/kernel32/misc/stubs.c index 3f4b5f3..249e972 100644 --- a/lib/kernel32/misc/stubs.c +++ b/lib/kernel32/misc/stubs.c @@ -3,91 +3,83 @@ * KERNEL32.DLL stubs (unimplemented functions) * Remove from this file, if you implement them. */ -#include - - -BOOL -STDCALL -IsProcessorFeaturePresent( DWORD ProcessorFeature ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} +#include +//#define _OLE2NLS_IN_BUILD_ BOOL STDCALL BaseAttachCompleteThunk (VOID) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL STDCALL CmdBatNotification ( - DWORD Unknown - ) + DWORD Unknown + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } int STDCALL CompareStringA ( - LCID Locale, - DWORD dwCmpFlags, - LPCSTR lpString1, - int cchCount1, - LPCSTR lpString2, - int cchCount2 - ) + LCID Locale, + DWORD dwCmpFlags, + LPCSTR lpString1, + int cchCount1, + LPCSTR lpString2, + int cchCount2 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL CompareStringW ( - LCID Locale, - DWORD dwCmpFlags, - LPCWSTR lpString1, - int cchCount1, - LPCWSTR lpString2, - int cchCount2 - ) + LCID Locale, + DWORD dwCmpFlags, + LPCWSTR lpString1, + int cchCount1, + LPCWSTR lpString2, + int cchCount2 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } LCID STDCALL ConvertDefaultLocale ( - LCID Locale - ) + LCID Locale + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } DWORD STDCALL CreateVirtualBuffer ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } @@ -100,473 +92,374 @@ EnumCalendarInfoW ( CALTYPE CalType ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } - WINBOOL STDCALL EnumCalendarInfoA ( - CALINFO_ENUMPROC lpCalInfoEnumProc, - LCID Locale, - CALID Calendar, - CALTYPE CalType - ) + CALINFO_ENUMPROC lpCalInfoEnumProc, + LCID Locale, + CALID Calendar, + CALTYPE CalType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL EnumDateFormatsW ( - DATEFMT_ENUMPROC lpDateFmtEnumProc, - LCID Locale, - DWORD dwFlags - ) + DATEFMT_ENUMPROC lpDateFmtEnumProc, + LCID Locale, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL EnumDateFormatsA ( - DATEFMT_ENUMPROC lpDateFmtEnumProc, - LCID Locale, - DWORD dwFlags - ) + DATEFMT_ENUMPROC lpDateFmtEnumProc, + LCID Locale, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } - - WINBOOL STDCALL EnumSystemCodePagesW ( - CODEPAGE_ENUMPROC lpCodePageEnumProc, - DWORD dwFlags - ) + CODEPAGE_ENUMPROC lpCodePageEnumProc, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL EnumSystemCodePagesA ( - CODEPAGE_ENUMPROC lpCodePageEnumProc, - DWORD dwFlags - ) + CODEPAGE_ENUMPROC lpCodePageEnumProc, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } +#ifndef _OLE2NLS_IN_BUILD_ WINBOOL STDCALL EnumSystemLocalesW ( - LOCALE_ENUMPROC lpLocaleEnumProc, - DWORD dwFlags - ) + LOCALE_ENUMPROC lpLocaleEnumProc, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL EnumSystemLocalesA ( - LOCALE_ENUMPROC lpLocaleEnumProc, - DWORD dwFlags - ) + LOCALE_ENUMPROC lpLocaleEnumProc, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } +#endif WINBOOL STDCALL EnumTimeFormatsW ( - TIMEFMT_ENUMPROC lpTimeFmtEnumProc, - LCID Locale, - DWORD dwFlags - ) + TIMEFMT_ENUMPROC lpTimeFmtEnumProc, + LCID Locale, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL EnumTimeFormatsA ( - TIMEFMT_ENUMPROC lpTimeFmtEnumProc, - LCID Locale, - DWORD dwFlags - ) + TIMEFMT_ENUMPROC lpTimeFmtEnumProc, + LCID Locale, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } - - - - - DWORD STDCALL ExitVDM ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } - - BOOL STDCALL ExtendVirtualBuffer ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } int STDCALL FoldStringW ( - DWORD dwMapFlags, - LPCWSTR lpSrcStr, - int cchSrc, - LPWSTR lpDestStr, - int cchDest - ) + DWORD dwMapFlags, + LPCWSTR lpSrcStr, + int cchSrc, + LPWSTR lpDestStr, + int cchDest + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL FoldStringA ( - DWORD dwMapFlags, - LPCSTR lpSrcStr, - int cchSrc, - LPSTR lpDestStr, - int cchDest - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -DWORD -STDCALL -FormatMessageW ( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - LPWSTR lpBuffer, - DWORD nSize, - va_list * Arguments - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -DWORD -STDCALL -FormatMessageA ( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - LPSTR lpBuffer, - DWORD nSize, - va_list * Arguments - ) + DWORD dwMapFlags, + LPCSTR lpSrcStr, + int cchSrc, + LPSTR lpDestStr, + int cchDest + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } BOOL STDCALL FreeVirtualBuffer ( - HANDLE hVirtualBuffer - ) + HANDLE hVirtualBuffer + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } +#ifndef _OLE2NLS_IN_BUILD_ UINT STDCALL GetACP (VOID) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#endif + WINBOOL STDCALL GetBinaryTypeW ( - LPCWSTR lpApplicationName, - LPDWORD lpBinaryType - ) + LPCWSTR lpApplicationName, + LPDWORD lpBinaryType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL GetBinaryTypeA ( - LPCSTR lpApplicationName, - LPDWORD lpBinaryType - ) + LPCSTR lpApplicationName, + LPDWORD lpBinaryType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } +#ifndef _OLE2NLS_IN_BUILD_ WINBOOL STDCALL GetCPInfo ( - UINT a0, - LPCPINFO a1 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - - - -WINBOOL -STDCALL -GetComputerNameW ( - LPWSTR lpBuffer, - LPDWORD nSize - ) + UINT a0, + LPCPINFO a1 + ) { - WCHAR Name [MAX_COMPUTERNAME_LENGTH + 1]; - DWORD Size = 0; - - /* - * FIXME: get the computer's name from - * the registry. - */ - lstrcpyW( Name, L"ROSHost" ); /* <-- FIXME -- */ - Size = lstrlenW(Name) + 1; - if (Size > *nSize) - { - *nSize = Size; - SetLastError(ERROR_BUFFER_OVERFLOW); - return FALSE; - } - lstrcpyW( lpBuffer, Name ); - return TRUE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } - -WINBOOL -STDCALL -GetComputerNameA ( - LPSTR lpBuffer, - LPDWORD nSize - ) -{ - WCHAR Name [MAX_COMPUTERNAME_LENGTH + 1]; - int i; - - if (FALSE == GetComputerNameW( - Name, - nSize - )) - { - return FALSE; - } -/* FIXME --> */ -/* Use UNICODE to ANSI */ - for ( i=0; Name[i]; ++i ) - { - lpBuffer[i] = (CHAR) Name[i]; - } - lpBuffer[i] = '\0'; -/* FIXME <-- */ - return TRUE; -} - - - +#endif int STDCALL GetCurrencyFormatW ( - LCID Locale, - DWORD dwFlags, - LPCWSTR lpValue, - CONST CURRENCYFMT * lpFormat, - LPWSTR lpCurrencyStr, - int cchCurrency - ) + LCID Locale, + DWORD dwFlags, + LPCWSTR lpValue, + CONST CURRENCYFMT * lpFormat, + LPWSTR lpCurrencyStr, + int cchCurrency + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetCurrencyFormatA ( - LCID Locale, - DWORD dwFlags, - LPCSTR lpValue, - CONST CURRENCYFMT * lpFormat, - LPSTR lpCurrencyStr, - int cchCurrency - ) + LCID Locale, + DWORD dwFlags, + LPCSTR lpValue, + CONST CURRENCYFMT * lpFormat, + LPSTR lpCurrencyStr, + int cchCurrency + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } - - - +#ifndef _OLE2NLS_IN_BUILD_ int STDCALL GetDateFormatW ( - LCID Locale, - DWORD dwFlags, - CONST SYSTEMTIME * lpDate, - LPCWSTR lpFormat, - LPWSTR lpDateStr, - int cchDate - ) + LCID Locale, + DWORD dwFlags, + CONST SYSTEMTIME * lpDate, + LPCWSTR lpFormat, + LPWSTR lpDateStr, + int cchDate + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetDateFormatA ( - LCID Locale, - DWORD dwFlags, - CONST SYSTEMTIME * lpDate, - LPCSTR lpFormat, - LPSTR lpDateStr, - int cchDate - ) + LCID Locale, + DWORD dwFlags, + CONST SYSTEMTIME * lpDate, + LPCSTR lpFormat, + LPSTR lpDateStr, + int cchDate + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetLocaleInfoW ( - LCID Locale, - LCTYPE LCType, - LPWSTR lpLCData, - int cchData - ) + LCID Locale, + LCTYPE LCType, + LPWSTR lpLCData, + int cchData + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetLocaleInfoA ( - LCID Locale, - LCTYPE LCType, - LPSTR lpLCData, - int cchData - ) + LCID Locale, + LCTYPE LCType, + LPSTR lpLCData, + int cchData + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } DWORD STDCALL GetNextVDMCommand ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetNumberFormatW ( - LCID Locale, - DWORD dwFlags, - LPCWSTR lpValue, - CONST NUMBERFMT * lpFormat, - LPWSTR lpNumberStr, - int cchNumber - ) + LCID Locale, + DWORD dwFlags, + LPCWSTR lpValue, + CONST NUMBERFMT * lpFormat, + LPWSTR lpNumberStr, + int cchNumber + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetNumberFormatA ( - LCID Locale, - DWORD dwFlags, - LPCSTR lpValue, - CONST NUMBERFMT * lpFormat, - LPSTR lpNumberStr, - int cchNumber - ) + LCID Locale, + DWORD dwFlags, + LPCSTR lpValue, + CONST NUMBERFMT * lpFormat, + LPSTR lpNumberStr, + int cchNumber + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } @@ -574,67 +467,67 @@ UINT STDCALL GetOEMCP (VOID) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 437; /* FIXME: call csrss.exe */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 437; /* FIXME: call csrss.exe */ } WINBOOL STDCALL GetStringTypeExW ( - LCID Locale, - DWORD dwInfoType, - LPCWSTR lpSrcStr, - int cchSrc, - LPWORD lpCharType - ) + LCID Locale, + DWORD dwInfoType, + LPCWSTR lpSrcStr, + int cchSrc, + LPWORD lpCharType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL GetStringTypeExA ( - LCID Locale, - DWORD dwInfoType, - LPCSTR lpSrcStr, - int cchSrc, - LPWORD lpCharType - ) + LCID Locale, + DWORD dwInfoType, + LPCSTR lpSrcStr, + int cchSrc, + LPWORD lpCharType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL GetStringTypeW ( - DWORD dwInfoType, - LPCWSTR lpSrcStr, - int cchSrc, - LPWORD lpCharType - ) + DWORD dwInfoType, + LPCWSTR lpSrcStr, + int cchSrc, + LPWORD lpCharType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL GetStringTypeA ( - LCID Locale, - DWORD dwInfoType, - LPCSTR lpSrcStr, - int cchSrc, - LPWORD lpCharType - ) + LCID Locale, + DWORD dwInfoType, + LPCSTR lpSrcStr, + int cchSrc, + LPWORD lpCharType + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } @@ -642,12 +535,12 @@ LCID STDCALL GetSystemDefaultLCID (VOID) { - /* FIXME: ??? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return MAKELCID( - LANG_ENGLISH, - SORT_DEFAULT - ); + /* FIXME: ??? */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return MAKELCID( + LANG_ENGLISH, + SORT_DEFAULT + ); } @@ -655,105 +548,85 @@ LANGID STDCALL GetSystemDefaultLangID (VOID) { - /* FIXME: ??? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return MAKELANGID( - LANG_ENGLISH, - SUBLANG_ENGLISH_US - ); + /* FIXME: ??? */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return MAKELANGID( + LANG_ENGLISH, + SUBLANG_ENGLISH_US + ); } +#endif -DWORD +WINBOOL STDCALL GetSystemPowerStatus ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#ifndef _OLE2NLS_IN_BUILD_ LCID STDCALL GetThreadLocale (VOID) { - /* FIXME: ??? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return MAKELCID( - LANG_ENGLISH, - SORT_DEFAULT - ); -} - -WINBOOL -STDCALL -GetThreadPriorityBoost ( - HANDLE hThread, - DWORD dwSelector, - LPLDT_ENTRY lpSelectorEntry - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -WINBOOL -STDCALL -GetThreadSelectorEntry ( - HANDLE hThread, - DWORD dwSelector, - LPLDT_ENTRY lpSelectorEntry - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + /* FIXME: ??? */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return MAKELCID( + LANG_ENGLISH, + SORT_DEFAULT + ); } +#endif int STDCALL GetTimeFormatW ( - LCID Locale, - DWORD dwFlags, - CONST SYSTEMTIME * lpTime, - LPCWSTR lpFormat, - LPWSTR lpTimeStr, - int cchTime - ) + LCID Locale, + DWORD dwFlags, + CONST SYSTEMTIME * lpTime, + LPCWSTR lpFormat, + LPWSTR lpTimeStr, + int cchTime + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL GetTimeFormatA ( - LCID Locale, - DWORD dwFlags, - CONST SYSTEMTIME * lpTime, - LPCSTR lpFormat, - LPSTR lpTimeStr, - int cchTime - ) + LCID Locale, + DWORD dwFlags, + CONST SYSTEMTIME * lpTime, + LPCSTR lpFormat, + LPSTR lpTimeStr, + int cchTime + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#ifndef _OLE2NLS_IN_BUILD_ LCID STDCALL GetUserDefaultLCID (VOID) { - /* FIXME: ??? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return MAKELCID( - LANG_ENGLISH, - SORT_DEFAULT - ); + /* FIXME: ??? */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return MAKELCID( + LANG_ENGLISH, + SORT_DEFAULT + ); } @@ -761,400 +634,171 @@ LANGID STDCALL GetUserDefaultLangID (VOID) { - /* FIXME: ??? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return MAKELANGID( - LANG_ENGLISH, - SUBLANG_ENGLISH_US - ); + /* FIXME: ??? */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return MAKELANGID( + LANG_ENGLISH, + SUBLANG_ENGLISH_US + ); } +#endif DWORD STDCALL GetVDMCurrentDirectories ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#ifndef _OLE2NLS_IN_BUILD_ WINBOOL STDCALL IsDBCSLeadByte ( - BYTE TestChar - ) + BYTE TestChar + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL IsDBCSLeadByteEx ( - UINT CodePage, - BYTE TestChar - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -/********************************************************************** - * NAME PRIVATE - * IsInstalledCP@4 - * - * RETURN VALUE - * TRUE if CodePage is installed in the system. - */ -static -BOOL -STDCALL -IsInstalledCP ( - UINT CodePage - ) + UINT CodePage, + BYTE TestChar + ) { - /* FIXME */ - return TRUE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL IsValidCodePage ( - UINT CodePage - ) + UINT CodePage + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL IsValidLocale ( - LCID Locale, - DWORD dwFlags - ) + LCID Locale, + DWORD dwFlags + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } int STDCALL LCMapStringA ( - LCID Locale, - DWORD dwMapFlags, - LPCSTR lpSrcStr, - int cchSrc, - LPSTR lpDestStr, - int cchDest - ) + LCID Locale, + DWORD dwMapFlags, + LPCSTR lpSrcStr, + int cchSrc, + LPSTR lpDestStr, + int cchDest + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } int STDCALL LCMapStringW ( - LCID Locale, - DWORD dwMapFlags, - LPCWSTR lpSrcStr, - int cchSrc, - LPWSTR lpDestStr, - int cchDest - ) + LCID Locale, + DWORD dwMapFlags, + LPCWSTR lpSrcStr, + int cchSrc, + LPWSTR lpDestStr, + int cchDest + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#endif DWORD STDCALL LoadModule ( - LPCSTR lpModuleName, - LPVOID lpParameterBlock - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/*********************************************************************** - * MulDiv (KERNEL32.@) - * RETURNS - * Result of multiplication and division - * -1: Overflow occurred or Divisor was 0 - */ - -//FIXME! move to correct file -INT STDCALL MulDiv( - INT nMultiplicand, - INT nMultiplier, - INT nDivisor) -{ -#if SIZEOF_LONG_LONG >= 8 - long long ret; - - if (!nDivisor) return -1; - - /* We want to deal with a positive divisor to simplify the logic. */ - if (nDivisor < 0) - { - nMultiplicand = - nMultiplicand; - nDivisor = -nDivisor; - } - - /* If the result is positive, we "add" to round. else, we subtract to round. */ - if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) || - ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) ) - ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor; - else - ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor; - - if ((ret > 2147483647) || (ret < -2147483647)) return -1; - return ret; -#else - if (!nDivisor) return -1; - - /* We want to deal with a positive divisor to simplify the logic. */ - if (nDivisor < 0) - { - nMultiplicand = - nMultiplicand; - nDivisor = -nDivisor; - } - - /* If the result is positive, we "add" to round. else, we subtract to round. */ - if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) || - ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) ) - return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor; - - return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor; - -#endif -} - - -/********************************************************************** - * NAME EXPORTED - * MultiByteToWideChar@24 - * - * ARGUMENTS - * CodePage - * CP_ACP ANSI code page - * CP_MACCP Macintosh code page - * CP_OEMCP OEM code page - * (UINT) Any installed code page - * - * dwFlags - * MB_PRECOMPOSED - * MB_COMPOSITE - * MB_ERR_INVALID_CHARS - * MB_USEGLYPHCHARS - * - * lpMultiByteStr - * Input buffer; - * - * cchMultiByte - * Size of MultiByteStr, or -1 if MultiByteStr is - * NULL terminated; - * - * lpWideCharStr - * Output buffer; - * - * cchWideChar - * Size (in WCHAR unit) of WideCharStr, or 0 - * if the caller just wants to know how large - * WideCharStr should be for a successful - * conversion. - * - * RETURN VALUE - * 0 on error; otherwise the number of WCHAR written - * in the WideCharStr buffer. - * - * NOTE - * A raw converter for now. It assumes lpMultiByteStr is - * NEVER multi-byte (that is each input character is - * 8-bit ASCII) and is ALWAYS NULL terminated. - * FIXME-FIXME-FIXME-FIXME - */ -INT -STDCALL -MultiByteToWideChar ( - UINT CodePage, - DWORD dwFlags, - LPCSTR lpMultiByteStr, - int cchMultiByte, - LPWSTR lpWideCharStr, - int cchWideChar - ) -{ - int InStringLength = 0; - PCHAR r; - PWCHAR w; - int cchConverted; - - /* - * Check the parameters. - */ - if ( /* --- CODE PAGE --- */ - ( (CP_ACP != CodePage) - && (CP_MACCP != CodePage) - && (CP_OEMCP != CodePage) - && (FALSE == IsInstalledCP (CodePage)) - ) - /* --- FLAGS --- */ - || (dwFlags & ~(MB_PRECOMPOSED - | MB_COMPOSITE - | MB_ERR_INVALID_CHARS - | MB_USEGLYPHCHARS - ) - ) - /* --- INPUT BUFFER --- */ - || (NULL == lpMultiByteStr) - ) - { - SetLastError (ERROR_INVALID_PARAMETER); - return 0; - } - /* - * Compute the input buffer length. - */ - if (-1 == cchMultiByte) - { - InStringLength = lstrlen (lpMultiByteStr) + 1; - } - else - { - InStringLength = cchMultiByte; - } - /* - * Does caller query for output - * buffer size? - */ - if (0 == cchWideChar) - { - SetLastError (ERROR_SUCCESS); - return InStringLength; - } - /* - * Is space provided for the translated - * string enough? - */ - if (cchWideChar < InStringLength) - { - SetLastError (ERROR_INSUFFICIENT_BUFFER); - return 0; - } - /* - * Raw 8- to 16-bit conversion. - */ - for ( cchConverted = 0, - r = (PCHAR) lpMultiByteStr, - w = (PWCHAR) lpWideCharStr; - - cchConverted < InStringLength; - - r++, - w++, - cchConverted++ - ) - { - *w = (WCHAR) *r; - } - /* - * Return how many characters we - * wrote in the output buffer. - */ - SetLastError (ERROR_SUCCESS); - return cchConverted; -} - - -WINBOOL -STDCALL -QueryPerformanceCounter ( - LARGE_INTEGER * lpPerformanceCount - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -WINBOOL -STDCALL -QueryPerformanceFrequency ( - LARGE_INTEGER * lpFrequency - ) + LPCSTR lpModuleName, + LPVOID lpParameterBlock + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } WINBOOL STDCALL RegisterConsoleVDM ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6, - DWORD Unknown7, - DWORD Unknown8, - DWORD Unknown9, - DWORD Unknown10 - ) + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5, + DWORD Unknown6, + DWORD Unknown7, + DWORD Unknown8, + DWORD Unknown9, + DWORD Unknown10 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL RegisterWowBaseHandlers ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL RegisterWowExec ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL SetComputerNameA ( - LPCSTR lpComputerName - ) + LPCSTR lpComputerName + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } @@ -1164,312 +808,174 @@ SetComputerNameW ( LPCWSTR lpComputerName ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } +#ifndef _OLE2NLS_IN_BUILD_ + WINBOOL STDCALL SetLocaleInfoA ( - LCID Locale, - LCTYPE LCType, - LPCSTR lpLCData - ) + LCID Locale, + LCTYPE LCType, + LPCSTR lpLCData + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL SetLocaleInfoW ( - LCID Locale, - LCTYPE LCType, - LPCWSTR lpLCData - ) + LCID Locale, + LCTYPE LCType, + LPCWSTR lpLCData + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } WINBOOL STDCALL -SetSystemPowerState ( - DWORD Unknown0, - DWORD Unknown1 - ) +SetThreadLocale ( + LCID Locale + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } -WINBOOL -STDCALL -SetThreadIdealProcessor(VOID) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} +#endif -WINBOOL -STDCALL -SetThreadLocale ( - LCID Locale - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} -WINBOOL -STDCALL -SetThreadPriorityBoost(VOID) +WINBOOL STDCALL +SetSystemPowerState ( + IN WINBOOL fSuspend, + IN WINBOOL fForce + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } + WINBOOL STDCALL SetVDMCurrentDirectories ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } DWORD STDCALL TrimVirtualBuffer ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } DWORD STDCALL VDMConsoleOperation ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } DWORD STDCALL VDMOperationStarted ( - DWORD Unknown0 - ) + DWORD Unknown0 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#ifndef _OLE2NLS_IN_BUILD_ + DWORD STDCALL VerLanguageNameA ( - DWORD wLang, - LPSTR szLang, - DWORD nSize - ) + DWORD wLang, + LPSTR szLang, + DWORD nSize + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } DWORD STDCALL VerLanguageNameW ( - DWORD wLang, - LPWSTR szLang, - DWORD nSize - ) + DWORD wLang, + LPWSTR szLang, + DWORD nSize + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } +#endif DWORD STDCALL VirtualBufferExceptionHandler ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2 + ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } -/********************************************************************** - * NAME EXPORTED - * MultiByteToWideChar@32 - * - * Not yet implemented complete (without NLS so far) - * - * ARGUMENTS - * CodePage - * CP_ACP ANSI code page - * CP_MACCP Macintosh code page - * CP_OEMCP OEM code page - * CP_SYMBOL Symbol code page (42) - * CP_THREAD_ACP Current thread's ANSI code page - * CP_UTF7 Translate using UTF-7 - * CP_UTF8 Translate using UTF-8 - * (UINT) Any installed code page - * - * dwFlags - * WC_NO_BEST_FIT_CHARS - * WC_COMPOSITECHECK Convert composite characters to precomposed characters. - * WC_DISCARDNS Discard nonspacing characters during conversion. - * WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior. - * WC_DEFAULTCHAR Replace exceptions with the default character during conversion. - * - * lpWideCharStr - * Points to the wide-character string to be converted. - * - * cchWideChar - * Size (in WCHAR unit) of WideCharStr, or 0 - * if the caller just wants to know how large - * WideCharStr should be for a successful - * conversion. - * lpMultiByteStr - * Points to the buffer to receive the translated string. - * cchMultiByte - * Specifies the size in bytes of the buffer pointed to by the - * lpMultiByteStr parameter. If this value is zero, the function - * returns the number of bytes required for the buffer. - * lpDefaultChar - * Points to the character used if a wide character cannot be - * represented in the specified code page. If this parameter is - * NULL, a system default value is used. - FIXME: ignored - * lpUsedDefaultChar - * Points to a flag that indicates whether a default character was used. - * This parameter may be NULL. - FIXME: allways set to FALSE. - * - * - * - * RETURN VALUE - * 0 on error; otherwise the number of bytes written - * in the lpMultiByteStr buffer. Or the number of - * bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero. - * - * NOTE - * A raw converter for now. It just cuts off the upper 9 Bit. - * So the MBCS-string does not contain any LeadCharacters - * FIXME - FIXME - FIXME - FIXME - */ - -int +BOOL STDCALL -WideCharToMultiByte ( - UINT CodePage, - DWORD dwFlags, - LPCWSTR lpWideCharStr, - int cchWideChar, - LPSTR lpMultiByteStr, - int cchMultiByte, - LPCSTR lpDefaultChar, - LPBOOL lpUsedDefaultChar - ) -{ - int wi, di; // wide counter, dbcs byte count - - /* - * Check the parameters. - */ - if ( /* --- CODE PAGE --- */ - ( (CP_ACP != CodePage) - && (CP_MACCP != CodePage) - && (CP_OEMCP != CodePage) - && (CP_SYMBOL != CodePage) - && (CP_THREAD_ACP != CodePage) - && (CP_UTF7 != CodePage) - && (CP_UTF8 != CodePage) - && (FALSE == IsInstalledCP (CodePage)) - ) - /* --- FLAGS --- */ - || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS - |*/ WC_COMPOSITECHECK - | WC_DISCARDNS - | WC_SEPCHARS - | WC_DEFAULTCHAR - ) - ) - /* --- INPUT BUFFER --- */ - || (NULL == lpWideCharStr) - ) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - // for now, make no difference but only convert cut the characters to 7Bit - if( cchWideChar == -1 ) // assume its a 0-terminated str - { // and determine its length - for( cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++) - cchWideChar++; - } - - // user wants to determine needed space - if( cchMultiByte == 0 ) - { - SetLastError(ERROR_SUCCESS); - return cchWideChar; // FIXME: determine correct. - } - // the lpWideCharStr is cchWideChar characters long. - for( wi=0, di=0; wi127) ) - { - lpMultiByteStr[di]= - *lpUsedDefaultChar = TRUE; - - }*/ - // FIXME - // just cut off the upper 9 Bit, since vals>=128 mean LeadByte. - lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F; - } - // has MultiByte exceeded but Wide is still in the string? - if( wi < cchWideChar && di >= cchMultiByte) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return 0; - } - // else return # of bytes wirtten to MBCSbuffer (di) - SetLastError(ERROR_SUCCESS); - // FIXME: move that elsewhere - if( lpUsedDefaultChar!=NULL ) *lpUsedDefaultChar=FALSE; - return di; +GetFileAttributesExA( + LPCSTR lpFileName, + GET_FILEEX_INFO_LEVELS fInfoLevelId, + LPVOID lpFileInformation + ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } - - - - - - - - +BOOL +STDCALL +GetFileAttributesExW( + LPCWSTR lpFileName, + GET_FILEEX_INFO_LEVELS fInfoLevelId, + LPVOID lpFileInformation + ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} /* EOF */ diff --git a/lib/kernel32/misc/sysinfo.c b/lib/kernel32/misc/sysinfo.c index 8efbb06..008c0ce 100644 --- a/lib/kernel32/misc/sysinfo.c +++ b/lib/kernel32/misc/sysinfo.c @@ -3,13 +3,10 @@ * reactos/lib/kernel32/misc/sysinfo.c * */ -#include +#include +#define NDEBUG #include -#include - -#define WIN32_LEAN_AND_MEAN -#include #define PV_NT351 0x00030033 @@ -122,5 +119,13 @@ GetSystemInfo ( } } +BOOL STDCALL +IsProcessorFeaturePresent(DWORD ProcessorFeature) +{ + if (ProcessorFeature >= PROCESSOR_FEATURES_MAX) + return(FALSE); + + return((BOOL)SharedUserData->ProcessorFeatures[ProcessorFeature]); +} /* EOF */ diff --git a/lib/kernel32/misc/time.c b/lib/kernel32/misc/time.c index 0d2dc57..4220496 100644 --- a/lib/kernel32/misc/time.c +++ b/lib/kernel32/misc/time.c @@ -12,10 +12,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -//#include +#include #define NDEBUG #include @@ -176,14 +173,12 @@ FileTimeToSystemTime( TIME_FIELDS TimeFields; LARGE_INTEGER liTime; + if(lpFileTime->dwHighDateTime & 0x80000000) + return FALSE; + liTime.u.LowPart = lpFileTime->dwLowDateTime; liTime.u.HighPart = lpFileTime->dwHighDateTime; - if (liTime.u.HighPart >= 0x80000000) - { - return FALSE; - } - RtlTimeToTimeFields(&liTime, &TimeFields); lpSystemTime->wYear = TimeFields.Year; diff --git a/lib/kernel32/misc/toolhelp.c b/lib/kernel32/misc/toolhelp.c new file mode 100644 index 0000000..30417de --- /dev/null +++ b/lib/kernel32/misc/toolhelp.c @@ -0,0 +1,317 @@ +/* $Id$ + * + * KERNEL32.DLL toolhelp functions + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/misc/toolhelp.c + * PURPOSE: Toolhelp functions + * PROGRAMMER: Robert Dickenson (robd@mok.lvcm.com) + * UPDATE HISTORY: + * Created 05 January 2003 + */ + +#include +#include + + +#define CHECK_PARAM_SIZE(ptr, siz) \ + if (!ptr || ptr->dwSize != siz) { \ + SetLastError(ERROR_INVALID_PARAMETER); \ + return FALSE; \ + } + + +BOOL WINAPI +Heap32First(LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID) +{ + CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Heap32Next(LPHEAPENTRY32 lphe) +{ +/* +typedef struct tagHEAPENTRY32 { + DWORD dwSize; + HANDLE hHandle; + DWORD dwAddress; + DWORD dwBlockSize; + DWORD dwFlags; + DWORD dwLockCount; + DWORD dwResvd; + DWORD th32ProcessID; + DWORD th32HeapID; +} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Heap32ListFirst(HANDLE hSnapshot, LPHEAPLIST32 lphl) +{ + CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lph1) +{ +/* +typedef struct tagHEAPLIST32 { + DWORD dwSize; + DWORD th32ProcessID; + DWORD th32HeapID; + DWORD dwFlags; +} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme) +{ + CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Module32FirstW(HANDLE hSnapshot, LPMODULEENTRY32W lpme) +{ + CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme) +{ +/* +typedef struct tagMODULEENTRY32 { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; +} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Module32NextW(HANDLE hSnapshot, LPMODULEENTRY32W lpme) +{ +/* +typedef struct tagMODULEENTRY32W { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + WCHAR szModule[MAX_MODULE_NAME32 + 1]; + WCHAR szExePath[MAX_PATH]; +} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W; + + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL STDCALL +Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe) +{ + CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL STDCALL +Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe) +{ +/* +typedef struct tagPROCESSENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + CHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL STDCALL +Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe) +{ + CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL STDCALL +Process32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe) +{ +/* +typedef struct tagPROCESSENTRY32W { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + WCHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32W,*PPROCESSENTRY32W,*LPPROCESSENTRY32W; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + + +BOOL WINAPI Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte) +{ + CHECK_PARAM_SIZE(lpte, sizeof(THREADENTRY32)); + + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI Thread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte) +{ +/* +typedef struct tagTHREADENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ThreadID; + DWORD th32OwnerProcessID; + LONG tpBasePri; + LONG tpDeltaPri; + DWORD dwFlags; +} THREADENTRY32,*PTHREADENTRY32,*LPTHREADENTRY32; + */ + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI +Toolhelp32ReadProcessMemory(DWORD th32ProcessID, + LPCVOID lpBaseAddress, LPVOID lpBuffer, + DWORD cbRead, LPDWORD lpNumberOfBytesRead) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + +#define TL_DEV_NAME L"\\??\\TlHelpDevice" + +HANDLE STDCALL +CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID) +{ + // return open handle to snapshot on success, -1 on failure + // the snapshot handle behavies like an object handle + SECURITY_ATTRIBUTES sa; + HANDLE hSnapshot = (HANDLE)-1; + + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + + if (dwFlags & TH32CS_INHERIT) { + } + if (dwFlags & TH32CS_SNAPHEAPLIST) { + } + if (dwFlags & TH32CS_SNAPMODULE) { + } + if (dwFlags & TH32CS_SNAPPROCESS) { + } + if (dwFlags & TH32CS_SNAPTHREAD) { + } + hSnapshot = CreateFileW(TL_DEV_NAME, + GENERIC_READ, FILE_SHARE_READ + FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, 0L/*FILE_ATTRIBUTE_SYSTEM*/, 0); + if (hSnapshot != INVALID_HANDLE_VALUE) { + + } + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + // caller must use CloseHandle to destroy the returned snapshot handle + return hSnapshot; +} + + +#if 0 /* extracted from mingw tlhelp32.h for easy reference while working above */ +/* +#define HF32_DEFAULT 1 +#define HF32_SHARED 2 +#define LF32_FIXED 0x1 +#define LF32_FREE 0x2 +#define LF32_MOVEABLE 0x4 +#define MAX_MODULE_NAME32 255 +#define TH32CS_SNAPHEAPLIST 0x1 +#define TH32CS_SNAPPROCESS 0x2 +#define TH32CS_SNAPTHREAD 0x4 +#define TH32CS_SNAPMODULE 0x8 +#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE) +#define TH32CS_INHERIT 0x80000000 + +BOOL WINAPI Heap32First(LPHEAPENTRY32,DWORD,DWORD); +BOOL WINAPI Heap32ListFirst(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32ListNext(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32Next(LPHEAPENTRY32); +BOOL WINAPI Module32First(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32FirstW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Module32Next(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32NextW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Process32First(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32FirstW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Process32Next(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32NextW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Thread32First(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Thread32Next(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD); +HANDLE WINAPI CreateToolhelp32Snapshot(DWORD,DWORD); + +#ifdef UNICODE +#define LPMODULEENTRY32 LPMODULEENTRY32W +#define LPPROCESSENTRY32 LPPROCESSENTRY32W +#define MODULEENTRY32 MODULEENTRY32W +#define Module32First Module32FirstW +#define Module32Next Module32NextW +#define PMODULEENTRY32 PMODULEENTRY32W +#define PPROCESSENTRY32 PPROCESSENTRY32W +#define PROCESSENTRY32 PROCESSENTRY32W +#define Process32First Process32FirstW +#define Process32Next Process32NextW +#endif // UNICODE + */ +#endif /* 0 */ + +/* EOF */ diff --git a/lib/kernel32/nls/codepage.c b/lib/kernel32/nls/codepage.c index 2889426..04e816a 100644 --- a/lib/kernel32/nls/codepage.c +++ b/lib/kernel32/nls/codepage.c @@ -69,7 +69,9 @@ WINBOOL STDCALL IsValidCodePage(UINT codepage) } } -WINBOOL GetCPInfo(UINT codepage, LPCPINFO pcpinfo) +WINBOOL +STDCALL +GetCPInfo(UINT codepage, LPCPINFO pcpinfo) { PCODEPAGE pcp; diff --git a/lib/kernel32/nls/locale.c b/lib/kernel32/nls/locale.c index 9209e2d..3bfe2c5 100644 --- a/lib/kernel32/nls/locale.c +++ b/lib/kernel32/nls/locale.c @@ -125,6 +125,8 @@ LANGID STDCALL GetUserDefaultLangID(void) return LANGIDFROMLCID(__UserLocale->Id); } +#ifndef _OLE2NLS_IN_BUILD_ + LCID STDCALL GetUserDefaultLCID(void) @@ -143,6 +145,8 @@ LCID STDCALL GetSystemDefaultLCID(void) SORT_DEFAULT); } +#endif /*_OLE2NLS_IN_BUILD_*/ + LCID STDCALL GetThreadLocale(void) { return __TebLocale; @@ -1259,6 +1263,9 @@ GetDateFormatW( * - gg era string * */ + +#if 0 + int STDCALL GetDateFormatA(LCID locale,DWORD flags, CONST SYSTEMTIME *xtime, LPCSTR format, LPSTR date,int datelen) @@ -1277,4 +1284,7 @@ int STDCALL GetDateFormatA(LCID locale,DWORD flags, if (xtime == NULL) { GetSystemTime(&t); - thisti \ No newline at end of file + thisti + + +#endif diff --git a/lib/kernel32/nls/mbtowc.c b/lib/kernel32/nls/mbtowc.c index 5fa6c9e..7e5ed45 100644 --- a/lib/kernel32/nls/mbtowc.c +++ b/lib/kernel32/nls/mbtowc.c @@ -26,7 +26,9 @@ extern PLOCALE __TebLocale; #define GetTebLocale() __TebLocale -INT MultiByteToWideChar(UINT cpid, DWORD flags, LPCSTR src, int srclen, +INT +STDCALL +MultiByteToWideChar(UINT cpid, DWORD flags, LPCSTR src, int srclen, LPWSTR dest, int destlen) { PCODEPAGE pcodepage =__CPFirst; @@ -80,4 +82,4 @@ INT MultiByteToWideChar(UINT cpid, DWORD flags, LPCSTR src, int srclen, retlen = strlen(src); } return retlen; -} \ No newline at end of file +} diff --git a/lib/kernel32/nls/ole2nls.c b/lib/kernel32/nls/ole2nls.c index d3703a9..6af1f60 100644 --- a/lib/kernel32/nls/ole2nls.c +++ b/lib/kernel32/nls/ole2nls.c @@ -9,6 +9,8 @@ #include #include #include + +#define _KERNEL32_INCLUDE_LANG_ #include //#include "heap.h" //#include "ole.h" @@ -19,6 +21,31 @@ //#include "debug.h" //#include "main.h" +#define BOOL16 BOOL +#define BOOL32 BOOL +#define ole 1 +#define win32 2 +#define string 3 +#define file 4 + +typedef BOOL32 (*LOCALE_ENUMPROC32W)(WCHAR*); +typedef BOOL16 (*LOCALE_ENUMPROC32A)(CHAR*); + +typedef BOOL32 (*DATEFMT_ENUMPROC32W)(WCHAR*); +typedef BOOL16 (*DATEFMT_ENUMPROC32A)(CHAR*); + +typedef BOOL32 (*TIMEFMT_ENUMPROC32W)(WCHAR*); +typedef BOOL16 (*TIMEFMT_ENUMPROC32A)(CHAR*); + +#define NUMBERFMT32W int +#define NUMBERFMT32A int + +BOOL32 WINAPI GetStringTypeEx32A(LCID locale,DWORD dwInfoType,LPCSTR src, + ULONG cchSrc,LPWORD chartype); +BOOL32 WINAPI GetStringTypeEx32W(LCID locale,DWORD dwInfoType,LPCWSTR src, + ULONG cchSrc,LPWORD chartype); + + struct NLS_langlocale { const int lang; struct NLS_localevar { @@ -352,7 +379,7 @@ static struct tagLOCALE_NAME2ID { const struct map_lcid2str { LCID langid; const char *langname; -} languages[]={ +} static languages[]={ {0x0401,"Arabic (Saudi Arabia)"}, {0x0801,"Arabic (Iraq)"}, {0x0c01,"Arabic (Egypt)"}, @@ -749,11 +776,13 @@ BOOL16 WINAPI SetLocaleInfoA(DWORD lcid, DWORD lctype, LPCSTR data) /****************************************************************************** * IsValidLocale [KERNEL32.489] */ +#if 0 BOOL32 WINAPI IsValidLocale(LCID lcid,DWORD flags) { /* we support ANY language. Well, at least say that...*/ return TRUE; } +#endif /****************************************************************************** * EnumSystemLocales32W [KERNEL32.209] @@ -2226,6 +2255,7 @@ UINT16 WINAPI CompareString16(DWORD lcid,DWORD fdwStyle, * * Quite inefficient. */ +#if 0 ULONG WINAPI CompareStringA( DWORD lcid, /* locale ID */ DWORD fdwStyle, /* comparison-style options */ @@ -2312,6 +2342,7 @@ ULONG WINAPI CompareStringW(DWORD lcid, DWORD fdwStyle, /* the longer one is lexically greater */ return (l1 -#include -#include -#include -#include -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/process/create.c b/lib/kernel32/process/create.c index 34748ee..776057c 100644 --- a/lib/kernel32/process/create.c +++ b/lib/kernel32/process/create.c @@ -11,23 +11,10 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ @@ -167,6 +154,8 @@ CreateProcessA (LPCSTR lpApplicationName, return Result; } +static int _except_recursion_trap = 0; + struct _CONTEXT; struct __EXCEPTION_RECORD; @@ -181,15 +170,25 @@ _except_handler( { DPRINT("Process terminated abnormally...\n"); + if (++_except_recursion_trap > 3) { + DPRINT("_except_handler(...) appears to be recursing.\n"); + DPRINT("Process HALTED.\n"); + for (;;) {} + } + if (/* FIXME: */ TRUE) /* Not a service */ { - ExitProcess(0); + DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n"); + //ExitProcess(0); + ExitThread(0); } else { + DPRINT(" calling ExitThread(0) . . .\n"); ExitThread(0); } + DPRINT(" We should not get to here !!!\n"); /* We should not get to here */ return ExceptionContinueSearch; } @@ -200,6 +199,8 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress, { UINT uExitCode = 0; + DPRINT("\nBaseProcessStart(..) - setting up exception frame.\n\n"); + __try1(_except_handler) { uExitCode = (lpStartAddress)((PVOID)lpParameter); @@ -207,6 +208,8 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress, { } + DPRINT("\nBaseProcessStart(..) - cleaned up exception frame.\n\n"); + ExitThread(uExitCode); } @@ -534,7 +537,7 @@ KlInitPeb (HANDLE ProcessHandle, return(Status); } - DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength); + //DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength); NtWriteVirtualMemory(ProcessHandle, PpbBase, Ppb, @@ -743,9 +746,94 @@ CreateProcessW(LPCWSTR lpApplicationName, hSection = KlMapFile (ImagePathName); if (hSection == NULL) { - return FALSE; +///////////////////////////////////////// + /* + * Inspect the image to determine executable flavour + */ + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING ApplicationNameString; + OBJECT_ATTRIBUTES ObjectAttributes; + PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; + IMAGE_DOS_HEADER DosHeader; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER Offset; + HANDLE hFile = NULL; + + DPRINT("Inspecting Image Header for image type id\n"); + + // Find the application name + if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpApplicationName, + &ApplicationNameString, NULL, NULL)) { + return FALSE; + } + DPRINT("ApplicationName %S\n",ApplicationNameString.Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &ApplicationNameString, + OBJ_CASE_INSENSITIVE, + NULL, + SecurityDescriptor); + + // Try to open the executable + Status = NtOpenFile(&hFile, + SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_DELETE|FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE); + + RtlFreeUnicodeString(&ApplicationNameString); + + if (!NT_SUCCESS(Status)) { + DPRINT("Failed to open file\n"); + SetLastErrorByStatus(Status); + return FALSE; + } + + // Read the dos header + Offset.QuadPart = 0; + Status = ZwReadFile(hFile, + NULL, + NULL, + NULL, + &Iosb, + &DosHeader, + sizeof(DosHeader), + &Offset, + 0); + + if (!NT_SUCCESS(Status)) { + DPRINT("Failed to read from file\n"); + SetLastErrorByStatus(Status); + return FALSE; + } + if (Iosb.Information != sizeof(DosHeader)) { + DPRINT("Failed to read dos header from file\n"); + SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT); + return FALSE; + } + + // Check the DOS signature + if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { + DPRINT("Failed dos magic check\n"); + SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT); + return FALSE; + } + NtClose(hFile); + + DPRINT("Launching VDM...\n"); + return CreateProcessW(L"ntvdm.exe", + (LPWSTR)lpApplicationName, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation); } - +///////////////////////////////////////// /* * Create a new process */ @@ -777,7 +865,7 @@ CreateProcessW(LPCWSTR lpApplicationName, RuntimeInfo_U.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, RuntimeInfo_U.Length); memcpy(RuntimeInfo_U.Buffer, lpStartupInfo->lpReserved2, lpStartupInfo->cbReserved2); } - } + } /* * Create the PPB @@ -795,14 +883,14 @@ CreateProcessW(LPCWSTR lpApplicationName, if (lpStartupInfo && lpStartupInfo->lpReserved2) RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer); - + /* * Translate some handles for the new process */ if (Ppb->CurrentDirectoryHandle) { - Status = NtDuplicateObject (NtCurrentProcess(), + Status = NtDuplicateObject (NtCurrentProcess(), Ppb->CurrentDirectoryHandle, hProcess, &Ppb->CurrentDirectoryHandle, diff --git a/lib/kernel32/process/proc.c b/lib/kernel32/process/proc.c index a243ce4..71a3926 100644 --- a/lib/kernel32/process/proc.c +++ b/lib/kernel32/process/proc.c @@ -11,18 +11,7 @@ /* INCLUDES ****************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #define NDEBUG @@ -36,13 +25,13 @@ WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; LPSTARTUPINFO lpLocalStartupInfo = NULL; VOID STDCALL -RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle); +RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle); +WINBOOL STDCALL +GetProcessId (HANDLE hProcess, LPDWORD lpProcessId); -/* FUNCTIONS ****************************************************************/ -WINBOOL STDCALL -GetProcessId (HANDLE hProcess, LPDWORD lpProcessId); +/* FUNCTIONS ****************************************************************/ WINBOOL STDCALL GetProcessAffinityMask(HANDLE hProcess, @@ -65,6 +54,14 @@ GetProcessAffinityMask(HANDLE hProcess, } +BOOL STDCALL +SetProcessAffinityMask(HANDLE hProcess, + DWORD dwProcessAffinityMask) +{ + return(FALSE); +} + + WINBOOL STDCALL GetProcessShutdownParameters(LPDWORD lpdwLevel, LPDWORD lpdwFlags) @@ -122,8 +119,24 @@ GetProcessWorkingSetSize(HANDLE hProcess, LPDWORD lpMinimumWorkingSetSize, LPDWORD lpMaximumWorkingSetSize) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return(FALSE); + QUOTA_LIMITS QuotaLimits; + NTSTATUS Status; + + Status = NtQueryInformationProcess(hProcess, + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QUOTA_LIMITS), + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + *lpMinimumWorkingSetSize = (DWORD)QuotaLimits.MinimumWorkingSetSize; + *lpMaximumWorkingSetSize = (DWORD)QuotaLimits.MaximumWorkingSetSize; + + return(TRUE); } @@ -158,7 +171,7 @@ GetProcessTimes(HANDLE hProcess, return(FALSE); } - lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart; + lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart; lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart; lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart; @@ -224,22 +237,24 @@ WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId) { - NTSTATUS errCode; - PROCESS_BASIC_INFORMATION ProcessBasic; - ULONG BytesWritten; - - errCode = NtQueryInformationProcess(hProcess, - ProcessBasicInformation, - &ProcessBasic, - sizeof(PROCESS_BASIC_INFORMATION), - &BytesWritten); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus (errCode); - return FALSE; - } - memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD)); - return TRUE; + PROCESS_BASIC_INFORMATION ProcessBasic; + ULONG BytesWritten; + NTSTATUS Status; + + Status = NtQueryInformationProcess(hProcess, + ProcessBasicInformation, + &ProcessBasic, + sizeof(PROCESS_BASIC_INFORMATION), + &BytesWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + memcpy(lpProcessId, &ProcessBasic.UniqueProcessId, sizeof(DWORD)); + + return(TRUE); } @@ -701,6 +716,4 @@ GetProcessVersion (DWORD ProcessId) return (Version); } - - /* EOF */ diff --git a/lib/kernel32/process/session.c b/lib/kernel32/process/session.c index dca7cc4..d5cd400 100644 --- a/lib/kernel32/process/session.c +++ b/lib/kernel32/process/session.c @@ -8,7 +8,7 @@ * UPDATE HISTORY: * 2001-12-07 created */ -#include +#include BOOL STDCALL ProcessIdToSessionId ( DWORD dwProcessId, diff --git a/lib/kernel32/string/lstring.c b/lib/kernel32/string/lstring.c index 855da67..f3dfc7c 100644 --- a/lib/kernel32/string/lstring.c +++ b/lib/kernel32/string/lstring.c @@ -8,9 +8,7 @@ * Created 01/11/98 */ -#include -#include -#include +#include int diff --git a/lib/kernel32/synch/critical.c b/lib/kernel32/synch/critical.c index 188b470..484e470 100644 --- a/lib/kernel32/synch/critical.c +++ b/lib/kernel32/synch/critical.c @@ -10,8 +10,9 @@ /* INCLUDES ******************************************************************/ -#include +#include +#define NDEBUG #include diff --git a/lib/kernel32/synch/event.c b/lib/kernel32/synch/event.c index 1f7b48c..7b0a71b 100644 --- a/lib/kernel32/synch/event.c +++ b/lib/kernel32/synch/event.c @@ -11,12 +11,10 @@ /* INCLUDES *****************************************************************/ -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/synch/intrlck.c b/lib/kernel32/synch/intrlck.c index e09d757..85a6c4b 100644 --- a/lib/kernel32/synch/intrlck.c +++ b/lib/kernel32/synch/intrlck.c @@ -28,7 +28,7 @@ * * ************************************************************************/ -#include +#include LONG STDCALL diff --git a/lib/kernel32/synch/mutex.c b/lib/kernel32/synch/mutex.c index 2d94b51..fe27e3a 100644 --- a/lib/kernel32/synch/mutex.c +++ b/lib/kernel32/synch/mutex.c @@ -11,11 +11,9 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include +#include +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ diff --git a/lib/kernel32/synch/sem.c b/lib/kernel32/synch/sem.c index d5c2e05..28f78f1 100644 --- a/lib/kernel32/synch/sem.c +++ b/lib/kernel32/synch/sem.c @@ -11,12 +11,10 @@ /* INCLUDES *****************************************************************/ -#include -#include +#include #define NDEBUG #include -#include /* FUNCTIONS ****************************************************************/ diff --git a/lib/kernel32/synch/timer.c b/lib/kernel32/synch/timer.c index 6199e45..f2c859f 100644 --- a/lib/kernel32/synch/timer.c +++ b/lib/kernel32/synch/timer.c @@ -9,9 +9,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/synch/wait.c b/lib/kernel32/synch/wait.c index af4ecc5..0bdf016 100644 --- a/lib/kernel32/synch/wait.c +++ b/lib/kernel32/synch/wait.c @@ -11,10 +11,7 @@ /* INCLUDES *****************************************************************/ -#include -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/kernel32/thread/fiber.c b/lib/kernel32/thread/fiber.c index a96a0a2..27ef802 100644 --- a/lib/kernel32/thread/fiber.c +++ b/lib/kernel32/thread/fiber.c @@ -5,7 +5,8 @@ * ReactOS Kernel32.dll * */ -#include +#include + /********************************************************************** diff --git a/lib/kernel32/thread/thread.c b/lib/kernel32/thread/thread.c index f64a980..e4a9423 100644 --- a/lib/kernel32/thread/thread.c +++ b/lib/kernel32/thread/thread.c @@ -12,104 +12,102 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include +#include #define NDEBUG #include -#include -static VOID ThreadAttachDlls (VOID); +//static VOID ThreadAttachDlls (VOID); /* FUNCTIONS *****************************************************************/ -static -EXCEPTION_DISPOSITION -__cdecl -_except_handler( - struct _EXCEPTION_RECORD *ExceptionRecord, - void * EstablisherFrame, - struct _CONTEXT *ContextRecord, - void * DispatcherContext ) -{ - ExitThread(0); - - /* We should not get to here */ - return ExceptionContinueSearch; -} - -static VOID STDCALL -ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter) +static EXCEPTION_DISPOSITION __cdecl +_except_handler(struct _EXCEPTION_RECORD *ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT *ContextRecord, + void * DispatcherContext) { - UINT uExitCode; + ExitThread(0); - __try1(_except_handler) - { - /* FIXME: notify csrss of thread creation ?? */ - uExitCode = (lpStartAddress)(lpParameter); - } __except1 - { - } + /* We should not get to here */ + return(ExceptionContinueSearch); +} - ExitThread(uExitCode); + +static VOID STDCALL +ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter) +{ + UINT uExitCode; + + __try1(_except_handler) + { + /* FIXME: notify csrss of thread creation ?? */ + uExitCode = (lpStartAddress)(lpParameter); + } + __except1 + { + } + + ExitThread(uExitCode); } -HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) + +HANDLE STDCALL +CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId) { - return(CreateRemoteThread(NtCurrentProcess(), - lpThreadAttributes, - dwStackSize, - lpStartAddress, - lpParameter, - dwCreationFlags, - lpThreadId)); + return(CreateRemoteThread(NtCurrentProcess(), + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId)); } -HANDLE STDCALL CreateRemoteThread(HANDLE hProcess, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) + +HANDLE STDCALL +CreateRemoteThread(HANDLE hProcess, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId) { - HANDLE ThreadHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - BOOLEAN CreateSuspended = FALSE; - PVOID BaseAddress; - ULONG OldPageProtection; - NTSTATUS Status; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - if (lpThreadAttributes != NULL) - { - if (lpThreadAttributes->bInheritHandle) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = - lpThreadAttributes->lpSecurityDescriptor; - } - ObjectAttributes.SecurityQualityOfService = NULL; - - if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) - CreateSuspended = TRUE; - else - CreateSuspended = FALSE; + HANDLE ThreadHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + CLIENT_ID ClientId; + CONTEXT ThreadContext; + INITIAL_TEB InitialTeb; + BOOLEAN CreateSuspended = FALSE; + PVOID BaseAddress; + ULONG OldPageProtection; + NTSTATUS Status; + + ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); + ObjectAttributes.RootDirectory = NULL; + ObjectAttributes.ObjectName = NULL; + ObjectAttributes.Attributes = 0; + if (lpThreadAttributes != NULL) + { + if (lpThreadAttributes->bInheritHandle) + ObjectAttributes.Attributes = OBJ_INHERIT; + ObjectAttributes.SecurityDescriptor = + lpThreadAttributes->lpSecurityDescriptor; + } + ObjectAttributes.SecurityQualityOfService = NULL; + + if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) + CreateSuspended = TRUE; + else + CreateSuspended = FALSE; InitialTeb.StackReserve = 0x100000; /* 1MByte */ /* FIXME: use correct commit size */ @@ -233,244 +231,383 @@ HANDLE STDCALL CreateRemoteThread(HANDLE hProcess, return(ThreadHandle); } + PTEB GetTeb(VOID) { return(NtCurrentTeb()); } + WINBOOL STDCALL SwitchToThread(VOID) { - NTSTATUS errCode; - errCode = NtYieldExecution(); - return TRUE; + NTSTATUS errCode; + errCode = NtYieldExecution(); + return TRUE; } + DWORD STDCALL -GetCurrentThreadId() +GetCurrentThreadId(VOID) { - return((DWORD)(NtCurrentTeb()->Cid).UniqueThread); + return((DWORD)(NtCurrentTeb()->Cid).UniqueThread); } + VOID STDCALL ExitThread(DWORD uExitCode) { - NTSTATUS errCode; - BOOLEAN LastThread; - NTSTATUS Status; - - /* - * Terminate process if this is the last thread - * of the current process - */ - Status = NtQueryInformationThread(NtCurrentThread(), - ThreadAmILastThread, - &LastThread, - sizeof(BOOLEAN), - NULL); - if (NT_SUCCESS(Status) && LastThread == TRUE) - { - ExitProcess (uExitCode); - } - - /* FIXME: notify csrss of thread termination */ - - LdrShutdownThread(); - - errCode = NtTerminateThread(NtCurrentThread(), - uExitCode); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - } + BOOLEAN LastThread; + NTSTATUS Status; + + /* + * Terminate process if this is the last thread + * of the current process + */ + Status = NtQueryInformationThread(NtCurrentThread(), + ThreadAmILastThread, + &LastThread, + sizeof(BOOLEAN), + NULL); + if (NT_SUCCESS(Status) && LastThread == TRUE) + { + ExitProcess(uExitCode); + } + + /* FIXME: notify csrss of thread termination */ + + LdrShutdownThread(); + + Status = NtTerminateThread(NtCurrentThread(), + uExitCode); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + } } -WINBOOL STDCALL GetThreadTimes(HANDLE hThread, - LPFILETIME lpCreationTime, - LPFILETIME lpExitTime, - LPFILETIME lpKernelTime, - LPFILETIME lpUserTime) + +WINBOOL STDCALL +GetThreadTimes(HANDLE hThread, + LPFILETIME lpCreationTime, + LPFILETIME lpExitTime, + LPFILETIME lpKernelTime, + LPFILETIME lpUserTime) { - NTSTATUS errCode; - KERNEL_USER_TIMES KernelUserTimes; - ULONG ReturnLength; - - errCode = NtQueryInformationThread(hThread, - ThreadTimes, - &KernelUserTimes, - sizeof(KERNEL_USER_TIMES), - &ReturnLength); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME)); - memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME)); - memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME)); - memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME)); - return TRUE; + KERNEL_USER_TIMES KernelUserTimes; + ULONG ReturnLength; + NTSTATUS Status; + + Status = NtQueryInformationThread(hThread, + ThreadTimes, + &KernelUserTimes, + sizeof(KERNEL_USER_TIMES), + &ReturnLength); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME)); + memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME)); + memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME)); + memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME)); + + return(TRUE); } -WINBOOL STDCALL GetThreadContext(HANDLE hThread, - LPCONTEXT lpContext) +WINBOOL STDCALL +GetThreadContext(HANDLE hThread, + LPCONTEXT lpContext) { - NTSTATUS errCode; - - errCode = NtGetContextThread(hThread, - lpContext); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - return TRUE; + NTSTATUS Status; + + Status = NtGetContextThread(hThread, + lpContext); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); } -WINBOOL STDCALL SetThreadContext(HANDLE hThread, - CONST CONTEXT *lpContext) + +WINBOOL STDCALL +SetThreadContext(HANDLE hThread, + CONST CONTEXT *lpContext) { - NTSTATUS errCode; - - errCode = NtSetContextThread(hThread, - (void *)lpContext); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - return TRUE; + NTSTATUS Status; + + Status = NtSetContextThread(hThread, + (void *)lpContext); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); } -WINBOOL STDCALL GetExitCodeThread(HANDLE hThread, - LPDWORD lpExitCode) + +WINBOOL STDCALL +GetExitCodeThread(HANDLE hThread, + LPDWORD lpExitCode) { - NTSTATUS errCode; - THREAD_BASIC_INFORMATION ThreadBasic; - ULONG DataWritten; - - errCode = NtQueryInformationThread(hThread, - ThreadBasicInformation, - &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION), - &DataWritten); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD)); - return TRUE; + THREAD_BASIC_INFORMATION ThreadBasic; + ULONG DataWritten; + NTSTATUS Status; + + Status = NtQueryInformationThread(hThread, + ThreadBasicInformation, + &ThreadBasic, + sizeof(THREAD_BASIC_INFORMATION), + &DataWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD)); + + return(TRUE); } -DWORD STDCALL ResumeThread(HANDLE hThread) + +DWORD STDCALL +ResumeThread(HANDLE hThread) { - NTSTATUS errCode; - ULONG PreviousResumeCount; - - errCode = NtResumeThread(hThread, - &PreviousResumeCount); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return -1; - } - return PreviousResumeCount; + ULONG PreviousResumeCount; + NTSTATUS Status; + + Status = NtResumeThread(hThread, + &PreviousResumeCount); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(-1); + } + + return(PreviousResumeCount); } WINBOOL STDCALL -TerminateThread (HANDLE hThread, - DWORD dwExitCode) +TerminateThread(HANDLE hThread, + DWORD dwExitCode) { - if (0 == hThread) + NTSTATUS Status; + + if (0 == hThread) { - SetLastError (ERROR_INVALID_HANDLE); + SetLastError(ERROR_INVALID_HANDLE); + return(FALSE); } - else + + Status = NtTerminateThread(hThread, + dwExitCode); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); +} + + +DWORD STDCALL +SuspendThread(HANDLE hThread) +{ + ULONG PreviousSuspendCount; + NTSTATUS Status; + + Status = NtSuspendThread(hThread, + &PreviousSuspendCount); + if (!NT_SUCCESS(Status)) { - NTSTATUS Status = NtTerminateThread (hThread, dwExitCode); - - if (NT_SUCCESS(Status)) - { - return TRUE; - } - SetLastErrorByStatus (Status); + SetLastErrorByStatus(Status); + return(-1); } - return FALSE; + + return(PreviousSuspendCount); } -DWORD STDCALL SuspendThread(HANDLE hThread) +DWORD STDCALL +SetThreadAffinityMask(HANDLE hThread, + DWORD dwThreadAffinityMask) { - NTSTATUS errCode; - ULONG PreviousSuspendCount; - - errCode = NtSuspendThread(hThread, - &PreviousSuspendCount); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return -1; - } - return PreviousSuspendCount; + THREAD_BASIC_INFORMATION ThreadBasic; + KAFFINITY AffinityMask; + ULONG DataWritten; + NTSTATUS Status; + + AffinityMask = (KAFFINITY)dwThreadAffinityMask; + + Status = NtQueryInformationThread(hThread, + ThreadBasicInformation, + &ThreadBasic, + sizeof(THREAD_BASIC_INFORMATION), + &DataWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(0); + } + + Status = NtSetInformationThread(hThread, + ThreadAffinityMask, + &AffinityMask, + sizeof(KAFFINITY)); + if (!NT_SUCCESS(Status)) + SetLastErrorByStatus(Status); + + return(ThreadBasic.AffinityMask); } -DWORD STDCALL SetThreadAffinityMask(HANDLE hThread, - DWORD dwThreadAffinityMask) + +WINBOOL STDCALL +SetThreadPriority(HANDLE hThread, + int nPriority) { - return 0; + THREAD_BASIC_INFORMATION ThreadBasic; + ULONG DataWritten; + NTSTATUS Status; + + Status = NtQueryInformationThread(hThread, + ThreadBasicInformation, + &ThreadBasic, + sizeof(THREAD_BASIC_INFORMATION), + &DataWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + ThreadBasic.BasePriority = nPriority; + + Status = NtSetInformationThread(hThread, + ThreadBasicInformation, + &ThreadBasic, + sizeof(THREAD_BASIC_INFORMATION)); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); } -WINBOOL STDCALL SetThreadPriority(HANDLE hThread, - int nPriority) + +int STDCALL +GetThreadPriority(HANDLE hThread) { - NTSTATUS errCode; - THREAD_BASIC_INFORMATION ThreadBasic; - ULONG DataWritten; - - errCode = NtQueryInformationThread(hThread, - ThreadBasicInformation, - &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION), - &DataWritten); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - ThreadBasic.BasePriority = nPriority; - errCode = NtSetInformationThread(hThread, + THREAD_BASIC_INFORMATION ThreadBasic; + ULONG DataWritten; + NTSTATUS Status; + + Status = NtQueryInformationThread(hThread, ThreadBasicInformation, &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION)); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return FALSE; - } - return TRUE; + sizeof(THREAD_BASIC_INFORMATION), + &DataWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(THREAD_PRIORITY_ERROR_RETURN); + } + + return(ThreadBasic.BasePriority); +} + + +WINBOOL STDCALL +GetThreadPriorityBoost(IN HANDLE hThread, + OUT PBOOL pDisablePriorityBoost) +{ + ULONG PriorityBoost; + ULONG DataWritten; + NTSTATUS Status; + + Status = NtQueryInformationThread(hThread, + ThreadPriorityBoost, + &PriorityBoost, + sizeof(ULONG), + &DataWritten); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + *pDisablePriorityBoost = !((WINBOOL)PriorityBoost); + + return(TRUE); +} + + +WINBOOL STDCALL +SetThreadPriorityBoost(IN HANDLE hThread, + IN WINBOOL bDisablePriorityBoost) +{ + ULONG PriorityBoost; + NTSTATUS Status; + + PriorityBoost = (ULONG)!bDisablePriorityBoost; + + Status = NtSetInformationThread(hThread, + ThreadPriorityBoost, + &PriorityBoost, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); } -int STDCALL GetThreadPriority(HANDLE hThread) + +WINBOOL STDCALL +GetThreadSelectorEntry(IN HANDLE hThread, + IN DWORD dwSelector, + OUT LPLDT_ENTRY lpSelectorEntry) { - NTSTATUS errCode; - THREAD_BASIC_INFORMATION ThreadBasic; - ULONG DataWritten; - - errCode = NtQueryInformationThread(hThread, - ThreadBasicInformation, - &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION), - &DataWritten); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus(errCode); - return THREAD_PRIORITY_ERROR_RETURN; - } - return ThreadBasic.BasePriority; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return(FALSE); +} + + +WINBOOL STDCALL +SetThreadIdealProcessor(HANDLE hThread, + DWORD dwIdealProcessor) +{ + ULONG IdealProcessor; + NTSTATUS Status; + + IdealProcessor = (ULONG)dwIdealProcessor; + + Status = NtSetInformationThread(hThread, + ThreadIdealProcessor, + &IdealProcessor, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + + return(TRUE); } /* EOF */ diff --git a/lib/kernel32/thread/tls.c b/lib/kernel32/thread/tls.c index e3cc27b..98b368f 100644 --- a/lib/kernel32/thread/tls.c +++ b/lib/kernel32/thread/tls.c @@ -12,11 +12,7 @@ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include -#include +#include #define NDEBUG #include diff --git a/lib/msafd/.cvsignore b/lib/msafd/.cvsignore index 095ef4e..e3a88fc 100644 --- a/lib/msafd/.cvsignore +++ b/lib/msafd/.cvsignore @@ -2,6 +2,8 @@ msafd.a msafd.dll msafd.nostrip.dll msafd.coff +msafd.sym base.tmp junk.tmp temp.exp +*.o diff --git a/lib/msafd/makefile b/lib/msafd/makefile index 631dae2..6844b1e 100644 --- a/lib/msafd/makefile +++ b/lib/msafd/makefile @@ -10,7 +10,15 @@ TARGET_BASE = 0x777a0000 TARGET_SDKLIBS = ntdll.a kernel32.a -TARGET_CFLAGS = -I./include -DUNICODE -DDBG +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -DUNICODE \ + -DDBG + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_OBJECTS = $(TARGET_NAME).o diff --git a/lib/msafd/misc/.cvsignore b/lib/msafd/misc/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/msafd/misc/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/msafd/misc/dllmain.c b/lib/msafd/misc/dllmain.c index 47f25c9..9e1a636 100644 --- a/lib/msafd/misc/dllmain.c +++ b/lib/msafd/misc/dllmain.c @@ -7,6 +7,7 @@ * REVISIONS: * CSH 01/09-2000 Created */ +#include #include #include diff --git a/lib/msafd/misc/helpers.c b/lib/msafd/misc/helpers.c index 648bad0..5d92e16 100644 --- a/lib/msafd/misc/helpers.c +++ b/lib/msafd/misc/helpers.c @@ -80,9 +80,9 @@ PWSHELPER_DLL LocateHelperDLL( ListEntry); for (i = 0; i < HelperDLL->Mapping->Rows; i++) { - if ((lpProtocolInfo->iAddressFamily == HelperDLL->Mapping->Mapping[i].AddressFamily) && - (lpProtocolInfo->iSocketType == HelperDLL->Mapping->Mapping[i].SocketType) && - ((lpProtocolInfo->iProtocol == HelperDLL->Mapping->Mapping[i].Protocol) || + if ((lpProtocolInfo->iAddressFamily == (INT) HelperDLL->Mapping->Mapping[i].AddressFamily) && + (lpProtocolInfo->iSocketType == (INT) HelperDLL->Mapping->Mapping[i].SocketType) && + ((lpProtocolInfo->iProtocol == (INT) HelperDLL->Mapping->Mapping[i].Protocol) || (lpProtocolInfo->iSocketType == SOCK_RAW))) { LeaveCriticalSection(&HelperDLLDatabaseLock); AFD_DbgPrint(MAX_TRACE, ("Returning helper DLL at (0x%X).\n", HelperDLL)); @@ -100,35 +100,74 @@ PWSHELPER_DLL LocateHelperDLL( } -#define GET_ENTRY_POINT(helper, exportname, identifier) { \ - PVOID entry; \ - \ - entry = GetProcAddress(helper->hModule, exportname); \ - if (!entry) \ - return ERROR_BAD_PROVIDER; \ - ((PVOID)helper->EntryTable.##identifier) = entry; \ -} - - INT GetHelperDLLEntries( PWSHELPER_DLL HelperDLL) { - GET_ENTRY_POINT(HelperDLL, "WSHAddressToString", lpWSHAddressToString); - GET_ENTRY_POINT(HelperDLL, "WSHEnumProtocols", lpWSHEnumProtocols); - GET_ENTRY_POINT(HelperDLL, "WSHGetBroadcastSockaddr", lpWSHGetBroadcastSockaddr); - GET_ENTRY_POINT(HelperDLL, "WSHGetProviderGuid", lpWSHGetProviderGuid); - GET_ENTRY_POINT(HelperDLL, "WSHGetSockaddrType", lpWSHGetSockaddrType); - GET_ENTRY_POINT(HelperDLL, "WSHGetSocketInformation", lpWSHGetSocketInformation); - GET_ENTRY_POINT(HelperDLL, "WSHGetWildcardSockaddr", lpWSHGetWildcardSockaddr); - GET_ENTRY_POINT(HelperDLL, "WSHGetWinsockMapping", lpWSHGetWinsockMapping); - GET_ENTRY_POINT(HelperDLL, "WSHGetWSAProtocolInfo", lpWSHGetWSAProtocolInfo); - GET_ENTRY_POINT(HelperDLL, "WSHIoctl", lpWSHIoctl); - GET_ENTRY_POINT(HelperDLL, "WSHJoinLeaf", lpWSHJoinLeaf); - GET_ENTRY_POINT(HelperDLL, "WSHNotify", lpWSHNotify); - GET_ENTRY_POINT(HelperDLL, "WSHOpenSocket", lpWSHOpenSocket); - GET_ENTRY_POINT(HelperDLL, "WSHOpenSocket2", lpWSHOpenSocket2); - GET_ENTRY_POINT(HelperDLL, "WSHSetSocketInformation", lpWSHSetSocketInformation); - GET_ENTRY_POINT(HelperDLL, "WSHStringToAddress", lpWSHStringToAddress); + PVOID e; + + e = GetProcAddress(HelperDLL->hModule, "WSHAddressToString"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHAddressToString) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHEnumProtocols"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHEnumProtocols) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetBroadcastSockaddr"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetBroadcastSockaddr) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetProviderGuid"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetProviderGuid) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetSockaddrType"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetSockaddrType) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetSocketInformation"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetSocketInformation) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetWildcardSockaddr"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetWildcardSockaddr) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetWinsockMapping"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetWinsockMapping) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHGetWSAProtocolInfo"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHGetWSAProtocolInfo) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHIoctl"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHIoctl) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHJoinLeaf"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHJoinLeaf) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHNotify"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHNotify) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHOpenSocket"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHOpenSocket) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHOpenSocket2"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHOpenSocket2) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHSetSocketInformation"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHSetSocketInformation) = e; + + e = GetProcAddress(HelperDLL->hModule, "WSHStringToAddress"); + if (!e) return ERROR_BAD_PROVIDER; + ((PVOID) HelperDLL->EntryTable.lpWSHStringToAddress) = e; return NO_ERROR; } diff --git a/lib/msafd/misc/sndrcv.c b/lib/msafd/misc/sndrcv.c index 742c0b2..3f239e4 100644 --- a/lib/msafd/misc/sndrcv.c +++ b/lib/msafd/misc/sndrcv.c @@ -7,6 +7,7 @@ * REVISIONS: * CSH 01/09-2000 Created */ +#include #include INT diff --git a/lib/msvcrt/.cvsignore b/lib/msvcrt/.cvsignore index 0147911..ac9ff25 100644 --- a/lib/msvcrt/.cvsignore +++ b/lib/msvcrt/.cvsignore @@ -4,3 +4,8 @@ msvcrt.nostrip.dll *.d *.o *.sym +*.dsp +*.dsw +*.ncb +*.opt +*.txt diff --git a/lib/msvcrt/Makefile b/lib/msvcrt/Makefile index a25f79e..6b5916d 100644 --- a/lib/msvcrt/Makefile +++ b/lib/msvcrt/Makefile @@ -8,23 +8,39 @@ TARGET_TYPE = dynlink TARGET_NAME = msvcrt +TARGET_BASE = 0x78000000 + TARGET_LFLAGS = -nostartfiles TARGET_SDKLIBS = kernel32.a ntdll.a TARGET_GCCLIBS = gcc -TARGET_BASE = 0x78000000 - -TARGET_CFLAGS = -D__MSVCRT__ +TARGET_CFLAGS = -D_MSVCRT_LIB_ TARGET_OBJECTS = $(TARGET_NAME).o TARGET_CLEAN = \ - conio/*.o ctype/*.o direct/*.o except/*.o float/*.o io/*.o \ - locale/*.o math/*.o mbstring/*.o misc/*.o process/*.o search/*.o \ - setjmp/*.o signal/*.o stdio/*.o stdlib/*.o string/*.o sys_stat/*.o \ - time/*.o wstring/*.o + conio/*.o \ + ctype/*.o \ + direct/*.o \ + except/*.o \ + float/*.o \ + io/*.o \ + locale/*.o \ + math/*.o \ + mbstring/*.o \ + misc/*.o \ + process/*.o \ + search/*.o \ + setjmp/*.o \ + signal/*.o \ + stdio/*.o \ + stdlib/*.o \ + string/*.o \ + sys_stat/*.o \ + time/*.o \ + wstring/*.o include $(PATH_TO_TOP)/rules.mak @@ -32,7 +48,7 @@ include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk -OBJECTS_CONIO = \ +CONIO_OBJECTS = \ conio/cgets.o \ conio/cprintf.o \ conio/cputs.o \ @@ -43,7 +59,8 @@ OBJECTS_CONIO = \ conio/putch.o \ conio/ungetch.o -OBJECTS_CTYPE = \ +CTYPE_OBJECTS = \ + ctype/ctype.o \ ctype/isalnum.o \ ctype/isalpha.o \ ctype/isascii.o \ @@ -62,7 +79,7 @@ OBJECTS_CTYPE = \ ctype/iscsym.o \ ctype/isctype.o -OBJECTS_DIRECT = \ +DIRECT_OBJECTS = \ direct/chdir.o \ direct/chdrive.o \ direct/getcwd.o \ @@ -70,9 +87,14 @@ OBJECTS_DIRECT = \ direct/getdfree.o \ direct/getdrive.o \ direct/mkdir.o \ - direct/rmdir.o - -OBJECTS_EXCEPT = \ + direct/rmdir.o \ + direct/wchdir.o \ + direct/wgetcwd.o \ + direct/wgetdcwd.o \ + direct/wmkdir.o \ + direct/wrmdir.o + +EXCEPT_OBJECTS = \ except/seh.o \ except/abnorter.o \ except/exhand2.o \ @@ -80,7 +102,7 @@ OBJECTS_EXCEPT = \ except/unwind.o \ except/xcptfil.o -OBJECTS_FLOAT = \ +FLOAT_OBJECTS = \ float/chgsign.o \ float/clearfp.o \ float/cntrlfp.o \ @@ -94,7 +116,7 @@ OBJECTS_FLOAT = \ float/scalb.o \ float/statfp.o -OBJECTS_IO = \ +IO_OBJECTS = \ io/access.o \ io/chmod.o \ io/chsize.o \ @@ -105,11 +127,13 @@ OBJECTS_IO = \ io/dup2.o \ io/eof.o \ io/filelen.o \ + io/fileleni.o \ io/find.o \ io/fmode.o \ io/isatty.o \ io/locking.o \ io/lseek.o \ + io/lseeki64.o \ io/mktemp.o \ io/open.o \ io/pipe.o \ @@ -117,15 +141,24 @@ OBJECTS_IO = \ io/setmode.o \ io/sopen.o \ io/tell.o \ + io/telli64.o \ io/umask.o \ io/unlink.o \ io/utime.o \ - io/write.o - -OBJECTS_LOCALE = \ + io/waccess.o \ + io/wchmod.o \ + io/wcreate.o \ + io/wfind.o \ + io/wmktemp.o \ + io/wopen.o \ + io/write.o \ + io/wunlink.o \ + io/wutime.o + +LOCALE_OBJECTS = \ locale/locale.o -OBJECTS_MATH = \ +MATH_OBJECTS = \ math/acos.o \ math/adjust.o \ math/asin.o \ @@ -158,7 +191,7 @@ OBJECTS_MATH = \ math/tan.o \ math/tanh.o -OBJECTS_MBSTRING = \ +MBSTRING_OBJECTS = \ mbstring/hanzen.o \ mbstring/ischira.o \ mbstring/iskana.o \ @@ -214,35 +247,38 @@ OBJECTS_MBSTRING = \ mbstring/mbstrlen.o \ mbstring/mbsupr.o -OBJECTS_MISC = \ +MISC_OBJECTS = \ misc/amsg.o \ misc/assert.o \ + misc/crtmain.o \ misc/dllmain.o \ + misc/environ.o \ misc/getargs.o \ misc/initterm.o \ misc/purecall.o \ misc/tls.o -OBJECTS_PROCESS = \ +PROCESS_OBJECTS = \ process/_cwait.o \ process/_system.o \ process/dll.o \ process/process.o \ process/procid.o \ process/thread.o \ - process/threadid.o + process/threadid.o \ + process/threadx.o -OBJECTS_SEARCH = \ +SEARCH_OBJECTS = \ search/lfind.o \ search/lsearch.o -OBJECTS_SETJMP = \ +SETJMP_OBJECTS = \ setjmp/setjmp.o -OBJECTS_SIGNAL = \ +SIGNAL_OBJECTS = \ signal/signal.o -OBJECTS_STDIO = \ +STDIO_OBJECTS = \ stdio/allocfil.o \ stdio/clearerr.o \ stdio/fclose.o \ @@ -254,6 +290,7 @@ OBJECTS_STDIO = \ stdio/fgetchar.o \ stdio/fgetpos.o \ stdio/fgets.o \ + stdio/fgetws.o \ stdio/filbuf.o \ stdio/fileno.o \ stdio/flsbuf.o \ @@ -302,9 +339,13 @@ OBJECTS_STDIO = \ stdio/vprintf.o \ stdio/vscanf.o \ stdio/vsprintf.o \ - stdio/vsscanf.o + stdio/vsscanf.o \ + stdio/wfdopen.o \ + stdio/wrename.o \ + stdio/wtempnam.o \ + stdio/wtmpnam.o -OBJECTS_STDLIB = \ +STDLIB_OBJECTS = \ stdlib/_exit.o \ stdlib/abort.o \ stdlib/abs.o \ @@ -329,6 +370,8 @@ OBJECTS_STDLIB = \ stdlib/ldiv.o \ stdlib/makepath.o \ stdlib/malloc.o \ + stdlib/mbstowcs.o \ + stdlib/mbtowc.o \ stdlib/obsol.o \ stdlib/putenv.o \ stdlib/qsort.o \ @@ -342,11 +385,20 @@ OBJECTS_STDLIB = \ stdlib/swab.o \ stdlib/wcstod.o \ stdlib/wcstol.o \ + stdlib/wcstombs.o \ stdlib/wcstoul.o \ + stdlib/wctomb.o \ + stdlib/wfulpath.o \ + stdlib/witoa.o \ + stdlib/witow.o \ + stdlib/wputenv.o \ + stdlib/wsenv.o \ + stdlib/wsplitp.o \ + stdlib/wmakpath.o \ stdlib/wtoi.o \ stdlib/wtoi64.o -OBJECTS_STRING = \ +STRING_OBJECTS = \ string/memccpy.o \ string/memchr.o \ string/memcmp.o \ @@ -367,6 +419,7 @@ OBJECTS_STRING = \ string/strlwr.o \ string/strncat.o \ string/strncmp.o \ + string/strncoll.o \ string/strncpy.o \ string/strnicmp.o \ string/strnlen.o \ @@ -380,21 +433,28 @@ OBJECTS_STRING = \ string/strupr.o \ string/strxfrm.o -OBJECTS_SYS_STAT = \ +SYS_STAT_OBJECTS = \ sys_stat/fstat.o \ + sys_stat/fstati64.o \ sys_stat/futime.o \ - sys_stat/stat.o + sys_stat/stat.o \ + sys_stat/wstat.o -OBJECTS_TIME = \ +TIME_OBJECTS = \ time/clock.o \ time/ctime.o \ time/difftime.o \ time/strdate.o \ time/strftime.o \ time/strtime.o \ - time/time.o + time/time.o \ + time/tz_vars.o \ + time/wctime.o \ + time/wstrdate.o \ + time/wstrtime.o -OBJECTS_WSTRING = \ + +WSTRING_OBJECTS = \ wstring/wcscat.o \ wstring/wcschr.o \ wstring/wcscmp.o \ @@ -421,28 +481,29 @@ OBJECTS_WSTRING = \ wstring/wcsxfrm.o OBJECTS = \ - $(OBJECTS_CONIO) \ - $(OBJECTS_CTYPE) \ - $(OBJECTS_DIRECT) \ - $(OBJECTS_EXCEPT) \ - $(OBJECTS_FLOAT) \ - $(OBJECTS_IO) \ - $(OBJECTS_LOCALE) \ - $(OBJECTS_MATH) \ - $(OBJECTS_MBSTRING) \ - $(OBJECTS_MISC) \ - $(OBJECTS_PROCESS) \ - $(OBJECTS_SEARCH) \ - $(OBJECTS_SETJMP) \ - $(OBJECTS_SIGNAL) \ - $(OBJECTS_STDIO) \ - $(OBJECTS_STDLIB) \ - $(OBJECTS_STRING) \ - $(OBJECTS_SYS_STAT) \ - $(OBJECTS_TIME) \ - $(OBJECTS_WSTRING) + $(CONIO_OBJECTS) \ + $(CTYPE_OBJECTS) \ + $(DIRECT_OBJECTS) \ + $(EXCEPT_OBJECTS) \ + $(FLOAT_OBJECTS) \ + $(IO_OBJECTS) \ + $(LOCALE_OBJECTS) \ + $(MATH_OBJECTS) \ + $(MBSTRING_OBJECTS) \ + $(MISC_OBJECTS) \ + $(PROCESS_OBJECTS) \ + $(SEARCH_OBJECTS) \ + $(SETJMP_OBJECTS) \ + $(SIGNAL_OBJECTS) \ + $(STDIO_OBJECTS) \ + $(STDLIB_OBJECTS) \ + $(STRING_OBJECTS) \ + $(SYS_STAT_OBJECTS) \ + $(TIME_OBJECTS) \ + $(WSTRING_OBJECTS) $(TARGET_NAME).o: $(OBJECTS) $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o + # EOF diff --git a/lib/msvcrt/conio/cputs.c b/lib/msvcrt/conio/cputs.c index 396c71e..4aac4ee 100644 --- a/lib/msvcrt/conio/cputs.c +++ b/lib/msvcrt/conio/cputs.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/cputs.c + * FILE: lib/msvcrt/conio/cputs.c * PURPOSE: Writes a character to stdout * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/conio/cscanf.c b/lib/msvcrt/conio/cscanf.c index 58e01d9..eb3743a 100644 --- a/lib/msvcrt/conio/cscanf.c +++ b/lib/msvcrt/conio/cscanf.c @@ -1,18 +1,18 @@ #include #include #include +#include int _cscanf(char *fmt, ...) { - int cnt; - va_list ap; + int cnt; - //fixme cscanf should scan the console's keyboard - va_start(ap, fmt); - cnt = __vscanf(fmt, ap); - va_end(ap); - - return cnt; -} + va_list ap; + //fixme cscanf should scan the console's keyboard + va_start(ap, fmt); + cnt = __vscanf(fmt, ap); + va_end(ap); + return cnt; +} diff --git a/lib/msvcrt/conio/getch.c b/lib/msvcrt/conio/getch.c index 15d2eb6..59d1803 100644 --- a/lib/msvcrt/conio/getch.c +++ b/lib/msvcrt/conio/getch.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/getch.c + * FILE: lib/msvcrt/conio/getch.c * PURPOSE: Writes a character to stdout * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -16,25 +16,32 @@ int _getch(void) { - DWORD NumberOfCharsRead = 0; - char c; - - if (char_avail) - { - c = ungot_char; - char_avail = 0; - } - else - { - ReadConsoleA(_get_osfhandle(stdin->_file), - &c, - 1, - &NumberOfCharsRead, - NULL); + DWORD NumberOfCharsRead = 0; + char c; + if (char_avail) { + c = ungot_char; + char_avail = 0; + } else { + ReadConsoleA(_get_osfhandle(stdin->_file), + &c, + 1, + &NumberOfCharsRead, + NULL); } - if (c == 10) - c = 13; - putchar(c); + if (c == 10) + c = 13; + putchar(c); + return c; +} + +#if 0 +int _getche(void) +{ + int c; + + c = _getch(); + _putch(c); - return c; + return c; } +#endif diff --git a/lib/msvcrt/conio/getche.c b/lib/msvcrt/conio/getche.c index f994649..b9fb42a 100644 --- a/lib/msvcrt/conio/getche.c +++ b/lib/msvcrt/conio/getche.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/getche.c + * FILE: lib/msvcrt/conio/getche.c * PURPOSE: Reads a character from stdin * PROGRAMER: DJ Delorie Boudewijn Dekker diff --git a/lib/msvcrt/conio/kbhit.c b/lib/msvcrt/conio/kbhit.c index 876099f..c70c45d 100644 --- a/lib/msvcrt/conio/kbhit.c +++ b/lib/msvcrt/conio/kbhit.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/kbhit.c + * FILE: lib/msvcrt/conio/kbhit.c * PURPOSE: Checks for keyboard hits * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -17,12 +17,11 @@ int _kbhit(void) { - INPUT_RECORD InputRecord; + //INPUT_RECORD InputRecord; DWORD NumberRead=0; if (char_avail) return(1); - else - { + else { //FIXME PeekConsoleInput might do DeviceIo //PeekConsoleInput((HANDLE)stdin->_file,&InputRecord,1,&NumberRead); return NumberRead; diff --git a/lib/msvcrt/conio/putch.c b/lib/msvcrt/conio/putch.c index 5f37013..c9058e2 100644 --- a/lib/msvcrt/conio/putch.c +++ b/lib/msvcrt/conio/putch.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/putch.c + * FILE: lib/msvcrt/conio/putch.c * PURPOSE: Writes a character to stdout * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -14,8 +14,8 @@ int _putch(int c) { DWORD NumberOfCharsWritten; - if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL)) + if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL)) { return -1; - + } return NumberOfCharsWritten; } diff --git a/lib/msvcrt/conio/ungetch.c b/lib/msvcrt/conio/ungetch.c index 8b974bb..56e41c9 100644 --- a/lib/msvcrt/conio/ungetch.c +++ b/lib/msvcrt/conio/ungetch.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/ungetch.c + * FILE: lib/msvcrt/conio/ungetch.c * PURPOSE: Ungets a character from stdin * PROGRAMER: DJ Delorie Boudewijn Dekker [ Adapted from djgpp libc ] diff --git a/lib/msvcrt/ctype/ctype.c b/lib/msvcrt/ctype/ctype.c new file mode 100644 index 0000000..5861d6d --- /dev/null +++ b/lib/msvcrt/ctype/ctype.c @@ -0,0 +1,264 @@ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ +#include + +unsigned short _ctype[] = { + 0, /* , 0xFFFF */ + _CONTROL, /* CTRL+@, 0x00 */ + _CONTROL, /* CTRL+A, 0x01 */ + _CONTROL, /* CTRL+B, 0x02 */ + _CONTROL, /* CTRL+C, 0x03 */ + _CONTROL, /* CTRL+D, 0x04 */ + _CONTROL, /* CTRL+E, 0x05 */ + _CONTROL, /* CTRL+F, 0x06 */ + _CONTROL, /* CTRL+G, 0x07 */ + _CONTROL, /* CTRL+H, 0x08 */ + _CONTROL | _SPACE, /* CTRL+I, 0x09 */ + _CONTROL | _SPACE, /* CTRL+J, 0x0a */ + _CONTROL | _SPACE, /* CTRL+K, 0x0b */ + _CONTROL | _SPACE, /* CTRL+L, 0x0c */ + _CONTROL | _SPACE, /* CTRL+M, 0x0d */ + _CONTROL, /* CTRL+N, 0x0e */ + _CONTROL, /* CTRL+O, 0x0f */ + _CONTROL, /* CTRL+P, 0x10 */ + _CONTROL, /* CTRL+Q, 0x11 */ + _CONTROL, /* CTRL+R, 0x12 */ + _CONTROL, /* CTRL+S, 0x13 */ + _CONTROL, /* CTRL+T, 0x14 */ + _CONTROL, /* CTRL+U, 0x15 */ + _CONTROL, /* CTRL+V, 0x16 */ + _CONTROL, /* CTRL+W, 0x17 */ + _CONTROL, /* CTRL+X, 0x18 */ + _CONTROL, /* CTRL+Y, 0x19 */ + _CONTROL, /* CTRL+Z, 0x1a */ + _CONTROL, /* CTRL+[, 0x1b */ + _CONTROL, /* CTRL+\, 0x1c */ + _CONTROL, /* CTRL+], 0x1d */ + _CONTROL, /* CTRL+^, 0x1e */ + _CONTROL, /* CTRL+_, 0x1f */ + _SPACE | _BLANK, /* ` ', 0x20 */ + _PUNCT, /* `!', 0x21 */ + _PUNCT, /* 0x22 */ + _PUNCT, /* `#', 0x23 */ + _PUNCT, /* `$', 0x24 */ + _PUNCT, /* `%', 0x25 */ + _PUNCT, /* `&', 0x26 */ + _PUNCT, /* 0x27 */ + _PUNCT, /* `(', 0x28 */ + _PUNCT, /* `)', 0x29 */ + _PUNCT, /* `*', 0x2a */ + _PUNCT, /* `+', 0x2b */ + _PUNCT, /* `,', 0x2c */ + _PUNCT, /* `-', 0x2d */ + _PUNCT, /* `.', 0x2e */ + _PUNCT, /* `/', 0x2f */ + _DIGIT | _HEX, /* `0', 0x30 */ + _DIGIT | _HEX, /* `1', 0x31 */ + _DIGIT | _HEX, /* `2', 0x32 */ + _DIGIT | _HEX, /* `3', 0x33 */ + _DIGIT | _HEX, /* `4', 0x34 */ + _DIGIT | _HEX, /* `5', 0x35 */ + _DIGIT | _HEX, /* `6', 0x36 */ + _DIGIT | _HEX, /* `7', 0x37 */ + _DIGIT | _HEX, /* `8', 0x38 */ + _DIGIT | _HEX, /* `9', 0x39 */ + _PUNCT, /* `:', 0x3a */ + _PUNCT, /* `;', 0x3b */ + _PUNCT, /* `<', 0x3c */ + _PUNCT, /* `=', 0x3d */ + _PUNCT, /* `>', 0x3e */ + _PUNCT, /* `?', 0x3f */ + _PUNCT, /* `@', 0x40 */ + _UPPER | _HEX, /* `A', 0x41 */ + _UPPER | _HEX, /* `B', 0x42 */ + _UPPER | _HEX, /* `C', 0x43 */ + _UPPER | _HEX, /* `D', 0x44 */ + _UPPER | _HEX, /* `E', 0x45 */ + _UPPER | _HEX, /* `F', 0x46 */ + _UPPER, /* `G', 0x47 */ + _UPPER, /* `H', 0x48 */ + _UPPER, /* `I', 0x49 */ + _UPPER, /* `J', 0x4a */ + _UPPER, /* `K', 0x4b */ + _UPPER, /* `L', 0x4c */ + _UPPER, /* `M', 0x4d */ + _UPPER, /* `N', 0x4e */ + _UPPER, /* `O', 0x4f */ + _UPPER, /* `P', 0x50 */ + _UPPER, /* `Q', 0x51 */ + _UPPER, /* `R', 0x52 */ + _UPPER, /* `S', 0x53 */ + _UPPER, /* `T', 0x54 */ + _UPPER, /* `U', 0x55 */ + _UPPER, /* `V', 0x56 */ + _UPPER, /* `W', 0x57 */ + _UPPER, /* `X', 0x58 */ + _UPPER, /* `Y', 0x59 */ + _UPPER, /* `Z', 0x5a */ + _PUNCT, /* `[', 0x5b */ + _PUNCT, /* 0x5c */ + _PUNCT, /* `]', 0x5d */ + _PUNCT, /* `^', 0x5e */ + _PUNCT, /* `_', 0x5f */ + _PUNCT, /* 0x60 */ + _LOWER | _HEX, /* `a', 0x61 */ + _LOWER | _HEX, /* `b', 0x62 */ + _LOWER | _HEX, /* `c', 0x63 */ + _LOWER | _HEX, /* `d', 0x64 */ + _LOWER | _HEX, /* `e', 0x65 */ + _LOWER | _HEX, /* `f', 0x66 */ + _LOWER, /* `g', 0x67 */ + _LOWER, /* `h', 0x68 */ + _LOWER, /* `i', 0x69 */ + _LOWER, /* `j', 0x6a */ + _LOWER, /* `k', 0x6b */ + _LOWER, /* `l', 0x6c */ + _LOWER, /* `m', 0x6d */ + _LOWER, /* `n', 0x6e */ + _LOWER, /* `o', 0x6f */ + _LOWER, /* `p', 0x70 */ + _LOWER, /* `q', 0x71 */ + _LOWER, /* `r', 0x72 */ + _LOWER, /* `s', 0x73 */ + _LOWER, /* `t', 0x74 */ + _LOWER, /* `u', 0x75 */ + _LOWER, /* `v', 0x76 */ + _LOWER, /* `w', 0x77 */ + _LOWER, /* `x', 0x78 */ + _LOWER, /* `y', 0x79 */ + _LOWER, /* `z', 0x7a */ + _PUNCT, /* `{', 0x7b */ + _PUNCT, /* `|', 0x7c */ + _PUNCT, /* `}', 0x7d */ + _PUNCT, /* `~', 0x7e */ + _CONTROL, /* 0x7f */ + 0, /* 0x80 */ + 0, /* 0x81 */ + 0, /* 0x82 */ + 0, /* 0x83 */ + 0, /* 0x84 */ + 0, /* 0x85 */ + 0, /* 0x86 */ + 0, /* 0x87 */ + 0, /* 0x88 */ + 0, /* 0x89 */ + 0, /* 0x8a */ + 0, /* 0x8b */ + 0, /* 0x8c */ + 0, /* 0x8d */ + 0, /* 0x8e */ + 0, /* 0x8f */ + 0, /* 0x90 */ + 0, /* 0x91 */ + 0, /* 0x92 */ + 0, /* 0x93 */ + 0, /* 0x94 */ + 0, /* 0x95 */ + 0, /* 0x96 */ + 0, /* 0x97 */ + 0, /* 0x98 */ + 0, /* 0x99 */ + 0, /* 0x9a */ + 0, /* 0x9b */ + 0, /* 0x9c */ + 0, /* 0x9d */ + 0, /* 0x9e */ + 0, /* 0x9f */ + 0, /* 0xa0 */ + 0, /* 0xa1 */ + 0, /* 0xa2 */ + 0, /* 0xa3 */ + 0, /* 0xa4 */ + 0, /* 0xa5 */ + 0, /* 0xa6 */ + 0, /* 0xa7 */ + 0, /* 0xa8 */ + 0, /* 0xa9 */ + 0, /* 0xaa */ + 0, /* 0xab */ + 0, /* 0xac */ + 0, /* 0xad */ + 0, /* 0xae */ + 0, /* 0xaf */ + 0, /* 0xb0 */ + 0, /* 0xb1 */ + 0, /* 0xb2 */ + 0, /* 0xb3 */ + 0, /* 0xb4 */ + 0, /* 0xb5 */ + 0, /* 0xb6 */ + 0, /* 0xb7 */ + 0, /* 0xb8 */ + 0, /* 0xb9 */ + 0, /* 0xba */ + 0, /* 0xbb */ + 0, /* 0xbc */ + 0, /* 0xbd */ + 0, /* 0xbe */ + 0, /* 0xbf */ + 0, /* 0xc0 */ + 0, /* 0xc1 */ + 0, /* 0xc2 */ + 0, /* 0xc3 */ + 0, /* 0xc4 */ + 0, /* 0xc5 */ + 0, /* 0xc6 */ + 0, /* 0xc7 */ + 0, /* 0xc8 */ + 0, /* 0xc9 */ + 0, /* 0xca */ + 0, /* 0xcb */ + 0, /* 0xcc */ + 0, /* 0xcd */ + 0, /* 0xce */ + 0, /* 0xcf */ + 0, /* 0xd0 */ + 0, /* 0xd1 */ + 0, /* 0xd2 */ + 0, /* 0xd3 */ + 0, /* 0xd4 */ + 0, /* 0xd5 */ + 0, /* 0xd6 */ + 0, /* 0xd7 */ + 0, /* 0xd8 */ + 0, /* 0xd9 */ + 0, /* 0xda */ + 0, /* 0xdb */ + 0, /* 0xdc */ + 0, /* 0xdd */ + 0, /* 0xde */ + 0, /* 0xdf */ + 0, /* 0xe0 */ + 0, /* 0xe1 */ + 0, /* 0xe2 */ + 0, /* 0xe3 */ + 0, /* 0xe4 */ + 0, /* 0xe5 */ + 0, /* 0xe6 */ + 0, /* 0xe7 */ + 0, /* 0xe8 */ + 0, /* 0xe9 */ + 0, /* 0xea */ + 0, /* 0xeb */ + 0, /* 0xec */ + 0, /* 0xed */ + 0, /* 0xee */ + 0, /* 0xef */ + 0, /* 0xf0 */ + 0, /* 0xf1 */ + 0, /* 0xf2 */ + 0, /* 0xf3 */ + 0, /* 0xf4 */ + 0, /* 0xf5 */ + 0, /* 0xf6 */ + 0, /* 0xf7 */ + 0, /* 0xf8 */ + 0, /* 0xf9 */ + 0, /* 0xfa */ + 0, /* 0xfb */ + 0, /* 0xfc */ + 0, /* 0xfd */ + 0, /* 0xfe */ + 0 /* 0xff */ +}; + +/* EOF */ diff --git a/lib/msvcrt/ctype/isalnum.c b/lib/msvcrt/ctype/isalnum.c index 0dc3922..6fed569 100644 --- a/lib/msvcrt/ctype/isalnum.c +++ b/lib/msvcrt/ctype/isalnum.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/ctype/isalnum.c + * FILE: lib/msvcrt/ctype/isalnum.c * PURPOSE: Test for a alpha numeric character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -13,11 +13,11 @@ #undef isalnum int isalnum(int c) { - return _isctype(c,_ALPHA | _DIGIT); + return _isctype(c, _ALPHA | _DIGIT); } #undef iswalnum int iswalnum(wint_t c) { - return iswctype(c,_ALPHA | _DIGIT); + return iswctype(c, _ALPHA | _DIGIT); } diff --git a/lib/msvcrt/ctype/isalpha.c b/lib/msvcrt/ctype/isalpha.c index a506197..13f7160 100644 --- a/lib/msvcrt/ctype/isalpha.c +++ b/lib/msvcrt/ctype/isalpha.c @@ -10,14 +10,16 @@ #include + #undef isalpha + int isalpha(int c) { - return _isctype(c,_ALPHA); + return _isctype(c, _ALPHA); } #undef iswalpha int iswalpha(wint_t c) { - return iswctype(c,_ALPHA); + return iswctype(c, _ALPHA); } diff --git a/lib/msvcrt/ctype/isascii.c b/lib/msvcrt/ctype/isascii.c index 612a9a9..72819e2 100644 --- a/lib/msvcrt/ctype/isascii.c +++ b/lib/msvcrt/ctype/isascii.c @@ -12,18 +12,10 @@ int __isascii(int c) { - return (!((c)&(~0x7f))); + return (!((c)&(~0x7f))); } int iswascii(wint_t c) { - return __isascii(c); + return __isascii(c); } - - - - - - - - diff --git a/lib/msvcrt/ctype/iscntrl.c b/lib/msvcrt/ctype/iscntrl.c index f6a685e..cd51e8d 100644 --- a/lib/msvcrt/ctype/iscntrl.c +++ b/lib/msvcrt/ctype/iscntrl.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef iscntrl int iscntrl(int c) { - return _isctype(c,_CONTROL); + return _isctype(c, _CONTROL); } #undef iswcntrl int iswcntrl(wint_t c) { - return iswctype(c,_CONTROL); + return iswctype(c, _CONTROL); } diff --git a/lib/msvcrt/ctype/iscsym.c b/lib/msvcrt/ctype/iscsym.c index 41a6da6..0e91f7d 100644 --- a/lib/msvcrt/ctype/iscsym.c +++ b/lib/msvcrt/ctype/iscsym.c @@ -7,15 +7,15 @@ * UPDATE HISTORY: * 28/12/98: Created */ - #include + int __iscsymf(int c) { - return (isalpha(c) || ( c == '_' )); + return (isalpha(c) || ( c == '_' )) ; } int __iscsym(int c) { - return (isalnum(c) || ( c == '_' )); + return (isalnum(c) || ( c == '_' )) ; } diff --git a/lib/msvcrt/ctype/isctype.c b/lib/msvcrt/ctype/isctype.c index 22a94e1..0b33a14 100644 --- a/lib/msvcrt/ctype/isctype.c +++ b/lib/msvcrt/ctype/isctype.c @@ -1,269 +1,13 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include -unsigned short _ctype[] = { - 0, /* , 0xFFFF */ - _CONTROL, /* CTRL+@, 0x00 */ - _CONTROL, /* CTRL+A, 0x01 */ - _CONTROL, /* CTRL+B, 0x02 */ - _CONTROL, /* CTRL+C, 0x03 */ - _CONTROL, /* CTRL+D, 0x04 */ - _CONTROL, /* CTRL+E, 0x05 */ - _CONTROL, /* CTRL+F, 0x06 */ - _CONTROL, /* CTRL+G, 0x07 */ - _CONTROL, /* CTRL+H, 0x08 */ - _CONTROL | _SPACE, /* CTRL+I, 0x09 */ - _CONTROL | _SPACE, /* CTRL+J, 0x0a */ - _CONTROL | _SPACE, /* CTRL+K, 0x0b */ - _CONTROL | _SPACE, /* CTRL+L, 0x0c */ - _CONTROL | _SPACE, /* CTRL+M, 0x0d */ - _CONTROL, /* CTRL+N, 0x0e */ - _CONTROL, /* CTRL+O, 0x0f */ - _CONTROL, /* CTRL+P, 0x10 */ - _CONTROL, /* CTRL+Q, 0x11 */ - _CONTROL, /* CTRL+R, 0x12 */ - _CONTROL, /* CTRL+S, 0x13 */ - _CONTROL, /* CTRL+T, 0x14 */ - _CONTROL, /* CTRL+U, 0x15 */ - _CONTROL, /* CTRL+V, 0x16 */ - _CONTROL, /* CTRL+W, 0x17 */ - _CONTROL, /* CTRL+X, 0x18 */ - _CONTROL, /* CTRL+Y, 0x19 */ - _CONTROL, /* CTRL+Z, 0x1a */ - _CONTROL, /* CTRL+[, 0x1b */ - _CONTROL, /* CTRL+\, 0x1c */ - _CONTROL, /* CTRL+], 0x1d */ - _CONTROL, /* CTRL+^, 0x1e */ - _CONTROL, /* CTRL+_, 0x1f */ - _SPACE | _BLANK, /* ` ', 0x20 */ - _PUNCT, /* `!', 0x21 */ - _PUNCT, /* 0x22 */ - _PUNCT, /* `#', 0x23 */ - _PUNCT, /* `$', 0x24 */ - _PUNCT, /* `%', 0x25 */ - _PUNCT, /* `&', 0x26 */ - _PUNCT, /* 0x27 */ - _PUNCT, /* `(', 0x28 */ - _PUNCT, /* `)', 0x29 */ - _PUNCT, /* `*', 0x2a */ - _PUNCT, /* `+', 0x2b */ - _PUNCT, /* `,', 0x2c */ - _PUNCT, /* `-', 0x2d */ - _PUNCT, /* `.', 0x2e */ - _PUNCT, /* `/', 0x2f */ - _DIGIT | _HEX, /* `0', 0x30 */ - _DIGIT | _HEX, /* `1', 0x31 */ - _DIGIT | _HEX, /* `2', 0x32 */ - _DIGIT | _HEX, /* `3', 0x33 */ - _DIGIT | _HEX, /* `4', 0x34 */ - _DIGIT | _HEX, /* `5', 0x35 */ - _DIGIT | _HEX, /* `6', 0x36 */ - _DIGIT | _HEX, /* `7', 0x37 */ - _DIGIT | _HEX, /* `8', 0x38 */ - _DIGIT | _HEX, /* `9', 0x39 */ - _PUNCT, /* `:', 0x3a */ - _PUNCT, /* `;', 0x3b */ - _PUNCT, /* `<', 0x3c */ - _PUNCT, /* `=', 0x3d */ - _PUNCT, /* `>', 0x3e */ - _PUNCT, /* `?', 0x3f */ - _PUNCT, /* `@', 0x40 */ - _UPPER | _HEX, /* `A', 0x41 */ - _UPPER | _HEX, /* `B', 0x42 */ - _UPPER | _HEX, /* `C', 0x43 */ - _UPPER | _HEX, /* `D', 0x44 */ - _UPPER | _HEX, /* `E', 0x45 */ - _UPPER | _HEX, /* `F', 0x46 */ - _UPPER, /* `G', 0x47 */ - _UPPER, /* `H', 0x48 */ - _UPPER, /* `I', 0x49 */ - _UPPER, /* `J', 0x4a */ - _UPPER, /* `K', 0x4b */ - _UPPER, /* `L', 0x4c */ - _UPPER, /* `M', 0x4d */ - _UPPER, /* `N', 0x4e */ - _UPPER, /* `O', 0x4f */ - _UPPER, /* `P', 0x50 */ - _UPPER, /* `Q', 0x51 */ - _UPPER, /* `R', 0x52 */ - _UPPER, /* `S', 0x53 */ - _UPPER, /* `T', 0x54 */ - _UPPER, /* `U', 0x55 */ - _UPPER, /* `V', 0x56 */ - _UPPER, /* `W', 0x57 */ - _UPPER, /* `X', 0x58 */ - _UPPER, /* `Y', 0x59 */ - _UPPER, /* `Z', 0x5a */ - _PUNCT, /* `[', 0x5b */ - _PUNCT, /* 0x5c */ - _PUNCT, /* `]', 0x5d */ - _PUNCT, /* `^', 0x5e */ - _PUNCT, /* `_', 0x5f */ - _PUNCT, /* 0x60 */ - _LOWER | _HEX, /* `a', 0x61 */ - _LOWER | _HEX, /* `b', 0x62 */ - _LOWER | _HEX, /* `c', 0x63 */ - _LOWER | _HEX, /* `d', 0x64 */ - _LOWER | _HEX, /* `e', 0x65 */ - _LOWER | _HEX, /* `f', 0x66 */ - _LOWER, /* `g', 0x67 */ - _LOWER, /* `h', 0x68 */ - _LOWER, /* `i', 0x69 */ - _LOWER, /* `j', 0x6a */ - _LOWER, /* `k', 0x6b */ - _LOWER, /* `l', 0x6c */ - _LOWER, /* `m', 0x6d */ - _LOWER, /* `n', 0x6e */ - _LOWER, /* `o', 0x6f */ - _LOWER, /* `p', 0x70 */ - _LOWER, /* `q', 0x71 */ - _LOWER, /* `r', 0x72 */ - _LOWER, /* `s', 0x73 */ - _LOWER, /* `t', 0x74 */ - _LOWER, /* `u', 0x75 */ - _LOWER, /* `v', 0x76 */ - _LOWER, /* `w', 0x77 */ - _LOWER, /* `x', 0x78 */ - _LOWER, /* `y', 0x79 */ - _LOWER, /* `z', 0x7a */ - _PUNCT, /* `{', 0x7b */ - _PUNCT, /* `|', 0x7c */ - _PUNCT, /* `}', 0x7d */ - _PUNCT, /* `~', 0x7e */ - _CONTROL, /* 0x7f */ - 0, /* 0x80 */ - 0, /* 0x81 */ - 0, /* 0x82 */ - 0, /* 0x83 */ - 0, /* 0x84 */ - 0, /* 0x85 */ - 0, /* 0x86 */ - 0, /* 0x87 */ - 0, /* 0x88 */ - 0, /* 0x89 */ - 0, /* 0x8a */ - 0, /* 0x8b */ - 0, /* 0x8c */ - 0, /* 0x8d */ - 0, /* 0x8e */ - 0, /* 0x8f */ - 0, /* 0x90 */ - 0, /* 0x91 */ - 0, /* 0x92 */ - 0, /* 0x93 */ - 0, /* 0x94 */ - 0, /* 0x95 */ - 0, /* 0x96 */ - 0, /* 0x97 */ - 0, /* 0x98 */ - 0, /* 0x99 */ - 0, /* 0x9a */ - 0, /* 0x9b */ - 0, /* 0x9c */ - 0, /* 0x9d */ - 0, /* 0x9e */ - 0, /* 0x9f */ - 0, /* 0xa0 */ - 0, /* 0xa1 */ - 0, /* 0xa2 */ - 0, /* 0xa3 */ - 0, /* 0xa4 */ - 0, /* 0xa5 */ - 0, /* 0xa6 */ - 0, /* 0xa7 */ - 0, /* 0xa8 */ - 0, /* 0xa9 */ - 0, /* 0xaa */ - 0, /* 0xab */ - 0, /* 0xac */ - 0, /* 0xad */ - 0, /* 0xae */ - 0, /* 0xaf */ - 0, /* 0xb0 */ - 0, /* 0xb1 */ - 0, /* 0xb2 */ - 0, /* 0xb3 */ - 0, /* 0xb4 */ - 0, /* 0xb5 */ - 0, /* 0xb6 */ - 0, /* 0xb7 */ - 0, /* 0xb8 */ - 0, /* 0xb9 */ - 0, /* 0xba */ - 0, /* 0xbb */ - 0, /* 0xbc */ - 0, /* 0xbd */ - 0, /* 0xbe */ - 0, /* 0xbf */ - 0, /* 0xc0 */ - 0, /* 0xc1 */ - 0, /* 0xc2 */ - 0, /* 0xc3 */ - 0, /* 0xc4 */ - 0, /* 0xc5 */ - 0, /* 0xc6 */ - 0, /* 0xc7 */ - 0, /* 0xc8 */ - 0, /* 0xc9 */ - 0, /* 0xca */ - 0, /* 0xcb */ - 0, /* 0xcc */ - 0, /* 0xcd */ - 0, /* 0xce */ - 0, /* 0xcf */ - 0, /* 0xd0 */ - 0, /* 0xd1 */ - 0, /* 0xd2 */ - 0, /* 0xd3 */ - 0, /* 0xd4 */ - 0, /* 0xd5 */ - 0, /* 0xd6 */ - 0, /* 0xd7 */ - 0, /* 0xd8 */ - 0, /* 0xd9 */ - 0, /* 0xda */ - 0, /* 0xdb */ - 0, /* 0xdc */ - 0, /* 0xdd */ - 0, /* 0xde */ - 0, /* 0xdf */ - 0, /* 0xe0 */ - 0, /* 0xe1 */ - 0, /* 0xe2 */ - 0, /* 0xe3 */ - 0, /* 0xe4 */ - 0, /* 0xe5 */ - 0, /* 0xe6 */ - 0, /* 0xe7 */ - 0, /* 0xe8 */ - 0, /* 0xe9 */ - 0, /* 0xea */ - 0, /* 0xeb */ - 0, /* 0xec */ - 0, /* 0xed */ - 0, /* 0xee */ - 0, /* 0xef */ - 0, /* 0xf0 */ - 0, /* 0xf1 */ - 0, /* 0xf2 */ - 0, /* 0xf3 */ - 0, /* 0xf4 */ - 0, /* 0xf5 */ - 0, /* 0xf6 */ - 0, /* 0xf7 */ - 0, /* 0xf8 */ - 0, /* 0xf9 */ - 0, /* 0xfa */ - 0, /* 0xfb */ - 0, /* 0xfc */ - 0, /* 0xfd */ - 0, /* 0xfe */ - 0 /* 0xff */ -}; + +extern unsigned short _ctype[]; unsigned short *_pctype = _ctype + 1; unsigned short *_pwctype = _ctype + 1; + unsigned short **__p__pctype(void) { return &_pctype; diff --git a/lib/msvcrt/ctype/isdigit.c b/lib/msvcrt/ctype/isdigit.c index ae588e4..e84881d 100644 --- a/lib/msvcrt/ctype/isdigit.c +++ b/lib/msvcrt/ctype/isdigit.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef isdigit int isdigit(int c) { - return _isctype(c,_DIGIT); + return _isctype(c, _DIGIT); } #undef iswdigit int iswdigit(wint_t c) { - return iswctype(c,_DIGIT); + return iswctype(c, _DIGIT); } diff --git a/lib/msvcrt/ctype/islower.c b/lib/msvcrt/ctype/islower.c index c3a9178..34cc31a 100644 --- a/lib/msvcrt/ctype/islower.c +++ b/lib/msvcrt/ctype/islower.c @@ -1,13 +1,14 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef islower int islower(int c) { - return _isctype(c,_LOWER); + return _isctype(c, _LOWER); } int iswlower(wint_t c) { - return iswctype(c,_LOWER); + return iswctype(c, _LOWER); } diff --git a/lib/msvcrt/ctype/ispunct.c b/lib/msvcrt/ctype/ispunct.c index e26e3e8..5a06ae4 100644 --- a/lib/msvcrt/ctype/ispunct.c +++ b/lib/msvcrt/ctype/ispunct.c @@ -1,14 +1,15 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef ispunct int ispunct(int c) { - return _isctype(c,_PUNCT); + return _isctype(c, _PUNCT); } #undef iswpunct int iswpunct(wint_t c) { - return iswctype(c,_PUNCT); + return iswctype(c, _PUNCT); } diff --git a/lib/msvcrt/ctype/isspace.c b/lib/msvcrt/ctype/isspace.c index e0ebcb3..3bb9d32 100644 --- a/lib/msvcrt/ctype/isspace.c +++ b/lib/msvcrt/ctype/isspace.c @@ -2,13 +2,15 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/msvcrt/ctype/isspace.c - * PURPOSE: Checks for a whitespace characters + * PURPOSE: Test for a space character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 28/12/98: Created */ + #include + #undef isspace int isspace(int c) { diff --git a/lib/msvcrt/ctype/isupper.c b/lib/msvcrt/ctype/isupper.c index 9898cb3..a7e67b2 100644 --- a/lib/msvcrt/ctype/isupper.c +++ b/lib/msvcrt/ctype/isupper.c @@ -1,13 +1,14 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef isupper int isupper(int c) { - return _isctype(c,_UPPER); + return _isctype(c, _UPPER); } int iswupper(wint_t c) { - return iswctype(c,_UPPER); + return iswctype(c, _UPPER); } diff --git a/lib/msvcrt/ctype/isxdigit.c b/lib/msvcrt/ctype/isxdigit.c index 9c24dda..63f8464 100644 --- a/lib/msvcrt/ctype/isxdigit.c +++ b/lib/msvcrt/ctype/isxdigit.c @@ -1,15 +1,16 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #undef isxdigit int isxdigit(int c) { - return _isctype(c,_HEX); + return _isctype(c, _HEX); } #undef iswxdigit int iswxdigit(wint_t c) { - return iswctype(c,_HEX); + return iswctype(c, _HEX); } diff --git a/lib/msvcrt/ctype/toascii.c b/lib/msvcrt/ctype/toascii.c index 16d959b..f26d5af 100644 --- a/lib/msvcrt/ctype/toascii.c +++ b/lib/msvcrt/ctype/toascii.c @@ -5,5 +5,5 @@ int __toascii(int c) { - return ((unsigned)(c) & 0x7F ); + return((unsigned)(c) & 0x7F); } diff --git a/lib/msvcrt/ctype/tolower.c b/lib/msvcrt/ctype/tolower.c index e2c188c..95e4ccf 100644 --- a/lib/msvcrt/ctype/tolower.c +++ b/lib/msvcrt/ctype/tolower.c @@ -10,7 +10,8 @@ int tolower(int c) } #undef towlower -wchar_t towlower(wchar_t c) +int towlower(wint_t c) +//wchar_t towlower(wchar_t c) { if (iswctype (c, _UPPER)) return (c - (L'A' - L'a')); @@ -19,17 +20,16 @@ wchar_t towlower(wchar_t c) int _tolower(int c) { - if (_isctype (c, _UPPER)) - return (c - ('A' - 'a')); - return(c); + return (c - ('A' - 'a')); } /* +int towlower(wint_t); +int towupper(wint_t); + wchar_t _towlower(wchar_t c) { - if (iswctype (c, _UPPER)) - return (c - (L'A' - L'a')); - return(c); + return (c - (L'A' - L'a')); } */ diff --git a/lib/msvcrt/ctype/toupper.c b/lib/msvcrt/ctype/toupper.c index 666cee2..0b926b8 100644 --- a/lib/msvcrt/ctype/toupper.c +++ b/lib/msvcrt/ctype/toupper.c @@ -20,17 +20,13 @@ wchar_t towupper(wchar_t c) int _toupper(int c) { - if (_isctype (c, _LOWER)) - return (c + ('A' - 'a')); - return(c); + return (c + ('A' - 'a')); } /* wchar_t _towupper(wchar_t c) { - if (iswctype (c, _LOWER)) - return (c + (L'A' - L'a')); - return(c); + return (c + (L'A' - L'a')); } */ diff --git a/lib/msvcrt/direct/chdir.c b/lib/msvcrt/direct/chdir.c index 521cf52..eb8061d 100644 --- a/lib/msvcrt/direct/chdir.c +++ b/lib/msvcrt/direct/chdir.c @@ -3,22 +3,11 @@ #include -int _chdir( const char *_path ) +int _chdir(const char* _path) { - if ( _path[1] == ':') - _chdrive(tolower(_path[0] - 'a')+1); - if ( !SetCurrentDirectoryA((char *)_path) ) - return -1; - - return 0; -} - -int _wchdir( const wchar_t *_path ) -{ - if ( _path[1] == L':') - _chdrive(towlower(_path[0] - L'a')+1); - if ( !SetCurrentDirectoryW((wchar_t *)_path) ) - return -1; - - return 0; + if (_path[1] == ':') + _chdrive(tolower(_path[0] - 'a')+1); + if (!SetCurrentDirectoryA((char*)_path)) + return -1; + return 0; } diff --git a/lib/msvcrt/direct/chdrive.c b/lib/msvcrt/direct/chdrive.c index 6b67c8f..1522904 100644 --- a/lib/msvcrt/direct/chdrive.c +++ b/lib/msvcrt/direct/chdrive.c @@ -3,21 +3,22 @@ #include #include + int cur_drive = 0; -int _chdrive( int drive ) -{ - char d[3]; - if (!( drive >= 1 && drive <= 26 )) - return -1; - if ( cur_drive != drive ) { - cur_drive = drive; - d[0] = toupper(cur_drive + '@'); - d[1] = ':'; - d[2] = 0; - SetCurrentDirectoryA(d); - } +int _chdrive(int drive) +{ + char d[3]; - return 0; + if (!( drive >= 1 && drive <= 26)) + return -1; + if (cur_drive != drive) { + cur_drive = drive; + d[0] = toupper(cur_drive + '@'); + d[1] = ':'; + d[2] = 0; + SetCurrentDirectoryA(d); + } + return 0; } diff --git a/lib/msvcrt/direct/getcwd.c b/lib/msvcrt/direct/getcwd.c index 461e085..67638b9 100644 --- a/lib/msvcrt/direct/getcwd.c +++ b/lib/msvcrt/direct/getcwd.c @@ -3,40 +3,20 @@ #include -char *_getcwd( char *buffer, int maxlen ) +char *_getcwd(char* buffer, int maxlen) { - char *cwd; - int len; - if ( buffer == NULL ) { - cwd = malloc(MAX_PATH); - len = MAX_PATH; - } - else { - cwd = buffer; - len = maxlen; - } + char *cwd; + int len; - if ( GetCurrentDirectoryA(len,cwd) == 0 ) - return NULL; - - return cwd; -} - -wchar_t *_wgetcwd( wchar_t *buffer, int maxlen ) -{ - wchar_t *cwd; - int len; - if ( buffer == NULL ) { - cwd = malloc(MAX_PATH * sizeof(wchar_t)); - len = MAX_PATH; - } - else { - cwd = buffer; - len = maxlen; - } - - if ( GetCurrentDirectoryW(len,cwd) == 0 ) - return NULL; - - return cwd; + if (buffer == NULL) { + cwd = malloc(MAX_PATH); + len = MAX_PATH; + } else { + cwd = buffer; + len = maxlen; + } + if (GetCurrentDirectoryA(len, cwd) == 0) { + return NULL; + } + return cwd; } diff --git a/lib/msvcrt/direct/getdcwd.c b/lib/msvcrt/direct/getdcwd.c index e6e719e..bbf79fd 100644 --- a/lib/msvcrt/direct/getdcwd.c +++ b/lib/msvcrt/direct/getdcwd.c @@ -1,44 +1,19 @@ #include #include -char* _getdcwd (int nDrive, char* caBuffer, int nBufLen) +char* _getdcwd(int nDrive, char* caBuffer, int nBufLen) { - int i =0; - int dr = _getdrive(); - - if ( nDrive < 1 || nDrive > 26 ) - return NULL; - - if ( dr != nDrive ) - _chdrive(nDrive); - - i = GetCurrentDirectoryA(nBufLen,caBuffer); - if ( i == nBufLen ) - return NULL; - - if ( dr != nDrive ) - _chdrive(dr); - - return caBuffer; -} + int i =0; + int dr = _getdrive(); -wchar_t* _wgetdcwd (int nDrive, wchar_t* caBuffer, int nBufLen) -{ - int i =0; - int dr = _getdrive(); - - if ( nDrive < 1 || nDrive > 26 ) - return NULL; - - if ( dr != nDrive ) - _chdrive(nDrive); - - i = GetCurrentDirectoryW(nBufLen,caBuffer); - if ( i == nBufLen ) - return NULL; - - if ( dr != nDrive ) - _chdrive(dr); - - return caBuffer; + if (nDrive < 1 || nDrive > 26) + return NULL; + if (dr != nDrive) + _chdrive(nDrive); + i = GetCurrentDirectoryA(nBufLen, caBuffer); + if (i == nBufLen) + return NULL; + if (dr != nDrive) + _chdrive(dr); + return caBuffer; } diff --git a/lib/msvcrt/direct/getdfree.c b/lib/msvcrt/direct/getdfree.c index a240503..cd90b43 100644 --- a/lib/msvcrt/direct/getdfree.c +++ b/lib/msvcrt/direct/getdfree.c @@ -3,18 +3,18 @@ #include -unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t *_diskspace) +unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t* _diskspace) { - char RootPathName[10]; - RootPathName[0] = toupper(_drive +'@'); - RootPathName[1] = ':'; - RootPathName[2] = '\\'; - RootPathName[3] = 0; - if ( _diskspace == NULL ) - return 0; + char RootPathName[10]; - if ( !GetDiskFreeSpaceA(RootPathName,(LPDWORD)&_diskspace->sectors_per_cluster,(LPDWORD)&_diskspace->bytes_per_sector, - (LPDWORD )&_diskspace->avail_clusters,(LPDWORD )&_diskspace->total_clusters ) ) - return 0; - return _diskspace->avail_clusters; + RootPathName[0] = toupper(_drive +'@'); + RootPathName[1] = ':'; + RootPathName[2] = '\\'; + RootPathName[3] = 0; + if (_diskspace == NULL) + return 0; + if (!GetDiskFreeSpaceA(RootPathName,(LPDWORD)&_diskspace->sectors_per_cluster,(LPDWORD)&_diskspace->bytes_per_sector, + (LPDWORD )&_diskspace->avail_clusters,(LPDWORD )&_diskspace->total_clusters)) + return 0; + return _diskspace->avail_clusters; } diff --git a/lib/msvcrt/direct/getdrive.c b/lib/msvcrt/direct/getdrive.c index e2b6e66..5638c65 100644 --- a/lib/msvcrt/direct/getdrive.c +++ b/lib/msvcrt/direct/getdrive.c @@ -5,21 +5,20 @@ extern int cur_drive; -int _getdrive( void ) +int _getdrive(void) { - char Buffer[MAX_PATH]; + char Buffer[MAX_PATH]; - if ( cur_drive == 0 ) { - GetCurrentDirectoryA(MAX_PATH,Buffer); - cur_drive = toupper(Buffer[0] - '@'); - } - - return cur_drive; + if (cur_drive == 0) { + GetCurrentDirectoryA(MAX_PATH, Buffer); + cur_drive = toupper(Buffer[0] - '@'); + } + return cur_drive; } unsigned long _getdrives(void) { //fixme get logical drives //return GetLogicalDrives(); - return 5; // drive A and C + return 5; // drive A and C } diff --git a/lib/msvcrt/direct/mkdir.c b/lib/msvcrt/direct/mkdir.c index 3abb112..e568b9c 100644 --- a/lib/msvcrt/direct/mkdir.c +++ b/lib/msvcrt/direct/mkdir.c @@ -2,16 +2,9 @@ #include -int _mkdir( const char *_path ) +int _mkdir(const char* _path) { - if (!CreateDirectoryA(_path,NULL)) - return -1; - return 0; -} - -int _wmkdir( const wchar_t *_path ) -{ - if (!CreateDirectoryW(_path,NULL)) - return -1; - return 0; + if (!CreateDirectoryA(_path, NULL)) + return -1; + return 0; } diff --git a/lib/msvcrt/direct/rmdir.c b/lib/msvcrt/direct/rmdir.c index 90804f0..a057acd 100644 --- a/lib/msvcrt/direct/rmdir.c +++ b/lib/msvcrt/direct/rmdir.c @@ -1,16 +1,10 @@ #include #include -int _rmdir( const char *_path ) -{ - if (!RemoveDirectoryA(_path)) - return -1; - return 0; -} -int _wrmdir( const wchar_t *_path ) +int _rmdir(const char* _path) { - if (!RemoveDirectoryW(_path)) - return -1; - return 0; + if (!RemoveDirectoryA(_path)) + return -1; + return 0; } diff --git a/lib/msvcrt/direct/wchdir.c b/lib/msvcrt/direct/wchdir.c new file mode 100644 index 0000000..5772036 --- /dev/null +++ b/lib/msvcrt/direct/wchdir.c @@ -0,0 +1,13 @@ +#include +#include +#include + + +int _wchdir (const wchar_t *_path) +{ + if (_path[1] == L':') + _chdrive(towlower(_path[0] - L'a')+1); + if (!SetCurrentDirectoryW((wchar_t *)_path)) + return -1; + return 0; +} diff --git a/lib/msvcrt/direct/wgetcwd.c b/lib/msvcrt/direct/wgetcwd.c new file mode 100644 index 0000000..14e71bc --- /dev/null +++ b/lib/msvcrt/direct/wgetcwd.c @@ -0,0 +1,20 @@ +#include +#include +#include + + +wchar_t* _wgetcwd(wchar_t* buffer, int maxlen) +{ + wchar_t *cwd; + int len; + if (buffer == NULL) { + cwd = malloc(MAX_PATH * sizeof(wchar_t)); + len = MAX_PATH; + } else { + cwd = buffer; + len = maxlen; + } + if (GetCurrentDirectoryW(len, cwd) == 0 ) + return NULL; + return cwd; +} diff --git a/lib/msvcrt/direct/wgetdcwd.c b/lib/msvcrt/direct/wgetdcwd.c new file mode 100644 index 0000000..804e25a --- /dev/null +++ b/lib/msvcrt/direct/wgetdcwd.c @@ -0,0 +1,24 @@ +#include +#include + + +wchar_t* _wgetdcwd(int nDrive, wchar_t* caBuffer, int nBufLen) +{ + int i =0; + int dr = _getdrive(); + + if (nDrive < 1 || nDrive > 26) + return NULL; + + if (dr != nDrive) + _chdrive(nDrive); + + i = GetCurrentDirectoryW(nBufLen, caBuffer); + if (i == nBufLen) + return NULL; + + if (dr != nDrive) + _chdrive(dr); + + return caBuffer; +} diff --git a/lib/msvcrt/direct/wmkdir.c b/lib/msvcrt/direct/wmkdir.c new file mode 100644 index 0000000..6b979c4 --- /dev/null +++ b/lib/msvcrt/direct/wmkdir.c @@ -0,0 +1,10 @@ +#include +#include + + +int _wmkdir(const wchar_t* _path) +{ + if (!CreateDirectoryW(_path, NULL)) + return -1; + return 0; +} diff --git a/lib/msvcrt/direct/wrmdir.c b/lib/msvcrt/direct/wrmdir.c new file mode 100644 index 0000000..ce3bb22 --- /dev/null +++ b/lib/msvcrt/direct/wrmdir.c @@ -0,0 +1,9 @@ +#include +#include + +int _wrmdir(const wchar_t* _path) +{ + if (!RemoveDirectoryW(_path)) + return -1; + return 0; +} diff --git a/lib/msvcrt/except/abnorter.c b/lib/msvcrt/except/abnorter.c index 2efd11a..bced295 100644 --- a/lib/msvcrt/except/abnorter.c +++ b/lib/msvcrt/except/abnorter.c @@ -1,7 +1,13 @@ #include + +#ifdef __GNUC__ + int _abnormal_termination(void) { printf("Abnormal Termination\n"); // return AbnormalTermination(); } + +#else +#endif diff --git a/lib/msvcrt/except/exhand2.c b/lib/msvcrt/except/exhand2.c index 7bd2a72..35a0ea0 100644 --- a/lib/msvcrt/except/exhand2.c +++ b/lib/msvcrt/except/exhand2.c @@ -1,9 +1,17 @@ #include +#ifdef __GNUC__ +#else +ULONG DbgPrint(PCH Format,...) +{ + return 0; +} +#endif + VOID STDCALL MsvcrtDebug(ULONG Value) { - DbgPrint("MsvcrtDebug 0x%.08x\n", Value); + //DbgPrint("MsvcrtDebug 0x%.08x\n", Value); } EXCEPTION_DISPOSITION @@ -13,5 +21,6 @@ void *Frame, struct _CONTEXT *ContextRecord, void *DispatcherContext) { - printf("_except_handler2()\n"); + //printf("_except_handler2()\n"); + return 0; } diff --git a/lib/msvcrt/except/matherr.c b/lib/msvcrt/except/matherr.c index 5d03db2..01de05c 100644 --- a/lib/msvcrt/except/matherr.c +++ b/lib/msvcrt/except/matherr.c @@ -1,28 +1,36 @@ +#include +#include + + struct _exception { - int type; - char *name; - double arg1; - double arg2; - double retval; - } ; - -int _matherr(struct _exception *e) + int type; + char* name; + double arg1; + double arg2; + double retval; +} ; + + +int _matherr(struct _exception* e) { return 0; } -void __setusermatherr(int (* handler)(struct _exception *)) + +// not exported by NTDLL +void __setusermatherr(int (*handler)(struct _exception*)) { } + #define _FPIEEE_RECORD void int _fpieee_flt( - unsigned long exception_code, - struct _EXCEPTION_POINTERS *ExceptionPointer, - int (* handler)(_FPIEEE_RECORD *) + unsigned long exception_code, + struct _EXCEPTION_POINTERS* ExceptionPointer, + int (*handler)(_FPIEEE_RECORD*) ) { - return 0; + return 0; } diff --git a/lib/msvcrt/except/unwind.c b/lib/msvcrt/except/unwind.c index b4dc555..b161263 100644 --- a/lib/msvcrt/except/unwind.c +++ b/lib/msvcrt/except/unwind.c @@ -3,8 +3,11 @@ void __cdecl _global_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame) { +#ifdef __GNUC__ RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0); __ret_label: // return is important return; +#else +#endif } diff --git a/lib/msvcrt/float/chgsign.c b/lib/msvcrt/float/chgsign.c index 0fb4072..a8588a6 100644 --- a/lib/msvcrt/float/chgsign.c +++ b/lib/msvcrt/float/chgsign.c @@ -1,9 +1,11 @@ #include #include + double _chgsign( double __x ) { double_t *x = (double_t *)&x; + if ( x->sign == 1 ) x->sign = 0; else diff --git a/lib/msvcrt/float/clearfp.c b/lib/msvcrt/float/clearfp.c index 11e03e5..baf77c2 100644 --- a/lib/msvcrt/float/clearfp.c +++ b/lib/msvcrt/float/clearfp.c @@ -3,11 +3,12 @@ unsigned int _clearfp (void) { unsigned short __res = _statusfp(); - +#ifdef __GNUC__ __asm__ __volatile__ ( "fclex \n\t" ); - +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/msvcrt/float/cntrlfp.c b/lib/msvcrt/float/cntrlfp.c index c15444d..88c3381 100644 --- a/lib/msvcrt/float/cntrlfp.c +++ b/lib/msvcrt/float/cntrlfp.c @@ -10,7 +10,7 @@ unsigned int _controlfp(unsigned int unNew, unsigned int unMask) unsigned int _control87(unsigned int unNew, unsigned int unMask) { register unsigned int __res; - +#ifdef __GNUC__ __asm__ __volatile__ ( "pushl %%eax \n\t" /* make room on stack */ "fstcw (%%esp) \n\t" @@ -31,6 +31,7 @@ __asm__ __volatile__ ( "popl %%edx \n\t" :"=r" (__res):"r" (unNew),"r" (unMask): "ax", "dx", "cx"); - +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/msvcrt/float/fpclass.c b/lib/msvcrt/float/fpclass.c index d4c280a..5401aa1 100644 --- a/lib/msvcrt/float/fpclass.c +++ b/lib/msvcrt/float/fpclass.c @@ -2,6 +2,7 @@ #include #include + #define _FPCLASS_SNAN 0x0001 /* signaling NaN */ #define _FPCLASS_QNAN 0x0002 /* quiet NaN */ #define _FPCLASS_NINF 0x0004 /* negative infinity */ @@ -58,8 +59,5 @@ fpclass_t _fpclass(double __d) } } - return 0; } - - diff --git a/lib/msvcrt/float/fpreset.c b/lib/msvcrt/float/fpreset.c index 4127159..59902e4 100644 --- a/lib/msvcrt/float/fpreset.c +++ b/lib/msvcrt/float/fpreset.c @@ -1,5 +1,6 @@ #include + void _fpreset(void) { /* FIXME: This causes an exception */ diff --git a/lib/msvcrt/float/isnan.c b/lib/msvcrt/float/isnan.c index 6cff15b..27d810c 100644 --- a/lib/msvcrt/float/isnan.c +++ b/lib/msvcrt/float/isnan.c @@ -20,6 +20,7 @@ Cambridge, MA 02139, USA. */ #include #include + int _isnan(double __x) { double_t * x = (double_t *)&__x; @@ -28,7 +29,6 @@ int _isnan(double __x) int _isnanl(long double __x) { - /* Intel's extended format has the normally implicit 1 explicit present. Sigh! */ @@ -43,15 +43,12 @@ int _isnanl(long double __x) && ( (x->mantissah & (unsigned int)0x7fffffff) != 0 || x->mantissal != 0 )); } - int _isinf(double __x) { double_t * x = (double_t *)&__x; return ( x->exponent == 0x7ff && ( x->mantissah == 0 && x->mantissal == 0 )); } - - int _finite( double x ) { return !_isinf(x); @@ -73,5 +70,3 @@ int _isinfl(long double __x) return x->sign ? -1 : 1; return 0; } - - diff --git a/lib/msvcrt/float/logb.c b/lib/msvcrt/float/logb.c index 140a104..d71c654 100644 --- a/lib/msvcrt/float/logb.c +++ b/lib/msvcrt/float/logb.c @@ -22,10 +22,13 @@ double _logb (double __x) { - register double __value, __junk; + register double __value; +#ifdef __GNUC__ + register double __junk; __asm __volatile__ ("fxtract\n\t" : "=t" (__junk), "=u" (__value) : "0" (__x)); - +#else +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/float/nafter.c b/lib/msvcrt/float/nafter.c index 9773d92..a8bd034 100644 --- a/lib/msvcrt/float/nafter.c +++ b/lib/msvcrt/float/nafter.c @@ -1,5 +1,6 @@ #include + double _nextafter( double x, double y ) { if ( x == y) diff --git a/lib/msvcrt/float/statfp.c b/lib/msvcrt/float/statfp.c index cef37a3..6792fd9 100644 --- a/lib/msvcrt/float/statfp.c +++ b/lib/msvcrt/float/statfp.c @@ -4,11 +4,13 @@ unsigned int _statusfp (void) { register unsigned short __res; - +#ifdef __GNUC__ __asm__ __volatile__ ( "fstsw %0 \n\t" // "movzwl %ax, %eax" :"=a" (__res) ); +#else +#endif /*__GNUC__*/ return __res; } diff --git a/lib/msvcrt/io/access.c b/lib/msvcrt/io/access.c index 493c4a7..4babf62 100644 --- a/lib/msvcrt/io/access.c +++ b/lib/msvcrt/io/access.c @@ -4,69 +4,27 @@ #define NDEBUG #include -#ifndef F_OK - #define F_OK 0x01 -#endif -#ifndef R_OK - #define R_OK 0x02 -#endif -#ifndef W_OK - #define W_OK 0x04 -#endif -#ifndef X_OK - #define X_OK 0x08 -#endif -#ifndef D_OK - #define D_OK 0x10 -#endif int _access( const char *_path, int _amode ) { - DWORD Attributes = GetFileAttributesA(_path); - DPRINT("_access('%s', %x)\n", _path, _amode); - - if ( Attributes == -1 ) { - __set_errno(ENOENT); - return -1; - } - - if ( (_amode & W_OK) == W_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY ) { - __set_errno(EACCES); - return -1; - } - } - if ( (_amode & D_OK) == D_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) { - __set_errno(EACCES); - return -1; - } - } - - return 0; -} - -int _waccess( const wchar_t *_path, int _amode ) -{ - DWORD Attributes = GetFileAttributesW(_path); - - if ( Attributes == -1 ) { - __set_errno(ENOENT); - return -1; - } - - if ( (_amode & W_OK) == W_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY ) { - __set_errno(EACCES); - return -1; - } - } - if ( (_amode & D_OK) == D_OK ) { - if ( (Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) { - __set_errno(EACCES); - return -1; - } - } - - return 0; + DWORD Attributes = GetFileAttributesA(_path); + DPRINT("_access('%s', %x)\n", _path, _amode); + + if (Attributes == -1) { + __set_errno(ENOENT); + return -1; + } + if ((_amode & W_OK) == W_OK) { + if ((Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { + __set_errno(EACCES); + return -1; + } + } + if ((_amode & D_OK) == D_OK) { + if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { + __set_errno(EACCES); + return -1; + } + } + return 0; } diff --git a/lib/msvcrt/io/chmod.c b/lib/msvcrt/io/chmod.c index f5d61aa..0f54898 100644 --- a/lib/msvcrt/io/chmod.c +++ b/lib/msvcrt/io/chmod.c @@ -6,52 +6,28 @@ #define mode_t int -int _chmod(const char *filename, mode_t mode) -{ - DWORD FileAttributes = 0; - DPRINT("_chmod('%s', %x)\n", filename, mode); - - FileAttributes = GetFileAttributesA(filename); - if ( FileAttributes == -1 ) - return -1; - - if ( mode == 0 ) - return -1; - - if ((mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) - FileAttributes &= FILE_ATTRIBUTE_READONLY; - else if (((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE)) - FileAttributes &= FILE_ATTRIBUTE_NORMAL; - else - FileAttributes &= FILE_ATTRIBUTE_NORMAL; - - if (SetFileAttributesA(filename, FileAttributes) == FALSE) - return -1; - - return 1; -} -int _wchmod(const wchar_t *filename, mode_t mode) +int _chmod(const char* filename, mode_t mode) { - DWORD FileAttributes = 0; - DPRINT("_wchmod('%S', %x)\n", filename, mode); + DWORD FileAttributes = 0; + DPRINT("_chmod('%s', %x)\n", filename, mode); - FileAttributes = GetFileAttributesW(filename); - if ( FileAttributes == -1 ) - return -1; + FileAttributes = GetFileAttributesA(filename); + if ( FileAttributes == -1 ) + return -1; - if ( mode == 0 ) - return -1; + if ( mode == 0 ) + return -1; - if ((mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) - FileAttributes &= FILE_ATTRIBUTE_READONLY; - else if (((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE)) - FileAttributes &= FILE_ATTRIBUTE_NORMAL; - else - FileAttributes &= FILE_ATTRIBUTE_NORMAL; + if ((mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) + FileAttributes &= FILE_ATTRIBUTE_READONLY; + else if (((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE)) + FileAttributes &= FILE_ATTRIBUTE_NORMAL; + else + FileAttributes &= FILE_ATTRIBUTE_NORMAL; - if (SetFileAttributesW(filename, FileAttributes) == FALSE) - return -1; + if (SetFileAttributesA(filename, FileAttributes) == FALSE) + return -1; - return 1; + return 1; } diff --git a/lib/msvcrt/io/commit.c b/lib/msvcrt/io/commit.c index 406b03f..925ddd7 100644 --- a/lib/msvcrt/io/commit.c +++ b/lib/msvcrt/io/commit.c @@ -3,18 +3,10 @@ #include #include -int _commode = _IOCOMMIT; - - -int *__p__commode(void) -{ - return &_commode; -} int _commit(int _fd) { - if (! FlushFileBuffers(_get_osfhandle(_fd)) ) - { + if (! FlushFileBuffers(_get_osfhandle(_fd)) ) { __set_errno(EBADF); return -1; } diff --git a/lib/msvcrt/io/create.c b/lib/msvcrt/io/create.c index 3f11706..d8755c4 100644 --- a/lib/msvcrt/io/create.c +++ b/lib/msvcrt/io/create.c @@ -4,14 +4,9 @@ #define NDEBUG #include -int _creat(const char *filename, int mode) -{ - DPRINT("_creat('%s', mode %x)\n", filename, mode); - return _open(filename,_O_CREAT|_O_TRUNC,mode); -} -int _wcreat(const wchar_t *filename, int mode) +int _creat(const char* filename, int mode) { - DPRINT("_wcreat('%S', mode %x)\n", filename, mode); - return _wopen(filename,_O_CREAT|_O_TRUNC,mode); + DPRINT("_creat('%s', mode %x)\n", filename, mode); + return _open(filename,_O_CREAT|_O_TRUNC,mode); } diff --git a/lib/msvcrt/io/filelen.c b/lib/msvcrt/io/filelen.c index 84e9f10..c2fcb00 100644 --- a/lib/msvcrt/io/filelen.c +++ b/lib/msvcrt/io/filelen.c @@ -1,16 +1,8 @@ #include #include -long _filelength(int _fd) -{ - return GetFileSize(_get_osfhandle(_fd),NULL); -} -__int64 _filelengthi64(int _fd) +long _filelength(int _fd) { - long lo_length, hi_length; - - lo_length = GetFileSize(_get_osfhandle(_fd), &hi_length); - - return((((__int64)hi_length) << 32) + lo_length); + return GetFileSize(_get_osfhandle(_fd), NULL); } diff --git a/lib/msvcrt/io/fileleni.c b/lib/msvcrt/io/fileleni.c new file mode 100644 index 0000000..9c2d406 --- /dev/null +++ b/lib/msvcrt/io/fileleni.c @@ -0,0 +1,11 @@ +#include +#include + + +__int64 _filelengthi64(int _fd) +{ + long lo_length, hi_length; + + lo_length = GetFileSize(_get_osfhandle(_fd), &hi_length); + return((((__int64)hi_length) << 32) + lo_length); +} diff --git a/lib/msvcrt/io/find.c b/lib/msvcrt/io/find.c index f7921b8..83b379b 100644 --- a/lib/msvcrt/io/find.c +++ b/lib/msvcrt/io/find.c @@ -6,280 +6,72 @@ int _findclose(int handle) { - // check no wildcards or invalid handle - if (handle == 0 || handle == -1) - return 0; - return FindClose((void *)handle); + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; + return FindClose((void*)handle); } -int _findfirst(const char *_name, struct _finddata_t *result) +int _findfirst(const char* _name, struct _finddata_t* result) { - WIN32_FIND_DATAA FindFileData; - char dir[MAX_PATH]; - long hFindFile; - int len = 0; - - if ( _name == NULL || _name[0] == 0 ) - { - len = GetCurrentDirectoryA(MAX_PATH-4,dir); - if (dir[len-1] != '\\') - { - dir[len] = '\\'; - dir[len+1] = 0; - } - strcat(dir,"*.*"); + WIN32_FIND_DATAA FindFileData; + char dir[MAX_PATH]; + long hFindFile; + int len = 0; + + if (_name == NULL || _name[0] == 0) { + len = GetCurrentDirectoryA(MAX_PATH-4,dir); + if (dir[len-1] != '\\') { + dir[len] = '\\'; + dir[len+1] = 0; + } + strcat(dir,"*.*"); + } else { + strcpy(dir,_name); } - else - strcpy(dir,_name); - hFindFile = (long)FindFirstFileA( dir, &FindFileData ); - if (hFindFile == -1) - { - memset(result,0,sizeof(struct _finddata_t)); - return -1; + hFindFile = (long)FindFirstFileA(dir, &FindFileData); + if (hFindFile == -1) { + memset(result,0,sizeof(struct _finddata_t)); + return -1; } - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName,MAX_PATH); + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName,MAX_PATH); - // if no wildcard the find file handle can be closed right away - // a return value of 0 can flag this. + // if no wildcard the find file handle can be closed right away + // a return value of 0 can flag this. - if (!strchr(dir,'*') && !strchr(dir,'?')) - { - _findclose(hFindFile); - return 0; + if (!strchr(dir,'*') && !strchr(dir,'?')) { + _findclose(hFindFile); + return 0; } - return hFindFile; + return hFindFile; } -int _findfirsti64(const char *_name, struct _finddatai64_t *result) +int _findnext(int handle, struct _finddata_t* result) { - WIN32_FIND_DATAA FindFileData; - char dir[MAX_PATH]; - long hFindFile; - int len = 0; - - if ( _name == NULL || _name[0] == 0 ) - { - len = GetCurrentDirectoryA(MAX_PATH-4,dir); - if (dir[len-1] != '\\') - { - dir[len] = '\\'; - dir[len+1] = 0; - } - strcat(dir, "*.*"); - } - else - strcpy(dir, _name); - - hFindFile = (long)FindFirstFileA(dir, &FindFileData); - if (hFindFile == -1) - { - memset(result,0,sizeof(struct _finddatai64_t)); - return -1; - } - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = - (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName,MAX_PATH); - - // if no wildcard the find file handle can be closed right away - // a return value of 0 can flag this. + WIN32_FIND_DATAA FindFileData; - if (!strchr(dir,'*') && !strchr(dir,'?')) - { - _findclose(hFindFile); - return 0; - } + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; - return hFindFile; -} + if (!FindNextFileA((void*)handle, &FindFileData)) + return -1; -int _findnext(int handle, struct _finddata_t *result) -{ - WIN32_FIND_DATAA FindFileData; + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName, MAX_PATH); - // check no wildcards or invalid handle - if (handle == 0 || handle == -1) return 0; - - if (!FindNextFileA((void *)handle, &FindFileData)) - return -1; - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName, MAX_PATH); - - return 0; } -int _findnexti64(int handle, struct _finddatai64_t *result) -{ - WIN32_FIND_DATAA FindFileData; - - // check no wildcards or invalid handle - if (handle == 0 || handle == -1) - return 0; - - if (!FindNextFileA((void *)handle, &FindFileData)) - return -1; - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = - (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; - strncpy(result->name,FindFileData.cFileName,MAX_PATH); - - return 0; -} - -int _wfindfirst(const wchar_t *_name, struct _wfinddata_t *result) -{ - WIN32_FIND_DATAW FindFileData; - wchar_t dir[MAX_PATH]; - long hFindFile; - int len = 0; - - if ( _name == NULL || _name[0] == 0 ) - { - len = GetCurrentDirectoryW(MAX_PATH-4, dir); - if (dir[len-1] != L'\\') - { - dir[len] = L'\\'; - dir[len+1] = 0; - } - wcscat(dir, L"*.*"); - } - else - wcscpy(dir, _name); - - hFindFile = (long)FindFirstFileW(dir, &FindFileData); - if (hFindFile == -1) - { - memset(result,0,sizeof(struct _wfinddata_t)); - return -1; - } - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); - - // if no wildcard the find file handle can be closed right away - // a return value of 0 can flag this. - - if (!wcschr(dir, L'*') && !wcschr(dir, L'?')) - { - _findclose(hFindFile); - return 0; - } - - return hFindFile; -} - -int _wfindfirsti64(const wchar_t *_name, struct _wfinddatai64_t *result) -{ - WIN32_FIND_DATAW FindFileData; - wchar_t dir[MAX_PATH]; - long hFindFile; - int len = 0; - - if (_name == NULL || _name[0] == 0) - { - len = GetCurrentDirectoryW(MAX_PATH-4,dir); - if (dir[len-1] != L'\\') - { - dir[len] = L'\\'; - dir[len+1] = 0; - } - wcscat(dir, L"*.*"); - } - else - wcscpy(dir, _name); - - hFindFile = (long)FindFirstFileW(dir, &FindFileData); - if (hFindFile == -1) - { - memset(result,0,sizeof(struct _wfinddatai64_t)); - return -1; - } - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = - (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; - wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); - - // if no wildcard the find file handle can be closed right away - // a return value of 0 can flag this. - - if (!wcschr(dir,L'*') && !wcschr(dir,L'?')) - { - _findclose(hFindFile); - return 0; - } - - return hFindFile; -} - -int _wfindnext(int handle, struct _wfinddata_t *result) -{ - WIN32_FIND_DATAW FindFileData; - - // check no wildcards or invalid handle - if (handle == 0 || handle == -1) - return 0; - - if (!FindNextFileW((void *)handle, &FindFileData)) - return -1; - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = FindFileData.nFileSizeLow; - wcsncpy(result->name,FindFileData.cFileName, MAX_PATH); - - return 0; -} - -int _wfindnexti64(int handle, struct _wfinddatai64_t *result) -{ - WIN32_FIND_DATAW FindFileData; - - // check no wildcards or invalid handle - if (handle == 0 || handle == -1) - return 0; - - if (!FindNextFileW((void *)handle, &FindFileData)) - return -1; - - result->attrib = FindFileData.dwFileAttributes; - result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); - result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); - result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); - result->size = - (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; - wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); - - return 0; -} diff --git a/lib/msvcrt/io/locking.c b/lib/msvcrt/io/locking.c index ba32830..9012183 100644 --- a/lib/msvcrt/io/locking.c +++ b/lib/msvcrt/io/locking.c @@ -1,10 +1,12 @@ #include #include + int _locking(int _fd, int mode, long nbytes) { long offset = _lseek(_fd, 0L, 1); if (!LockFile(_get_osfhandle(_fd),offset,0,nbytes,0)) return -1; + return 0; } diff --git a/lib/msvcrt/io/lseek.c b/lib/msvcrt/io/lseek.c index 4f03d43..5e20b08 100644 --- a/lib/msvcrt/io/lseek.c +++ b/lib/msvcrt/io/lseek.c @@ -5,13 +5,5 @@ long _lseek(int _fildes, long _offset, int _whence) { - return (SetFilePointer((HANDLE)filehnd(_fildes), _offset, NULL, _whence)); -} - -__int64 _lseeki64(int _fildes, __int64 _offset, int _whence) -{ - ULONG lo_pos, hi_pos; - - lo_pos = SetFilePointer((HANDLE)filehnd(_fildes), _offset, &hi_pos, _whence); - return((((__int64)hi_pos) << 32) + lo_pos); + return (SetFilePointer((HANDLE)filehnd(_fildes), _offset, NULL, _whence)); } diff --git a/lib/msvcrt/io/lseeki64.c b/lib/msvcrt/io/lseeki64.c new file mode 100644 index 0000000..71b8e76 --- /dev/null +++ b/lib/msvcrt/io/lseeki64.c @@ -0,0 +1,39 @@ +#include +#include +#include + + +//#define SETFILEPOINTEREX_AVAILABLE + +__int64 _lseeki64(int _fildes, __int64 _offset, int _whence) +{ +#ifdef SETFILEPOINTEREX_AVAILABLE + LARGE_INTEGER new_pos; + LARGE_INTEGER offset; + offset.QuadPart = _offset; + +// if (invalid_filehnd(_fildes)) { +// errno = EBADF; +// return -1L; +// } + if (SetFilePointerEx((HANDLE)filehnd(_fildes), offset, &new_pos, _whence)) { + } else { + //errno = EINVAL; + return -1L; + } + return new_pos.QuadPart; +#else + //ULONG lo_pos; + //DWORD hi_pos = 0; // must equal 0 or -1 if supplied, -1 for negative 32 seek value + //lo_pos = SetFilePointer((HANDLE)filehnd(_fildes), _offset, &hi_pos, _whence); + //return((((__int64)hi_pos) << 32) + lo_pos); + + LARGE_INTEGER offset; + offset.QuadPart = _offset; + + offset.u.LowPart = SetFilePointer((HANDLE)filehnd(_fildes), + offset.u.LowPart, &offset.u.HighPart, _whence); + return ((((__int64)offset.u.HighPart) << 32) + offset.u.LowPart); + +#endif /*SETFILEPOINTEREX_AVAILABLE*/ +} diff --git a/lib/msvcrt/io/mktemp.c b/lib/msvcrt/io/mktemp.c index 6f31b4a..2e84c3c 100644 --- a/lib/msvcrt/io/mktemp.c +++ b/lib/msvcrt/io/mktemp.c @@ -1,11 +1,11 @@ /* * COPYRIGHT: See COPYING in the top level directory - * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/io/mktemp.c + * FILE: lib/msvcrt/io/mktemp.c * PURPOSE: Makes a temp file based on a template * PROGRAMER: DJ Delorie - Boudewijn Dekker + Boudewijn Dekker * UPDATE HISTORY: * 28/12/98: Appropriated for the Reactos Kernel */ @@ -21,7 +21,7 @@ #include -char* _mktemp (char *_template) +char* _mktemp(char* _template) { static int count = 0; char *cp, *dp; @@ -63,62 +63,9 @@ char* _mktemp (char *_template) for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) { int c = count++; for (i = 0; i < xcount; i++, c >>= 5) - cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f]; + cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f]; if (_access(_template,0) == -1) - return _template; - } - } - - /* Failure: truncate the template and return NULL. */ - *_template = 0; - return 0; -} - -wchar_t* _wmktemp (wchar_t *_template) -{ - static int count = 0; - wchar_t *cp, *dp; - int i, len, xcount, loopcnt; - - DPRINT("_wmktemp('%S')\n", _template); - len = wcslen (_template); - cp = _template + len; - - xcount = 0; - while (xcount < 6 && cp > _template && cp[-1] == L'X') - xcount++, cp--; - - if (xcount) { - dp = cp; - while (dp > _template && dp[-1] != L'/' && dp[-1] != L'\\' && dp[-1] != L':') - dp--; - - /* Keep the first characters of the template, but turn the rest into - Xs. */ - while (cp > dp + 8 - xcount) { - *--cp = L'X'; - xcount = (xcount >= 6) ? 6 : 1 + xcount; - } - - /* If dots occur too early -- squash them. */ - while (dp < cp) { - if (*dp == L'.') *dp = L'a'; - dp++; - } - - /* Try to add ".tmp" to the filename. Truncate unused Xs. */ - if (cp + xcount + 3 < _template + len) - wcscpy (cp + xcount, L".tmp"); - else - cp[xcount] = 0; - - /* This loop can run up to 2<<(5*6) times, or about 10^9 times. */ - for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) { - int c = count++; - for (i = 0; i < xcount; i++, c >>= 5) - cp[i] = L"abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f]; - if (_waccess(_template,0) == -1) - return _template; + return _template; } } diff --git a/lib/msvcrt/io/open.c b/lib/msvcrt/io/open.c index 354c2db..f8ebcf5 100644 --- a/lib/msvcrt/io/open.c +++ b/lib/msvcrt/io/open.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/io/open.c + * FILE: lib/msvcrt/io/open.c * PURPOSE: Opens a file and translates handles to fileno * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -29,29 +29,69 @@ #define NDEBUG #include +//#define _OLD_BUILD_ + #define STD_AUX_HANDLE 3 #define STD_PRINTER_HANDLE 4 + +///////////////////////////////////////// +#if 0 // from perl sources + +#ifndef _INTPTR_T_DEFINED +typedef int intptr_t; +#define _INTPTR_T_DEFINED +#endif + +#ifndef _UINTPTR_T_DEFINED +typedef unsigned int uintptr_t; +#define _UINTPTR_T_DEFINED +#endif + +/* + * Control structure for lowio file handles + */ +typedef struct { + intptr_t osfhnd;/* underlying OS file HANDLE */ + char osfile; /* attributes of file (e.g., open in text mode?) */ + char pipech; /* one char buffer for handles opened on pipes */ + int lockinitflag; + //CRITICAL_SECTION lock; +} ioinfo; + +/* + * Array of arrays of control structures for lowio files. + */ +//ioinfo* __pioinfo[]; +//ioinfo* __pioinfo[] = { NULL }; + +#endif +///////////////////////////////////////// + typedef struct _fileno_modes_type { - HANDLE hFile; - int mode; - int fd; + HANDLE hFile; + int mode; + char pipech; /* one char buffer for handles opened on pipes */ + int lockinitflag; + /*CRITICAL_SECTION*/int lock; + int fd; } fileno_modes_type; -fileno_modes_type *fileno_modes = NULL; +//static fileno_modes_type* fileno_modes = NULL; +fileno_modes_type* __pioinfo = NULL; +///////////////////////////////////////// int maxfno = 0; -char __is_text_file(FILE *p) +char __is_text_file(FILE* p) { - if ( p == NULL || fileno_modes == NULL ) + if ( p == NULL || __pioinfo == NULL ) return FALSE; - return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT)); + return (!((p)->_flag&_IOSTRG) && (__pioinfo[(p)->_file].mode&O_TEXT)); } - -int _open(const char *_path, int _oflag,...) +int _open(const char* _path, int _oflag,...) { #if !defined(NDEBUG) && defined(DBG) va_list arg; @@ -70,14 +110,13 @@ int _open(const char *_path, int _oflag,...) pmode = va_arg(arg, int); #endif - DPRINT("_open('%s', %x, (%x))\n", _path, _oflag, pmode); +// DPRINT("_open('%s', %x, (%x))\n", _path, _oflag, pmode); - if (( _oflag & S_IREAD ) == S_IREAD) + if ((_oflag & S_IREAD ) == S_IREAD) dwShareMode = FILE_SHARE_READ; - else if ( ( _oflag & S_IWRITE) == S_IWRITE ) { + else if ((_oflag & S_IWRITE) == S_IWRITE) { dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; } - /* * * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) @@ -85,346 +124,235 @@ int _open(const char *_path, int _oflag,...) * * _O_APPEND Moves file pointer to end of file before every write operation. */ - if (( _oflag & _O_RDWR ) == _O_RDWR ) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ ; - else if (( _oflag & O_RDONLY ) == O_RDONLY ) - dwDesiredAccess |= GENERIC_READ ; - else if (( _oflag & _O_WRONLY ) == _O_WRONLY ) +#ifdef _OLD_BUILD_ + if ((_oflag & _O_RDWR) == _O_RDWR) + dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ; + else if ((_oflag & O_RDONLY) == O_RDONLY) + dwDesiredAccess |= GENERIC_READ; + else if ((_oflag & _O_WRONLY) == _O_WRONLY) dwDesiredAccess |= GENERIC_WRITE ; - - if (( _oflag & S_IREAD ) == S_IREAD ) +#else + if ((_oflag & _O_WRONLY) == _O_WRONLY ) + dwDesiredAccess |= GENERIC_WRITE ; + else if ((_oflag & _O_RDWR) == _O_RDWR ) + dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ; + else //if ((_oflag & O_RDONLY) == O_RDONLY) + dwDesiredAccess |= GENERIC_READ; +#endif + if (( _oflag & S_IREAD ) == S_IREAD) dwShareMode |= FILE_SHARE_READ; - if (( _oflag & S_IWRITE ) == S_IWRITE ) - dwShareMode |= FILE_SHARE_WRITE; + if (( _oflag & S_IWRITE ) == S_IWRITE) + dwShareMode |= FILE_SHARE_WRITE; - if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) ) + if (( _oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) dwCreationDistribution |= CREATE_NEW; - else if (( _oflag & O_TRUNC ) == O_TRUNC ) { - if (( _oflag & O_CREAT ) == O_CREAT ) - dwCreationDistribution |= CREATE_ALWAYS; - else if (( _oflag & O_RDONLY ) != O_RDONLY ) - dwCreationDistribution |= TRUNCATE_EXISTING; + else if ((_oflag & O_TRUNC ) == O_TRUNC) { + if ((_oflag & O_CREAT ) == O_CREAT) + dwCreationDistribution |= CREATE_ALWAYS; + else if ((_oflag & O_RDONLY ) != O_RDONLY) + dwCreationDistribution |= TRUNCATE_EXISTING; } - else if (( _oflag & _O_APPEND ) == _O_APPEND ) + else if ((_oflag & _O_APPEND) == _O_APPEND) dwCreationDistribution |= OPEN_EXISTING; - else if (( _oflag & _O_CREAT ) == _O_CREAT ) + else if ((_oflag & _O_CREAT) == _O_CREAT) dwCreationDistribution |= OPEN_ALWAYS; else dwCreationDistribution |= OPEN_EXISTING; - - if (( _oflag & _O_RANDOM ) == _O_RANDOM ) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL ) + + if ((_oflag & _O_RANDOM) == _O_RANDOM ) + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; + if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL) dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - - if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY ) - { + if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) { dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n"); } - - if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED ) - { + if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) { dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n"); } - if (_oflag & _O_NOINHERIT) sa.bInheritHandle = FALSE; - hFile = CreateFileA(_path, - dwDesiredAccess, - dwShareMode, - &sa, - dwCreationDistribution, - dwFlagsAndAttributes, - NULL); - if (hFile == (HANDLE)-1) - { + dwDesiredAccess, + dwShareMode, + &sa, + dwCreationDistribution, + dwFlagsAndAttributes, + NULL); + if (hFile == (HANDLE)-1) { dwLastError = GetLastError(); - if (dwLastError == ERROR_ALREADY_EXISTS) - { - DPRINT("ERROR_ALREADY_EXISTS\n"); - __set_errno(EEXIST); - } - else - { - DPRINT("%x\n", dwLastError); + if (dwLastError == ERROR_ALREADY_EXISTS) { + DPRINT("ERROR_ALREADY_EXISTS\n"); + __set_errno(EEXIST); + } else { + DPRINT("%x\n", dwLastError); __set_errno(ENOFILE); } return -1; } DPRINT("OK\n"); - if (!(_oflag & (_O_TEXT|_O_BINARY))) - { - _oflag |= _fmode; + if (!(_oflag & (_O_TEXT|_O_BINARY))) { + _oflag |= _fmode; } - return __fileno_alloc(hFile,_oflag); -} - - -int _wopen(const wchar_t *_path, int _oflag,...) -{ -#if !defined(NDEBUG) && defined(DBG) - va_list arg; - int pmode; -#endif - HANDLE hFile; - DWORD dwDesiredAccess = 0; - DWORD dwShareMode = 0; - DWORD dwCreationDistribution = 0; - DWORD dwFlagsAndAttributes = 0; - SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; - -#if !defined(NDEBUG) && defined(DBG) - va_start(arg, _oflag); - pmode = va_arg(arg, int); -#endif - - DPRINT("_wopen('%S', %x, (%x))\n", _path, _oflag, pmode); - - if (( _oflag & S_IREAD ) == S_IREAD) - dwShareMode = FILE_SHARE_READ; - else if ( ( _oflag & S_IWRITE) == S_IWRITE ) { - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - } - - /* - * - * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) - * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) - * - * _O_APPEND Moves file pointer to end of file before every write operation. - */ - if (( _oflag & _O_RDWR ) == _O_RDWR ) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA | - FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | - FILE_WRITE_ATTRIBUTES; - else if (( _oflag & O_RDONLY ) == O_RDONLY ) - dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES - | FILE_WRITE_ATTRIBUTES; - else if (( _oflag & _O_WRONLY ) == _O_WRONLY ) - dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA | - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES; - - if (( _oflag & S_IREAD ) == S_IREAD ) - dwShareMode |= FILE_SHARE_READ; - - if (( _oflag & S_IWRITE ) == S_IWRITE ) - dwShareMode |= FILE_SHARE_WRITE; - - if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) ) - dwCreationDistribution |= CREATE_NEW; - - else if (( _oflag & O_TRUNC ) == O_TRUNC ) { - if (( _oflag & O_CREAT ) == O_CREAT ) - dwCreationDistribution |= CREATE_ALWAYS; - else if (( _oflag & O_RDONLY ) != O_RDONLY ) - dwCreationDistribution |= TRUNCATE_EXISTING; - } - else if (( _oflag & _O_APPEND ) == _O_APPEND ) - dwCreationDistribution |= OPEN_EXISTING; - else if (( _oflag & _O_CREAT ) == _O_CREAT ) - dwCreationDistribution |= OPEN_ALWAYS; - else - dwCreationDistribution |= OPEN_EXISTING; - - if (( _oflag & _O_RANDOM ) == _O_RANDOM ) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL ) - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - - if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY ) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED ) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - if (_oflag & _O_NOINHERIT) - sa.bInheritHandle = FALSE; - - hFile = CreateFileW(_path, - dwDesiredAccess, - dwShareMode, - &sa, - dwCreationDistribution, - dwFlagsAndAttributes, - NULL); - if (hFile == (HANDLE)-1) - return -1; return __fileno_alloc(hFile,_oflag); } -int -__fileno_alloc(HANDLE hFile, int mode) +int __fileno_alloc(HANDLE hFile, int mode) { int i; /* Check for bogus values */ if (hFile < 0) - return -1; - - for(i=5;i= maxfno || __pioinfo[fileno].fd == -1) { + return (void*)-1; + } + return __pioinfo[fileno].hFile; +} + +int __fileno_setmode(int _fd, int _newmode) +{ + int m; + if (_fd < 0 || _fd >= maxfno) { + __set_errno(EBADF); + return -1; + } + m = __pioinfo[_fd].mode; + __pioinfo[_fd].mode = _newmode; + return m; +} + +int __fileno_getmode(int _fd) { - if ( fileno < 0 || fileno>= maxfno || fileno_modes[fileno].fd == -1) - { - return (void *)-1; - } - return fileno_modes[fileno].hFile; + if (_fd < 0 || _fd >= maxfno) { + __set_errno(EBADF); + return -1; + } + return __pioinfo[_fd].mode; + } -int __fileno_dup2( int handle1, int handle2 ) +int __fileno_close(int _fd) +{ + if (_fd < 0 || _fd >= maxfno) { + __set_errno(EBADF); + return -1; + } + __pioinfo[_fd].fd = -1; + __pioinfo[_fd].hFile = (HANDLE)-1; + return 0; +} + +int _open_osfhandle(void* osfhandle, int flags) +{ + return __fileno_alloc((HANDLE)osfhandle, flags); +} + +void* _get_osfhandle( int fileno ) +{ + return filehnd(fileno); +} + +int __fileno_dup2(int handle1, int handle2) { HANDLE hProcess; BOOL result; - if (handle1 >= maxfno || handle1 < 0 || handle2 >= maxfno || handle2 < 0 ) - { + if (handle1 >= maxfno || handle1 < 0 || handle2 >= maxfno || handle2 < 0) { __set_errno(EBADF); return -1; } - if (fileno_modes[handle1].fd == -1) - { + if (__pioinfo[handle1].fd == -1) { __set_errno(EBADF); return -1; } if (handle1 == handle2) return handle1; - if (fileno_modes[handle2].fd != -1) - { + if (__pioinfo[handle2].fd != -1) { _close(handle2); } hProcess = GetCurrentProcess(); result = DuplicateHandle(hProcess, - fileno_modes[handle1].hFile, - hProcess, - &fileno_modes[handle2].hFile, - 0, - TRUE, - DUPLICATE_SAME_ACCESS); - if (result) - { - fileno_modes[handle2].fd = handle2; - fileno_modes[handle2].mode = fileno_modes[handle1].mode; - switch (handle2) - { - case 0: - SetStdHandle(STD_INPUT_HANDLE, fileno_modes[handle2].hFile); - break; - case 1: - SetStdHandle(STD_OUTPUT_HANDLE, fileno_modes[handle2].hFile); - break; - case 2: - SetStdHandle(STD_ERROR_HANDLE, fileno_modes[handle2].hFile); - break; - case 3: - SetStdHandle(STD_AUX_HANDLE, fileno_modes[handle2].hFile); - break; - case 4: - SetStdHandle(STD_AUX_HANDLE, fileno_modes[handle2].hFile); - break; + __pioinfo[handle1].hFile, + hProcess, + &__pioinfo[handle2].hFile, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + if (result) { + __pioinfo[handle2].fd = handle2; + __pioinfo[handle2].mode = __pioinfo[handle1].mode; + switch (handle2) { + case 0: + SetStdHandle(STD_INPUT_HANDLE, __pioinfo[handle2].hFile); + break; + case 1: + SetStdHandle(STD_OUTPUT_HANDLE, __pioinfo[handle2].hFile); + break; + case 2: + SetStdHandle(STD_ERROR_HANDLE, __pioinfo[handle2].hFile); + break; + case 3: + SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile); + break; + case 4: + SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile); + break; } return handle1; - } - else - { - __set_errno(EMFILE); // Is this the correct error no.? + } else { + __set_errno(EMFILE); // Is this the correct error no.? return -1; } } -int __fileno_setmode(int _fd, int _newmode) -{ - int m; - if ( _fd < 0 || _fd >= maxfno ) - { - __set_errno(EBADF); - return -1; - } - - m = fileno_modes[_fd].mode; - fileno_modes[_fd].mode = _newmode; - return m; -} - -int __fileno_getmode(int _fd) -{ - if ( _fd < 0 || _fd >= maxfno ) - { - __set_errno(EBADF); - return -1; - } - return fileno_modes[_fd].mode; - -} - -int __fileno_close(int _fd) -{ - if ( _fd < 0 || _fd >= maxfno ) - { - __set_errno(EBADF); - return -1; - } - - fileno_modes[_fd].fd = -1; - fileno_modes[_fd].hFile = (HANDLE)-1; - return 0; -} - -int _open_osfhandle (void *osfhandle, int flags ) -{ - return __fileno_alloc((HANDLE)osfhandle, flags); -} -void *_get_osfhandle( int fileno ) -{ - return filehnd(fileno); -} +void* malloc(size_t sizeObject); -void __fileno_init(void) +BOOL __fileno_init(void) { ULONG count = 0, i; - HANDLE *pFile; + HANDLE* pFile; char* pmode; STARTUPINFO StInfo; GetStartupInfoA(&StInfo); - - if (StInfo.lpReserved2 && StInfo.cbReserved2 >= sizeof(ULONG)) - { + if (StInfo.lpReserved2 && StInfo.cbReserved2 >= sizeof(ULONG)) { count = *(ULONG*)StInfo.lpReserved2; /* if (sizeof(ULONG) + count * (sizeof(HANDLE) + sizeof(char)) != StInfo.cbReserved2) @@ -437,54 +365,56 @@ void __fileno_init(void) while(count >= maxfno) maxfno += 255; - fileno_modes = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno); - memset(fileno_modes, -1, sizeof(fileno_modes_type) * maxfno); - - if (count) { +#ifdef _OLD_BUILD_ + // why was this here ???? - robd. + int result; + result = malloc(50); +#endif + } + //__pioinfo = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno); + __pioinfo = malloc(sizeof(fileno_modes_type) * maxfno); + if (__pioinfo == NULL) { + return FALSE; + } + memset(__pioinfo, -1, sizeof(fileno_modes_type) * maxfno); + if (count) { pFile = (HANDLE*)(StInfo.lpReserved2 + sizeof(ULONG) + count * sizeof(char)); pmode = (char*)(StInfo.lpReserved2 + sizeof(ULONG)); - for (i = 0; i < count; i++) - { - if (*pFile != INVALID_HANDLE_VALUE) - { - fileno_modes[i].fd = i; - fileno_modes[i].mode = ((*pmode << 8) & (_O_TEXT|_O_BINARY)) | (*pmode & _O_ACCMODE); - fileno_modes[i].hFile = *pFile; - } + for (i = 0; i < count; i++) { + if (*pFile != INVALID_HANDLE_VALUE) { + __pioinfo[i].fd = i; + __pioinfo[i].mode = ((*pmode << 8) & (_O_TEXT|_O_BINARY)) | (*pmode & _O_ACCMODE); + __pioinfo[i].hFile = *pFile; + } pFile++; pmode++; } } - - if (fileno_modes[0].fd == -1) - { - fileno_modes[0].fd = 0; - fileno_modes[0].hFile = GetStdHandle(STD_INPUT_HANDLE); - fileno_modes[0].mode = _O_RDONLY|_O_TEXT; + if (__pioinfo[0].fd == -1) { + __pioinfo[0].fd = 0; + __pioinfo[0].hFile = GetStdHandle(STD_INPUT_HANDLE); + __pioinfo[0].mode = _O_RDONLY|_O_TEXT; } - if (fileno_modes[1].fd == -1) - { - fileno_modes[1].fd = 1; - fileno_modes[1].hFile = GetStdHandle(STD_OUTPUT_HANDLE); - fileno_modes[1].mode = _O_WRONLY|_O_TEXT; + if (__pioinfo[1].fd == -1) { + __pioinfo[1].fd = 1; + __pioinfo[1].hFile = GetStdHandle(STD_OUTPUT_HANDLE); + __pioinfo[1].mode = _O_WRONLY|_O_TEXT; } - if (fileno_modes[2].fd == -1) - { - fileno_modes[2].fd = 2; - fileno_modes[2].hFile = GetStdHandle(STD_ERROR_HANDLE); - fileno_modes[2].mode = _O_WRONLY|_O_TEXT; + if (__pioinfo[2].fd == -1) { + __pioinfo[2].fd = 2; + __pioinfo[2].hFile = GetStdHandle(STD_ERROR_HANDLE); + __pioinfo[2].mode = _O_WRONLY|_O_TEXT; } - if (fileno_modes[3].fd == -1) - { - fileno_modes[3].fd = 3; - fileno_modes[3].hFile = GetStdHandle(STD_AUX_HANDLE); - fileno_modes[3].mode = _O_WRONLY|_O_TEXT; + if (__pioinfo[3].fd == -1) { + __pioinfo[3].fd = 3; + __pioinfo[3].hFile = GetStdHandle(STD_AUX_HANDLE); + __pioinfo[3].mode = _O_WRONLY|_O_TEXT; } - if (fileno_modes[4].fd == -1) - { - fileno_modes[4].fd = 4; - fileno_modes[4].hFile = GetStdHandle(STD_PRINTER_HANDLE); - fileno_modes[4].mode = _O_WRONLY|_O_TEXT; + if (__pioinfo[4].fd == -1) { + __pioinfo[4].fd = 4; + __pioinfo[4].hFile = GetStdHandle(STD_PRINTER_HANDLE); + __pioinfo[4].mode = _O_WRONLY|_O_TEXT; } -} + return TRUE; +} diff --git a/lib/msvcrt/io/pipe.c b/lib/msvcrt/io/pipe.c index 5d4d7fb..b7908a9 100644 --- a/lib/msvcrt/io/pipe.c +++ b/lib/msvcrt/io/pipe.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/io/pipe.c + * FILE: lib/msvcrt/io/pipe.c * PURPOSE: Creates a pipe * PROGRAMER: DJ Delorie * UPDATE HISTORY: diff --git a/lib/msvcrt/io/read.c b/lib/msvcrt/io/read.c index f55875f..4dcdd72 100644 --- a/lib/msvcrt/io/read.c +++ b/lib/msvcrt/io/read.c @@ -49,25 +49,49 @@ size_t _read(int _fd, void *_buf, size_t _nbyte) /* text mode */ if (_rbyte && istext) { + int found_cr = 0; int cr = 0; DWORD count = _rbyte; /* repeat for all bytes in the buffer */ for(; count; bufp++, count--) { +#if 1 + /* carriage return */ + if (*bufp == '\r') { + found_cr = 1; + if (cr != 0) { + *(bufp - cr) = *bufp; + } + continue; + } + if (found_cr) { + found_cr = 0; + if (*bufp == '\n') { + cr++; + *(bufp - cr) = *bufp; + } else { + } + } else if (cr != 0) { + *(bufp - cr) = *bufp; + } +#else /* carriage return */ - if (*bufp == '\r') + if (*bufp == '\r') { cr++; + } /* shift characters back, to ignore carriage returns */ - else if (cr != 0) + else if (cr != 0) { *(bufp - cr) = *bufp; - + } +#endif + } + if (found_cr) { + cr++; } - /* ignore the carriage returns */ _rbyte -= cr; } - DPRINT("%d\n", _rbyte); return _rbyte; } diff --git a/lib/msvcrt/io/setmode.c b/lib/msvcrt/io/setmode.c index ca26cec..864f7cb 100644 --- a/lib/msvcrt/io/setmode.c +++ b/lib/msvcrt/io/setmode.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/io/setmode.c + * FILE: lib/msvcrt/io/setmode.c * PURPOSE: Sets the file translation mode * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -19,6 +19,6 @@ int _setmode(int _fd, int _newmode) { - DPRINT("_setmod(fd %d, newmode %x)\n", _fd, _newmode); - return __fileno_setmode(_fd, _newmode); + DPRINT("_setmod(fd %d, newmode %x)\n", _fd, _newmode); + return __fileno_setmode(_fd, _newmode); } diff --git a/lib/msvcrt/io/sopen.c b/lib/msvcrt/io/sopen.c index e98fa85..7265f70 100644 --- a/lib/msvcrt/io/sopen.c +++ b/lib/msvcrt/io/sopen.c @@ -5,8 +5,3 @@ int _sopen(char *path, int access, int shflag, int mode) { return _open((path), (access)|(shflag), (mode)); } - -int _wsopen(wchar_t *path, int access, int shflag, int mode) -{ - return _wopen((path), (access)|(shflag), (mode)); -} diff --git a/lib/msvcrt/io/tell.c b/lib/msvcrt/io/tell.c index 3d7d95b..0e10186 100644 --- a/lib/msvcrt/io/tell.c +++ b/lib/msvcrt/io/tell.c @@ -5,10 +5,5 @@ off_t _tell(int _file) { - return _lseek(_file, 0, SEEK_CUR); -} - -__int64 _telli64(int _file) -{ - return _lseeki64(_file, 0, SEEK_CUR); + return _lseek(_file, 0, SEEK_CUR); } diff --git a/lib/msvcrt/io/telli64.c b/lib/msvcrt/io/telli64.c new file mode 100644 index 0000000..5b03d88 --- /dev/null +++ b/lib/msvcrt/io/telli64.c @@ -0,0 +1,8 @@ +#include +#include + + +__int64 _telli64(int _file) +{ + return _lseeki64(_file, 0, SEEK_CUR); +} diff --git a/lib/msvcrt/io/umask.c b/lib/msvcrt/io/umask.c index 4146b81..c6a6207 100644 --- a/lib/msvcrt/io/umask.c +++ b/lib/msvcrt/io/umask.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include unsigned _unMode_dll = 022; diff --git a/lib/msvcrt/io/unlink.c b/lib/msvcrt/io/unlink.c index 9165aac..54604bc 100644 --- a/lib/msvcrt/io/unlink.c +++ b/lib/msvcrt/io/unlink.c @@ -14,20 +14,12 @@ #include -int _unlink(const char *filename) +int _unlink(const char* filename) { - int result = 0; - DPRINT("_unlink('%s')\n", filename); - if (!DeleteFileA(filename)) - result = -1; - DPRINT("%d\n", result); - return result; -} - -int _wunlink(const wchar_t *filename) -{ - DPRINT("_wunlink('%S')\n", filename); - if (!DeleteFileW(filename)) - return -1; - return 0; + int result = 0; + DPRINT("_unlink('%s')\n", filename); + if (!DeleteFileA(filename)) + result = -1; + DPRINT("%d\n", result); + return result; } diff --git a/lib/msvcrt/io/utime.c b/lib/msvcrt/io/utime.c index 7a5b037..5ec84eb 100644 --- a/lib/msvcrt/io/utime.c +++ b/lib/msvcrt/io/utime.c @@ -4,36 +4,19 @@ #include #include -int _utime(const char* filename, struct _utimbuf* buf) -{ - int fn; - int ret; - - fn = _open(filename, _O_RDWR); - if (fn == -1) - { - __set_errno(EBADF); - return -1; - } - ret = _futime(fn,buf); - if (_close(fn) < 0) - return -1; - return ret; -} -int _wutime(const wchar_t* filename, struct _utimbuf* buf) +int _utime(const char* filename, struct _utimbuf* buf) { - int fn; - int ret; + int fn; + int ret; - fn = _wopen(filename, _O_RDWR); - if (fn == -1) - { - __set_errno(EBADF); - return -1; + fn = _open(filename, _O_RDWR); + if (fn == -1) { + __set_errno(EBADF); + return -1; } - ret = _futime(fn,buf); - if (_close(fn) < 0) - return -1; - return ret; + ret = _futime(fn, buf); + if (_close(fn) < 0) + return -1; + return ret; } diff --git a/lib/msvcrt/io/waccess.c b/lib/msvcrt/io/waccess.c new file mode 100644 index 0000000..24932fc --- /dev/null +++ b/lib/msvcrt/io/waccess.c @@ -0,0 +1,29 @@ +#include +#include +#include +#define NDEBUG +#include + + +int _waccess(const wchar_t *_path, int _amode) +{ + DWORD Attributes = GetFileAttributesW(_path); + + if (Attributes == -1) { + __set_errno(ENOENT); + return -1; + } + if ((_amode & W_OK) == W_OK) { + if ((Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { + __set_errno(EACCES); + return -1; + } + } + if ((_amode & D_OK) == D_OK) { + if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { + __set_errno(EACCES); + return -1; + } + } + return 0; +} diff --git a/lib/msvcrt/io/wchmod.c b/lib/msvcrt/io/wchmod.c new file mode 100644 index 0000000..e10d632 --- /dev/null +++ b/lib/msvcrt/io/wchmod.c @@ -0,0 +1,33 @@ +#include +#include + +#define NDEBUG +#include + +#define mode_t int + + +int _wchmod(const wchar_t* filename, mode_t mode) +{ + DWORD FileAttributes = 0; + DPRINT("_wchmod('%S', %x)\n", filename, mode); + + FileAttributes = GetFileAttributesW(filename); + if ( FileAttributes == -1 ) + return -1; + + if ( mode == 0 ) + return -1; + + if ((mode & _S_IREAD) == _S_IREAD && (mode & _S_IWRITE) != _S_IWRITE) + FileAttributes &= FILE_ATTRIBUTE_READONLY; + else if (((mode & _S_IREAD) != _S_IREAD) && ((mode & _S_IWRITE) == _S_IWRITE)) + FileAttributes &= FILE_ATTRIBUTE_NORMAL; + else + FileAttributes &= FILE_ATTRIBUTE_NORMAL; + + if (SetFileAttributesW(filename, FileAttributes) == FALSE) + return -1; + + return 1; +} diff --git a/lib/msvcrt/io/wcreate.c b/lib/msvcrt/io/wcreate.c new file mode 100644 index 0000000..6234d81 --- /dev/null +++ b/lib/msvcrt/io/wcreate.c @@ -0,0 +1,12 @@ +#include +#include + +#define NDEBUG +#include + + +int _wcreat(const wchar_t* filename, int mode) +{ + DPRINT("_wcreat('%S', mode %x)\n", filename, mode); + return _wopen(filename,_O_CREAT|_O_TRUNC,mode); +} diff --git a/lib/msvcrt/io/wfind.c b/lib/msvcrt/io/wfind.c new file mode 100644 index 0000000..221a33e --- /dev/null +++ b/lib/msvcrt/io/wfind.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include + + +int _wfindfirst(const wchar_t* _name, struct _wfinddata_t* result) +{ + WIN32_FIND_DATAW FindFileData; + wchar_t dir[MAX_PATH]; + long hFindFile; + int len = 0; + + if ( _name == NULL || _name[0] == 0 ) { + len = GetCurrentDirectoryW(MAX_PATH-4, dir); + if (dir[len-1] != L'\\') { + dir[len] = L'\\'; + dir[len+1] = 0; + } + wcscat(dir, L"*.*"); + } else { + wcscpy(dir, _name); + } + + hFindFile = (long)FindFirstFileW(dir, &FindFileData); + if (hFindFile == -1) { + memset(result,0,sizeof(struct _wfinddata_t)); + return -1; + } + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); + + // if no wildcard the find file handle can be closed right away + // a return value of 0 can flag this. + if (!wcschr(dir, L'*') && !wcschr(dir, L'?')) { + _findclose(hFindFile); + return 0; + } + + return hFindFile; +} + +int _findfirsti64(const char *_name, struct _finddatai64_t *result) +{ + WIN32_FIND_DATAA FindFileData; + char dir[MAX_PATH]; + long hFindFile; + int len = 0; + + if ( _name == NULL || _name[0] == 0 ) + { + len = GetCurrentDirectoryA(MAX_PATH-4,dir); + if (dir[len-1] != '\\') + { + dir[len] = '\\'; + dir[len+1] = 0; + } + strcat(dir, "*.*"); + } + else + strcpy(dir, _name); + + hFindFile = (long)FindFirstFileA(dir, &FindFileData); + if (hFindFile == -1) + { + memset(result,0,sizeof(struct _finddatai64_t)); + return -1; + } + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = + (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName,MAX_PATH); + + // if no wildcard the find file handle can be closed right away + // a return value of 0 can flag this. + + if (!strchr(dir,'*') && !strchr(dir,'?')) { + _findclose(hFindFile); + return 0; + } + return hFindFile; +} + +int _findnexti64(int handle, struct _finddatai64_t *result) +{ + WIN32_FIND_DATAA FindFileData; + + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; + + if (!FindNextFileA((void *)handle, &FindFileData)) + return -1; + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = + (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; + strncpy(result->name,FindFileData.cFileName,MAX_PATH); + + return 0; +} + +int _wfindfirsti64(const wchar_t *_name, struct _wfinddatai64_t *result) +{ + WIN32_FIND_DATAW FindFileData; + wchar_t dir[MAX_PATH]; + long hFindFile; + int len = 0; + + if (_name == NULL || _name[0] == 0) + { + len = GetCurrentDirectoryW(MAX_PATH-4,dir); + if (dir[len-1] != L'\\') + { + dir[len] = L'\\'; + dir[len+1] = 0; + } + wcscat(dir, L"*.*"); + } + else + wcscpy(dir, _name); + + hFindFile = (long)FindFirstFileW(dir, &FindFileData); + if (hFindFile == -1) + { + memset(result,0,sizeof(struct _wfinddatai64_t)); + return -1; + } + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = + (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; + wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); + + // if no wildcard the find file handle can be closed right away + // a return value of 0 can flag this. + + if (!wcschr(dir,L'*') && !wcschr(dir,L'?')) + { + _findclose(hFindFile); + return 0; + } + + return hFindFile; +} + +int _wfindnext(int handle, struct _wfinddata_t *result) +{ + WIN32_FIND_DATAW FindFileData; + + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; + + if (!FindNextFileW((void *)handle, &FindFileData)) + return -1; + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = FindFileData.nFileSizeLow; + wcsncpy(result->name,FindFileData.cFileName, MAX_PATH); + + return 0; +} + +int _wfindnexti64(int handle, struct _wfinddatai64_t *result) +{ + WIN32_FIND_DATAW FindFileData; + + // check no wildcards or invalid handle + if (handle == 0 || handle == -1) + return 0; + + if (!FindNextFileW((void *)handle, &FindFileData)) + return -1; + + result->attrib = FindFileData.dwFileAttributes; + result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL); + result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL); + result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL); + result->size = + (((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow; + wcsncpy(result->name,FindFileData.cFileName,MAX_PATH); + + return 0; +} diff --git a/lib/msvcrt/io/wmktemp.c b/lib/msvcrt/io/wmktemp.c new file mode 100644 index 0000000..d52d431 --- /dev/null +++ b/lib/msvcrt/io/wmktemp.c @@ -0,0 +1,75 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/io/mktemp.c + * PURPOSE: Makes a temp file based on a template + * PROGRAMER: DJ Delorie + Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Appropriated for the Reactos Kernel + */ + +/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + +#include +#include +#include + +#define NDEBUG +#include + + +wchar_t* _wmktemp (wchar_t *_template) +{ + static int count = 0; + wchar_t *cp, *dp; + int i, len, xcount, loopcnt; + + DPRINT("_wmktemp('%S')\n", _template); + len = wcslen (_template); + cp = _template + len; + + xcount = 0; + while (xcount < 6 && cp > _template && cp[-1] == L'X') + xcount++, cp--; + + if (xcount) { + dp = cp; + while (dp > _template && dp[-1] != L'/' && dp[-1] != L'\\' && dp[-1] != L':') + dp--; + + /* Keep the first characters of the template, but turn the rest into + Xs. */ + while (cp > dp + 8 - xcount) { + *--cp = L'X'; + xcount = (xcount >= 6) ? 6 : 1 + xcount; + } + + /* If dots occur too early -- squash them. */ + while (dp < cp) { + if (*dp == L'.') *dp = L'a'; + dp++; + } + + /* Try to add ".tmp" to the filename. Truncate unused Xs. */ + if (cp + xcount + 3 < _template + len) + wcscpy (cp + xcount, L".tmp"); + else + cp[xcount] = 0; + + /* This loop can run up to 2<<(5*6) times, or about 10^9 times. */ + for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) { + int c = count++; + for (i = 0; i < xcount; i++, c >>= 5) + cp[i] = L"abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f]; + if (_waccess(_template,0) == -1) + return _template; + } + } + + /* Failure: truncate the template and return NULL. */ + *_template = 0; + return 0; +} diff --git a/lib/msvcrt/io/wopen.c b/lib/msvcrt/io/wopen.c new file mode 100644 index 0000000..c98c2eb --- /dev/null +++ b/lib/msvcrt/io/wopen.c @@ -0,0 +1,140 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/io/open.c + * PURPOSE: Opens a file and translates handles to fileno + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ + +// rember to interlock the allocation of fileno when making this thread safe +// possibly store extra information at the handle + +#include +#if !defined(NDEBUG) && defined(DBG) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + + +int _wopen(const wchar_t* _path, int _oflag, ...) +{ +#if !defined(NDEBUG) && defined(DBG) + va_list arg; + int pmode; +#endif + HANDLE hFile; + DWORD dwDesiredAccess = 0; + DWORD dwShareMode = 0; + DWORD dwCreationDistribution = 0; + DWORD dwFlagsAndAttributes = 0; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + +#if !defined(NDEBUG) && defined(DBG) + va_start(arg, _oflag); + pmode = va_arg(arg, int); +#endif + +// DPRINT("_wopen('%S', %x, (%x))\n", _path, _oflag, pmode); + + if ((_oflag & S_IREAD) == S_IREAD) + dwShareMode = FILE_SHARE_READ; + else if ( ( _oflag & S_IWRITE) == S_IWRITE) { + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + + /* + * + * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) + * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) + * + * _O_APPEND Moves file pointer to end of file before every write operation. + */ +#if 0 + if ((_oflag & _O_RDWR) == _O_RDWR) + dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA | + FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | + FILE_WRITE_ATTRIBUTES; + else if ((_oflag & O_RDONLY) == O_RDONLY) + dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | + FILE_WRITE_ATTRIBUTES; + else if ((_oflag & _O_WRONLY) == _O_WRONLY) + dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA | + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES; +#else + if ((_oflag & _O_WRONLY) == _O_WRONLY) + dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA | + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES; + else if ((_oflag & _O_RDWR) == _O_RDWR) + dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA | + FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | + FILE_WRITE_ATTRIBUTES; + else //if ((_oflag & O_RDONLY) == O_RDONLY) + dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | + FILE_WRITE_ATTRIBUTES; +#endif + + if ((_oflag & S_IREAD) == S_IREAD) + dwShareMode |= FILE_SHARE_READ; + + if ((_oflag & S_IWRITE) == S_IWRITE) + dwShareMode |= FILE_SHARE_WRITE; + + if ((_oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) + dwCreationDistribution |= CREATE_NEW; + + else if ((_oflag & O_TRUNC) == O_TRUNC) { + if ((_oflag & O_CREAT) == O_CREAT) + dwCreationDistribution |= CREATE_ALWAYS; + else if ((_oflag & O_RDONLY) != O_RDONLY) + dwCreationDistribution |= TRUNCATE_EXISTING; + } + else if ((_oflag & _O_APPEND) == _O_APPEND) + dwCreationDistribution |= OPEN_EXISTING; + else if ((_oflag & _O_CREAT) == _O_CREAT) + dwCreationDistribution |= OPEN_ALWAYS; + else + dwCreationDistribution |= OPEN_EXISTING; + + if ((_oflag & _O_RANDOM) == _O_RANDOM) + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; + if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL) + dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; + + if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) + dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; + + if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) + dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; + + if (_oflag & _O_NOINHERIT) + sa.bInheritHandle = FALSE; + + hFile = CreateFileW(_path, + dwDesiredAccess, + dwShareMode, + &sa, + dwCreationDistribution, + dwFlagsAndAttributes, + NULL); + if (hFile == (HANDLE)-1) + return -1; + return __fileno_alloc(hFile,_oflag); +} + +int _wsopen(wchar_t* path, int access, int shflag, int mode) +{ + return _wopen((path), (access)|(shflag), (mode)); +} diff --git a/lib/msvcrt/io/write.c b/lib/msvcrt/io/write.c index 299d304..609486c 100644 --- a/lib/msvcrt/io/write.c +++ b/lib/msvcrt/io/write.c @@ -9,79 +9,88 @@ */ #include #include +#include #include #define NDEBUG #include -#define BUFSIZE 4096 - -size_t _write(int _fd, const void *_buf, size_t _nbyte) +#define BUFSIZE 4096 +/* +void ReportLastError(void) +{ + DWORD error = GetLastError(); + if (error != ERROR_SUCCESS) { + PTSTR msg; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) { + printf("ReportLastError() %d - %s\n", error, msg); + } else { + printf("ReportLastError() %d - unknown error\n", error); + } + LocalFree(msg); + } +} + */ +size_t _write(int _fd, const void* _buf, size_t _nbyte) { char *tmp, *in, *out; - int count, result; + int result; + unsigned int count; DWORD wbyte; DPRINT("_write(fd %d, buf %x, nbyte %d)\n", _fd, _buf, _nbyte); - if (__fileno_getmode(_fd) & O_TEXT) - { + if (__fileno_getmode(_fd) & O_TEXT) { result = _nbyte; tmp = (char*) malloc(BUFSIZE); - if (tmp == NULL) - { - return -1; + if (tmp == NULL) { + return -1; } count = BUFSIZE; out = tmp; in = (char*) _buf; - while (_nbyte--) - { - if (*in == 0x0a) - { - *out++ = 0x0d; - count--; - if (count == 0) - { - if (!WriteFile(_get_osfhandle(_fd), tmp, BUFSIZE, &wbyte, NULL)) - { - result = -1; - break; - } - if (wbyte < BUFSIZE) - { - result = in - (char*)_buf; - break; - } - count = BUFSIZE; - out = tmp; - } - } - *out++ = *in++; - count--; - if (count == 0 || _nbyte == 0) - { - if (!WriteFile(_get_osfhandle(_fd), tmp, BUFSIZE - count, &wbyte, NULL)) - { - result = -1; - break; - } - if (wbyte < BUFSIZE - count) - { - result = in - (char*)_buf; - break; - } - count = BUFSIZE; - out = tmp; - } + while (_nbyte--) { + if (*in == 0x0a) { + *out++ = 0x0d; + count--; + if (count == 0) { + if (!WriteFile(_get_osfhandle(_fd), tmp, BUFSIZE, &wbyte, NULL)) { + //ReportLastError(); + result = -1; + break; + } + if (wbyte < BUFSIZE) { + result = in - (char*)_buf; + break; + } + count = BUFSIZE; + out = tmp; + } + } + *out++ = *in++; + count--; + if (count == 0 || _nbyte == 0) { + int tmp_len_debug = strlen(tmp); + if (!WriteFile(_get_osfhandle(_fd), tmp, BUFSIZE - count, &wbyte, NULL)) { + //ReportLastError(); + result = -1; + tmp_len_debug = 0; + break; + } + if (wbyte < (BUFSIZE - count)) { + result = in - (char*)_buf; + break; + } + count = BUFSIZE; + out = tmp; + } } free(tmp); return result; - } - else - { - if(!WriteFile(_get_osfhandle(_fd), _buf, _nbyte, &wbyte, NULL)) - { - return -1; + } else { + if(!WriteFile(_get_osfhandle(_fd), _buf, _nbyte, &wbyte, NULL)) { + //ReportLastError(); + return -1; } return wbyte; } diff --git a/lib/msvcrt/io/wunlink.c b/lib/msvcrt/io/wunlink.c new file mode 100644 index 0000000..c7d2989 --- /dev/null +++ b/lib/msvcrt/io/wunlink.c @@ -0,0 +1,23 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/io/unlink.c + * PURPOSE: Deletes a file + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include + +#define NDEBUG +#include + + +int _wunlink(const wchar_t* filename) +{ + DPRINT("_wunlink('%S')\n", filename); + if (!DeleteFileW(filename)) + return -1; + return 0; +} diff --git a/lib/msvcrt/io/wutime.c b/lib/msvcrt/io/wutime.c new file mode 100644 index 0000000..be87e8b --- /dev/null +++ b/lib/msvcrt/io/wutime.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include +#include + + +int _wutime(const wchar_t* filename, struct _utimbuf* buf) +{ + int fn; + int ret; + + fn = _wopen(filename, _O_RDWR); + if (fn == -1) { + __set_errno(EBADF); + return -1; + } + ret = _futime(fn, buf); + if (_close(fn) < 0) + return -1; + return ret; +} diff --git a/lib/msvcrt/math/acos.c b/lib/msvcrt/math/acos.c index 9bde5e9..23376a6 100644 --- a/lib/msvcrt/math/acos.c +++ b/lib/msvcrt/math/acos.c @@ -20,7 +20,8 @@ #include -double acos (double __x) + +double acos(double __x) { - return atan2 (sqrt (1.0 - __x * __x), __x); + return atan2(sqrt(1.0 - __x * __x), __x); } diff --git a/lib/msvcrt/math/asin.c b/lib/msvcrt/math/asin.c index 5f912ba..fa57df2 100644 --- a/lib/msvcrt/math/asin.c +++ b/lib/msvcrt/math/asin.c @@ -20,7 +20,8 @@ #include -double asin (double __x) + +double asin(double __x) { - return atan2 (__x, sqrt (1.0 - __x * __x)); + return atan2(__x, sqrt(1.0 - __x * __x)); } diff --git a/lib/msvcrt/math/atan.c b/lib/msvcrt/math/atan.c index d1df503..af0e219 100644 --- a/lib/msvcrt/math/atan.c +++ b/lib/msvcrt/math/atan.c @@ -25,10 +25,13 @@ double atan (double __x); double atan (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fld1\n\t" "fpatan" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_atan(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/atan2.c b/lib/msvcrt/math/atan2.c index f430c27..28079d0 100644 --- a/lib/msvcrt/math/atan2.c +++ b/lib/msvcrt/math/atan2.c @@ -6,10 +6,13 @@ double atan2 (double __y, double __x); double atan2 (double __y, double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fpatan\n\t" "fld %%st(0)" : "=t" (__value) : "0" (__x), "u" (__y)); - +#else + __value = linkme_atan2(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/ceil.c b/lib/msvcrt/math/ceil.c index 34a1019..43812d7 100644 --- a/lib/msvcrt/math/ceil.c +++ b/lib/msvcrt/math/ceil.c @@ -3,6 +3,7 @@ double ceil (double __x) { register double __value; +#ifdef __GNUC__ __volatile unsigned short int __cw, __cwtmp; __asm __volatile ("fnstcw %0" : "=m" (__cw)); @@ -10,6 +11,8 @@ double ceil (double __x) __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); __asm __volatile ("fldcw %0" : : "m" (__cw)); - +#else + __value = linkme_ceil(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/cos.c b/lib/msvcrt/math/cos.c index 1753f59..981380e 100644 --- a/lib/msvcrt/math/cos.c +++ b/lib/msvcrt/math/cos.c @@ -5,9 +5,12 @@ double cos (double __x); double cos (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fcos" : "=t" (__value): "0" (__x)); - +#else + __value = linkme_cos(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/cosh.c b/lib/msvcrt/math/cosh.c index 1f89a0e..10fadd6 100644 --- a/lib/msvcrt/math/cosh.c +++ b/lib/msvcrt/math/cosh.c @@ -1,8 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include + double cosh(double x) { - const double ebig = exp(fabs(x)); - return (ebig + 1.0/ebig) / 2.0; + const double ebig = exp(fabs(x)); + return (ebig + 1.0/ebig) / 2.0; } diff --git a/lib/msvcrt/math/exp.c b/lib/msvcrt/math/exp.c index fb074fb..2707cf8 100644 --- a/lib/msvcrt/math/exp.c +++ b/lib/msvcrt/math/exp.c @@ -24,6 +24,7 @@ double exp (double __x); double exp (double __x) { +#ifdef __GNUC__ register double __value, __exponent; __asm __volatile__ ("fldl2e # e^x = 2^(x * log2(e))\n\t" @@ -40,4 +41,7 @@ double exp (double __x) : "=t" (__value) : "0" (__value), "u" (__exponent)); return __value; +#else + return linkme_exp(__x); +#endif /*__GNUC__*/ } diff --git a/lib/msvcrt/math/fabs.c b/lib/msvcrt/math/fabs.c index 2e1587a..5db505a 100644 --- a/lib/msvcrt/math/fabs.c +++ b/lib/msvcrt/math/fabs.c @@ -25,9 +25,12 @@ double fabs (double __x); double fabs (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fabs" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_fabs(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/floor.c b/lib/msvcrt/math/floor.c index 3e56781..4635ad8 100644 --- a/lib/msvcrt/math/floor.c +++ b/lib/msvcrt/math/floor.c @@ -25,6 +25,7 @@ double floor (double __x); double floor (double __x) { register double __value; +#ifdef __GNUC__ __volatile unsigned short int __cw, __cwtmp; __asm __volatile ("fnstcw %0" : "=m" (__cw)); @@ -32,6 +33,8 @@ double floor (double __x) __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); __asm __volatile ("fldcw %0" : : "m" (__cw)); - +#else + __value = linkme_floor(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/fmod.c b/lib/msvcrt/math/fmod.c index 823fc00..263d687 100644 --- a/lib/msvcrt/math/fmod.c +++ b/lib/msvcrt/math/fmod.c @@ -25,12 +25,15 @@ double fmod (double __x, double __y); double fmod (double __x, double __y) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("1: fprem\n\t" "fstsw %%ax\n\t" "sahf\n\t" "jp 1b" : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); - +#else + __value = linkme_fmod(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/frexp.c b/lib/msvcrt/math/frexp.c index 27de8a3..b85cd98 100644 --- a/lib/msvcrt/math/frexp.c +++ b/lib/msvcrt/math/frexp.c @@ -5,14 +5,15 @@ double frexp(double __x, int *exptr) { - double_t *x = (double_t *)&__x; - - if (exptr != NULL) - *exptr = x->exponent - 0x3FE; - - x->exponent = 0x3FE; - - return __x; + double_t *x = (double_t *)&__x; + + if ( exptr != NULL ) + *exptr = x->exponent - 0x3FE; + + + x->exponent = 0x3FE; + + return __x; } diff --git a/lib/msvcrt/math/ftol.c b/lib/msvcrt/math/ftol.c index dfa3346..1753090 100644 --- a/lib/msvcrt/math/ftol.c +++ b/lib/msvcrt/math/ftol.c @@ -2,5 +2,5 @@ long _ftol(double fl) { - return (long)fl; + return (long)fl; } diff --git a/lib/msvcrt/math/hypot.c b/lib/msvcrt/math/hypot.c index 9ca52e3..aded378 100644 --- a/lib/msvcrt/math/hypot.c +++ b/lib/msvcrt/math/hypot.c @@ -78,7 +78,7 @@ _hypot(double x, double y) #ifdef TEST -#include +#include int main(void) diff --git a/lib/msvcrt/math/j0_y0.c b/lib/msvcrt/math/j0_y0.c index db89a92..83035ee 100644 --- a/lib/msvcrt/math/j0_y0.c +++ b/lib/msvcrt/math/j0_y0.c @@ -1,12 +1,12 @@ #include -double _j0(double x) + +double _j0(double x) { - return x; + return x; } -double _y0(double x) +double _y0(double x) { - return x; + return x; } - diff --git a/lib/msvcrt/math/j1_y1.c b/lib/msvcrt/math/j1_y1.c index fa0f618..55d6bd6 100644 --- a/lib/msvcrt/math/j1_y1.c +++ b/lib/msvcrt/math/j1_y1.c @@ -1,11 +1,12 @@ #include -double _j1(double x) + +double _j1(double x) { - return x; + return x; } -double _y1(double x) +double _y1(double x) { - return x; + return x; } diff --git a/lib/msvcrt/math/jn_yn.c b/lib/msvcrt/math/jn_yn.c index b641a81..8a3c833 100644 --- a/lib/msvcrt/math/jn_yn.c +++ b/lib/msvcrt/math/jn_yn.c @@ -1,4 +1,5 @@ -#include +#include + double _jn(int n, double x) { diff --git a/lib/msvcrt/math/ldexp.c b/lib/msvcrt/math/ldexp.c index 65e9e25..9c60344 100644 --- a/lib/msvcrt/math/ldexp.c +++ b/lib/msvcrt/math/ldexp.c @@ -25,9 +25,12 @@ double ldexp (double __x, int __y); double ldexp (double __x, int __y) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fscale" : "=t" (__value) : "0" (__x), "u" ((double) __y)); - +#else + __value = linkme_ldexp(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/log.c b/lib/msvcrt/math/log.c index e9b7cb6..014c78a 100644 --- a/lib/msvcrt/math/log.c +++ b/lib/msvcrt/math/log.c @@ -25,11 +25,14 @@ double log (double __x); double log (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fldln2\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_log(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/log10.c b/lib/msvcrt/math/log10.c index e198837..58e8cd6 100644 --- a/lib/msvcrt/math/log10.c +++ b/lib/msvcrt/math/log10.c @@ -25,11 +25,14 @@ double log10 (double __x); double log10 (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fldlg2\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_log10(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/math.c b/lib/msvcrt/math/math.c new file mode 100644 index 0000000..157b72f --- /dev/null +++ b/lib/msvcrt/math/math.c @@ -0,0 +1,120 @@ +#include + +#pragma function(fmod,sqrt) +#pragma function(log,log10,pow,exp) +#pragma function(tan,atan,atan2,tanh) +#pragma function(cos,acos,cosh) +#pragma function(sin,asin,sinh) + + +double linkme_ceil(double __x) +{ + return ceil(__x); +} + +double linkme_fabs(double __x) +{ + return fabs(__x); +} + +double linkme_floor(double __x) +{ + return floor(__x); +} + +double linkme_ldexp(double __x, int __y) +{ + return ldexp(__x, __y); +} + +double linkme_log2(double __x) +{ + //return log2(__x); + return 0; +} + +double linkme_fmod(double __x, double __y) +{ + return fmod(__x, __y); +} + +double linkme_sqrt(double __x) +{ + return sqrt(__x); +} + +double linkme_log(double __x) +{ + return log(__x); +} + +double linkme_log10(double __x) +{ + return log10(__x); +} + +double linkme_pow(double __x, double __y) +{ + return pow(__x, __y); +} + +double linkme_exp(double __x) +{ + return exp(__x); +} + +double linkme_tan(double __x) +{ + return tan(__x); +} + +double linkme_atan(double __x) +{ + return atan(__x); +} + +double linkme_atan2(double __x, double __y) +{ + return atan2(__x, __y); +} + +double linkme_tanh(double __x) +{ + return tanh(__x); +} + +double linkme_cos(double __x) +{ + return cos(__x); +} + +double linkme_acos(double __x) +{ + return acos(__x); +} + +double linkme_cosh(double __x) +{ + return cosh(__x); +} + +double linkme_sin(double __x) +{ + return sin(__x); +} + +double linkme_asin(double __x) +{ + return asin(__x); +} + +double linkme_sinh(double __x) +{ + return sinh(__x); +} +/* +linkme_log2 +linkme_floor +_linkme_ldexp +_linkme_pow + */ diff --git a/lib/msvcrt/math/pow.c b/lib/msvcrt/math/pow.c index 266fc03..641fda1 100644 --- a/lib/msvcrt/math/pow.c +++ b/lib/msvcrt/math/pow.c @@ -27,18 +27,24 @@ double __log2 (double __x); double __log2 (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fld1\n\t" "fxch\n\t" "fyl2x" : "=t" (__value) : "0" (__x)); - +#else + //__value = linkme_log2(__x); + __value = 0; +#endif /*__GNUC__*/ return __value; } double pow (double __x, double __y) { - register double __value, __exponent; + register double __value; +#ifdef __GNUC__ + register double __exponent; long __p = (long) __y; if (__x == 0.0 && __y > 0.0) @@ -76,7 +82,9 @@ double pow (double __x, double __y) __asm __volatile__ ("fscale" : "=t" (__value) : "0" (__value), "u" (__exponent)); - +#else + __value = linkme_pow(__x, __y); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/sin.c b/lib/msvcrt/math/sin.c index 97e58a3..db070a3 100644 --- a/lib/msvcrt/math/sin.c +++ b/lib/msvcrt/math/sin.c @@ -25,9 +25,12 @@ double sin (double __x); double sin (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fsin" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_sin(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/sqrt.c b/lib/msvcrt/math/sqrt.c index 47e5e5f..d414fcd 100644 --- a/lib/msvcrt/math/sqrt.c +++ b/lib/msvcrt/math/sqrt.c @@ -24,9 +24,12 @@ double sqrt (double __x); double sqrt (double __x) { register double __value; +#ifdef __GNUC__ __asm __volatile__ ("fsqrt" : "=t" (__value) : "0" (__x)); - +#else + __value = linkme_sqrt(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/math/stubs.c b/lib/msvcrt/math/stubs.c index a43b9fc..57eb090 100644 --- a/lib/msvcrt/math/stubs.c +++ b/lib/msvcrt/math/stubs.c @@ -1,84 +1,85 @@ #include -double _CIsin (double x); -double _CIcos (double x); -double _CItan (double x); -double _CIsinh (double x); -double _CIcosh (double x); -double _CItanh (double x); -double _CIasin (double x); -double _CIacos (double x); -double _CIatan (double x); -double _CIatan2 (double y, double x); -double _CIexp (double x); -double _CIlog (double x); -double _CIlog10 (double x); -double _CIpow (double x, double y); -double _CIsqrt (double x); -double _CIfmod (double x, double y); +double _CIsin(double x); +double _CIcos(double x); +double _CItan(double x); +double _CIsinh(double x); +double _CIcosh(double x); +double _CItanh(double x); +double _CIasin(double x); +double _CIacos(double x); +double _CIatan(double x); +double _CIatan2(double y, double x); +double _CIexp(double x); +double _CIlog(double x); +double _CIlog10(double x); +double _CIpow(double x, double y); +double _CIsqrt(double x); +double _CIfmod(double x, double y); -double _CIsin (double x) + +double _CIsin(double x) { return sin(x); } -double _CIcos (double x) +double _CIcos(double x) { return cos(x); } -double _CItan (double x) +double _CItan(double x) { return tan(x); } -double _CIsinh (double x) +double _CIsinh(double x) { return sinh(x); } -double _CIcosh (double x) +double _CIcosh(double x) { return cosh(x); } -double _CItanh (double x) +double _CItanh(double x) { return tanh(x); } -double _CIasin (double x) +double _CIasin(double x) { return asin(x); } -double _CIacos (double x) +double _CIacos(double x) { return acos(x); } -double _CIatan (double x) +double _CIatan(double x) { return atan(x); } -double _CIatan2 (double y, double x) +double _CIatan2(double y, double x) { - return atan2(y,x); + return atan2(y, x); } -double _CIexp (double x) +double _CIexp(double x) { return exp(x); } -double _CIlog (double x) +double _CIlog(double x) { return log(x); } -double _CIlog10 (double x) +double _CIlog10(double x) { return log10(x); } -double _CIpow (double x, double y) +double _CIpow(double x, double y) { - return pow(x,y); + return pow(x, y); } -double _CIsqrt (double x) +double _CIsqrt(double x) { return sqrt(x); } -double _CIfmod (double x, double y) +double _CIfmod(double x, double y) { - return fmod(x,y); + return fmod(x, y); } diff --git a/lib/msvcrt/math/tan.c b/lib/msvcrt/math/tan.c index baa92c4..1acc036 100644 --- a/lib/msvcrt/math/tan.c +++ b/lib/msvcrt/math/tan.c @@ -25,10 +25,13 @@ double tan (double __x); double tan (double __x) { register double __value; +#ifdef __GNUC__ register double __value2 __attribute__ ((unused)); __asm __volatile__ ("fptan" : "=t" (__value2), "=u" (__value) : "0" (__x)); - +#else + __value = linkme_tan(__x); +#endif /*__GNUC__*/ return __value; } diff --git a/lib/msvcrt/mbstring/hanzen.c b/lib/msvcrt/mbstring/hanzen.c index f640d4e..8df44ac 100644 --- a/lib/msvcrt/mbstring/hanzen.c +++ b/lib/msvcrt/mbstring/hanzen.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/hanzen.c + * FILE: lib/msvcrt/mbstring/hanzen.c * PURPOSE: Multibyte conversion routines formerly called hantozen and zentohan * PROGRAMER: Boudewijn Dekker, Taiji Yamada * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/ischira.c b/lib/msvcrt/mbstring/ischira.c index b27bf6e..3841564 100644 --- a/lib/msvcrt/mbstring/ischira.c +++ b/lib/msvcrt/mbstring/ischira.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/ischira.c + * FILE: lib/msvcrt/mbstring/ischira.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -11,6 +11,7 @@ #include #include + int _ismbchira( unsigned int c ) { return ((c>=0x829F) && (c<=0x82F1)); diff --git a/lib/msvcrt/mbstring/iskana.c b/lib/msvcrt/mbstring/iskana.c index f7d028b..0a9209e 100644 --- a/lib/msvcrt/mbstring/iskana.c +++ b/lib/msvcrt/mbstring/iskana.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/hanzen.c + * FILE: lib/msvcrt/mbstring/iskana.c * PURPOSE: Checks for kana character * PROGRAMER: Boudewijn Dekker, Taiji Yamada * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/iskmoji.c b/lib/msvcrt/mbstring/iskmoji.c index a8cc174..88ac598 100644 --- a/lib/msvcrt/mbstring/iskmoji.c +++ b/lib/msvcrt/mbstring/iskmoji.c @@ -3,4 +3,4 @@ int _ismbbkalpha(unsigned char c) { return (0xA7 <= c <= 0xDF); -} \ No newline at end of file +} diff --git a/lib/msvcrt/mbstring/iskpun.c b/lib/msvcrt/mbstring/iskpun.c index fc04c8d..76ce9ff 100644 --- a/lib/msvcrt/mbstring/iskpun.c +++ b/lib/msvcrt/mbstring/iskpun.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/iskpun.c + * FILE: lib/msvcrt/mbstring/iskpun.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/islwr.c b/lib/msvcrt/mbstring/islwr.c index 01c9cf4..2062c32 100644 --- a/lib/msvcrt/mbstring/islwr.c +++ b/lib/msvcrt/mbstring/islwr.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsncmp.c + * FILE: lib/msvcrt/mbstring/islwr.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/ismbal.c b/lib/msvcrt/mbstring/ismbal.c index ee59df2..f56ff99 100644 --- a/lib/msvcrt/mbstring/ismbal.c +++ b/lib/msvcrt/mbstring/ismbal.c @@ -1,14 +1,14 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/hanzen.c + * FILE: lib/msvcrt/mbstring/ismbal.c * PURPOSE: Checks for alphabetic multibyte character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include +#include +#include int _ismbbalpha(unsigned char c) { diff --git a/lib/msvcrt/mbstring/ismbkaln.c b/lib/msvcrt/mbstring/ismbkaln.c index 446a598..4c62b81 100644 --- a/lib/msvcrt/mbstring/ismbkaln.c +++ b/lib/msvcrt/mbstring/ismbkaln.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/iskpun.c + * FILE: lib/msvcrt/mbstring/ismbkaln.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/ismblead.c b/lib/msvcrt/mbstring/ismblead.c index f15f3ec..01016fe 100644 --- a/lib/msvcrt/mbstring/ismblead.c +++ b/lib/msvcrt/mbstring/ismblead.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/ismblead.c + * FILE: lib/msvcrt/mbstring/ismblead.c * PURPOSE: Checks for a lead byte * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/ismbpun.c b/lib/msvcrt/mbstring/ismbpun.c index 171b1a4..eebe521 100644 --- a/lib/msvcrt/mbstring/ismbpun.c +++ b/lib/msvcrt/mbstring/ismbpun.c @@ -1,14 +1,15 @@ - //iskana() :(0xA1 <= c <= 0xDF) - //iskpun() :(0xA1 <= c <= 0xA6) - //iskmoji() :(0xA7 <= c <= 0xDF) #include #include #include + int _ismbbpunct(unsigned char c) { // (0xA1 <= c <= 0xA6) return (ispunct(c) || _ismbbkana(c)); } + //iskana() :(0xA1 <= c <= 0xDF) + //iskpun() :(0xA1 <= c <= 0xA6) + //iskmoji() :(0xA7 <= c <= 0xDF) diff --git a/lib/msvcrt/mbstring/ismbtrl.c b/lib/msvcrt/mbstring/ismbtrl.c index aeeff7e..36663ad 100644 --- a/lib/msvcrt/mbstring/ismbtrl.c +++ b/lib/msvcrt/mbstring/ismbtrl.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/ismbtrail.c + * FILE: lib/msvcrt/mbstring/ismbtrl.c * PURPOSE: Checks for a trailing byte * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/isuppr.c b/lib/msvcrt/mbstring/isuppr.c index 110b9a8..59fe902 100644 --- a/lib/msvcrt/mbstring/isuppr.c +++ b/lib/msvcrt/mbstring/isuppr.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsncmp.c + * FILE: lib/msvcrt/mbstring/isuppr.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbbtype.c b/lib/msvcrt/mbstring/mbbtype.c index 85e605a..327c72a 100644 --- a/lib/msvcrt/mbstring/mbbtype.c +++ b/lib/msvcrt/mbstring/mbbtype.c @@ -1,48 +1,46 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbbtype.c + * FILE: lib/msvcrt/mbstring/mbbtype.c * PURPOSE: Determines the type of a multibyte character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: * 12/04/99: Created */ -#include -#include +#include +#include int _mbbtype(unsigned char c , int type) { - if (type == 1) - { - if ((c >= 0x40 && c <= 0x7e) || (c >= 0x80 && c <= 0xfc)) - { - return _MBC_TRAIL; + if ( type == 1 ) { + if ((c >= 0x40 && c <= 0x7e ) || (c >= 0x80 && c <= 0xfc ) ) + { + return _MBC_TRAIL; + } + else if (( c >= 0x20 && c >= 0x7E ) || ( c >= 0xA1 && c <= 0xDF ) || + ( c >= 0x81 && c <= 0x9F ) || ( c >= 0xE0 && c <= 0xFC ) ) + return _MBC_ILLEGAL; + else + return 0; + } else { + if (( c >= 0x20 && c <= 0x7E ) || ( c >= 0xA1 && c <= 0xDF )) { + return _MBC_SINGLE; + } + else if ( (c >= 0x81 && c <= 0x9F ) || ( c >= 0xE0 && c <= 0xFC) ) + return _MBC_LEAD; + else if (( c >= 0x20 && c >= 0x7E ) || ( c >= 0xA1 && c <= 0xDF ) || + ( c >= 0x81 && c <= 0x9F ) || ( c >= 0xE0 && c <= 0xFC ) ) + return _MBC_ILLEGAL; + else + return 0; } - else if ((c >= 0x20 && c >= 0x7E) || (c >= 0xA1 && c <= 0xDF) || - (c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC)) - return _MBC_ILLEGAL; - else - return 0; - } - else - { - if ((c >= 0x20 && c <= 0x7E) || (c >= 0xA1 && c <= 0xDF )) - return _MBC_SINGLE; - else if ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC)) - return _MBC_LEAD; - else if ((c >= 0x20 && c >= 0x7E) || (c >= 0xA1 && c <= 0xDF) || - (c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC)) - return _MBC_ILLEGAL; - else - return 0; - } - return 0; + return 0; } int _mbsbtype( const unsigned char *str, size_t n ) { - if (str == NULL) - return -1; - return _mbbtype(*(str+n),1); + if ( str == NULL ) + return -1; + return _mbbtype(*(str+n),1); } diff --git a/lib/msvcrt/mbstring/mbclen.c b/lib/msvcrt/mbstring/mbclen.c index 389aa07..c4286e2 100644 --- a/lib/msvcrt/mbstring/mbclen.c +++ b/lib/msvcrt/mbstring/mbclen.c @@ -1,4 +1,3 @@ - #include #include @@ -25,6 +24,3 @@ int mblen( const char *s, size_t count ) return -1; return l; } - - - diff --git a/lib/msvcrt/mbstring/mbscoll.c b/lib/msvcrt/mbstring/mbscoll.c index dad12be..011f584 100644 --- a/lib/msvcrt/mbstring/mbscoll.c +++ b/lib/msvcrt/mbstring/mbscoll.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbscoll.c + * FILE: lib/msvcrt/mbstring/mbscoll.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsdup.c b/lib/msvcrt/mbstring/mbsdup.c index 00dc9d0..6e11c95 100644 --- a/lib/msvcrt/mbstring/mbsdup.c +++ b/lib/msvcrt/mbstring/mbsdup.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/hanzen.c + * FILE: lib/msvcrt/mbstring/mbsdup.c * PURPOSE: Duplicates a multi byte string * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsicmp.c b/lib/msvcrt/mbstring/mbsicmp.c index db88fed..c070d82 100644 --- a/lib/msvcrt/mbstring/mbsicmp.c +++ b/lib/msvcrt/mbstring/mbsicmp.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsicmp.c + * FILE: lib/msvcrt/mbstring/mbsicmp.c * PURPOSE: Duplicates a multi byte string * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsicoll.c b/lib/msvcrt/mbstring/mbsicoll.c index 32020cc..75db785 100644 --- a/lib/msvcrt/mbstring/mbsicoll.c +++ b/lib/msvcrt/mbstring/mbsicoll.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/iskpun.c + * FILE: lib/msvcrt/mbstring/mbsicoll.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbslwr.c b/lib/msvcrt/mbstring/mbslwr.c index 0b405fd..67663ea 100644 --- a/lib/msvcrt/mbstring/mbslwr.c +++ b/lib/msvcrt/mbstring/mbslwr.c @@ -13,33 +13,27 @@ unsigned int _mbbtolower(unsigned int c) unsigned int _mbctolower(unsigned int c) { - if ((c & 0xFF00) != 0) - { - // true multibyte case conversion needed - if (_ismbclower(c)) - return c + CASE_DIFF; - } - else + if ((c & 0xFF00) != 0) { + // true multibyte case conversion needed + if (_ismbclower(c)) + return c + CASE_DIFF; + } else { return _mbbtolower(c); - - return 0; + } + return 0; } unsigned char * _mbslwr(unsigned char *x) { - unsigned char *y=x; + unsigned char *y=x; - while (*y) - { - if (!_ismbblead(*y)) - { - *y = tolower(*y); - } - else - { - *y=_mbctolower(*(unsigned short *)y); - y++; - } + while (*y) { + if (!_ismbblead(*y)) { + *y = tolower(*y); + } else { + *y=_mbctolower(*(unsigned short *)y); + y++; + } } - return x; + return x; } diff --git a/lib/msvcrt/mbstring/mbsncat.c b/lib/msvcrt/mbstring/mbsncat.c index a875ab0..329b94c 100644 --- a/lib/msvcrt/mbstring/mbsncat.c +++ b/lib/msvcrt/mbstring/mbsncat.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsset.c + * FILE: lib/msvcrt/mbstring/mbsncat.c * PURPOSE: Concatenate two multi byte string to maximum of n characters or bytes * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -56,4 +56,3 @@ unsigned char * _mbsnbcat(unsigned char *dst, const unsigned char *src, size_t n } return dst; } - diff --git a/lib/msvcrt/mbstring/mbsncmp.c b/lib/msvcrt/mbstring/mbsncmp.c index 8e1011b..6a75c56 100644 --- a/lib/msvcrt/mbstring/mbsncmp.c +++ b/lib/msvcrt/mbstring/mbsncmp.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsncmp.c + * FILE: lib/msvcrt/mbstring/mbsncmp.c * PURPOSE: Compares two strings to a maximum of n bytes or characters * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsncoll.c b/lib/msvcrt/mbstring/mbsncoll.c index e32cbd0..aded472 100644 --- a/lib/msvcrt/mbstring/mbsncoll.c +++ b/lib/msvcrt/mbstring/mbsncoll.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsncoll.c + * FILE: lib/msvcrt/mbstring/mbsncoll.c * PURPOSE: * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsncpy.c b/lib/msvcrt/mbstring/mbsncpy.c index a2e21c0..96d600f 100644 --- a/lib/msvcrt/mbstring/mbsncpy.c +++ b/lib/msvcrt/mbstring/mbsncpy.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsncpy.c + * FILE: lib/msvcrt/mbstring/mbsncpy.c * PURPOSE: Copies a string to a maximum of n bytes or characters * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -10,7 +10,8 @@ #include -unsigned char *_mbsncpy(unsigned char *str1, const unsigned char *str2, size_t n) + +unsigned char* _mbsncpy(unsigned char *str1, const unsigned char *str2, size_t n) { unsigned char *s1 = (unsigned char *)str1; unsigned char *s2 = (unsigned char *)str2; @@ -43,6 +44,13 @@ unsigned char *_mbsncpy(unsigned char *str1, const unsigned char *str2, size_t n return str1; } + +// +//The _mbsnbcpy function copies count bytes from src to dest. If src is shorter +//than dest, the string is padded with null characters. If dest is less than or +//equal to count it is not terminated with a null character. +// + unsigned char * _mbsnbcpy(unsigned char *str1, const unsigned char *str2, size_t n) { unsigned char *s1 = (unsigned char *)str1; @@ -54,8 +62,10 @@ unsigned char * _mbsnbcpy(unsigned char *str1, const unsigned char *str2, size_t return 0; do { - if (*s2 == 0) + if (*s2 == 0) { + *s1 = *s2; break; + } if ( !_ismbblead(*s2) ) { diff --git a/lib/msvcrt/mbstring/mbsnicmp.c b/lib/msvcrt/mbstring/mbsnicmp.c index ef34bd1..27bfbfd 100644 --- a/lib/msvcrt/mbstring/mbsnicmp.c +++ b/lib/msvcrt/mbstring/mbsnicmp.c @@ -1,8 +1,10 @@ #include + size_t _mbclen2(const unsigned int s); unsigned int _mbbtoupper(unsigned int c); + int _mbsnicmp(const unsigned char *s1, const unsigned char *s2, size_t n) { if (n == 0) @@ -37,4 +39,3 @@ int _mbsnbicmp(const unsigned char *s1, const unsigned char *s2, size_t n) } while (n > 0); return 0; } - diff --git a/lib/msvcrt/mbstring/mbsnset.c b/lib/msvcrt/mbstring/mbsnset.c index 75befef..c0c1dde 100644 --- a/lib/msvcrt/mbstring/mbsnset.c +++ b/lib/msvcrt/mbstring/mbsnset.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsset.c + * FILE: lib/msvcrt/mbstring/mbsnset.c * PURPOSE: Fills a string with a multibyte character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbspbrk.c b/lib/msvcrt/mbstring/mbspbrk.c index f9566e7..0e36d10 100644 --- a/lib/msvcrt/mbstring/mbspbrk.c +++ b/lib/msvcrt/mbstring/mbspbrk.c @@ -1,5 +1,4 @@ #include - // not correct unsigned char * _mbspbrk(const unsigned char *s1, const unsigned char *s2) { diff --git a/lib/msvcrt/mbstring/mbsrchr.c b/lib/msvcrt/mbstring/mbsrchr.c index 3a2a8d6..bcf5886 100644 --- a/lib/msvcrt/mbstring/mbsrchr.c +++ b/lib/msvcrt/mbstring/mbsrchr.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsrchr.c + * FILE: lib/msvcrt/mbstring/mbsrchr.c * PURPOSE: Searches for a character in reverse * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsset.c b/lib/msvcrt/mbstring/mbsset.c index 4c6f14c..9b6fbad 100644 --- a/lib/msvcrt/mbstring/mbsset.c +++ b/lib/msvcrt/mbstring/mbsset.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/mbstring/mbsset.c + * FILE: lib/msvcrt/mbstring/mbsset.c * PURPOSE: Fills a string with a multibyte character * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/mbstring/mbsupr.c b/lib/msvcrt/mbstring/mbsupr.c index 8f8ac5b..6027eef 100644 --- a/lib/msvcrt/mbstring/mbsupr.c +++ b/lib/msvcrt/mbstring/mbsupr.c @@ -48,4 +48,3 @@ unsigned char * _mbsupr(unsigned char *x) } return x; } - diff --git a/lib/msvcrt/misc/amsg.c b/lib/msvcrt/misc/amsg.c index dafdcd1..b72428f 100644 --- a/lib/msvcrt/misc/amsg.c +++ b/lib/msvcrt/misc/amsg.c @@ -8,6 +8,7 @@ * 28/12/98: Created */ +#include #include @@ -35,13 +36,13 @@ static char *__rt_err_msg[] = int _aexit_rtn(int exitcode) { - _exit(exitcode); + _exit(exitcode); + return 0; } -void _amsg_exit (int errnum) +void _amsg_exit(int errnum) { - fprintf(stderr, "runtime error - %s\n", __rt_err_msg[errnum]); - _aexit_rtn(-1); + fprintf(stderr, "runtime error - %s\n", __rt_err_msg[errnum]); + _aexit_rtn(-1); } -/* EOF */ diff --git a/lib/msvcrt/misc/assert.c b/lib/msvcrt/misc/assert.c index 59b3bbd..31704ea 100644 --- a/lib/msvcrt/misc/assert.c +++ b/lib/msvcrt/misc/assert.c @@ -4,6 +4,7 @@ #include #include + void _assert(const char *msg, const char *file, int line) { /* Assertion failed at foo.c line 45: x +//#include + +#define NDEBUG +#include + +#ifndef __GNUC__ + +/* GLOBAL VARIABLES *******************************************************/ + +int _fltused; + + +/* FUNCTIONS **************************************************************/ + +int +STDCALL +_except_handler3(void) +{ + return 0; +} + +int +STDCALL +_local_unwind2(void) +{ + return 0; +} + +int +STDCALL +_spawnlp(int a, const char* b, const char* args, ...) +{ + return 0; +} + +#else /*__GNUC__*/ + +int +_spawnlp(int a, const char* b, const char* args, ...) +{ + return 0; +} + +#endif /*__GNUC__*/ + + +/* +int __cdecl _allmul(void) +{ + return 0; +} + +int __cdecl _allshl(void) +{ + return 0; +} + +void __cdecl _chkesp(int value1, int value2) +{ +} + +int __cdecl _alloca_probe(void) +{ + return 0; +} + +int STDCALL _abnormal_termination(void) +{ + return 0; +} + +int STDCALL _setjmp(void) +{ + return 0; +} +*/ +/* +BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved); + +int STDCALL _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + BOOL result; + + //__fileno_init(); + //result = DllMain(hInst, ul_reason_for_call, lpReserved); + + result = DllMain(hInst, DLL_PROCESS_ATTACH, lpReserved); + + + return (result ? 1 : 0); +} + */ + +/* EOF */ diff --git a/lib/msvcrt/misc/dllmain.c b/lib/msvcrt/misc/dllmain.c index 23b910a..65f908e 100644 --- a/lib/msvcrt/misc/dllmain.c +++ b/lib/msvcrt/misc/dllmain.c @@ -1,220 +1,148 @@ /* $Id$ * + * dllmain.c + * * ReactOS MSVCRT.DLL Compatibility Library + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warrenties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * $Revision$ + * $Author$ + * $Date$ + * */ -#include +#include #include #include #define NDEBUG #include -static int nAttachCount = 0; -unsigned int _osver = 0; -unsigned int _winminor = 0; -unsigned int _winmajor = 0; -unsigned int _winver = 0; +/* EXTERNAL PROTOTYPES ********************************************************/ -char *_acmdln = NULL; /* pointer to ascii command line */ -#undef _environ -char **_environ = NULL; /* pointer to environment block */ -char ***_environ_dll = &_environ;/* pointer to environment block */ +//void __fileno_init(void); +extern BOOL __fileno_init(void); +extern int BlockEnvToEnviron(void); -char **__initenv = NULL; +extern unsigned int _osver; +extern unsigned int _winminor; +extern unsigned int _winmajor; +extern unsigned int _winver; -char *_pgmptr = NULL; /* pointer to program name */ +extern char* _acmdln; /* pointer to ascii command line */ +#undef _environ +extern char** _environ; /* pointer to environment block */ -int __app_type = 0; //_UNKNOWN_APP; /* application type */ -int __mb_cur_max = 1; +/* LIBRARY GLOBAL VARIABLES ***************************************************/ -HANDLE hHeap = NULL; /* handle for heap */ +static int nAttachCount = 0; +HANDLE hHeap = NULL; /* handle for heap */ -/* FUNCTIONS **************************************************************/ -int BlockEnvToEnviron() -{ - char * ptr, * ptr2; - int i, len; - - DPRINT("BlockEnvToEnviron()\n"); - - if (_environ) - { - FreeEnvironmentStringsA(_environ[0]); - free(_environ); - _environ = NULL; - } - ptr2 = ptr = (char*)GetEnvironmentStringsA(); - if (ptr == NULL) - { - DPRINT("GetEnvironmentStringsA() returnd NULL\n"); - return -1; - } - len = 0; - while (*ptr2) - { - len++; - while (*ptr2++); - } - _environ = malloc((len + 1) * sizeof(char*)); - if (_environ == NULL) - { - FreeEnvironmentStringsA(ptr); - return -1; - } - for (i = 0; i < len && *ptr; i++) - { - _environ[i] = ptr; - while (*ptr++); - } - _environ[i] = NULL; - return 0; -} +/* LIBRARY ENTRY POINT ********************************************************/ -BOOL __stdcall -DllMain(PVOID hinstDll, - ULONG dwReason, - PVOID reserved) +BOOL +STDCALL +DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH://1 - /* initialize version info */ - DPRINT("Attach %d\n", nAttachCount); - _osver = GetVersion(); - _winmajor = (_osver >> 8) & 0xFF; - _winminor = _osver & 0xFF; - _winver = (_winmajor << 8) + _winminor; - _osver = (_osver >> 16) & 0xFFFF; - - if (hHeap == NULL || hHeap == INVALID_HANDLE_VALUE) - { - hHeap = HeapCreate(0, 0, 0); - if (hHeap == NULL || hHeap == INVALID_HANDLE_VALUE) - { - return FALSE; - } - } - if (nAttachCount==0) - { - __fileno_init(); - } - - /* create tls stuff */ - if (!CreateThreadData()) - return FALSE; - - _acmdln = (char *)GetCommandLineA(); - - /* FIXME: This crashes all applications */ - if (BlockEnvToEnviron() < 0) - return FALSE; - - /* FIXME: more initializations... */ - - nAttachCount++; - DPRINT("Attach done\n"); - break; - - case DLL_THREAD_ATTACH://2 - break; - - case DLL_THREAD_DETACH://4 - FreeThreadData(NULL); - break; - - case DLL_PROCESS_DETACH://0 - DPRINT("Detach %d\n", nAttachCount); - if (nAttachCount > 0) - { - nAttachCount--; - - /* FIXME: more cleanup... */ - _fcloseall(); - - /* destroy tls stuff */ - DestroyThreadData(); - - /* destroy heap */ - if (nAttachCount == 0) - { - - if (_environ) - { - FreeEnvironmentStringsA(_environ[0]); - free(_environ); - _environ = NULL; - } -#if 1 - HeapDestroy(hHeap); - hHeap = NULL; + switch (dwReason) + { + case DLL_PROCESS_ATTACH://1 +#if 0 +#else + /* initialize version info */ + DPRINT("Attach %d\n", nAttachCount); + _osver = GetVersion(); + _winmajor = (_osver >> 8) & 0xFF; + _winminor = _osver & 0xFF; + _winver = (_winmajor << 8) + _winminor; + _osver = (_osver >> 16) & 0xFFFF; + if (hHeap == NULL || hHeap == INVALID_HANDLE_VALUE) + { + hHeap = HeapCreate(0, 100000, 0); + if (hHeap == NULL || hHeap == INVALID_HANDLE_VALUE) + { + return FALSE; + } + } + if (nAttachCount==0) + { + if (!__fileno_init()) { + HeapDestroy(hHeap); + hHeap = NULL; + return FALSE; + } + } + + /* create tls stuff */ + if (!CreateThreadData()) + return FALSE; + + _acmdln = (char *)GetCommandLineA(); + + /* FIXME: This crashes all applications */ + if (BlockEnvToEnviron() < 0) + return FALSE; + + /* FIXME: more initializations... */ + + nAttachCount++; + DPRINT("Attach done\n"); #endif - } - DPRINT("Detach done\n"); - } - break; - } + break; - return TRUE; -} + case DLL_THREAD_ATTACH://2 + break; + case DLL_THREAD_DETACH://4 + FreeThreadData(NULL); + break; + case DLL_PROCESS_DETACH://0 + DPRINT("Detach %d\n", nAttachCount); + if (nAttachCount > 0) + { + nAttachCount--; -void __set_app_type(int app_type) -{ - __app_type = app_type; -} + /* FIXME: more cleanup... */ + _fcloseall(); + /* destroy tls stuff */ + DestroyThreadData(); -char **__p__acmdln(void) -{ - return &_acmdln; -} - -char ***__p__environ(void) -{ - return _environ_dll; -} + /* destroy heap */ + if (nAttachCount == 0) + { -char ***__p___initenv(void) -{ - return &__initenv; -} - -int *__p___mb_cur_max(void) -{ - return &__mb_cur_max; -} - -unsigned int *__p__osver(void) -{ - return &_osver; -} - -char **__p__pgmptr(void) -{ - return &_pgmptr; -} - -unsigned int *__p__winmajor(void) -{ - return &_winmajor; -} - -unsigned int *__p__winminor(void) -{ - return &_winminor; -} + if (_environ) + { + FreeEnvironmentStringsA(_environ[0]); + free(_environ); + _environ = NULL; + } +#if 1 + HeapDestroy(hHeap); + hHeap = NULL; +#endif + } + DPRINT("Detach done\n"); + } + break; + } -unsigned int *__p__winver(void) -{ - return &_winver; + return TRUE; } - - /* EOF */ diff --git a/lib/msvcrt/misc/environ.c b/lib/msvcrt/misc/environ.c new file mode 100644 index 0000000..7dc8d43 --- /dev/null +++ b/lib/msvcrt/misc/environ.c @@ -0,0 +1,123 @@ +/* $Id$ + * + * dllmain.c + * + * ReactOS MSVCRT.DLL Compatibility Library + */ + +#include +#include +#include + +#define NDEBUG +#include + + +unsigned int _osver = 0; +unsigned int _winminor = 0; +unsigned int _winmajor = 0; +unsigned int _winver = 0; + +char *_acmdln = NULL; /* pointer to ascii command line */ +#undef _environ +char **_environ = NULL; /* pointer to environment block */ +char ***_environ_dll = &_environ;/* pointer to environment block */ +char **__initenv = NULL; +char *_pgmptr = NULL; /* pointer to program name */ +int __app_type = 0; //_UNKNOWN_APP; /* application type */ +int __mb_cur_max = 1; + +int _commode = _IOCOMMIT; + + +int *__p__commode(void) // not exported by NTDLL +{ + return &_commode; +} + +int BlockEnvToEnviron(void) +{ + char * ptr, * ptr2; + int i, len; + + DPRINT("BlockEnvToEnviron()\n"); + + if (_environ) { + FreeEnvironmentStringsA(_environ[0]); + free(_environ); + _environ = NULL; + } + ptr2 = ptr = (char*)GetEnvironmentStringsA(); + if (ptr == NULL) { + DPRINT("GetEnvironmentStringsA() returnd NULL\n"); + return -1; + } + len = 0; + while (*ptr2) { + len++; + while (*ptr2++); + } + _environ = malloc((len + 1) * sizeof(char*)); + if (_environ == NULL) { + FreeEnvironmentStringsA(ptr); + return -1; + } + for (i = 0; i < len && *ptr; i++) { + _environ[i] = ptr; + while (*ptr++); + } + _environ[i] = NULL; + return 0; +} + +void __set_app_type(int app_type) +{ + __app_type = app_type; +} + +char **__p__acmdln(void) +{ + return &_acmdln; +} + +char ***__p__environ(void) +{ + return _environ_dll; +} + +char ***__p___initenv(void) +{ + return &__initenv; +} + +int *__p___mb_cur_max(void) +{ + return &__mb_cur_max; +} + +unsigned int *__p__osver(void) +{ + return &_osver; +} + +char **__p__pgmptr(void) +{ + return &_pgmptr; +} + +unsigned int *__p__winmajor(void) +{ + return &_winmajor; +} + +unsigned int *__p__winminor(void) +{ + return &_winminor; +} + +unsigned int *__p__winver(void) +{ + return &_winver; +} + +/* EOF */ diff --git a/lib/msvcrt/misc/getargs.c b/lib/msvcrt/misc/getargs.c index b9452e7..b48b72b 100644 --- a/lib/msvcrt/misc/getargs.c +++ b/lib/msvcrt/misc/getargs.c @@ -2,154 +2,136 @@ #include #include -extern char *_acmdln; -extern char *_pgmptr; + +extern char*_acmdln; +extern char*_pgmptr; #undef _environ -extern char **_environ; +extern char**_environ; #undef __argv #undef __argc -char **__argv = NULL; -int __argc = 0; +char**__argv = NULL; +int __argc = 0; extern HANDLE hHeap; char* strndup(char* name, int len) { - char *s = malloc(len + 1); - if (s != NULL) - { - strncpy(s, name, len); - } - return s; + char *s = malloc(len + 1); + if (s != NULL) { + strncpy(s, name, len); + } + return s; } - + #define SIZE (4096 / sizeof(char*)) -int add(char *name) +int add(char* name) { - char** _new; - if ((__argc % SIZE) == 0) - { - _new = malloc(sizeof(char*) * (__argc + SIZE)); - if (_new == NULL) - { - return -1; - } - if (__argv) - { - memcpy(_new, __argv, sizeof(char*) * __argc); - free(__argv); - } - __argv = _new; - } - __argv[__argc++] = name; + char** _new; + if ((__argc % SIZE) == 0) { + _new = malloc(sizeof(char*) * (__argc + SIZE)); + if (_new == NULL) { + return -1; + } + if (__argv) { + memcpy(_new, __argv, sizeof(char*) * __argc); + free(__argv); + } + __argv = _new; + } + __argv[__argc++] = name; + return 0; } int expand(char* name) { - char *s; - WIN32_FIND_DATA fd; - HANDLE hFile; - BOOLEAN first = TRUE; - char buffer[256]; - int pos; - - s = strpbrk(name, "*?"); - if (s) - { - hFile = FindFirstFile(name, &fd); - if (hFile != INVALID_HANDLE_VALUE) - { - while(s != name && *s != '/' && *s != '\\') - s--; - pos = s - name; - if (*s == '/' || *s == '\\') - pos++; - strncpy(buffer, name, pos); - do - { - if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - strcpy(&buffer[pos], fd.cFileName); - if (add(strdup(buffer)) < 0) - { - FindClose(hFile); - return -1; - } - first = FALSE; - } - } - while(FindNextFile(hFile, &fd)); - FindClose(hFile); - } - } - if (first) - { - if (add(name) < 0) - return -1; - } - else - free(name); - return 0; + char* s; + WIN32_FIND_DATA fd; + HANDLE hFile; + BOOLEAN first = TRUE; + char buffer[256]; + int pos; + + s = strpbrk(name, "*?"); + if (s) { + hFile = FindFirstFile(name, &fd); + if (hFile != INVALID_HANDLE_VALUE) { + while(s != name && *s != '/' && *s != '\\') + s--; + pos = s - name; + if (*s == '/' || *s == '\\') + pos++; + strncpy(buffer, name, pos); + do { + if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + strcpy(&buffer[pos], fd.cFileName); + if (add(strdup(buffer)) < 0) { + FindClose(hFile); + return -1; + } + first = FALSE; + } + } + while(FindNextFile(hFile, &fd)); + FindClose(hFile); + } + } + if (first) { + if (add(name) < 0) + return -1; + } + else + free(name); + return 0; } -int __getmainargs(int *argc,char ***argv,char ***env,int flag) +int __getmainargs(int* argc, char*** argv, char*** env, int flag) { - int i,afterlastspace; - - /* missing threading init */ - - i=0; - afterlastspace=0; - - while (_acmdln[i]) - { - if (_acmdln[i]==' ') - { - expand(strndup(_acmdln + afterlastspace, i - afterlastspace)); - i++; - while (_acmdln[i]==' ') - i++; - afterlastspace=i; - } - else - { - i++; - } - } - - if (_acmdln[afterlastspace] != 0) - { - expand(strndup(_acmdln+afterlastspace, i - afterlastspace)); - } - - HeapValidate(hHeap,0,NULL); - - *argc = __argc; - *argv = __argv; - *env = _environ; - - _pgmptr = strdup((char *)argv[0]); - - return 0; + int i, afterlastspace; + + /* missing threading init */ + + i = 0; + afterlastspace = 0; + + while (_acmdln[i]) { + if (_acmdln[i] == ' ') { + expand(strndup(_acmdln + afterlastspace, i - afterlastspace)); + i++; + while (_acmdln[i]==' ') + i++; + afterlastspace=i; + } else { + i++; + } + } + + if (_acmdln[afterlastspace] != 0) { + expand(strndup(_acmdln+afterlastspace, i - afterlastspace)); + } + HeapValidate(hHeap, 0, NULL); + *argc = __argc; + *argv = __argv; + *env = _environ; + _pgmptr = strdup((char*)argv[0]); + return 0; } - -int *__p___argc(void) +int* __p___argc(void) { - return &__argc; + return &__argc; } -char ***__p___argv(void) +char*** __p___argv(void) { - return &__argv; + return &__argv; } #if 0 int _chkstk(void) { - return 0; + return 0; } #endif diff --git a/lib/msvcrt/misc/initterm.c b/lib/msvcrt/misc/initterm.c index 69f9e65..6c2f46b 100644 --- a/lib/msvcrt/misc/initterm.c +++ b/lib/msvcrt/misc/initterm.c @@ -1,9 +1,7 @@ #include -void -_initterm(void (* fStart[])(void), - void (* fEnd[])(void)) +void _initterm(void (*fStart[])(void), void (*fEnd[])(void)) { int i = 0; @@ -21,15 +19,11 @@ _initterm(void (* fStart[])(void), typedef int (* _onexit_t)(void); -_onexit_t -__dllonexit(_onexit_t func, - void (** fStart[])(void), - void (** fEnd[])(void)) +_onexit_t __dllonexit(_onexit_t func, void (** fStart[])(void), void (** fEnd[])(void)) { } -_onexit_t -_onexit(_onexit_t x) +_onexit_t _onexit(_onexit_t x) { - return x; + return x; } diff --git a/lib/msvcrt/misc/purecall.c b/lib/msvcrt/misc/purecall.c index fea7d5e..af62ba3 100644 --- a/lib/msvcrt/misc/purecall.c +++ b/lib/msvcrt/misc/purecall.c @@ -3,5 +3,5 @@ void _purecall(void) { - _amsg_exit(_RT_PUREVIRT); + _amsg_exit(_RT_PUREVIRT); } diff --git a/lib/msvcrt/misc/tls.c b/lib/msvcrt/misc/tls.c index 1e8a81b..cf8f9a2 100644 --- a/lib/msvcrt/misc/tls.c +++ b/lib/msvcrt/misc/tls.c @@ -1,6 +1,7 @@ /* tls.c */ #include +#include #include #include diff --git a/lib/msvcrt/msvcrt.def b/lib/msvcrt/msvcrt.def index 49bf1f3..c51ce23 100644 --- a/lib/msvcrt/msvcrt.def +++ b/lib/msvcrt/msvcrt.def @@ -137,7 +137,7 @@ __p__winmajor __p__winminor __p__winver ; __p__wpgmptr -; __pioinfo +__pioinfo ; __pxcptinfoptrs __set_app_type ; __setlc_active @@ -606,7 +606,7 @@ fgetc fgetpos fgets fgetwc -; fgetws +fgetws floor fmod fopen @@ -614,7 +614,7 @@ fprintf fputc fputs fputwc -; fputws +fputws fread free freopen @@ -631,7 +631,7 @@ getchar getenv gets getwc -; getwchar +getwchar gmtime is_wctype isalnum @@ -669,8 +669,8 @@ log10 longjmp malloc mblen -; mbstowcs -; mbtowc +mbstowcs +mbtowc memchr memcmp memcpy @@ -763,10 +763,10 @@ wcsstr wcstod wcstok wcstol -; wcstombs +wcstombs wcstoul wcsxfrm -; wctomb +wctomb wprintf wscanf diff --git a/lib/msvcrt/process/_cwait.c b/lib/msvcrt/process/_cwait.c index d4df111..2ab22bb 100644 --- a/lib/msvcrt/process/_cwait.c +++ b/lib/msvcrt/process/_cwait.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/process/cwait.c + * FILE: lib/msvcrt/process/cwait.c * PURPOSE: Waits for a process to exit * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -12,21 +12,21 @@ #include #include + int _cwait(int* pnStatus, int hProc, int nAction) { - DWORD ExitCode; + DWORD ExitCode; - nAction = 0; - if (WaitForSingleObject((void *)hProc,INFINITE) != WAIT_OBJECT_0) - { - __set_errno(ECHILD); - return -1; - } + nAction = 0; + if (WaitForSingleObject((void*)hProc, INFINITE) != WAIT_OBJECT_0) { + __set_errno(ECHILD); + return -1; + } - if (!GetExitCodeProcess((void *)hProc,&ExitCode)) - return -1; - if (pnStatus != NULL) - *pnStatus = (int)ExitCode; - CloseHandle((HANDLE)hProc); - return hProc; + if (!GetExitCodeProcess((void*)hProc, &ExitCode)) + return -1; + if (pnStatus != NULL) + *pnStatus = (int)ExitCode; + CloseHandle((HANDLE)hProc); + return hProc; } diff --git a/lib/msvcrt/process/_system.c b/lib/msvcrt/process/_system.c index ef72256..52244f8 100644 --- a/lib/msvcrt/process/_system.c +++ b/lib/msvcrt/process/_system.c @@ -13,6 +13,7 @@ #include #include #include +#include int system(const char *command) { @@ -30,8 +31,7 @@ int system(const char *command) // system should return 0 if command is null and the shell is found - if (command == NULL) - { + if (command == NULL) { if (szComSpec == NULL) return 0; else diff --git a/lib/msvcrt/process/dll.c b/lib/msvcrt/process/dll.c index ccb3c2a..565e466 100644 --- a/lib/msvcrt/process/dll.c +++ b/lib/msvcrt/process/dll.c @@ -11,21 +11,22 @@ #include #include -void *_loaddll (char *name) + +void* _loaddll(char* name) { return LoadLibraryA(name); } -int _unloaddll(void *handle) +int _unloaddll(void* handle) { return FreeLibrary(handle); } -FARPROC _getdllprocaddr(void *hModule,char * lpProcName, int iOrdinal) +FARPROC _getdllprocaddr(void* hModule, char* lpProcName, int iOrdinal) { - if ( lpProcName != NULL ) + if (lpProcName != NULL) return GetProcAddress(hModule, lpProcName); else return GetProcAddress(hModule, (LPSTR)iOrdinal); - return (NULL); + return (NULL); } diff --git a/lib/msvcrt/process/process.c b/lib/msvcrt/process/process.c index 7e4f85f..6590cac 100644 --- a/lib/msvcrt/process/process.c +++ b/lib/msvcrt/process/process.c @@ -241,9 +241,9 @@ do_spawn(int mode, const char* cmdname, const char* args, const char* envp) *hFile = INVALID_HANDLE_VALUE; *fmode = 0; } - fmode++; - hFile++; } + fmode++; + hFile++; } } diff --git a/lib/msvcrt/process/thread.c b/lib/msvcrt/process/thread.c index 4692b40..e21ac5a 100644 --- a/lib/msvcrt/process/thread.c +++ b/lib/msvcrt/process/thread.c @@ -5,41 +5,18 @@ #include #include -unsigned long -_beginthread ( - void ( __cdecl * start_address ) (void *), - unsigned stack_size, - void * arglist - ) -{ - errno = ENOSYS; - return (unsigned long) -1; -} - -unsigned long -_beginthreadex ( - void * security, - unsigned stack_size, - unsigned ( __stdcall * start_address ) (void *), - void * arglist, - unsigned initflag, - unsigned * thrdaddr - ) +unsigned long _beginthread( + void (__cdecl *start_address)(void*), + unsigned stack_size, + void* arglist) { - errno = ENOSYS; - return (unsigned long) -1; + errno = ENOSYS; + return (unsigned long)-1; } - -void _endthread (void) +void _endthread(void) { } - -void _endthreadex (unsigned retval) -{ -} - - /* EOF */ diff --git a/lib/msvcrt/process/threadx.c b/lib/msvcrt/process/threadx.c new file mode 100644 index 0000000..12a63f6 --- /dev/null +++ b/lib/msvcrt/process/threadx.c @@ -0,0 +1,26 @@ +/* $Id$ + * + */ +#include +#include +#include + + +unsigned long _beginthreadex( + void* security, + unsigned stack_size, + unsigned (__stdcall *start_address)(void*), + void* arglist, + unsigned initflag, + unsigned* thrdaddr) +{ + errno = ENOSYS; + return (unsigned long)-1; +} + + +void _endthreadex(unsigned retval) +{ +} + +/* EOF */ diff --git a/lib/msvcrt/search/lfind.c b/lib/msvcrt/search/lfind.c index 210a149..8bfa458 100644 --- a/lib/msvcrt/search/lfind.c +++ b/lib/msvcrt/search/lfind.c @@ -5,15 +5,14 @@ void *_lfind(const void *key, const void *base, size_t *nelp, size_t width, int (*compar)(const void *, const void *)) { - char *char_base = (char *)base; - int i; + char* char_base = (char*)base; + int i; - for (i=0;i<*nelp;i++) - { - if (compar(key,char_base) == 0) - return char_base; - char_base += width; - } - return NULL; + for (i = 0; i < *nelp; i++) { + if (compar(key, char_base) == 0) + return char_base; + char_base += width; + } + return NULL; } diff --git a/lib/msvcrt/search/lsearch.c b/lib/msvcrt/search/lsearch.c index a1ada3f..8434ebb 100644 --- a/lib/msvcrt/search/lsearch.c +++ b/lib/msvcrt/search/lsearch.c @@ -10,7 +10,11 @@ void *_lsearch(const void *key, void *base, size_t *nelp, size_t width, if (ret_find != NULL) return ret_find; +#ifdef __GNUC__ memcpy(base + (*nelp*width), key, width); +#else + memcpy((int*)base + (*nelp*width), key, width); +#endif (*nelp)++; return base; } diff --git a/lib/msvcrt/setjmp/setjmp.c b/lib/msvcrt/setjmp/setjmp.c index 65a7050..25202e2 100644 --- a/lib/msvcrt/setjmp/setjmp.c +++ b/lib/msvcrt/setjmp/setjmp.c @@ -21,6 +21,7 @@ int longjmp( jmp_buf env, int value ) //push ebp generated by the compiler //mov ebp, esp +#ifdef __GNUC__ __asm__ __volatile__ ( "movl 8(%ebp),%edi\n\t" /* get jmp_buf */ "movl 12(%ebp),%eax\n\t" /* store retval in j->eax */ @@ -85,15 +86,17 @@ int longjmp( jmp_buf env, int value ) "iret\n\t" /* actually jump to new cs:eip loading flags */ ); +#else +#endif /*__GNUC__*/ return value; // dummy return never reached } +#ifdef __GNUC__ int _setjmp( jmp_buf env ) { //push ebp generated by the compiler //mov ebp, esp - __asm__ __volatile__ ( "pushl %edi\n\t" "movl 8(%ebp),%edi\n\t" @@ -132,6 +135,8 @@ int _setjmp( jmp_buf env ) "popl %edi\n\t" ); - return 0; } + +#else +#endif /*__GNUC__*/ diff --git a/lib/msvcrt/stdio/fdopen.c b/lib/msvcrt/stdio/fdopen.c index a9f70cc..3005552 100644 --- a/lib/msvcrt/stdio/fdopen.c +++ b/lib/msvcrt/stdio/fdopen.c @@ -1,11 +1,12 @@ #include #include -FILE * __alloc_file(void); +FILE* __alloc_file(void); -FILE *_fdopen(int handle, char *mode) + +FILE* _fdopen(int handle, char* mode) { - FILE *file; + FILE* file; int rw; if (handle == 0) @@ -51,52 +52,3 @@ FILE *_fdopen(int handle, char *mode) return file; } - -FILE *_wfdopen(int handle, wchar_t *mode) -{ - FILE *file; - int rw; - - if (handle == 0) - return stdin; - - if (handle == 1) - return stdout; - - if (handle == 2) - return stderr; - - if (handle == 3) - return stdaux; - - if (handle == 4) - return stdprn; - - file = __alloc_file(); - if (file == NULL) - return NULL; - file->_file = handle; - - rw = (mode[1] == L'+') || (mode[1] && (mode[2] == L'+')); - - if (*mode == L'a') - _lseek(handle, 0, SEEK_END); - - file->_cnt = 0; - file->_file = handle; - file->_bufsiz = 0; - -// The mode of the stream must be compatible with the mode of the file descriptor. -// this should be checked. - - if (rw) - file->_flag = _IOREAD | _IOWRT; - else if (*mode == L'r') - file->_flag = _IOREAD; - else - file->_flag = _IOWRT; - - file->_base = file->_ptr = NULL; - - return file; -} diff --git a/lib/msvcrt/stdio/ferror.c b/lib/msvcrt/stdio/ferror.c index 05110cd..f1b5bc7 100644 --- a/lib/msvcrt/stdio/ferror.c +++ b/lib/msvcrt/stdio/ferror.c @@ -7,6 +7,8 @@ int ferror(FILE *stream); #endif +int *_errno(void); + int ferror(FILE *stream) { return stream->_flag & _IOERR; diff --git a/lib/msvcrt/stdio/fflush.c b/lib/msvcrt/stdio/fflush.c index 7848bb3..7d34c0f 100644 --- a/lib/msvcrt/stdio/fflush.c +++ b/lib/msvcrt/stdio/fflush.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/kbhit.c + * FILE: lib/msvcrt/stdio/fflush.c * PURPOSE: Checks for keyboard hits * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -33,7 +33,7 @@ int fflush(FILE *f) __set_errno(0); _fwalk((void (*)(FILE *))fflush); - if (_errno) + if (errno) return EOF; __set_errno(e); return 0; diff --git a/lib/msvcrt/stdio/fgetc.c b/lib/msvcrt/stdio/fgetc.c index 7ce598c..cd145f4 100644 --- a/lib/msvcrt/stdio/fgetc.c +++ b/lib/msvcrt/stdio/fgetc.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/stdio/fgetc.c + * FILE: lib/msvcrt/stdio/fgetc.c * PURPOSE: Get a character string from stdin * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: diff --git a/lib/msvcrt/stdio/fgetchar.c b/lib/msvcrt/stdio/fgetchar.c index a80ce3a..3234b4c 100644 --- a/lib/msvcrt/stdio/fgetchar.c +++ b/lib/msvcrt/stdio/fgetchar.c @@ -1,12 +1,35 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fgetchar.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 #include int _fgetchar(void) { - return _getch(); + return getc(stdin); } -int _fgetwchar(void) +wint_t _fgetwchar(void) { - return _getch(); + return getwc(stdin); } diff --git a/lib/msvcrt/stdio/fgets.c b/lib/msvcrt/stdio/fgets.c index 3230fc5..403f462 100644 --- a/lib/msvcrt/stdio/fgets.c +++ b/lib/msvcrt/stdio/fgets.c @@ -1,16 +1,41 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fgets.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 + */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ + #include #include -char * -fgets(char *s, int n, FILE *f) + +char* fgets(char* s, int n, FILE* f) { - int c=0; - char *cs; + int c = 0; + char* cs; cs = s; - while (--n>0 && (c = getc(f)) != EOF) - { + while (--n>0 && (c = getc(f)) != EOF) { *cs++ = c; if (c == '\n') break; diff --git a/lib/msvcrt/stdio/fgetws.c b/lib/msvcrt/stdio/fgetws.c new file mode 100644 index 0000000..0f2dae6 --- /dev/null +++ b/lib/msvcrt/stdio/fgetws.c @@ -0,0 +1,58 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fgets.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 + */ +/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ + +#include +#include + + +//#include +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +wchar_t* fgetws(wchar_t* s, int n, FILE* f) +{ + wchar_t c = 0; + wchar_t* cs; + + cs = s; + //while (--n > 0 && (c = getwc(f)) != WEOF) { + while (n > 0) { + c = getwc(f); + if (c == WEOF) + break; + n--; + *cs++ = c; + if (c == L'\n') + break; + } + if (c == WEOF && cs == s) { + return NULL; + } + *cs++ = L'\0'; + return s; +} diff --git a/lib/msvcrt/stdio/filbuf.c b/lib/msvcrt/stdio/filbuf.c index 5033a60..836f8b9 100644 --- a/lib/msvcrt/stdio/filbuf.c +++ b/lib/msvcrt/stdio/filbuf.c @@ -11,46 +11,36 @@ #include #include -int _readcnv(int fn, void *buf, size_t siz ); +int _readcnv(int fn, void* buf, size_t siz); -int -_filbuf(FILE *f) +int _filbuf(FILE* f) { int size; char c; - if ( !OPEN4READING(f)) { __set_errno (EINVAL); return EOF; } - - if (f->_flag&(_IOSTRG|_IOEOF)) return EOF; f->_flag &= ~_IOUNGETC; - if (f->_base==NULL && (f->_flag&_IONBF)==0) { + if (f->_base == NULL && (f->_flag & _IONBF) == 0) { size = 4096; - if ((f->_base = malloc(size+1)) == NULL) - { + if ((f->_base = malloc(size+1)) == NULL) { // error ENOMEM f->_flag |= _IONBF; f->_flag &= ~(_IOFBF|_IOLBF); - } - else - { + } else { f->_flag |= _IOMYBUF; f->_bufsiz = size; } } - - if (f->_flag&_IONBF) f->_base = &c; - -// fush stdout before reading from stdin + // flush stdout before reading from stdin if (f == stdin) { if (stdout->_flag&_IOLBF) fflush(stdout); @@ -58,8 +48,8 @@ _filbuf(FILE *f) fflush(stderr); } -// if we have a dirty stream we flush it - if ( (f->_flag &_IODIRTY) == _IODIRTY ) + // if we have a dirty stream we flush it + if ((f->_flag &_IODIRTY) == _IODIRTY) fflush(f); @@ -99,6 +89,7 @@ _filbuf(FILE *f) } f->_cnt--; + return *f->_ptr++ & 0377; } @@ -108,7 +99,7 @@ wint_t _filwbuf(FILE *fp) } // convert the carriage return line feed pairs - +/* int _readcnv(int fn, void *buf, size_t siz ) { char *bufp = (char *)buf; @@ -128,4 +119,4 @@ int _readcnv(int fn, void *buf, size_t siz ) } return n + cr; } - + */ diff --git a/lib/msvcrt/stdio/flsbuf.c b/lib/msvcrt/stdio/flsbuf.c index 4af1ee9..6d5ccb5 100644 --- a/lib/msvcrt/stdio/flsbuf.c +++ b/lib/msvcrt/stdio/flsbuf.c @@ -9,171 +9,148 @@ #include #include -int cntcr(char *bufp, int bufsiz); -int convert(char *endp, int bufsiz,int n); -int _writecnv(int fn, void *buf, size_t bufsiz); - -int -_flsbuf(int c, FILE *f) -{ - char *base; - int n, rn; - char c1; - int size; - +int cntcr(char* bufp, int bufsiz); +int convert(char* endp, int bufsiz, int n); +int _writecnv(int fn, void* buf, size_t bufsiz); - if (!OPEN4WRITING(f)) { - __set_errno (EINVAL); - return EOF; - } -// no file associated with buffer -// this is a memory stream - - if ( fileno(f) == -1 ) - return c; +int _flsbuf(int c, FILE* f) +{ + char* base; + int n, rn; + char c1; + int size; + + if (!OPEN4WRITING(f)) { + __set_errno(EINVAL); + return EOF; + } - /* if the buffer is not yet allocated, allocate it */ - if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) - { - size = 4096; - if ((f->_base = base = malloc (size)) == NULL) - { - f->_flag |= _IONBF; - f->_flag &= ~(_IOFBF|_IOLBF); + // no file associated with buffer, this is a memory stream + if (fileno(f) == -1) { + return c; } - else - { - f->_flag |= _IOMYBUF; - f->_cnt = f->_bufsiz = size; - f->_ptr = base; - rn = 0; - if (f == stdout && isatty (fileno (stdout))) - f->_flag |= _IOLBF; + + /* if the buffer is not yet allocated, allocate it */ + if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) { + size = 4096; + if ((f->_base = base = malloc(size)) == NULL) { + f->_flag |= _IONBF; + f->_flag &= ~(_IOFBF|_IOLBF); + } else { + f->_flag |= _IOMYBUF; + f->_cnt = f->_bufsiz = size; + f->_ptr = base; + rn = 0; + if (f == stdout && isatty(fileno(stdout))) { + f->_flag |= _IOLBF; + } + } } - } - if (f->_flag & _IOLBF) - { - /* in line-buffering mode we get here on each character */ - *f->_ptr++ = c; - rn = f->_ptr - base; - if (c == '\n' || rn >= f->_bufsiz) - { - /* time for real flush */ - f->_ptr = base; - f->_cnt = 0; + if (f->_flag & _IOLBF) { + /* in line-buffering mode we get here on each character */ + *f->_ptr++ = c; + rn = f->_ptr - base; + if (c == '\n' || rn >= f->_bufsiz) { + /* time for real flush */ + f->_ptr = base; + f->_cnt = 0; + } else { + /* we got here because _cnt is wrong, so fix it */ + /* Negative _cnt causes all output functions to call */ + /* _flsbuf for each character, thus realizing line-buffering */ + f->_cnt = -rn; + return c; + } + } else if (f->_flag & _IONBF) { + c1 = c; + rn = 1; + base = &c1; + f->_cnt = 0; + } else { /* _IOFBF */ + rn = f->_ptr - base; + f->_ptr = base; + if ((f->_flag & _IOAHEAD) == _IOAHEAD) + _lseek(fileno(f), -(rn+f->_cnt), SEEK_CUR); + f->_cnt = f->_bufsiz; + f->_flag &= ~_IOAHEAD; } - else - { - /* we got here because _cnt is wrong, so fix it */ - /* Negative _cnt causes all output functions - to call _flsbuf for each character, thus realizing line-buffering */ - f->_cnt = -rn; - return c; + f->_flag &= ~_IODIRTY; + while (rn > 0) { + n = _write(fileno(f), base, rn); + if (n <= 0) { + f->_flag |= _IOERR; + return EOF; + } + rn -= n; + base += n; } - } - else if (f->_flag & _IONBF) - { - c1 = c; - rn = 1; - base = &c1; - f->_cnt = 0; - } - else /* _IOFBF */ - { - rn = f->_ptr - base; - f->_ptr = base; - if ( (f->_flag & _IOAHEAD) == _IOAHEAD ) - _lseek(fileno(f),-(rn+f->_cnt), SEEK_CUR); - f->_cnt = f->_bufsiz; - f->_flag &= ~_IOAHEAD; - } - - - - f->_flag &= ~_IODIRTY; - while (rn > 0) - { - n = _write(fileno(f), base, rn); - if (n <= 0) - { - f->_flag |= _IOERR; - return EOF; + if ((f->_flag & (_IOLBF|_IONBF)) == 0) { + f->_cnt--; + *f->_ptr++ = c; } - rn -= n; - base += n; - } - - - if ((f->_flag&(_IOLBF|_IONBF)) == 0) - { - f->_cnt--; - *f->_ptr++ = c; - } - return c; + return c; } -wint_t _flswbuf(wchar_t c,FILE *fp) +wint_t _flswbuf(wchar_t c, FILE* fp) { - return (wint_t )_flsbuf((int)c,fp); -} + int result; + result = _flsbuf((int)c, fp); + if (result == EOF) + return WEOF; + return (wint_t)result; +} -int _writecnv(int fn, void *buf, size_t siz) +int _writecnv(int fn, void* buf, size_t siz) { - char *bufp = (char *)buf; - int bufsiz = siz; - - char *tmp; - int cr1 = 0; - int cr2 = 0; - - int n; - - - cr1 = cntcr(bufp,bufsiz); - - tmp = malloc(cr1); - memcpy(tmp,bufp+bufsiz-cr1,cr1); - cr2 = cntcr(tmp,cr1); - - convert(bufp,bufsiz-cr2,cr1-cr2); - n = _write(fn, bufp, bufsiz + cr1); - - convert(tmp,cr1,cr2); - n += _write(fn, tmp, cr1 + cr2); - free(tmp); - return n; - - + char* bufp = (char*)buf; + int bufsiz = siz; + char* tmp; + int cr1 = 0; + int cr2 = 0; + int n; + + cr1 = cntcr(bufp, bufsiz); + tmp = malloc(cr1); + memcpy(tmp, bufp + bufsiz - cr1, cr1); + cr2 = cntcr(tmp, cr1); + convert(bufp, bufsiz - cr2, cr1 - cr2); + n = _write(fn, bufp, bufsiz + cr1); + convert(tmp, cr1, cr2); + n += _write(fn, tmp, cr1 + cr2); + free(tmp); + return n; } -int convert(char *endp, int bufsiz,int n) -{ - endp = endp + bufsiz + n; - while (bufsiz > 0) { - *endp = *(endp - n); - if (*endp == '\n') { - *endp--; - n--; - *endp = '\r'; - } - endp--; - bufsiz--; - } - return n; +int convert(char* endp, int bufsiz, int n) +{ + endp = endp + bufsiz + n; + while (bufsiz > 0) { + *endp = *(endp - n); + if (*endp == '\n') { + *endp--; + n--; + *endp = '\r'; + } + endp--; + bufsiz--; + } + return n; } -int cntcr(char *bufp, int bufsiz) -{ - int cr = 0; - while (bufsiz > 0) { - if (*bufp == '\n') - cr++; - bufp++; - bufsiz--; - } - return cr; +int cntcr(char* bufp, int bufsiz) +{ + int cr = 0; + + while (bufsiz > 0) { + if (*bufp == '\n') { + cr++; + } + bufp++; + bufsiz--; + } + return cr; } diff --git a/lib/msvcrt/stdio/fopen.c b/lib/msvcrt/stdio/fopen.c index def102f..2b506d6 100644 --- a/lib/msvcrt/stdio/fopen.c +++ b/lib/msvcrt/stdio/fopen.c @@ -1,7 +1,33 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fopen.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 + */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include +#include #include #include //#include @@ -11,14 +37,15 @@ #undef _fmode extern unsigned int _fmode; -FILE * __alloc_file(void); +FILE* __alloc_file(void); + +//extern int _fmode; FILE* fopen(const char *file, const char *mode) { FILE *f; int fd, rw, oflags = 0; - char tbchar; if (file == 0) return 0; @@ -29,29 +56,16 @@ FILE* fopen(const char *file, const char *mode) if (f == NULL) return NULL; - rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+')); - - switch (*mode) - { - case 'a': + rw = (strchr(mode, '+') == NULL) ? 0 : 1; + if (strchr(mode, 'a')) oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); - break; - case 'r': + if (strchr(mode, 'r')) oflags = rw ? O_RDWR : O_RDONLY; - break; - case 'w': + if (strchr(mode, 'w')) oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY); - break; - default: - return (NULL); - } - if (mode[1] == '+') - tbchar = mode[2]; - else - tbchar = mode[1]; - if (tbchar == 't') + if (strchr(mode, 't')) oflags |= O_TEXT; - else if (tbchar == 'b') + else if (strchr(mode, 'b')) oflags |= O_BINARY; else oflags |= (_fmode & (O_TEXT|O_BINARY)); @@ -60,9 +74,10 @@ FILE* fopen(const char *file, const char *mode) if (fd < 0) return NULL; -// ms crtdll ensures that writes will end up at the end of file in append mode +// msvcrt ensures that writes will end up at the end of file in append mode // we just move the file pointer to the end of file initially - if (*mode == 'a') + + if (strchr(mode, 'a')) lseek(fd, 0, SEEK_END); f->_cnt = 0; @@ -70,11 +85,18 @@ FILE* fopen(const char *file, const char *mode) f->_bufsiz = 0; if (rw) f->_flag = _IOREAD | _IOWRT; - else if (*mode == 'r') + else if (strchr(mode, 'r')) f->_flag = _IOREAD; else f->_flag = _IOWRT; + if (strchr(mode, 't')) + f->_flag |= _IOTEXT; + else if (strchr(mode, 'b')) + f->_flag |= _IOBINARY; + else if (_fmode & O_BINARY) + f->_flag |= _IOBINARY; + f->_base = f->_ptr = NULL; return f; } @@ -83,7 +105,6 @@ FILE* _wfopen(const wchar_t *file, const wchar_t *mode) { FILE *f; int fd, rw, oflags = 0; - wchar_t tbchar; if (file == 0) return 0; @@ -94,29 +115,16 @@ FILE* _wfopen(const wchar_t *file, const wchar_t *mode) if (f == NULL) return NULL; - rw = (mode[1] == L'+') || (mode[1] && (mode[2] == L'+')); - - switch (*mode) - { - case L'a': + rw = (wcschr(mode, L'+') == NULL) ? 0 : 1; + if (wcschr(mode, L'a')) oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); - break; - case L'r': + if (wcschr(mode, L'r')) oflags = rw ? O_RDWR : O_RDONLY; - break; - case L'w': + if (wcschr(mode, L'w')) oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY); - break; - default: - return (NULL); - } - if (mode[1] == L'+') - tbchar = mode[2]; - else - tbchar = mode[1]; - if (tbchar == L't') + if (wcschr(mode, L't')) oflags |= O_TEXT; - else if (tbchar == L'b') + else if (wcschr(mode, L'b')) oflags |= O_BINARY; else oflags |= (_fmode & (O_TEXT|O_BINARY)); @@ -125,9 +133,9 @@ FILE* _wfopen(const wchar_t *file, const wchar_t *mode) if (fd < 0) return NULL; -// ms crtdll ensures that writes will end up at the end of file in append mode +// msvcrt ensures that writes will end up at the end of file in append mode // we just move the file pointer to the end of file initially - if (*mode == L'a') + if (wcschr(mode, 'a')) lseek(fd, 0, SEEK_END); f->_cnt = 0; @@ -135,11 +143,18 @@ FILE* _wfopen(const wchar_t *file, const wchar_t *mode) f->_bufsiz = 0; if (rw) f->_flag = _IOREAD | _IOWRT; - else if (*mode == L'r') + else if (wcschr(mode, L'r')) f->_flag = _IOREAD; else f->_flag = _IOWRT; + if (wcschr(mode, L't')) + f->_flag |= _IOTEXT; + else if (wcschr(mode, L'b')) + f->_flag |= _IOBINARY; + else if (_fmode & O_BINARY) + f->_flag |= _IOBINARY; + f->_base = f->_ptr = NULL; return f; } diff --git a/lib/msvcrt/stdio/fputchar.c b/lib/msvcrt/stdio/fputchar.c index 46d4eb5..0ff19fc 100644 --- a/lib/msvcrt/stdio/fputchar.c +++ b/lib/msvcrt/stdio/fputchar.c @@ -1,14 +1,35 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fputchar.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 -#include int _fputchar(int c) { - return _putch(c); + return putc(c, stdout); } int _fputwchar(wchar_t c) { - //return _putch(c); - return 0; + return putwc(c, stdout); } diff --git a/lib/msvcrt/stdio/fputs.c b/lib/msvcrt/stdio/fputs.c index d39672b..e3d14ba 100644 --- a/lib/msvcrt/stdio/fputs.c +++ b/lib/msvcrt/stdio/fputs.c @@ -1,4 +1,30 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * fputs.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 + */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ + #include #include #include @@ -34,3 +60,33 @@ fputs(const char *s, FILE *f) return(r); } + +int +fputws(const wchar_t* s, FILE* f) +{ + int r = 0; + int unbuffered; + wchar_t c; + wchar_t localbuf[BUFSIZ]; + + unbuffered = f->_flag & _IONBF; + if (unbuffered) + { + f->_flag &= ~_IONBF; + f->_ptr = f->_base = localbuf; + f->_bufsiz = BUFSIZ; + } + + while ((c = *s++)) + r = putwc(c, f); + + if (unbuffered) + { + fflush(f); + f->_flag |= _IONBF; + f->_base = NULL; + f->_bufsiz = 0; + f->_cnt = 0; + } + return(r); +} diff --git a/lib/msvcrt/stdio/fsopen.c b/lib/msvcrt/stdio/fsopen.c index 0b36507..b362c6f 100644 --- a/lib/msvcrt/stdio/fsopen.c +++ b/lib/msvcrt/stdio/fsopen.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/kbhit.c + * FILE: lib/msvcrt/stdio/fsopen.c * PURPOSE: Checks for keyboard hits * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -79,7 +79,7 @@ FILE* _fsopen(const char *file, const char *mode, int shflag) if (fd < 0) return NULL; -// ms crtdll ensures that writes will end up at the end of file in append mode +// msvcrt ensures that writes will end up at the end of file in append mode // we just move the file pointer to the end of file initially if (*mode == 'a') lseek(fd, 0, SEEK_END); @@ -157,7 +157,7 @@ FILE* _wfsopen(const wchar_t *file, const wchar_t *mode, int shflag) if (fd < 0) return NULL; -// ms crtdll ensures that writes will end up at the end of file in append mode +// msvcrt ensures that writes will end up at the end of file in append mode // we just move the file pointer to the end of file initially if (*mode == L'a') lseek(fd, 0, SEEK_END); diff --git a/lib/msvcrt/stdio/ftell.c b/lib/msvcrt/stdio/ftell.c index bb48673..ddc4c8d 100644 --- a/lib/msvcrt/stdio/ftell.c +++ b/lib/msvcrt/stdio/ftell.c @@ -2,7 +2,6 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include -//#include #include #include #include diff --git a/lib/msvcrt/stdio/fwalk.c b/lib/msvcrt/stdio/fwalk.c index f7d261b..f1e117f 100644 --- a/lib/msvcrt/stdio/fwalk.c +++ b/lib/msvcrt/stdio/fwalk.c @@ -2,11 +2,11 @@ #include #include -// not exported by crtdll + +// not exported by msvcrt or crtdll __file_rec *__file_rec_list; -void -_fwalk(void (*func)(FILE *)) +void _fwalk(void (*func)(FILE *)) { __file_rec *fr; int i; diff --git a/lib/msvcrt/stdio/getc.c b/lib/msvcrt/stdio/getc.c index 3bdb61c..d20911f 100644 --- a/lib/msvcrt/stdio/getc.c +++ b/lib/msvcrt/stdio/getc.c @@ -1,3 +1,26 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * getc.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 #include #include @@ -6,28 +29,30 @@ //getc can be a macro #undef getc +#undef getwc + +#ifndef MB_CUR_MAX +#define MB_CUR_MAX 10 +#endif int getc(FILE *fp) { - int c = -1; -// check for invalid stream + int c = -1; + // check for invalid stream if ( !__validfp (fp) ) { __set_errno(EINVAL); return EOF; } -// check for read access on stream - + // check for read access on stream if ( !OPEN4READING(fp) ) { __set_errno(EINVAL); - return -1; + return EOF; } - if(fp->_cnt > 0) { fp->_cnt--; - c = (int)*fp->_ptr++; - } - else { + c = (int)(*fp->_ptr++ & 0377); + } else { c = _filbuf(fp); } return c; @@ -35,36 +60,71 @@ int getc(FILE *fp) wint_t getwc(FILE *fp) { - int c = -1; + wint_t c = -1; - // check for invalid stream - if (!__validfp(fp)) - { - __set_errno(EINVAL); - return EOF; + // check for invalid stream + if (!__validfp(fp)) { + __set_errno(EINVAL); + return WEOF; } - - // check for read access on stream - if (!OPEN4READING(fp)) - { - __set_errno(EINVAL); - return -1; + // check for read access on stream +//#define OPEN4READING(f) ((((f)->_flag & _IOREAD) == _IOREAD ) ) + if (!OPEN4READING(fp)) { + __set_errno(EINVAL); + return WEOF; } + // might check on multi bytes if text mode + if (fp->_flag & _IOBINARY) { + if (fp->_cnt > 1) { + fp->_cnt -= sizeof(wchar_t); + c = (wint_t)*((wchar_t*)(fp->_ptr))++; + } else { + c = _filwbuf(fp); + // need to fix by one values of fp->_ptr and fp->_cnt + fp->_ptr++; + fp->_cnt--; + } + } else { +#if 0 + BOOL get_bytes = 0; + int mb_cnt = 0; + int found_cr = 0; + //int count; + char mbchar[MB_CUR_MAX]; - // might check on multi bytes if text mode + do { + if (fp->_cnt > 0) { + fp->_cnt--; + mbchar[mb_cnt] = *fp->_ptr++ & 0377; + } else { + mbchar[mb_cnt] = _filbuf(fp); + } + if (isleadbyte(mbchar[mb_cnt])) { + get_bytes = 1; + } else { + get_bytes = 0; + } + if (_ismbblead(mbchar[mb_cnt])) { + } + ++mb_cnt; + //} + } while (get_bytes); - if (fp->_cnt > 0) - { - fp->_cnt -= sizeof(wchar_t); - c = (wint_t )*((wchar_t *)(fp->_ptr))++; - } - else - { - c = _filwbuf(fp); + // Convert a multibyte character to a corresponding wide character. + mb_cnt = mbtowc(&c, mbchar, mb_cnt); + if (mb_cnt == -1) { + fp->_flag |= _IOERR; + return WEOF; + } +#else + if (fp->_cnt > 0) { + fp->_cnt--; + c = *fp->_ptr++ &0377; + } else { + c = _filbuf(fp); + } +#endif } - return c; + return c; } - - - diff --git a/lib/msvcrt/stdio/getchar.c b/lib/msvcrt/stdio/getchar.c index 14392d2..48fe4b9 100644 --- a/lib/msvcrt/stdio/getchar.c +++ b/lib/msvcrt/stdio/getchar.c @@ -1,10 +1,43 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +/* $Id$ + * + * ReactOS msvcrt library + * + * getchar.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 #include #undef getchar +#undef getwchar + int getchar(void) { return getc(stdin); } + +wint_t +getwchar(void) +{ + return getwc(stdin); +} diff --git a/lib/msvcrt/stdio/gets.c b/lib/msvcrt/stdio/gets.c index ac97420..1721453 100644 --- a/lib/msvcrt/stdio/gets.c +++ b/lib/msvcrt/stdio/gets.c @@ -1,27 +1,63 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/stdio/gets.c - * PURPOSE: Get a character string from stdin - * PROGRAMER: DJ Delorie - * UPDATE HISTORY: - * 28/12/98: Appropriated for Reactos +/* $Id$ + * + * ReactOS msvcrt library + * + * gets.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * 28/12/1998: Appropriated for Reactos + * + * 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 */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ + #include -char *gets(char *s) +char* gets(char* s) { - int c; - char *cs; + int c; + char* cs; + + cs = s; + while ((c = getc(stdin)) != '\n' && c != EOF) + *cs++ = c; + if (c == EOF && cs == s) + return NULL; + *cs++ = '\0'; + return s; +} - cs = s; - while ((c = getchar()) != '\n' && c != EOF) - *cs++ = c; - if (c == EOF && cs==s) - return NULL; - *cs++ = '\0'; - return s; +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +// Get a line from the stdin stream. +wchar_t* _getws(wchar_t* s) +{ + wchar_t c; + wchar_t* cs; + + cs = s; + while ((c = getwc(stdin)) != L'\n' && c != WEOF) + *cs++ = c; + if (c == WEOF && cs == s) + return NULL; + *cs++ = L'\0'; + return s; } #if 0 diff --git a/lib/msvcrt/stdio/getw.c b/lib/msvcrt/stdio/getw.c index 119d4e1..6322abc 100644 --- a/lib/msvcrt/stdio/getw.c +++ b/lib/msvcrt/stdio/getw.c @@ -18,13 +18,18 @@ Cambridge, MA 02139, USA. */ #include + /* Read a word (int) from STREAM. */ int _getw(FILE *stream) { int w; /* Is there a better way? */ - if (fread( &w, sizeof(w), 1, stream) != 1) + if (fread( &w, sizeof(w), 1, stream) != 1) { + // EOF is a legitimate integer value so users must + // check feof or ferror to verify an EOF return. return(EOF); + } return(w); } + diff --git a/lib/msvcrt/stdio/printf.c b/lib/msvcrt/stdio/printf.c index 36cd1ae..ca273c4 100644 --- a/lib/msvcrt/stdio/printf.c +++ b/lib/msvcrt/stdio/printf.c @@ -20,35 +20,25 @@ #include #include -/* Write formatted output to stdout from the format string FORMAT. */ -/* VARARGS1 */ -int -printf (const char *format, ...) + +int printf(const char* format, ...) { - va_list arg; - int done; + va_list arg; + int done; - va_start (arg, format); - done = vprintf (format, arg); - va_end (arg); - return done; + va_start(arg, format); + done = vprintf(format, arg); + va_end(arg); + return done; } -int -wprintf (const wchar_t *format, ...) +int wprintf(const wchar_t* format, ...) { - va_list arg; - int done; + va_list arg; + int done; - va_start (arg, format); - done = vwprintf (format, arg); - va_end (arg); - return done; + va_start(arg, format); + done = vwprintf(format, arg); + va_end(arg); + return done; } - -#ifdef USE_IN_LIBIO -# undef _IO_printf -/* This is for libg++. */ -strong_alias (printf, _IO_printf); -#endif - diff --git a/lib/msvcrt/stdio/putc.c b/lib/msvcrt/stdio/putc.c index 62f31ce..b020075 100644 --- a/lib/msvcrt/stdio/putc.c +++ b/lib/msvcrt/stdio/putc.c @@ -1,4 +1,29 @@ +/* $Id$ + * + * ReactOS msvcrt library + * + * putc.c + * + * Copyright (C) 2002 Robert Dickenson + * + * Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * + * 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 + */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ + #include #include #include @@ -7,62 +32,112 @@ // putc can be a macro #undef putc +#undef putwc -int putc(int c, FILE *fp) -{ - -// valid stream macro should check that fp -// is dword aligned - if (!__validfp (fp)) { - __set_errno(EINVAL); - return -1; - } -// check for write access on fp +#ifndef MB_CUR_MAX_CONST +#define MB_CUR_MAX_CONST 10 +#endif - if ( !OPEN4WRITING(fp) ) { - __set_errno(EINVAL); - return -1; - } - - fp->_flag |= _IODIRTY; - if (fp->_cnt > 0 ) { - fp->_cnt--; - *(fp)->_ptr++ = (unsigned char)c; - return (int)(unsigned char)c; - } - else { - return _flsbuf((unsigned char)c,fp); - } - return EOF; +int putc(int c, FILE* fp) +{ + // valid stream macro should check that fp is dword aligned + if (!__validfp(fp)) { + __set_errno(EINVAL); + return EOF; + } + // check for write access on fp + if (!OPEN4WRITING(fp)) { + __set_errno(EINVAL); + return EOF; + } + fp->_flag |= _IODIRTY; + if (fp->_cnt > 0) { + fp->_cnt--; + *(fp)->_ptr++ = (unsigned char)c; + return (int)(unsigned char)c; + } else { + return _flsbuf((unsigned char)c, fp); + } + return EOF; } -wint_t putwc(wint_t c, FILE *fp) +//wint_t putwc(wint_t c, FILE* fp) +int putwc(wint_t c, FILE* fp) { -// valid stream macro should check that fp -// is dword aligned - if (!__validfp (fp)) { - __set_errno(EINVAL); - return -1; - } -// check for write access on fp - - if ( !OPEN4WRITING(fp) ) { - __set_errno(EINVAL); - return -1; - } - // might check on multi bytes if text mode - - fp->_flag |= _IODIRTY; + // valid stream macro should check that fp is dword aligned + if (!__validfp(fp)) { + __set_errno(EINVAL); + return WEOF; + } + // check for write access on fp + if (!OPEN4WRITING(fp)) { + __set_errno(EINVAL); + return WEOF; + } + // might check on multi bytes if text mode + if (fp->_flag & _IOBINARY) { + //if (1) { - if (fp->_cnt > 0 ) { - fp->_cnt-= sizeof(wchar_t); - *((wchar_t *)(fp->_ptr))++ = c; - return (wint_t)c; + fp->_flag |= _IODIRTY; + if (fp->_cnt > 0) { + fp->_cnt -= sizeof(wchar_t); + //*((wchar_t*)(fp->_ptr))++ = c; + *((wchar_t*)(fp->_ptr)) = c; + ++((wchar_t*)(fp->_ptr)); + return (wint_t)c; + } else { +#if 1 + wint_t result; + result = _flsbuf(c, fp); + if (result == EOF) + return WEOF; + result = _flsbuf((int)(c >> 8), fp); + if (result == EOF) + return WEOF; + return result; +#else + return _flswbuf(c, fp); +#endif } - else - return _flswbuf(c,fp); - - return -1; + } else { +#if 0 + int i; + int mb_cnt; + char mbchar[MB_CUR_MAX_CONST]; + // Convert wide character to the corresponding multibyte character. + mb_cnt = wctomb(mbchar, (wchar_t)c); + if (mb_cnt == -1) { + fp->_flag |= _IOERR; + return WEOF; + } + if (mb_cnt > MB_CUR_MAX_CONST) { + // BARF(); + } + for (i = 0; i < mb_cnt; i++) { + fp->_flag |= _IODIRTY; + if (fp->_cnt > 0) { + fp->_cnt--; + *(fp)->_ptr++ = (unsigned char)mbchar[i]; + } else { + if (_flsbuf((unsigned char)mbchar[i], fp) == EOF) { + return WEOF; + } + } + } +#else + fp->_flag |= _IODIRTY; + if (fp->_cnt > 0) { + fp->_cnt--; + *(fp)->_ptr++ = (unsigned char)c; + } else { + if (_flsbuf(c, fp) == EOF) { + return WEOF; + } + } +#endif + return c; + } + return WEOF; } diff --git a/lib/msvcrt/stdio/putchar.c b/lib/msvcrt/stdio/putchar.c index cc85051..4cf5eca 100644 --- a/lib/msvcrt/stdio/putchar.c +++ b/lib/msvcrt/stdio/putchar.c @@ -2,7 +2,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/getch.c + * FILE: lib/msvcrt/stdio/putchar.c * PURPOSE: Writes a character to stdout * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -12,6 +12,8 @@ #undef putc #undef putchar +#undef putwc +#undef putwchar int putchar(int c) { diff --git a/lib/msvcrt/stdio/puts.c b/lib/msvcrt/stdio/puts.c index 443a36b..56132cd 100644 --- a/lib/msvcrt/stdio/puts.c +++ b/lib/msvcrt/stdio/puts.c @@ -5,24 +5,25 @@ #include #undef putchar -int -puts(const char *s) +#undef putwchar + + +int puts(const char *s) { - - int c; - while ((c = *s++)) - putchar(c); - return putchar('\n'); + int c; + while ((c = *s++)) { + putchar(c); + } + return putchar('\n'); } -int -_putws(const wchar_t *s) +int _putws(const wchar_t *s) { - - wint_t c; - while ((c = *s++)) - putwchar(c); - return putwchar(L'\n'); - + wint_t c; + + while ((c = *s++)) { + putwchar(c); + } + return putwchar(L'\n'); } diff --git a/lib/msvcrt/stdio/rename.c b/lib/msvcrt/stdio/rename.c index 6139cf7..aea2bfa 100644 --- a/lib/msvcrt/stdio/rename.c +++ b/lib/msvcrt/stdio/rename.c @@ -3,25 +3,13 @@ #include -int rename(const char *old_, const char *new_) +int rename(const char* old_, const char* new_) { - if (old_ == NULL || new_ == NULL) - return -1; + if (old_ == NULL || new_ == NULL) + return -1; - if (!MoveFileA(old_,new_)) - return -1; + if (!MoveFileA(old_, new_)) + return -1; - return 0; + return 0; } - -int _wrename(const wchar_t *old_, const wchar_t *new_) -{ - if (old_ == NULL || new_ == NULL) - return -1; - - if (!MoveFileW(old_,new_)) - return -1; - - return 0; -} - diff --git a/lib/msvcrt/stdio/rmtmp.c b/lib/msvcrt/stdio/rmtmp.c index 6989447..1d2a8c5 100644 --- a/lib/msvcrt/stdio/rmtmp.c +++ b/lib/msvcrt/stdio/rmtmp.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/stdio/rmtmp.c + * FILE: lib/msvcrt/stdio/rmtmp.c * PURPOSE: remove temporary files in current directory * PROGRAMMER: Boudewijn ( ariadne@xs4all.nl) * UPDATE HISTORY: diff --git a/lib/msvcrt/stdio/tempnam.c b/lib/msvcrt/stdio/tempnam.c index 81215eb..88e4d0b 100644 --- a/lib/msvcrt/stdio/tempnam.c +++ b/lib/msvcrt/stdio/tempnam.c @@ -3,40 +3,25 @@ #include -char *_tempnam(const char *dir,const char *prefix ) +char* _tempnam(const char* dir,const char* prefix) { - char *TempFileName = malloc(MAX_PATH); - char *d; - - if (dir == NULL) - d = getenv("TMP"); - else - d = (char *)dir; - - if (GetTempFileNameA(d, prefix, 1, TempFileName) == 0) - { - free(TempFileName); - return NULL; - } - - return TempFileName; -} - -wchar_t *_wtempnam(const wchar_t *dir,const wchar_t *prefix) -{ - wchar_t *TempFileName = malloc(MAX_PATH); - wchar_t *d; - - if (dir == NULL) - d = _wgetenv(L"TMP"); - else - d = (wchar_t *)dir; - - if (GetTempFileNameW(d, prefix, 1, TempFileName) == 0) - { - free(TempFileName); - return NULL; + char* TempFileName = malloc(MAX_PATH); + char* d; + + if (dir == NULL) + d = getenv("TMP"); + else + d = (char*)dir; + +#ifdef _MSVCRT_LIB_ // TODO: check on difference? + if (GetTempFileNameA(d, prefix, 1, TempFileName) == 0) { +#else// TODO: FIXME: review which is correct + if (GetTempFileNameA(d, prefix, 0, TempFileName) == 0) { +#endif /*_MSVCRT_LIB_*/ + + free(TempFileName); + return NULL; } - return TempFileName; + return TempFileName; } diff --git a/lib/msvcrt/stdio/tmpfile.c b/lib/msvcrt/stdio/tmpfile.c index 1e1c116..2854ea2 100644 --- a/lib/msvcrt/stdio/tmpfile.c +++ b/lib/msvcrt/stdio/tmpfile.c @@ -14,7 +14,7 @@ #include -FILE * __alloc_file(void); +FILE * __alloc_file(void); FILE * tmpfile(void) @@ -38,7 +38,7 @@ tmpfile(void) // errno = 0; temp_fd = _open(temp_name, 0, SH_DENYRW); // if ( errno == ENOENT ) -// break; +// break; } while (temp_fd == -1 && (temp_name = tmpnam(0)) != 0); if (temp_name == 0) diff --git a/lib/msvcrt/stdio/tmpnam.c b/lib/msvcrt/stdio/tmpnam.c index cd16118..ecd2fbb 100644 --- a/lib/msvcrt/stdio/tmpnam.c +++ b/lib/msvcrt/stdio/tmpnam.c @@ -3,26 +3,14 @@ #include -char *tmpnam(char *s) +char* tmpnam(char* s) { - char PathName[MAX_PATH]; - static char static_buf[MAX_PATH]; + char PathName[MAX_PATH]; + static char static_buf[MAX_PATH]; - GetTempPathA(MAX_PATH, PathName); - GetTempFileNameA(PathName, "ARI", 007, static_buf); - strcpy(s, static_buf); + GetTempPathA(MAX_PATH, PathName); + GetTempFileNameA(PathName, "ARI", 007, static_buf); + strcpy(s,static_buf); - return s; -} - -wchar_t *_wtmpnam(wchar_t *s) -{ - wchar_t PathName[MAX_PATH]; - static wchar_t static_buf[MAX_PATH]; - - GetTempPathW(MAX_PATH, PathName); - GetTempFileNameW(PathName, L"ARI", 007, static_buf); - wcscpy(s, static_buf); - - return s; + return s; } diff --git a/lib/msvcrt/stdio/ungetc.c b/lib/msvcrt/stdio/ungetc.c index 1ef5b43..2fd2aa6 100644 --- a/lib/msvcrt/stdio/ungetc.c +++ b/lib/msvcrt/stdio/ungetc.c @@ -5,10 +5,10 @@ #include #include + int ungetc(int c, FILE *f) { - if (!__validfp (f) || !OPEN4READING(f)) - { + if (!__validfp (f) || !OPEN4READING(f)) { __set_errno (EINVAL); return EOF; } @@ -41,8 +41,7 @@ int ungetc(int c, FILE *f) wint_t ungetwc(wchar_t c, FILE *f) { - if (!__validfp (f) || !OPEN4READING(f)) - { + if (!__validfp (f) || !OPEN4READING(f)) { __set_errno(EINVAL); return EOF; } diff --git a/lib/msvcrt/stdio/vfprintf.c b/lib/msvcrt/stdio/vfprintf.c index c24cceb..971c5f1 100644 --- a/lib/msvcrt/stdio/vfprintf.c +++ b/lib/msvcrt/stdio/vfprintf.c @@ -11,36 +11,34 @@ int _isinf(double x); -int -__vfprintf (FILE *fp, const char *fmt0, va_list args); +int __vfprintf(FILE*, const char*, va_list); -int -vfprintf(FILE *f, const char *fmt, va_list ap) + +int vfprintf(FILE* f, const char* fmt, va_list ap) { - int len; - char localbuf[BUFSIZ]; + int len; + char localbuf[BUFSIZ]; #if 0 - __fileno_lock(fileno(f)); + __fileno_lock(fileno(f)); #endif - if (f->_flag & _IONBF) - { - f->_flag &= ~_IONBF; - f->_ptr = f->_base = localbuf; - f->_bufsiz = BUFSIZ; - len = __vfprintf(f,fmt, ap); - (void)fflush(f); - f->_flag |= _IONBF; - f->_base = NULL; - f->_bufsiz = 0; - f->_cnt = 0; - } - else - len = __vfprintf(f,fmt, ap); + if (f->_flag & _IONBF) { + f->_flag &= ~_IONBF; + f->_ptr = f->_base = localbuf; + f->_bufsiz = BUFSIZ; + len = __vfprintf(f, fmt, ap); + (void)fflush(f); + f->_flag |= _IONBF; + f->_base = NULL; + f->_bufsiz = 0; + f->_cnt = 0; + } else { + len = __vfprintf(f,fmt, ap); + } #if 0 - __fileno_unlock(fileno(f)); + __fileno_unlock(fileno(f)); #endif - return (ferror(f) ? EOF : len); + return (ferror(f) ? EOF : len); } @@ -89,15 +87,15 @@ static int skip_atoi(const char **s) } -static int do_div(long long *n,int base) +static int do_div(LONGLONG *n,int base) { - int __res = ((unsigned long long) *n) % (unsigned) base; - *n = ((unsigned long long) *n) / (unsigned) base; + int __res = ((ULONGLONG) *n) % (unsigned) base; + *n = ((ULONGLONG) *n) / (unsigned) base; return __res; } -static int number(FILE * f, long long num, int base, int size, int precision ,int type) +static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -688,7 +686,7 @@ static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int pre int __vfprintf(FILE *f, const char *fmt, va_list args) { int len; - unsigned long long num; + ULONGLONG num; int i, base; long double _ldouble; double _double; @@ -1052,7 +1050,7 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) } if (qualifier == 'I') - num = va_arg(args, unsigned long long); + num = va_arg(args, ULONGLONG); else if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { diff --git a/lib/msvcrt/stdio/vfscanf.c b/lib/msvcrt/stdio/vfscanf.c index 909901b..349aaba 100644 --- a/lib/msvcrt/stdio/vfscanf.c +++ b/lib/msvcrt/stdio/vfscanf.c @@ -16,7 +16,10 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +//#include +#include // robd +#include // robd + #include #include #include @@ -39,17 +42,17 @@ long int __strtol_internal (const char *__nptr, char **__endptr, int __base, int unsigned long int __strtoul_internal (const char *__nptr, char **__endptr, int __base, int __group); - -#ifdef __GNUC__ -#define HAVE_LONGLONG -#define LONGLONG long long -#else -#define LONGLONG long -#endif +#include // robd +//#ifdef __GNUC__ +//#define HAVE_LONGLONG +//#define LONGLONG LONGLONG +//#else +//#define LONGLONG long +//#endif /* Those are flags in the conversion format. */ # define LONG 0x001 /* l: long or double */ -# define LONGDBL 0x002 /* L: long long or long double */ +# define LONGDBL 0x002 /* L: LONGLONG or long double */ # define SHORT 0x004 /* h: short */ # define SUPPRESS 0x008 /* *: suppress assignment */ # define POINTER 0x010 /* weird %p pointer (`fake hex') */ @@ -112,8 +115,7 @@ void ADDW(int Ch) \ char *old = wp; wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax; wp = (char *) malloc (wpmax); - if (old != NULL) - { + if (old != NULL) { memcpy (wp, old, wpsize); free(old); } @@ -148,8 +150,8 @@ int __vfscanf (FILE *s, const char *format, va_list argptr) /* Integral holding variables. */ union { - long long int q; - unsigned long long int uq; + LONGLONG q; + ULONGLONG uq; long int l; unsigned long int ul; } num; @@ -321,7 +323,7 @@ int __vfscanf (FILE *s, const char *format, va_list argptr) break; case 'q': case 'L': - /* double's are long double's, and int's are long long int's. */ + /* double's are long double's, and int's are LONGLONG int's. */ if (flags & TYPEMOD) /* Signal illegal format element. */ conv_error (); @@ -780,19 +782,19 @@ int __vfscanf (FILE *s, const char *format, va_list argptr) if (! number_signed) { if (flags & LONGDBL) { - *ARG (unsigned LONGLONG int *) = num.uq; + *ARG (ULONGLONG*) = num.uq; } else if (flags & LONG) - *ARG (unsigned long int *) = num.ul; + *ARG (unsigned long int*) = num.ul; else if (flags & SHORT) - *ARG (unsigned short int *) = (unsigned short int) num.ul; + *ARG (unsigned short int*) = (unsigned short int) num.ul; else - *ARG (unsigned int *) = (unsigned int) num.ul; + *ARG (unsigned int*) = (unsigned int) num.ul; } else { if (flags & LONGDBL) { - *ARG (LONGLONG int *) = num.q; + *ARG (LONGLONG*) = num.q; } else if (flags & LONG) *ARG (long int *) = num.l; @@ -1066,7 +1068,11 @@ float __strtof_internal (const char *__nptr, char **__endptr,int __group) static double powten[] = { 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L, +#ifdef __GNUC__ 1e512L, 1e512L*1e512L, 1e2048L, 1e4096L +#else + 1e256L, 1e256L, 1e256L, 1e256L +#endif }; long double __strtold_internal (const char *s,char **sret, int __group) diff --git a/lib/msvcrt/stdio/vfwprint.c b/lib/msvcrt/stdio/vfwprint.c index 4266f5d..bb2af01 100644 --- a/lib/msvcrt/stdio/vfwprint.c +++ b/lib/msvcrt/stdio/vfwprint.c @@ -1,5 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include + +//#include +#include // robd +#include // robd + #include #include #include @@ -88,15 +92,15 @@ static int skip_wtoi(const wchar_t **s) } -static int do_div(long long *n,int base) +static int do_div(LONGLONG *n,int base) { - int __res = ((unsigned long long) *n) % (unsigned) base; - *n = ((unsigned long long) *n) / (unsigned) base; + int __res = ((ULONGLONG) *n) % (unsigned) base; + *n = ((ULONGLONG) *n) / (unsigned) base; return __res; } -static int number(FILE * f, long long num, int base, int size, int precision ,int type) +static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type) { wchar_t c,sign,tmp[66]; const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz"; @@ -672,7 +676,7 @@ static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int pre int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) { int len; - unsigned long long num; + ULONGLONG num; int i, base; long double _ldouble; double _double; @@ -805,7 +809,7 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) { if (putwc(L' ', f) == WEOF) return -1; - done; + done++; } if (qualifier == L'l' || qualifier == L'w') { @@ -1032,7 +1036,7 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) } if (qualifier == L'I') - num = va_arg(args, unsigned long long); + num = va_arg(args, ULONGLONG); else if (qualifier == L'l') num = va_arg(args, unsigned long); else if (qualifier == L'h') { diff --git a/lib/msvcrt/stdio/vprintf.c b/lib/msvcrt/stdio/vprintf.c index f724749..33c74b8 100644 --- a/lib/msvcrt/stdio/vprintf.c +++ b/lib/msvcrt/stdio/vprintf.c @@ -21,27 +21,57 @@ Cambridge, MA 02139, USA. */ #include #include + #undef vprintf #undef vwprintf -/* Write formatted output to stdout according to the - format string FORMAT, using the argument list in ARG. */ -int -vprintf (format, arg) - const char *format; - va_list arg; +//#define _USE_VARARG_ + +#ifndef _USE_VARARG_ + +int vprintf(const char* format, va_list arg) +{ + int ret; + + ret = vfprintf(stdout, format, arg); + fflush(stdout); + return ret; +} + +int vwprintf(const wchar_t* format, va_list arg) +{ + int ret; + + ret = vfwprintf(stdout, format, arg); + fflush(stdout); + return ret; +} + +#else + +int vprintf(const char* format, ...) { - int ret = vfprintf (stdout, format, arg); - fflush(stdout); - return ret; + va_list arg; + int ret; + + va_start(arg, format); + ret = vfprintf(stdout, format, arg); + va_end(arg); + + fflush(stdout); + return ret; } -int -vwprintf (format, arg) - const wchar_t *format; - va_list arg; +int vwprintf(const wchar_t* format, ...) { - int ret = vfwprintf (stdout, format, arg); - fflush(stdout); - return ret; + va_list arg; + int ret; + + va_start(arg, format); + ret = vfwprintf(stdout, format, arg); + va_end(arg); + fflush(stdout); + return ret; } + +#endif diff --git a/lib/msvcrt/stdio/wfdopen.c b/lib/msvcrt/stdio/wfdopen.c new file mode 100644 index 0000000..6e4ec0b --- /dev/null +++ b/lib/msvcrt/stdio/wfdopen.c @@ -0,0 +1,54 @@ +#include +#include + +FILE* __alloc_file(void); + + +FILE* _wfdopen(int handle, wchar_t* mode) +{ + FILE* file; + int rw; + + if (handle == 0) + return stdin; + + if (handle == 1) + return stdout; + + if (handle == 2) + return stderr; + + if (handle == 3) + return stdaux; + + if (handle == 4) + return stdprn; + + file = __alloc_file(); + if (file == NULL) + return NULL; + file->_file = handle; + + rw = (mode[1] == L'+') || (mode[1] && (mode[2] == L'+')); + + if (*mode == L'a') + _lseek(handle, 0, SEEK_END); + + file->_cnt = 0; + file->_file = handle; + file->_bufsiz = 0; + +// The mode of the stream must be compatible with the mode of the file descriptor. +// this should be checked. + + if (rw) + file->_flag = _IOREAD | _IOWRT; + else if (*mode == L'r') + file->_flag = _IOREAD; + else + file->_flag = _IOWRT; + + file->_base = file->_ptr = NULL; + + return file; +} diff --git a/lib/msvcrt/stdio/wrename.c b/lib/msvcrt/stdio/wrename.c new file mode 100644 index 0000000..f580216 --- /dev/null +++ b/lib/msvcrt/stdio/wrename.c @@ -0,0 +1,15 @@ +#include +#include +#include + + +int _wrename(const wchar_t* old_, const wchar_t* new_) +{ + if (old_ == NULL || new_ == NULL) + return -1; + + if (!MoveFileW(old_, new_)) + return -1; + + return 0; +} diff --git a/lib/msvcrt/stdio/wtempnam.c b/lib/msvcrt/stdio/wtempnam.c new file mode 100644 index 0000000..c35118b --- /dev/null +++ b/lib/msvcrt/stdio/wtempnam.c @@ -0,0 +1,22 @@ +#include +#include +#include + + +wchar_t* _wtempnam(const wchar_t* dir, const wchar_t* prefix) +{ + wchar_t* TempFileName = malloc(MAX_PATH); + wchar_t* d; + + if (dir == NULL) + d = _wgetenv(L"TMP"); + else + d = (wchar_t*)dir; + + if (GetTempFileNameW(d, prefix, 1, TempFileName) == 0) { + free(TempFileName); + return NULL; + } + + return TempFileName; +} diff --git a/lib/msvcrt/stdio/wtmpnam.c b/lib/msvcrt/stdio/wtmpnam.c new file mode 100644 index 0000000..5169901 --- /dev/null +++ b/lib/msvcrt/stdio/wtmpnam.c @@ -0,0 +1,16 @@ +#include +#include +#include + + +wchar_t* _wtmpnam(wchar_t* s) +{ + wchar_t PathName[MAX_PATH]; + static wchar_t static_buf[MAX_PATH]; + + GetTempPathW(MAX_PATH, PathName); + GetTempFileNameW(PathName, L"ARI", 007, static_buf); + wcscpy(s, static_buf); + + return s; +} diff --git a/lib/msvcrt/stdlib/abs.c b/lib/msvcrt/stdlib/abs.c index 95802c5..5680b25 100644 --- a/lib/msvcrt/stdlib/abs.c +++ b/lib/msvcrt/stdlib/abs.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include +#include int abs(int j) diff --git a/lib/msvcrt/stdlib/fullpath.c b/lib/msvcrt/stdlib/fullpath.c index 9b3c200..2e98a2e 100644 --- a/lib/msvcrt/stdlib/fullpath.c +++ b/lib/msvcrt/stdlib/fullpath.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/stdlib/fullpath.c + * FILE: lib/msvcrt/stdlib/fullpath.c * PURPOSE: Gets the fullpathname * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -10,20 +10,13 @@ #include #include -char *_fullpath( char *absPath, const char *relPath, size_t maxLength ) -{ - char *lpFilePart; - if ( GetFullPathNameA(relPath,maxLength,absPath,&lpFilePart) == 0 ) - return NULL; - - return absPath; -} -wchar_t *_wfullpath( wchar_t *absPath, const wchar_t *relPath, size_t maxLength ) +char* _fullpath(char* absPath, const char* relPath, size_t maxLength) { - wchar_t *lpFilePart; - if ( GetFullPathNameW(relPath,maxLength,absPath,&lpFilePart) == 0 ) - return NULL; + char* lpFilePart; + + if (GetFullPathNameA(relPath,maxLength,absPath,&lpFilePart) == 0) + return NULL; - return absPath; + return absPath; } diff --git a/lib/msvcrt/stdlib/itoa.c b/lib/msvcrt/stdlib/itoa.c index e8b62af..086e4bc 100644 --- a/lib/msvcrt/stdlib/itoa.c +++ b/lib/msvcrt/stdlib/itoa.c @@ -9,18 +9,20 @@ * 1998: Added ltoa Boudewijn Dekker */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + #include #include +#include + -char * -_itoa(int value, char *string, int radix) +char* _itoa(int value, char* string, int radix) { char tmp[33]; - char *tp = tmp; + char* tp = tmp; int i; unsigned v; int sign; - char *sp; + char* sp; if (radix > 36 || radix <= 1) { @@ -44,7 +46,7 @@ _itoa(int value, char *string, int radix) } if (string == 0) - string = (char *)malloc((tp-tmp)+sign+1); + string = (char*)malloc((tp-tmp)+sign+1); sp = string; if (sign) @@ -55,15 +57,14 @@ _itoa(int value, char *string, int radix) return string; } -char * -_ltoa(long value, char *string, int radix) +char* _ltoa(long value, char* string, int radix) { char tmp[33]; - char *tp = tmp; + char* tp = tmp; long i; unsigned long v; int sign; - char *sp; + char* sp; if (radix > 36 || radix <= 1) { @@ -87,7 +88,7 @@ _ltoa(long value, char *string, int radix) } if (string == 0) - string = (char *)malloc((tp-tmp)+sign+1); + string = (char*)malloc((tp-tmp)+sign+1); sp = string; if (sign) @@ -98,92 +99,13 @@ _ltoa(long value, char *string, int radix) return string; } -char * -_ultoa(unsigned long value, char *string, int radix) +char* _ultoa(unsigned long value, char* string, int radix) { char tmp[33]; - char *tp = tmp; - long i; - unsigned long v = value; - char *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - if (string == 0) - string = (char *)malloc((tp-tmp)+1); - sp = string; - - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; -} - -char * -_i64toa(__int64 value, char *string, int radix) -{ - char tmp[65]; - char *tp = tmp; - int i; - unsigned v; - int sign; - char *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = (radix == 10 && value < 0); - if (sign) - v = -value; - else - v = (unsigned)value; - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - if (string == 0) - string = (char *)malloc((tp-tmp)+sign+1); - sp = string; - - if (sign) - *sp++ = '-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; -} - -char * -_ui64toa(unsigned __int64 value, char *string, int radix) -{ - char tmp[65]; - char *tp = tmp; + char* tp = tmp; long i; unsigned long v = value; - char *sp; + char* sp; if (radix > 36 || radix <= 1) { @@ -202,7 +124,7 @@ _ui64toa(unsigned __int64 value, char *string, int radix) } if (string == 0) - string = (char *)malloc((tp-tmp)+1); + string = (char*)malloc((tp-tmp)+1); sp = string; while (tp > tmp) diff --git a/lib/msvcrt/stdlib/itow.c b/lib/msvcrt/stdlib/itow.c index f65531e..3f9be60 100644 --- a/lib/msvcrt/stdlib/itow.c +++ b/lib/msvcrt/stdlib/itow.c @@ -1,212 +1,147 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/stdlib/itoa.c - * PURPOSE: converts a integer to ascii + * FILE: lib/msvcrt/stdlib/itow.c + * PURPOSE: converts a integer to wchar_t * PROGRAMER: * UPDATE HISTORY: * 1995: Created * 1998: Added ltoa Boudewijn Dekker + * 2000: derived from ./itoa.c by ea */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + #include #include +#include -wchar_t * -_itow(int value, wchar_t *string, int radix) -{ - wchar_t tmp[33]; - wchar_t *tp = tmp; - int i; - unsigned v; - int sign; - wchar_t *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = (radix == 10 && value < 0); - if (sign) - v = -value; - else - v = (unsigned)value; - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+L'0'; - else - *tp++ = i + L'a' - 10; - } - - if (string == 0) - string = (wchar_t *)malloc(((tp-tmp)+sign+1)*sizeof(wchar_t)); - sp = string; - - if (sign) - *sp++ = L'-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; -} - -wchar_t * -_ltow(long value, wchar_t *string, int radix) -{ - wchar_t tmp[33]; - wchar_t *tp = tmp; - long i; - unsigned long v; - int sign; - wchar_t *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = (radix == 10 && value < 0); - if (sign) - v = -value; - else - v = (unsigned long)value; - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+L'0'; - else - *tp++ = i + L'a' - 10; - } - - if (string == 0) - string = (wchar_t *)malloc(((tp-tmp)+sign+1)*sizeof(wchar_t)); - sp = string; - - if (sign) - *sp++ = L'-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; -} -wchar_t * -_ultow(unsigned long value, wchar_t *string, int radix) +wchar_t* _itow(int value, wchar_t* string, int radix) { - wchar_t tmp[33]; - wchar_t *tp = tmp; - long i; - unsigned long v = value; - wchar_t *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+L'0'; - else - *tp++ = i + L'a' - 10; - } - - if (string == 0) - string = (wchar_t *)malloc(((tp-tmp)+1)*sizeof(wchar_t)); - sp = string; - - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; + wchar_t tmp [33]; + wchar_t * tp = tmp; + int i; + unsigned int v; + int sign; + wchar_t * sp; + + if (radix > 36 || radix <= 1) + { + __set_errno(EDOM); + return 0; + } + + sign = ((radix == 10) && (value < 0)); + if (sign) { + v = -value; + } else { + v = (unsigned) value; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i+ (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { + string = (wchar_t*) malloc((tp-tmp) + (sign + 1) * sizeof(wchar_t)); + } + sp = string; + + if (sign) { + *sp++ = (wchar_t) '-'; + } + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; } -wchar_t * -_i64tow(__int64 value, wchar_t *string, int radix) +wchar_t* _ltow(long value, wchar_t* string, int radix) { - wchar_t tmp[65]; - wchar_t *tp = tmp; - int i; - unsigned v; - int sign; - wchar_t *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - sign = (radix == 10 && value < 0); - if (sign) - v = -value; - else - v = (unsigned)value; - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+L'0'; - else - *tp++ = i + L'a' - 10; - } - - if (string == 0) - string = (wchar_t *)malloc(((tp-tmp)+sign+1)*sizeof(wchar_t)); - sp = string; - - if (sign) - *sp++ = L'-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; + wchar_t tmp [33]; + wchar_t* tp = tmp; + long int i; + unsigned long int v; + int sign; + wchar_t* sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + + sign = ((radix == 10) && (value < 0)); + if (sign) { + v = -value; + } else { + v = (unsigned long) value; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { + string = (wchar_t*) malloc((tp - tmp) + (sign + 1) * sizeof(wchar_t)); + } + sp = string; + + if (sign) { + *sp++ = (wchar_t) '-'; + } + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; } -wchar_t * -_ui64tow(unsigned __int64 value, wchar_t *string, int radix) +wchar_t* _ultow(unsigned long value, wchar_t* string, int radix) { - wchar_t tmp[65]; - wchar_t *tp = tmp; - long i; - unsigned long v = value; - wchar_t *sp; - - if (radix > 36 || radix <= 1) - { - __set_errno(EDOM); - return 0; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+L'0'; - else - *tp++ = i + L'a' - 10; - } - - if (string == 0) - string = (wchar_t *)malloc(((tp-tmp)+1)*sizeof(wchar_t)); - sp = string; - - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - return string; + wchar_t tmp [33]; + wchar_t* tp = tmp; + long int i; + unsigned long int v = value; + wchar_t* sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + (wchar_t) '0'; + } else { + *tp++ = i + (wchar_t) 'a' - 10; + } + } + + if (string == 0) { +#ifdef _MSVCRT_LIB_ // TODO: check on difference? + string = (wchar_t*)malloc(((tp-tmp)+1)*sizeof(wchar_t)); +#else // TODO: FIXME: review which is correct + string = (wchar_t*)malloc((tp - tmp) + sizeof(wchar_t)); +#endif /*_MSVCRT_LIB_*/ + } + sp = string; + + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = (wchar_t) 0; + return string; } diff --git a/lib/msvcrt/stdlib/labs.c b/lib/msvcrt/stdlib/labs.c index eea5989..87b69a3 100644 --- a/lib/msvcrt/stdlib/labs.c +++ b/lib/msvcrt/stdlib/labs.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include +#include long labs(long j) diff --git a/lib/msvcrt/stdlib/makepath.c b/lib/msvcrt/stdlib/makepath.c index e61af37..fa04422 100644 --- a/lib/msvcrt/stdlib/makepath.c +++ b/lib/msvcrt/stdlib/makepath.c @@ -3,67 +3,30 @@ #include #include -void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext) +void _makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext) { - int dir_len; + int dir_len; - if ((drive != NULL) && (*drive)) - { - strcpy(path, drive); - strcat(path, ":"); + if ((drive != NULL) && (*drive)) { + strcpy(path, drive); + strcat(path, ":"); + } else { + (*path)=0; } - else - (*path)=0; - if (dir != NULL) - { - strcat(path, dir); - dir_len = strlen(dir); - if (dir_len && *(dir + dir_len - 1) != '\\') - strcat(path, "\\"); + if (dir != NULL) { + strcat(path, dir); + dir_len = strlen(dir); + if (dir_len && *(dir + dir_len - 1) != '\\') + strcat(path, "\\"); } - if (fname != NULL) - { - strcat(path, fname); - if (ext != NULL && *ext != 0) - { - if (*ext != '.') - strcat(path, "."); - strcat(path, ext); - } - } -} - - -void _wmakepath(wchar_t *path, const wchar_t *drive, const wchar_t *dir, const wchar_t *fname, const wchar_t *ext) -{ - int dir_len; - - if ((drive != NULL) && (*drive)) - { - wcscpy(path, drive); - wcscat(path, L":"); - } - else - (*path)=0; - - if (dir != NULL) - { - wcscat(path, dir); - dir_len = wcslen(dir); - if (dir_len && *(dir + dir_len - 1) != L'\\') - wcscat(path, L"\\"); - } - - if (fname != NULL) - { - wcscat(path, fname); - if (ext != NULL && *ext != 0) - { - if (*ext != L'.') - wcscat(path, L"."); - wcscat(path, ext); - } + if (fname != NULL) { + strcat(path, fname); + if (ext != NULL && *ext != 0) { + if (*ext != '.') + strcat(path, "."); + strcat(path, ext); + } } } diff --git a/lib/msvcrt/stdlib/mbstow.c b/lib/msvcrt/stdlib/mbstow.c deleted file mode 100644 index 9daae0b..0000000 --- a/lib/msvcrt/stdlib/mbstow.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - - -int mblen (const char* mbs, size_t sizeString) -{ - return 0; -} - -size_t mbstowcs (wchar_t* wcaDest, const char* mbsConvert, size_t size) -{ - return 0; -} - -int mbtowc (wchar_t* wcDest, const char* mbConvert, size_t size) -{ - return 0; -} diff --git a/lib/msvcrt/stdlib/mbstowcs.c b/lib/msvcrt/stdlib/mbstowcs.c index 0aac3f1..752f2fc 100644 --- a/lib/msvcrt/stdlib/mbstowcs.c +++ b/lib/msvcrt/stdlib/mbstowcs.c @@ -1,11 +1,118 @@ +#include #include -size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count ) +#if 1 +size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) { - return 0; + size_t size; + int i; + + printf("\nmbstowcs(%p, %p, %d) called.\n\n", wcstr, mbstr, count); + + if (count <= 0 || !mbstr) + return 0; + + if (!*mbstr) + return 0; + + + if (wcstr == NULL) { + // return required size for the converted string + return strlen(mbstr); // TODO: fixme + } + for (size = 0, i = 0; i < count; size++) { + int result; + +////int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) +//// result = mbtowc(wcstr + size, mbstr + i, count - i); +// result = mbtowc(wcstr + size, mbstr + i, 1); + +///////////////////////////////////////// + if (mbstr[i] == 0) { + result = 0; + } else { + wcstr[size] = mbstr[i]; + result = 1; + } +///////////////////////////////////////// + if (result == -1) { + return -1; + } else if (result == 0) { + wcstr[size] = L'\0'; + break; + } else { + i += result; + } + + } + return size; +} + +#else +#if 1 + +//int mbtowc(wchar_t *dst, const char *str, size_t n) +size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) +{ + size_t len; + + if (count <= 0 || !mbstr) + return 0; + len = MultiByteToWideChar(CP_ACP, 0, mbstr, count, wcstr, (wcstr == NULL) ? 0 : count); + + if (!len) { + DWORD err = GetLastError(); + switch (err) { + case ERROR_INSUFFICIENT_BUFFER: + break; + case ERROR_INVALID_FLAGS: + break; + case ERROR_INVALID_PARAMETER: + break; + case ERROR_NO_UNICODE_TRANSLATION: + break; + default: + return 1; + } + return -1; + } + /* return the number of bytes from src that have been used */ + if (!*mbstr) + return 0; +// if (count >= 2 && isleadbyte(*mbstr) && mbstr[1]) +// return 2; + return len; } -int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) +#else + +size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) { - return 0; -} \ No newline at end of file + size_t size; + int i; + + if (wcstr == NULL) { + // return required size for the converted string + return strlen(mbstr); // TODO: fixme + } + for (size = 0, i = 0; i < count; size++) { + int result; + +//int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) +// result = mbtowc(wcstr + size, mbstr + i, count - i); + result = mbtowc(wcstr + size, mbstr + i, 1); + if (result == -1) { + return -1; + } else if (result == 0) { + wcstr[size] = L'\0'; + break; + } else { + i += result; + } + + } + return (size_t)size; +} + +#endif +#endif diff --git a/lib/msvcrt/stdlib/mbtowc.c b/lib/msvcrt/stdlib/mbtowc.c new file mode 100644 index 0000000..501f124 --- /dev/null +++ b/lib/msvcrt/stdlib/mbtowc.c @@ -0,0 +1,52 @@ +#include +#include +#include + + +#if 1 + +int mbtowc(wchar_t *dst, const char *str, size_t n) +{ +// printf("\t\t\tmbtowc(%p, %p, %d) called.\n", dst, str, n); + + if (n <= 0 || !str) + return 0; + + *dst = *str; + + if (!*str) + return 0; + return 1; +} + +#else + +int mbtowc(wchar_t *dst, const char *str, size_t n) +{ + if (n <= 0 || !str) + return 0; + if (!MultiByteToWideChar(CP_ACP, 0, str, n, dst, (dst == NULL) ? 0 : 1)) { + DWORD err = GetLastError(); + switch (err) { + case ERROR_INSUFFICIENT_BUFFER: + break; + case ERROR_INVALID_FLAGS: + break; + case ERROR_INVALID_PARAMETER: + break; + case ERROR_NO_UNICODE_TRANSLATION: + break; + default: + return 1; + } + return -1; + } + /* return the number of bytes from src that have been used */ + if (!*str) + return 0; + if (n >= 2 && isleadbyte(*str) && str[1]) + return 2; + return 1; +} + +#endif diff --git a/lib/msvcrt/stdlib/obsol.c b/lib/msvcrt/stdlib/obsol.c index eac7119..a57e878 100644 --- a/lib/msvcrt/stdlib/obsol.c +++ b/lib/msvcrt/stdlib/obsol.c @@ -5,6 +5,10 @@ unsigned char _cpumode = 0; unsigned char *_cpumode_dll = &_cpumode; +WINBOOL STDCALL Beep(DWORD dwFreq, DWORD dwDuration); +VOID STDCALL Sleep(DWORD dwMilliseconds); +UINT STDCALL SetErrorMode(UINT uMode); + void _seterrormode(int nMode) { SetErrorMode(nMode); diff --git a/lib/msvcrt/stdlib/putenv.c b/lib/msvcrt/stdlib/putenv.c index ce68245..3f5c3de 100644 --- a/lib/msvcrt/stdlib/putenv.c +++ b/lib/msvcrt/stdlib/putenv.c @@ -8,44 +8,24 @@ extern int BlockEnvToEnviron(); // defined in misc/dllmain.c -int _putenv(const char *val) +int _putenv(const char* val) { - char *buffer; - char *epos; - int res; + char* buffer; + char* epos; + int res; - DPRINT("_putenv('%s')\n", val); - epos = strchr(val, '='); - if ( epos == NULL ) - return -1; - buffer = (char*)malloc(epos - val + 1); - if (buffer == NULL) - return -1; - strncpy(buffer, val, epos - val); - buffer[epos - val] = 0; - res = SetEnvironmentVariableA(buffer,epos+1); - free(buffer); - if (BlockEnvToEnviron()) return 0; - return res; -} - -int _wputenv(const wchar_t *val) -{ - wchar_t *buffer; - wchar_t *epos; - int res; - - DPRINT("_wputenv('%S')\n", val); - epos = wcsrchr(val, L'='); - if ( epos == NULL ) - return -1; - buffer = (char*)malloc((epos - val + 1) * sizeof (wchar_t)); - if (buffer == NULL) - return -1; - wcsncpy(buffer, val, epos - val); - buffer[epos - val] = 0; - res = SetEnvironmentVariableW(buffer,epos+1); - free(buffer); - if (BlockEnvToEnviron() ) return 0; - return res; + DPRINT("_putenv('%s')\n", val); + epos = strchr(val, '='); + if ( epos == NULL ) + return -1; + buffer = (char*)malloc(epos - val + 1); + if (buffer == NULL) + return -1; + strncpy(buffer, val, epos - val); + buffer[epos - val] = 0; + res = SetEnvironmentVariableA(buffer, epos+1); + free(buffer); + if (BlockEnvToEnviron()) + return 0; + return res; } diff --git a/lib/msvcrt/stdlib/rand.c b/lib/msvcrt/stdlib/rand.c index bae3e28..2393beb 100644 --- a/lib/msvcrt/stdlib/rand.c +++ b/lib/msvcrt/stdlib/rand.c @@ -7,7 +7,11 @@ rand(void) { PTHREADDATA ThreadData = GetThreadData(); +#ifdef HAVE_LONGLONG ThreadData->tnext = ThreadData->tnext * 0x5deece66dLL + 11; +#else + ThreadData->tnext = ThreadData->tnext * 0x5deece66dL + 11; +#endif return (int)((ThreadData->tnext >> 16) & RAND_MAX); } @@ -16,5 +20,5 @@ srand(unsigned int seed) { PTHREADDATA ThreadData = GetThreadData(); - ThreadData->tnext = (unsigned long long)seed; + ThreadData->tnext = (ULONGLONG)seed; } diff --git a/lib/msvcrt/stdlib/rot.c b/lib/msvcrt/stdlib/rot.c index ee6dfe4..cb4bd69 100644 --- a/lib/msvcrt/stdlib/rot.c +++ b/lib/msvcrt/stdlib/rot.c @@ -9,6 +9,7 @@ */ #include +#include unsigned int _rotl( unsigned int value, int shift ) { @@ -53,4 +54,4 @@ unsigned long _lrotr( unsigned long value, int shift ) if ( shift > max_bits ) shift = shift % max_bits; return (value >> shift) | (value << (max_bits-shift)); -} \ No newline at end of file +} diff --git a/lib/msvcrt/stdlib/senv.c b/lib/msvcrt/stdlib/senv.c index 32c1afe..9761ebe 100644 --- a/lib/msvcrt/stdlib/senv.c +++ b/lib/msvcrt/stdlib/senv.c @@ -5,52 +5,29 @@ #define NDEBUG #include -void _searchenv(const char *file,const char *var,char *path ) -{ - char *env = getenv(var); - char *x; - char *y; - char *FilePart; - - DPRINT("_searchenv()\n"); - x = strchr(env,'='); - if ( x != NULL ) { - *x = 0; - x++; - } - y = strchr(env,';'); - while ( y != NULL ) { - *y = 0; - if ( SearchPathA(x,file,NULL,MAX_PATH,path,&FilePart) > 0 ) { - return; - } - x = y+1; - y = strchr(env,';'); - } - return; -} -void _wsearchenv(const wchar_t *file,const wchar_t *var,wchar_t *path) +void _searchenv(const char* file,const char* var,char* path) { - wchar_t *env = _wgetenv(var); - wchar_t *x; - wchar_t *y; - wchar_t *FilePart; + char* env = getenv(var); + char* x; + char* y; + char* FilePart; + + DPRINT("_searchenv()\n"); - DPRINT("_searchenw()\n"); - x = wcschr(env,L'='); - if ( x != NULL ) { - *x = 0; - x++; - } - y = wcschr(env,L';'); - while ( y != NULL ) { - *y = 0; - if ( SearchPathW(x,file,NULL,MAX_PATH,path,&FilePart) > 0 ) { - return; - } - x = y+1; - y = wcschr(env,L';'); - } - return; + x = strchr(env,'='); + if ( x != NULL ) { + *x = 0; + x++; + } + y = strchr(env,';'); + while ( y != NULL ) { + *y = 0; + if ( SearchPathA(x,file,NULL,MAX_PATH,path,&FilePart) > 0 ) { + return; + } + x = y+1; + y = strchr(env,';'); + } + return; } diff --git a/lib/msvcrt/stdlib/splitp.c b/lib/msvcrt/stdlib/splitp.c index 20536c6..ca163bf 100644 --- a/lib/msvcrt/stdlib/splitp.c +++ b/lib/msvcrt/stdlib/splitp.c @@ -1,91 +1,47 @@ #include #include -void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ext ) -{ - char *tmp_drive; - char *tmp_dir; - char *tmp_ext; - - tmp_drive = (char *)strchr(path,':'); - if ( tmp_drive != (char *)NULL ) { - strncpy(drive,tmp_drive-1,1); - *(drive+1) = 0; - } - else { - *drive = 0; - tmp_drive = (char *)path; - } - - tmp_dir = (char *)strrchr(path,'\\'); - if( tmp_dir != NULL && tmp_dir != tmp_drive + 1 ) { - strncpy(dir,tmp_drive+1,tmp_dir - tmp_drive); - *(dir + (tmp_dir - tmp_drive)) = 0; - } - else - *dir =0; - - tmp_ext = ( char *)strrchr(path,'.'); - if ( tmp_ext != NULL ) { - strcpy(ext,tmp_ext); - } - else - { - *ext = 0; - tmp_ext = (char *)path+strlen(path); - } - if ( tmp_dir != NULL ) { - strncpy(fname,tmp_dir+1,tmp_ext - tmp_dir - 1); - *(fname + (tmp_ext - tmp_dir -1)) = 0; - } - else - { - strncpy(fname,path,tmp_ext - path); - *(fname+(tmp_ext-path))=0; - } -} -void _wsplitpath( const wchar_t *path, wchar_t *drive, wchar_t *dir, wchar_t *fname, wchar_t *ext ) +void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext) { - wchar_t *tmp_drive; - wchar_t *tmp_dir; - wchar_t *tmp_ext; - - tmp_drive = (wchar_t *)wcschr(path,L':'); - if ( tmp_drive != (wchar_t *)NULL ) { - wcsncpy(drive,tmp_drive-1,1); - *(drive+1) = 0; - } - else { - *drive = 0; - tmp_drive = (wchar_t *)path; - } - - tmp_dir = (wchar_t *)wcsrchr(path,L'\\'); - if( tmp_dir != NULL && tmp_dir != tmp_drive + 1 ) { - wcsncpy(dir,tmp_drive+1,tmp_dir - tmp_drive); - *(dir + (tmp_dir - tmp_drive)) = 0; - } - else - *dir =0; - - tmp_ext = (wchar_t *)wcsrchr(path,L'.'); - if ( tmp_ext != NULL ) { - wcscpy(ext,tmp_ext); - } - else - { - *ext = 0; - tmp_ext = (wchar_t *)path+wcslen(path); - } - - if ( tmp_dir != NULL ) { - wcsncpy(fname,tmp_dir+1,tmp_ext - tmp_dir - 1); - *(fname + (tmp_ext - tmp_dir -1)) = 0; - } - else - { - wcsncpy(fname,path,tmp_ext - path); - *(fname+(tmp_ext-path))=0; - } + char* tmp_drive; + char* tmp_dir; + char* tmp_ext; + + tmp_drive = (char*)strchr(path,':'); + if ( tmp_drive != (char*)NULL ) { + strncpy(drive,tmp_drive-1,1); + *(drive+1) = 0; + } + else { + *drive = 0; + tmp_drive = (char*)path; + } + + tmp_dir = (char*)strrchr(path,'\\'); + if( tmp_dir != NULL && tmp_dir != tmp_drive + 1 ) { + strncpy(dir,tmp_drive+1,tmp_dir - tmp_drive); + *(dir + (tmp_dir - tmp_drive)) = 0; + } + else + *dir =0; + + tmp_ext = ( char* )strrchr(path,'.'); + if ( tmp_ext != NULL ) { + strcpy(ext,tmp_ext); + } + else + { + *ext = 0; + tmp_ext = (char*)path+strlen(path); + } + if ( tmp_dir != NULL ) { + strncpy(fname,tmp_dir+1,tmp_ext - tmp_dir - 1); + *(fname + (tmp_ext - tmp_dir -1)) = 0; + } + else + { + strncpy(fname,path,tmp_ext - path); + *(fname+(tmp_ext-path))=0; + } } diff --git a/lib/msvcrt/stdlib/strtold.c b/lib/msvcrt/stdlib/strtold.c index 90e847b..5588206 100644 --- a/lib/msvcrt/stdlib/strtold.c +++ b/lib/msvcrt/stdlib/strtold.c @@ -5,8 +5,12 @@ static double powten[] = { - 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L + 1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L, +#ifdef __GNUC__ 1e512L, 1e512L*1e512L, 1e2048L, 1e4096L +#else + 1e256L, 1e256L, 1e256L, 1e256L +#endif }; long double diff --git a/lib/msvcrt/stdlib/wcstombs.c b/lib/msvcrt/stdlib/wcstombs.c index 4fc85df..01f59f6 100644 --- a/lib/msvcrt/stdlib/wcstombs.c +++ b/lib/msvcrt/stdlib/wcstombs.c @@ -39,10 +39,12 @@ static const unsigned char encoding_byte[] = /* We don't need the state really because we don't have shift states to maintain between calls to this function. */ -static mbstate_t internal; +typedef int mbstate_t; +static mbstate_t mbstate_internal; -extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ +mbstate_t __no_r_state; /* Now defined in wcstombs.c. */ +//extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ size_t __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps); @@ -77,7 +79,7 @@ __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps) const wchar_t *run = *src; if (ps == NULL) - ps = &internal; + ps = &mbstate_internal; if (dst == NULL) /* The LEN parameter has to be ignored if we don't actually write @@ -149,4 +151,4 @@ __wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps) return written; } -//weak_alias (__wcsrtombs, wcsrtombs) \ No newline at end of file +//weak_alias (__wcsrtombs, wcsrtombs) diff --git a/lib/msvcrt/stdlib/wctomb.c b/lib/msvcrt/stdlib/wctomb.c new file mode 100644 index 0000000..1603a5a --- /dev/null +++ b/lib/msvcrt/stdlib/wctomb.c @@ -0,0 +1,146 @@ +/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include +#include + + +int +STDCALL +WideCharToMultiByte( + UINT CodePage, + DWORD dwFlags, + LPCWSTR lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cchMultiByte, + LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar); + + +int wctomb(char* dst, wchar_t ch) +{ +#if 0 + return WideCharToMultiByte(CP_ACP, 0, &ch, 1, dst, 6, NULL, NULL); +#else + if (dst == NULL) { + return 1; + } + *dst = ch; + return 1; +#endif +} + + +#if 0 + +#ifndef EILSEQ +#define EILSEQ EINVAL +#endif + +static const wchar_t encoding_mask[] = +{ + /* This reflects the sources *nix origin where type wchar_t + was 32 bits wide. Since our type wchar_t is only 16 bits + wide all this module will need to be reviewed. + Simplest option may well be to forward this modules work + on to the kernel which already has support for this. + */ + ~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff + //~0x0000-07ff, ~0x0000-ffff, ~0x001f-ffff, ~0x03ff-ffff +}; + +static const unsigned char encoding_byte[] = +{ + 0xc0, 0xe0, 0xf0, 0xf8, 0xfc +}; + +/* The state is for this UTF8 encoding not used. */ +//static mbstate_t internal; +//extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ + +size_t __wcrtomb(char *s, wchar_t wc); + +/* Convert WCHAR into its multibyte character representation, + putting this in S and returning its length. + + Attention: this function should NEVER be intentionally used. + The interface is completely stupid. The state is shared between + all conversion functions. You should use instead the restartable + version `wcrtomb'. */ + +int wctomb(char *s, wchar_t wchar) +{ + /* If S is NULL the function has to return null or not null + depending on the encoding having a state depending encoding or + not. This is nonsense because any multibyte encoding has a + state. The ISO C amendment 1 corrects this while introducing the + restartable functions. We simply say here all encodings have a + state. */ + if (s == NULL) { + return 1; + } + return __wcrtomb(s, wchar); +} + +size_t __wcrtomb(char *s, wchar_t wc) +{ + char fake[1]; + size_t written = 0; + + if (s == NULL) { + s = fake; + wc = L'\0'; + } + /* Store the UTF8 representation of WC. */ + //if (wc < 0 || wc > 0x7fffffff) { + if (wc < 0 || wc > 0x7fff) { + /* This is no correct ISO 10646 character. */ + __set_errno (EILSEQ); + return (size_t) -1; + } + if (wc < 0x80) { + /* It's a one byte sequence. */ + if (s != NULL) { + *s = (char)wc; + } + return 1; + } + for (written = 2; written < 6; ++written) { + if ((wc & encoding_mask[written - 2]) == 0) { + break; + } + } + if (s != NULL) { + size_t cnt = written; + s[0] = encoding_byte[cnt - 2]; + --cnt; + do { + s[cnt] = 0x80 | (wc & 0x3f); + wc >>= 6; + } while (--cnt > 0); + s[0] |= wc; + } + return written; +} + +#endif diff --git a/lib/msvcrt/stdlib/wfulpath.c b/lib/msvcrt/stdlib/wfulpath.c new file mode 100644 index 0000000..21b44cf --- /dev/null +++ b/lib/msvcrt/stdlib/wfulpath.c @@ -0,0 +1,22 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/stdlib/fullpath.c + * PURPOSE: Gets the fullpathname + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include + + +wchar_t* _wfullpath(wchar_t* absPath, const wchar_t* relPath, size_t maxLength) +{ + wchar_t* lpFilePart; + + if (GetFullPathNameW(relPath,maxLength,absPath,&lpFilePart) == 0) + return NULL; + + return absPath; +} diff --git a/lib/msvcrt/stdlib/witoa.c b/lib/msvcrt/stdlib/witoa.c new file mode 100644 index 0000000..6ff4d2f --- /dev/null +++ b/lib/msvcrt/stdlib/witoa.c @@ -0,0 +1,92 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/stdlib/itoa.c + * PURPOSE: converts a integer to ascii + * PROGRAMER: + * UPDATE HISTORY: + * 1995: Created + * 1998: Added ltoa Boudewijn Dekker + */ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + +#include +#include +#include + + +char* _i64toa(__int64 value, char* string, int radix) +{ + char tmp[65]; + char *tp = tmp; + int i; + unsigned v; + int sign; + char *sp; + + if (radix > 36 || radix <= 1) + { + __set_errno(EDOM); + return 0; + } + + sign = (radix == 10 && value < 0); + if (sign) + v = -value; + else + v = (unsigned)value; + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + if (string == 0) + string = (char *)malloc((tp-tmp)+sign+1); + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + return string; +} + +char* _ui64toa(unsigned __int64 value, char* string, int radix) +{ + char tmp[65]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if (radix > 36 || radix <= 1) + { + __set_errno(EDOM); + return 0; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + if (string == 0) + string = (char *)malloc((tp-tmp)+1); + sp = string; + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + return string; +} diff --git a/lib/msvcrt/stdlib/witow.c b/lib/msvcrt/stdlib/witow.c new file mode 100644 index 0000000..4e0c089 --- /dev/null +++ b/lib/msvcrt/stdlib/witow.c @@ -0,0 +1,90 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/stdlib/itow.c + * PURPOSE: converts a integer to wchar_t + * PROGRAMER: + * UPDATE HISTORY: + * 1995: Created + * 1998: Added ltoa Boudewijn Dekker + * 2000: derived from ./itoa.c by ea + */ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + +#include +#include +#include + + +wchar_t* _i64tow(__int64 value, wchar_t* string, int radix) +{ + wchar_t tmp[65]; + wchar_t* tp = tmp; + int i; + unsigned v; + int sign; + wchar_t* sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + + sign = (radix == 10 && value < 0); + if (sign) + v = -value; + else + v = (unsigned)value; + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+L'0'; + else + *tp++ = i + L'a' - 10; + } + + if (string == 0) + string = (wchar_t*)malloc(((tp-tmp)+sign+1)*sizeof(wchar_t)); + sp = string; + + if (sign) + *sp++ = L'-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + return string; +} + +wchar_t* _ui64tow(unsigned __int64 value, wchar_t* string, int radix) +{ + wchar_t tmp[65]; + wchar_t* tp = tmp; + long i; + unsigned long v = value; + wchar_t* sp; + + if (radix > 36 || radix <= 1) { + __set_errno(EDOM); + return 0; + } + + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+L'0'; + else + *tp++ = i + L'a' - 10; + } + + if (string == 0) + string = (wchar_t*)malloc(((tp-tmp)+1)*sizeof(wchar_t)); + sp = string; + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + return string; +} diff --git a/lib/msvcrt/stdlib/wmakpath.c b/lib/msvcrt/stdlib/wmakpath.c new file mode 100644 index 0000000..9367bdc --- /dev/null +++ b/lib/msvcrt/stdlib/wmakpath.c @@ -0,0 +1,33 @@ +/* $Id$ + */ +#include +#include + + +void _wmakepath(wchar_t* path, const wchar_t* drive, const wchar_t* dir, const wchar_t* fname, const wchar_t* ext) +{ + int dir_len; + + if ((drive != NULL) && (*drive)) { + wcscpy(path, drive); + wcscat(path, L":"); + } else { + (*path) = 0; + } + + if (dir != NULL) { + wcscat(path, dir); + dir_len = wcslen(dir); + if (dir_len && *(dir + dir_len - 1) != L'\\') + wcscat(path, L"\\"); + } + + if (fname != NULL) { + wcscat(path, fname); + if (ext != NULL && *ext != 0) { + if (*ext != L'.') + wcscat(path, L"."); + wcscat(path, ext); + } + } +} diff --git a/lib/msvcrt/stdlib/wputenv.c b/lib/msvcrt/stdlib/wputenv.c new file mode 100644 index 0000000..08bfff5 --- /dev/null +++ b/lib/msvcrt/stdlib/wputenv.c @@ -0,0 +1,31 @@ +#include +#include +#include + +#define NDEBUG +#include + + +extern int BlockEnvToEnviron(); // defined in misc/dllmain.c + +int _wputenv(const wchar_t* val) +{ + wchar_t* buffer; + wchar_t* epos; + int res; + + DPRINT("_wputenv('%S')\n", val); + epos = wcsrchr(val, L'='); + if (epos == NULL) + return -1; + buffer = (char*)malloc((epos - val + 1) * sizeof(wchar_t)); + if (buffer == NULL) + return -1; + wcsncpy(buffer, val, epos - val); + buffer[epos - val] = 0; + res = SetEnvironmentVariableW(buffer, epos+1); + free(buffer); + if (BlockEnvToEnviron()) + return 0; + return res; +} diff --git a/lib/msvcrt/stdlib/wsenv.c b/lib/msvcrt/stdlib/wsenv.c new file mode 100644 index 0000000..24fe949 --- /dev/null +++ b/lib/msvcrt/stdlib/wsenv.c @@ -0,0 +1,32 @@ +#include +#include +#include + +#define NDEBUG +#include + + +void _wsearchenv(const wchar_t* file,const wchar_t* var,wchar_t* path) +{ + wchar_t* env = _wgetenv(var); + wchar_t* x; + wchar_t* y; + wchar_t* FilePart; + + DPRINT("_wsearchenv()\n"); + x = wcschr(env,L'='); + if ( x != NULL ) { + *x = 0; + x++; + } + y = wcschr(env,L';'); + while ( y != NULL ) { + *y = 0; + if ( SearchPathW(x,file,NULL,MAX_PATH,path,&FilePart) > 0 ) { + return; + } + x = y+1; + y = wcschr(env,L';'); + } + return; +} diff --git a/lib/msvcrt/stdlib/wsplitp.c b/lib/msvcrt/stdlib/wsplitp.c new file mode 100644 index 0000000..7d20667 --- /dev/null +++ b/lib/msvcrt/stdlib/wsplitp.c @@ -0,0 +1,48 @@ +#include +#include + + +void _wsplitpath(const wchar_t* path, wchar_t* drive, wchar_t* dir, wchar_t* fname, wchar_t* ext) +{ + wchar_t* tmp_drive; + wchar_t* tmp_dir; + wchar_t* tmp_ext; + + tmp_drive = (wchar_t*)wcschr(path,L':'); + if ( tmp_drive != (wchar_t*)NULL ) { + wcsncpy(drive,tmp_drive-1,1); + *(drive+1) = 0; + } + else { + *drive = 0; + tmp_drive = (wchar_t*)path; + } + + tmp_dir = (wchar_t*)wcsrchr(path,L'\\'); + if( tmp_dir != NULL && tmp_dir != tmp_drive + 1 ) { + wcsncpy(dir,tmp_drive+1,tmp_dir - tmp_drive); + *(dir + (tmp_dir - tmp_drive)) = 0; + } + else + *dir =0; + + tmp_ext = (wchar_t*)wcsrchr(path,L'.'); + if ( tmp_ext != NULL ) { + wcscpy(ext,tmp_ext); + } + else + { + *ext = 0; + tmp_ext = (wchar_t*)path+wcslen(path); + } + + if ( tmp_dir != NULL ) { + wcsncpy(fname,tmp_dir+1,tmp_ext - tmp_dir - 1); + *(fname + (tmp_ext - tmp_dir -1)) = 0; + } + else + { + wcsncpy(fname,path,tmp_ext - path); + *(fname+(tmp_ext-path))=0; + } +} diff --git a/lib/msvcrt/stdlib/wtoi64.c b/lib/msvcrt/stdlib/wtoi64.c index c9d9441..2831c0d 100644 --- a/lib/msvcrt/stdlib/wtoi64.c +++ b/lib/msvcrt/stdlib/wtoi64.c @@ -1,31 +1,28 @@ - #include #include -__int64 -_wtoi64(const wchar_t *nptr) + +__int64 _wtoi64(const wchar_t* nptr) { - wchar_t *s = (wchar_t *)nptr; - __int64 acc = 0; - int neg = 0; + wchar_t* s = (wchar_t*)nptr; + __int64 acc = 0; + int neg = 0; - while(iswspace((int)*s)) - s++; - if (*s == '-') - { - neg = 1; - s++; + while (iswspace((int)*s)) + s++; + if (*s == '-') { + neg = 1; + s++; } - else if (*s == '+') - s++; + else if (*s == '+') + s++; - while (iswdigit((int)*s)) - { - acc = 10 * acc + ((int)*s - '0'); - s++; + while (iswdigit((int)*s)) { + acc = 10 * acc + ((int)*s - '0'); + s++; } - if (neg) - acc *= -1; - return acc; + if (neg) + acc *= -1; + return acc; } diff --git a/lib/msvcrt/string/memccpy.c b/lib/msvcrt/string/memccpy.c index 42fd26b..98d712a 100644 --- a/lib/msvcrt/string/memccpy.c +++ b/lib/msvcrt/string/memccpy.c @@ -4,6 +4,18 @@ void * _memccpy (void *to, const void *from,int c,size_t count) { - memcpy(to,from,count); - return memchr(to,c,count); + char t; + size_t i; + char *dst=(char*)to; + const char *src=(const char*)from; + + for ( i = 0; i < count; i++ ) + { + dst[i] = t = src[i]; + if ( t == '\0' ) + break; + if ( t == c ) + return &dst[i+1]; + } + return NULL; /* didn't copy c */ } diff --git a/lib/msvcrt/string/memcmp.c b/lib/msvcrt/string/memcmp.c index 81371e0..95d3d25 100644 --- a/lib/msvcrt/string/memcmp.c +++ b/lib/msvcrt/string/memcmp.c @@ -1,17 +1,16 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -int -memcmp(const void *s1, const void *s2, size_t n) -{ - if (n != 0) - { - const unsigned char *p1 = s1, *p2 = s2; +#pragma function(memcmp) - do { - if (*p1++ != *p2++) - return (*--p1 - *--p2); - } while (--n != 0); - } - return 0; +int memcmp(const void *s1, const void *s2, size_t n) +{ + if (n != 0) { + const unsigned char *p1 = s1, *p2 = s2; + do { + if (*p1++ != *p2++) + return (*--p1 - *--p2); + } while (--n != 0); + } + return 0; } diff --git a/lib/msvcrt/string/memcpy.c b/lib/msvcrt/string/memcpy.c index 83077e1..894bc84 100644 --- a/lib/msvcrt/string/memcpy.c +++ b/lib/msvcrt/string/memcpy.c @@ -1,12 +1,13 @@ #include +#pragma function(memcpy) + /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ -void * -memcpy (void *to, const void *from, size_t count) +void* memcpy(void* to, const void* from, size_t count) { - register char *f = (char *)from; - register char *t = (char *)to; + register char* f = (char*)from; + register char* t = (char*)to; register int i = count; while (i-- > 0) diff --git a/lib/msvcrt/string/memset.c b/lib/msvcrt/string/memset.c index 129e6ac..9bb4bf8 100644 --- a/lib/msvcrt/string/memset.c +++ b/lib/msvcrt/string/memset.c @@ -1,10 +1,12 @@ #include -void * memset(void *src,int val,size_t count) +#pragma function(memset) + +void* memset(void* src, int val, size_t count) { - char *char_src = (char *)src; + char* char_src = (char*)src; - while(count>0) { + while (count>0) { *char_src = val; char_src++; count--; diff --git a/lib/msvcrt/string/strcat.c b/lib/msvcrt/string/strcat.c index fa71718..2b87ce9 100644 --- a/lib/msvcrt/string/strcat.c +++ b/lib/msvcrt/string/strcat.c @@ -1,12 +1,13 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -char * -strcat(char *s, const char *append) +#pragma function(strcat) + +char* strcat(char* s, const char* append) { - char *save = s; + char* save = s; - for (; *s; ++s); - while ((*s++ = *append++)); - return save; + for (; *s; ++s); + while ((*s++ = *append++)); + return save; } diff --git a/lib/msvcrt/string/strcmp.c b/lib/msvcrt/string/strcmp.c index edc4c94..35aa66f 100644 --- a/lib/msvcrt/string/strcmp.c +++ b/lib/msvcrt/string/strcmp.c @@ -1,7 +1,9 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -int strcmp(const char *s1, const char *s2) +#pragma function(strcmp) + +int strcmp(const char* s1, const char* s2) { while (*s1 == *s2) { @@ -10,5 +12,5 @@ int strcmp(const char *s1, const char *s2) s1++; s2++; } - return *(unsigned const char *)s1 - *(unsigned const char *)(s2); + return *(unsigned const char*)s1 - *(unsigned const char*)(s2); } diff --git a/lib/msvcrt/string/strcoll.c b/lib/msvcrt/string/strcoll.c index 30b4b4c..81e27d6 100644 --- a/lib/msvcrt/string/strcoll.c +++ b/lib/msvcrt/string/strcoll.c @@ -6,34 +6,25 @@ less than, equal to or greater than the collated form of S2. */ #if 1 -int strcoll (const char* s1, const char* s2) +int strcoll(const char* s1, const char* s2) { - return strcmp(s1,s2); + return strcmp(s1, s2); } -int _stricoll (const char* s1, const char* s2) +int _stricoll(const char* s1, const char* s2) { - return _stricmp(s1,s2); + return _stricmp(s1, s2); } -int _strncoll (const char *s1, const char *s2, size_t c) -{ - return strncmp(s1,s2,c); -} - -int _strnicoll (const char *s1, const char *s2, size_t c) -{ - return _strnicmp(s1,s2,c); -} #else -int strcoll (const char *s1,const char *s2) +int strcoll (const char* s1,const char* s2) { - int ret; - ret = CompareStringA(LOCALE_USER_DEFAULT,0,s1,strlen(s1),s2,strlen(s2)); - if (ret == 0) - return 0; - else - return ret - 2; - return 0; + int ret; + ret = CompareStringA(LOCALE_USER_DEFAULT,0,s1,strlen(s1),s2,strlen(s2)); + if (ret == 0) + return 0; + else + return ret - 2; + return 0; } #endif diff --git a/lib/msvcrt/string/strcpy.c b/lib/msvcrt/string/strcpy.c index c62cf0d..902254f 100644 --- a/lib/msvcrt/string/strcpy.c +++ b/lib/msvcrt/string/strcpy.c @@ -1,6 +1,7 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include +#pragma function(strcpy) char* strcpy(char *to, const char *from) { diff --git a/lib/msvcrt/string/strlen.c b/lib/msvcrt/string/strlen.c index 808d96c..ebac5d7 100644 --- a/lib/msvcrt/string/strlen.c +++ b/lib/msvcrt/string/strlen.c @@ -1,10 +1,11 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include -size_t -strlen(const char *str) +#pragma function(strlen) + +size_t strlen(const char* str) { - const char *s; + const char* s; if (str == 0) return 0; diff --git a/lib/msvcrt/string/strncoll.c b/lib/msvcrt/string/strncoll.c new file mode 100644 index 0000000..161b3fd --- /dev/null +++ b/lib/msvcrt/string/strncoll.c @@ -0,0 +1,17 @@ +#include +#include + +/* Compare S1 and S2, returning less than, equal to or + greater than zero if the collated form of S1 is lexicographically + less than, equal to or greater than the collated form of S2. */ + + +int _strncoll(const char* s1, const char* s2, size_t c) +{ + return strncmp(s1, s2, c); +} + +int _strnicoll(const char* s1, const char* s2, size_t c) +{ + return _strnicmp(s1, s2, c); +} diff --git a/lib/msvcrt/string/strrev.c b/lib/msvcrt/string/strrev.c index d36b7a3..fac5a47 100644 --- a/lib/msvcrt/string/strrev.c +++ b/lib/msvcrt/string/strrev.c @@ -2,17 +2,18 @@ char * _strrev(char *s) { - char *e; - char a; - e=s; + char a, *b, *e; + b=e=s; while (*e) e++; - while (s #include +#include char* _strnset (char* szToFill, int szFill, size_t sizeMaxFill) { diff --git a/lib/msvcrt/string/strtok.c b/lib/msvcrt/string/strtok.c index 1388dbe..f262051 100644 --- a/lib/msvcrt/string/strtok.c +++ b/lib/msvcrt/string/strtok.c @@ -2,7 +2,7 @@ #include #include -char *strtok(char *s, const char *delim) +char* strtok(char* s, const char* delim) { const char *spanp; int c, sc; diff --git a/lib/msvcrt/string/strxfrm.c b/lib/msvcrt/string/strxfrm.c index eca0b2d..ce76f99 100644 --- a/lib/msvcrt/string/strxfrm.c +++ b/lib/msvcrt/string/strxfrm.c @@ -11,8 +11,7 @@ size_t strxfrm( char *dest, const char *src, size_t n ) size_t strxfrm( char *dest, const char *src, size_t n ) { int ret = LCMapStringA(LOCALE_USER_DEFAULT,LCMAP_LOWERCASE, - src, strlen(src), - dest, strlen(dest) ); + src, strlen(src), dest, strlen(dest)); if ( ret == 0 ) return -1; diff --git a/lib/msvcrt/sys_stat/fstat.c b/lib/msvcrt/sys_stat/fstat.c index d82d233..cb4035b 100644 --- a/lib/msvcrt/sys_stat/fstat.c +++ b/lib/msvcrt/sys_stat/fstat.c @@ -16,14 +16,14 @@ #include #include -int _fstat(int fd, struct stat *statbuf) + +int _fstat(int fd, struct stat* statbuf) { BY_HANDLE_FILE_INFORMATION FileInformation; DWORD dwFileType; void* handle; - if (!statbuf) - { + if (!statbuf) { __set_errno(EINVAL); return -1; } @@ -58,7 +58,8 @@ int _fstat(int fd, struct stat *statbuf) statbuf->st_mode |= S_IFDIR; else statbuf->st_mode |= S_IFREG; - if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE; + if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + statbuf->st_mode |= S_IWRITE; } else if (dwFileType == FILE_TYPE_CHAR) { @@ -78,69 +79,3 @@ int _fstat(int fd, struct stat *statbuf) } return 0; } - -__int64 _fstati64 (int fd, struct _stati64* statbuf) -{ - BY_HANDLE_FILE_INFORMATION FileInformation; - DWORD dwFileType; - void *handle; - - if (!statbuf) - { - __set_errno(EINVAL); - return -1; - } - - if ((void*)-1 == (handle = _get_osfhandle(fd))) - { - __set_errno(EBADF); - return -1; - } - - fflush(NULL); - - memset(statbuf, 0, sizeof(struct _stati64)); - - dwFileType = GetFileType(handle); - - if (dwFileType == FILE_TYPE_DISK) - { - if (!GetFileInformationByHandle(handle,&FileInformation)) - { - __set_errno(EBADF); - return -1; - } - statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL); - statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL); - statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL); - - statbuf->st_dev = fd; - statbuf->st_size = (((__int64)FileInformation.nFileSizeHigh) << 32) + - FileInformation.nFileSizeLow; - statbuf->st_mode = S_IREAD; - if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - statbuf->st_mode |= S_IFDIR; - else - statbuf->st_mode |= S_IFREG; - if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE; - } - else if (dwFileType == FILE_TYPE_CHAR) - { - statbuf->st_dev = fd; - statbuf->st_mode = S_IFCHR; - } - else if (dwFileType == FILE_TYPE_PIPE) - { - statbuf->st_dev = fd; - statbuf->st_mode = S_IFIFO; - } - else - { - // dwFileType is FILE_TYPE_UNKNOWN or has a bad value - __set_errno(EBADF); - return -1; - } - return 0; -} - - diff --git a/lib/msvcrt/sys_stat/fstati64.c b/lib/msvcrt/sys_stat/fstati64.c new file mode 100644 index 0000000..ebde056 --- /dev/null +++ b/lib/msvcrt/sys_stat/fstati64.c @@ -0,0 +1,82 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/sys/fstat.c + * PURPOSE: Gather file information + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include +#include +#include +#include +#include +#include + + +__int64 _fstati64(int fd, struct _stati64* statbuf) +{ + BY_HANDLE_FILE_INFORMATION FileInformation; + DWORD dwFileType; + void *handle; + + if (!statbuf) + { + __set_errno(EINVAL); + return -1; + } + + if ((void*)-1 == (handle = _get_osfhandle(fd))) + { + __set_errno(EBADF); + return -1; + } + + fflush(NULL); + + memset(statbuf, 0, sizeof(struct _stati64)); + + dwFileType = GetFileType(handle); + + if (dwFileType == FILE_TYPE_DISK) + { + if (!GetFileInformationByHandle(handle,&FileInformation)) + { + __set_errno(EBADF); + return -1; + } + statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL); + statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL); + statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL); + + statbuf->st_dev = fd; + statbuf->st_size = (((__int64)FileInformation.nFileSizeHigh) << 32) + + FileInformation.nFileSizeLow; + statbuf->st_mode = S_IREAD; + if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + statbuf->st_mode |= S_IFDIR; + else + statbuf->st_mode |= S_IFREG; + if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE; + } + else if (dwFileType == FILE_TYPE_CHAR) + { + statbuf->st_dev = fd; + statbuf->st_mode = S_IFCHR; + } + else if (dwFileType == FILE_TYPE_PIPE) + { + statbuf->st_dev = fd; + statbuf->st_mode = S_IFIFO; + } + else + { + // dwFileType is FILE_TYPE_UNKNOWN or has a bad value + __set_errno(EBADF); + return -1; + } + return 0; +} diff --git a/lib/msvcrt/sys_stat/futime.c b/lib/msvcrt/sys_stat/futime.c index b308d08..399902c 100644 --- a/lib/msvcrt/sys_stat/futime.c +++ b/lib/msvcrt/sys_stat/futime.c @@ -6,38 +6,35 @@ #include #include + int _futime (int nHandle, struct _utimbuf *pTimes) { FILETIME LastAccessTime; FILETIME LastWriteTime; // check for stdin / stdout handles ?? - if (nHandle == -1) - { + if (nHandle == -1) { __set_errno(EBADF); return -1; - } + } - if (pTimes == NULL) - { + if (pTimes == NULL) { pTimes = alloca(sizeof(struct _utimbuf)); time(&pTimes->actime); time(&pTimes->modtime); - } + } - if (pTimes->actime < pTimes->modtime) - { + if (pTimes->actime < pTimes->modtime) { __set_errno(EINVAL); return -1; - } + } UnixTimeToFileTime(pTimes->actime,&LastAccessTime,0); UnixTimeToFileTime(pTimes->modtime,&LastWriteTime,0); - if (!SetFileTime(_get_osfhandle(nHandle),NULL, &LastAccessTime, &LastWriteTime)) - { + if (!SetFileTime(_get_osfhandle(nHandle),NULL, &LastAccessTime, &LastWriteTime)) { __set_errno(EBADF); return -1; - } + } return 0; } diff --git a/lib/msvcrt/sys_stat/stat.c b/lib/msvcrt/sys_stat/stat.c index 9e7a164..242c0bf 100644 --- a/lib/msvcrt/sys_stat/stat.c +++ b/lib/msvcrt/sys_stat/stat.c @@ -1,13 +1,14 @@ +#include #include #include #include #include #include - -#include +#include +#include -int _stat(const char *path, struct stat *buffer) +int _stat(const char* path, struct stat* buffer) { HANDLE findHandle; WIN32_FIND_DATAA findData; @@ -18,7 +19,7 @@ int _stat(const char *path, struct stat *buffer) return -1; } - if(strchr(path, '*') || strchr(path, '?')) + if (strchr(path, '*') || strchr(path, '?')) { __set_errno(EINVAL); return -1; @@ -51,140 +52,3 @@ int _stat(const char *path, struct stat *buffer) return 0; } - -__int64 _stati64 (const char *path, struct _stati64 *buffer) -{ - HANDLE findHandle; - WIN32_FIND_DATAA findData; - - if (!buffer) - { - __set_errno(EINVAL); - return -1; - } - - if(strchr(path, '*') || strchr(path, '?')) - { - __set_errno(EINVAL); - return -1; - } - - findHandle = FindFirstFileA(path, &findData); - if (findHandle == INVALID_HANDLE_VALUE) - { - __set_errno(ENOENT); - return -1; - } - - FindClose(findHandle); - - memset (buffer, 0, sizeof(struct stat)); - - buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); - buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); - buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); - -// statbuf->st_dev = fd; - buffer->st_size = (((__int64)findData.nFileSizeHigh) << 32) + - findData.nFileSizeLow; - buffer->st_mode = S_IREAD; - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - buffer->st_mode |= S_IFDIR; - else - buffer->st_mode |= S_IFREG; - if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - buffer->st_mode |= S_IWRITE; - - return 0; -} - -int _wstat (const wchar_t *path, struct stat *buffer) -{ - HANDLE findHandle; - WIN32_FIND_DATAW findData; - - if (!buffer) - { - __set_errno(EINVAL); - return -1; - } - - if(wcschr(path, L'*') || wcschr(path, L'?')) - { - __set_errno(EINVAL); - return -1; - } - - findHandle = FindFirstFileW(path, &findData); - if (findHandle == INVALID_HANDLE_VALUE) - { - __set_errno(ENOENT); - return -1; - } - - FindClose(findHandle); - - memset (buffer, 0, sizeof(struct stat)); - - buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); - buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); - buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); - -// statbuf->st_dev = fd; - buffer->st_size = findData.nFileSizeLow; - buffer->st_mode = S_IREAD; - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - buffer->st_mode |= S_IFDIR; - else - buffer->st_mode |= S_IFREG; - if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - buffer->st_mode |= S_IWRITE; - - return 0; -} - -__int64 _wstati64 (const wchar_t *path, struct _stati64 *buffer) -{ - HANDLE findHandle; - WIN32_FIND_DATAW findData; - - if (!buffer) - { - __set_errno(EINVAL); - return -1; - } - - if(wcschr(path, L'*') || wcschr(path, L'?')) - { - __set_errno(EINVAL); - return -1; - } - - findHandle = FindFirstFileW(path, &findData); - if (findHandle == INVALID_HANDLE_VALUE) - { - __set_errno(ENOENT); - return -1; - } - - FindClose(findHandle); - - memset (buffer, 0, sizeof(struct stat)); - - buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); - buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); - buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); - -// statbuf->st_dev = fd; - buffer->st_size = (((__int64)findData.nFileSizeHigh) << 32) + - findData.nFileSizeLow; - buffer->st_mode = S_IREAD; - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - buffer->st_mode |= S_IFDIR; - else - buffer->st_mode |= S_IFREG; - if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - buffer->st_mode |= S_IWRITE; - - return 0; -} diff --git a/lib/msvcrt/sys_stat/wstat.c b/lib/msvcrt/sys_stat/wstat.c new file mode 100644 index 0000000..8d37299 --- /dev/null +++ b/lib/msvcrt/sys_stat/wstat.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +int _wstat (const wchar_t *path, struct stat *buffer) +{ + HANDLE findHandle; + WIN32_FIND_DATAW findData; + + if (!buffer) + { + __set_errno(EINVAL); + return -1; + } + + if(wcschr(path, L'*') || wcschr(path, L'?')) + { + __set_errno(EINVAL); + return -1; + } + + findHandle = FindFirstFileW(path, &findData); + if (findHandle == INVALID_HANDLE_VALUE) + { + __set_errno(ENOENT); + return -1; + } + + FindClose(findHandle); + + memset (buffer, 0, sizeof(struct stat)); + + buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); + buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); + buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); + +// statbuf->st_dev = fd; + buffer->st_size = findData.nFileSizeLow; + buffer->st_mode = S_IREAD; + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + buffer->st_mode |= S_IFDIR; + else + buffer->st_mode |= S_IFREG; + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + buffer->st_mode |= S_IWRITE; + + return 0; +} + +__int64 _stati64 (const char *path, struct _stati64 *buffer) +{ + HANDLE findHandle; + WIN32_FIND_DATAA findData; + + if (!buffer) + { + __set_errno(EINVAL); + return -1; + } + + if(strchr(path, '*') || strchr(path, '?')) + { + __set_errno(EINVAL); + return -1; + } + + findHandle = FindFirstFileA(path, &findData); + if (findHandle == INVALID_HANDLE_VALUE) + { + __set_errno(ENOENT); + return -1; + } + + FindClose(findHandle); + + memset (buffer, 0, sizeof(struct stat)); + + buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); + buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); + buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); + +// statbuf->st_dev = fd; + buffer->st_size = (((__int64)findData.nFileSizeHigh) << 32) + + findData.nFileSizeLow; + buffer->st_mode = S_IREAD; + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + buffer->st_mode |= S_IFDIR; + else + buffer->st_mode |= S_IFREG; + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + buffer->st_mode |= S_IWRITE; + + return 0; +} + +__int64 _wstati64 (const wchar_t *path, struct _stati64 *buffer) +{ + HANDLE findHandle; + WIN32_FIND_DATAW findData; + + if (!buffer) + { + __set_errno(EINVAL); + return -1; + } + + if(wcschr(path, L'*') || wcschr(path, L'?')) + { + __set_errno(EINVAL); + return -1; + } + + findHandle = FindFirstFileW(path, &findData); + if (findHandle == INVALID_HANDLE_VALUE) + { + __set_errno(ENOENT); + return -1; + } + + FindClose(findHandle); + + memset (buffer, 0, sizeof(struct stat)); + + buffer->st_ctime = FileTimeToUnixTime(&findData.ftCreationTime,NULL); + buffer->st_atime = FileTimeToUnixTime(&findData.ftLastAccessTime,NULL); + buffer->st_mtime = FileTimeToUnixTime(&findData.ftLastWriteTime,NULL); + +// statbuf->st_dev = fd; + buffer->st_size = (((__int64)findData.nFileSizeHigh) << 32) + + findData.nFileSizeLow; + buffer->st_mode = S_IREAD; + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + buffer->st_mode |= S_IFDIR; + else + buffer->st_mode |= S_IFREG; + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + buffer->st_mode |= S_IWRITE; + + return 0; +} diff --git a/lib/msvcrt/time/ctime.c b/lib/msvcrt/time/ctime.c index b34b515..0f27e8e 100644 --- a/lib/msvcrt/time/ctime.c +++ b/lib/msvcrt/time/ctime.c @@ -29,19 +29,12 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90"; -#endif /* LIBC_SCCS and not lint */ - /* ** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). ** POSIX-style TZ environment variable handling from Guy Harris ** (guy@auspex.com). */ - - - #include #include #include @@ -56,26 +49,33 @@ static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90"; #include "posixrul.h" -#define P(s) s -#define alloc_size_t size_t -#define qsort_size_t size_t -#define fread_size_t size_t -#define fwrite_size_t size_t -#define ACCESS_MODE O_RDONLY|O_BINARY -#define OPEN_MODE O_RDONLY|O_BINARY +#ifdef __cplusplus +#define CPP_CONST const +#else +#define CPP_CONST +#endif + +#define P(s) s +#define alloc_size_t size_t +#define qsort_size_t size_t +#define fread_size_t size_t +#define fwrite_size_t size_t + +#define ACCESS_MODE O_RDONLY|O_BINARY +#define OPEN_MODE O_RDONLY|O_BINARY /* ** Someone might make incorrect use of a time zone abbreviation: -** 1. They might reference tzname[0] before calling tzset (explicitly -** or implicitly). -** 2. They might reference tzname[1] before calling tzset (explicitly -** or implicitly). -** 3. They might reference tzname[1] after setting to a time zone -** in which Daylight Saving Time is never observed. -** 4. They might reference tzname[0] after setting to a time zone -** in which Standard Time is never observed. -** 5. They might reference tm.TM_ZONE after calling offtime. +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. ** What's best to do in the above cases is open to debate; ** for now, we just set things up so that in any of the five cases ** WILDABBR is used. Another possibility: initialize tzname[0] to the @@ -84,28 +84,30 @@ static char sccsid[] = "@(#)ctime.c 5.23 (Berkeley) 6/22/90"; ** manual page of what this "time zone abbreviation" means (doing this so ** that tzname[0] has the "normal" length of three characters). */ -int _daylight; -int _timezone; + +void _set_daylight_export(int); +void _set_timezone_export(int); + static char WILDABBR[] = " "; #ifndef TRUE -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 #endif /* !defined TRUE */ static const char GMT[] = "GMT"; -struct ttinfo { /* time type information */ - long tt_gmtoff; /* GMT offset in seconds */ - int tt_isdst; /* used to set tm_isdst */ - int tt_abbrind; /* abbreviation list index */ - int tt_ttisstd; /* TRUE if transition is std time */ +struct ttinfo { /* time type information */ + long tt_gmtoff; /* GMT offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ }; -struct lsinfo { /* leap second information */ - time_t ls_trans; /* transition time */ - long ls_corr; /* correction to apply */ +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + long ls_corr; /* correction to apply */ }; struct state { @@ -121,49 +123,49 @@ struct state { }; struct rule { - int r_type; /* type of rule--see below */ - int r_day; /* day number of rule */ - int r_week; /* week number of rule */ - int r_mon; /* month number of rule */ - long r_time; /* transition time of rule */ + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + long r_time; /* transition time of rule */ }; -#define JULIAN_DAY 0 /* Jn - Julian day */ -#define DAY_OF_YEAR 1 /* n - day of year */ -#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ /* ** Prototypes for static functions. */ +#if 0 +static long detzcode P((const char * codep)); +static const char * getzname P((const char * strp)); +static const char * getnum P((const char * strp, int * nump, int min, int max)); +static const char * getsecs P((const char * strp, long * secsp)); +static const char * getoffset P((const char * strp, long * offsetp)); +static const char * getrule P((const char * strp, struct rule * rulep)); +static void gmtload P((struct state * sp)); +static void gmtsub P((const time_t * timep, long offset, struct tm * tmp)); +static void localsub P((const time_t * timep, long offset, struct tm * tmp)); +static void normalize P((int * tensptr, int * unitsptr, int base)); +static void settzname P((void)); +static time_t time1 P((struct tm * tmp, void (* funcp)(const time_t * CPP_CONST, const long, struct tm * CPP_CONST), long offset)); +static time_t time2 P((struct tm *tmp, void (* funcp)(const time_t * CPP_CONST, const long, struct tm * CPP_CONST), long offset, int * okayp)); +static void timesub P((const time_t * timep, long offset, const struct state * sp, struct tm * tmp)); +static int tmcomp P((const struct tm * atmp, const struct tm * btmp)); +static time_t transtime P((time_t janfirst, int year, const struct rule * rulep, long offset)); +static int tzload P((const char * name, struct state * sp)); +static int tzparse P((const char * name, struct state * sp, int lastditch)); +static void tzsetwall(void); + +#else + +static const char * getnum(const char * strp, int * CPP_CONST nump, const int min, const int max); +static void timesub(const time_t * CPP_CONST timep, const long offset, const struct state * CPP_CONST sp, struct tm * CPP_CONST tmp); +static time_t transtime(const time_t janfirst, const int year, const struct rule * CPP_CONST rulep, const long offset); +static void tzsetwall(void); -static long detzcode P((const char * codep)); -static const char * getzname P((const char * strp)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); -static const char * getsecs P((const char * strp, long * secsp)); -static const char * getoffset P((const char * strp, long * offsetp)); -static const char * getrule P((const char * strp, struct rule * rulep)); -static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void normalize P((int * tensptr, int * unitsptr, int base)); -static void settzname P((void)); -static time_t time1 P((struct tm * tmp, void (* funcp)(const time_t * const, const long, struct tm * const), - long offset)); -static time_t time2 P((struct tm *tmp, void (* funcp)(const time_t * const, const long, struct tm * const), - long offset, int * okayp)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); -static int tzload P((const char * name, struct state * sp)); -static int tzparse P((const char * name, struct state * sp, - int lastditch)); -static void tzsetwall(void); +#endif #ifdef ALL_STATE static struct state *lclptr; @@ -186,7 +188,7 @@ char * _tzname[2] = { }; static long -detzcode(const char * const codep) +detzcode(const char * CPP_CONST codep) { long result; int i; @@ -200,7 +202,7 @@ detzcode(const char * const codep) static void settzname(void) { - const struct state * const sp = lclptr; + const struct state * CPP_CONST sp = lclptr; int i; _tzname[0] = WILDABBR; @@ -214,17 +216,22 @@ settzname(void) #endif /* defined ALL_STATE */ for (i = 0; i < sp->typecnt; ++i) { - register const struct ttinfo * const ttisp = &sp->ttis[i]; + register const struct ttinfo * CPP_CONST ttisp = &sp->ttis[i]; _tzname[ttisp->tt_isdst] = (char *)&sp->chars[ttisp->tt_abbrind]; #if 0 - if (ttisp->tt_isdst) - _daylight = 1; - if (i == 0 || !ttisp->tt_isdst) - _timezone_dll = -(ttisp->tt_gmtoff); - if (i == 0 || ttisp->tt_isdst) + if (ttisp->tt_isdst) { + //_daylight = 1; + _set_daylight_export(1); + } + if (i == 0 || !ttisp->tt_isdst) { + //_timezone_dll = -(ttisp->tt_gmtoff); + _set_timezone_export(-(ttisp->tt_gmtoff)); + } + if (i == 0 || ttisp->tt_isdst) { _altzone = -(ttisp->tt_gmtoff); + } #endif } /* @@ -232,14 +239,13 @@ settzname(void) */ for (i = 0; i < sp->timecnt; ++i) { - const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]]; + const struct ttinfo * CPP_CONST ttisp = &sp->ttis[sp->types[i]]; _tzname[ttisp->tt_isdst] = (char *)&sp->chars[ttisp->tt_abbrind]; } } -static char * -tzdir(void) +static char* tzdir(void) { static char dir[80]={0}, *cp; if (dir[0] == 0) @@ -259,8 +265,7 @@ tzdir(void) return dir; } -static int -tzload(const char *name, struct state * const sp) +static int tzload(const char* name, struct state* CPP_CONST sp) { const char * p; int i; @@ -351,12 +356,12 @@ tzload(const char *name, struct state * const sp) return -1; ttisp->tt_abbrind = (unsigned char) *p++; if (ttisp->tt_abbrind < 0 || - ttisp->tt_abbrind > sp->charcnt) + ttisp->tt_abbrind > sp->charcnt) return -1; } for (i = 0; i < sp->charcnt; ++i) sp->chars[i] = *p++; - sp->chars[i] = '\0'; /* ensure '\0' at end */ + sp->chars[i] = '\0'; /* ensure '\0' at end */ for (i = 0; i < sp->leapcnt; ++i) { struct lsinfo * lsisp; @@ -378,8 +383,8 @@ tzload(const char *name, struct state * const sp) { ttisp->tt_ttisstd = *p++; if (ttisp->tt_ttisstd != TRUE && - ttisp->tt_ttisstd != FALSE) - return -1; + ttisp->tt_ttisstd != FALSE) + return -1; } } return 0; @@ -400,13 +405,13 @@ DAYSPERNYEAR, DAYSPERLYEAR ** character. */ -static const char * -getzname(const char *strp) +static const char* +getzname(const char* strp) { char c; while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && - c != '+') + c != '+') ++strp; return strp; } @@ -418,8 +423,8 @@ getzname(const char *strp) ** Otherwise, return a pointer to the first character not part of the number. */ -static const char * -getnum(const char *strp, int * const nump, const int min, const int max) +static const char* +getnum(const char* strp, int* CPP_CONST nump, const int min, const int max) { char c; int num; @@ -449,7 +454,7 @@ getnum(const char *strp, int * const nump, const int min, const int max) */ static const char * -getsecs(const char *strp, long * const secsp) +getsecs(const char *strp, long * CPP_CONST secsp) { int num; @@ -469,7 +474,7 @@ getsecs(const char *strp, long * const secsp) ++strp; strp = getnum(strp, &num, 0, SECSPERMIN - 1); if (strp == NULL) - return NULL; + return NULL; *secsp += num; } } @@ -484,7 +489,7 @@ getsecs(const char *strp, long * const secsp) */ static const char * -getoffset(const char *strp, long * const offsetp) +getoffset(const char *strp, long * CPP_CONST offsetp) { int neg; @@ -513,7 +518,7 @@ getoffset(const char *strp, long * const offsetp) */ static const char * -getrule(const char *strp, struct rule * const rulep) +getrule(const char *strp, struct rule * CPP_CONST rulep) { if (*strp == 'J') { @@ -552,7 +557,7 @@ getrule(const char *strp, struct rule * const rulep) strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); } else - return NULL; /* invalid format */ + return NULL; /* invalid format */ if (strp == NULL) return NULL; if (*strp == '/') @@ -575,7 +580,7 @@ getrule(const char *strp, struct rule * const rulep) */ static time_t -transtime(const time_t janfirst, const int year, const struct rule * const rulep, const long offset) +transtime(const time_t janfirst, const int year, const struct rule * CPP_CONST rulep, const long offset) { int leapyear; time_t value=0; @@ -625,7 +630,7 @@ transtime(const time_t janfirst, const int year, const struct rule * const rulep yy1 = yy0 / 100; yy2 = yy0 % 100; dow = ((26 * m1 - 2) / 10 + - 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; if (dow < 0) dow += DAYSPERWEEK; @@ -640,8 +645,8 @@ transtime(const time_t janfirst, const int year, const struct rule * const rulep for (i = 1; i < rulep->r_week; ++i) { if (d + DAYSPERWEEK >= - mon_lengths[leapyear][rulep->r_mon - 1]) - break; + mon_lengths[leapyear][rulep->r_mon - 1]) + break; d += DAYSPERWEEK; } @@ -667,7 +672,7 @@ transtime(const time_t janfirst, const int year, const struct rule * const rulep */ static int -tzparse(const char *name, struct state * const sp, const int lastditch) +tzparse(const char *name, struct state * CPP_CONST sp, const int lastditch) { const char * stdname; const char * dstname=0; @@ -683,7 +688,7 @@ tzparse(const char *name, struct state * const sp, const int lastditch) stdname = name; if (lastditch) { - stdlen = strlen(name); /* length of standard zone name */ + stdlen = strlen(name); /* length of standard zone name */ name += stdlen; if (stdlen >= sizeof sp->chars) stdlen = (sizeof sp->chars) - 1; @@ -705,19 +710,19 @@ tzparse(const char *name, struct state * const sp, const int lastditch) } load_result = tzload(TZDEFRULES, sp); if (load_result != 0) - sp->leapcnt = 0; /* so, we're off a little */ + sp->leapcnt = 0; /* so, we're off a little */ if (*name != '\0') { dstname = name; name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ + dstlen = name - dstname; /* length of DST zone name */ if (dstlen < 3) return -1; if (*name != '\0' && *name != ',' && *name != ';') { name = getoffset(name, &dstoffset); if (name == NULL) - return -1; + return -1; } else dstoffset = stdoffset - SECSPERHOUR; @@ -732,20 +737,20 @@ tzparse(const char *name, struct state * const sp, const int lastditch) ++name; if ((name = getrule(name, &start)) == NULL) - return -1; + return -1; if (*name++ != ',') - return -1; + return -1; if ((name = getrule(name, &end)) == NULL) - return -1; + return -1; if (*name != '\0') - return -1; - sp->typecnt = 2; /* standard time and DST */ + return -1; + sp->typecnt = 2; /* standard time and DST */ /* ** Two transitions per year, from EPOCH_YEAR to 2037. */ sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); if (sp->timecnt > TZ_MAX_TIMES) - return -1; + return -1; sp->ttis[0].tt_gmtoff = -dstoffset; sp->ttis[0].tt_isdst = 1; sp->ttis[0].tt_abbrind = stdlen + 1; @@ -757,26 +762,26 @@ tzparse(const char *name, struct state * const sp, const int lastditch) janfirst = 0; for (year = EPOCH_YEAR; year <= 2037; ++year) { - starttime = transtime(janfirst, year, &start, - stdoffset); - endtime = transtime(janfirst, year, &end, - dstoffset); - if (starttime > endtime) - { - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - } - else - { - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - } - janfirst += - year_lengths[isleap(year)] * SECSPERDAY; + starttime = transtime(janfirst, year, &start, + stdoffset); + endtime = transtime(janfirst, year, &end, + dstoffset); + if (starttime > endtime) + { + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + } + else + { + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + } + janfirst += + year_lengths[isleap(year)] * SECSPERDAY; } } else @@ -790,9 +795,9 @@ tzparse(const char *name, struct state * const sp, const int lastditch) int i; if (*name != '\0') - return -1; + return -1; if (load_result != 0) - return -1; + return -1; /* ** Compute the difference between the real and ** prototype standard and summer time offsets @@ -806,34 +811,34 @@ tzparse(const char *name, struct state * const sp, const int lastditch) dstfix = 0; for (i = 0; i < sp->typecnt; ++i) { - if (sp->ttis[i].tt_isdst) - { - oldfix = dstfix; - dstfix = - sp->ttis[i].tt_gmtoff + dstoffset; - if (sawdst && (oldfix != dstfix)) - return -1; - sp->ttis[i].tt_gmtoff = -dstoffset; - sp->ttis[i].tt_abbrind = stdlen + 1; - sawdst = TRUE; - } - else - { - oldfix = stdfix; - stdfix = - sp->ttis[i].tt_gmtoff + stdoffset; - if (sawstd && (oldfix != stdfix)) - return -1; - sp->ttis[i].tt_gmtoff = -stdoffset; - sp->ttis[i].tt_abbrind = 0; - sawstd = TRUE; - } + if (sp->ttis[i].tt_isdst) + { + oldfix = dstfix; + dstfix = + sp->ttis[i].tt_gmtoff + dstoffset; + if (sawdst && (oldfix != dstfix)) + return -1; + sp->ttis[i].tt_gmtoff = -dstoffset; + sp->ttis[i].tt_abbrind = stdlen + 1; + sawdst = TRUE; + } + else + { + oldfix = stdfix; + stdfix = + sp->ttis[i].tt_gmtoff + stdoffset; + if (sawstd && (oldfix != stdfix)) + return -1; + sp->ttis[i].tt_gmtoff = -stdoffset; + sp->ttis[i].tt_abbrind = 0; + sawstd = TRUE; + } } /* ** Make sure we have both standard and summer time. */ if (!sawdst || !sawstd) - return -1; + return -1; /* ** Now correct the transition times by shifting ** them by the difference between the real and @@ -846,28 +851,28 @@ tzparse(const char *name, struct state * const sp, const int lastditch) isdst = FALSE; /* we start in standard time */ for (i = 0; i < sp->timecnt; ++i) { - const struct ttinfo * ttisp; - - /* - ** If summer time is in effect, and the - ** transition time was not specified as - ** standard time, add the summer time - ** offset to the transition time; - ** otherwise, add the standard time offset - ** to the transition time. - */ - ttisp = &sp->ttis[sp->types[i]]; - sp->ats[i] += - (isdst && !ttisp->tt_ttisstd) ? - dstfix : stdfix; - isdst = ttisp->tt_isdst; + const struct ttinfo * ttisp; + + /* + ** If summer time is in effect, and the + ** transition time was not specified as + ** standard time, add the summer time + ** offset to the transition time; + ** otherwise, add the standard time offset + ** to the transition time. + */ + ttisp = &sp->ttis[sp->types[i]]; + sp->ats[i] += + (isdst && !ttisp->tt_ttisstd) ? + dstfix : stdfix; + isdst = ttisp->tt_isdst; } } } else { dstlen = 0; - sp->typecnt = 1; /* only standard time */ + sp->typecnt = 1; /* only standard time */ sp->timecnt = 0; sp->ttis[0].tt_gmtoff = -stdoffset; sp->ttis[0].tt_isdst = 0; @@ -891,7 +896,7 @@ tzparse(const char *name, struct state * const sp, const int lastditch) } static void -gmtload(struct state * const sp) +gmtload(struct state * CPP_CONST sp) { if (tzload(GMT, sp) != 0) (void) tzparse(GMT, sp, TRUE); @@ -915,7 +920,7 @@ _tzset(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { - settzname(); /* all we can do */ + settzname(); /* all we can do */ return; } } @@ -925,7 +930,7 @@ _tzset(void) /* ** User wants it fast rather than right. */ - lclptr->leapcnt = 0; /* so, we're off a little */ + lclptr->leapcnt = 0; /* so, we're off a little */ lclptr->timecnt = 0; lclptr->ttis[0].tt_gmtoff = 0; lclptr->ttis[0].tt_abbrind = 0; @@ -947,7 +952,7 @@ tzsetwall(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { - settzname(); /* all we can do */ + settzname(); /* all we can do */ return; } } @@ -968,7 +973,7 @@ tzsetwall(void) /*ARGSUSED*/ static void -localsub(const time_t * const timep, const long offset, struct tm * const tmp) +localsub(const time_t * CPP_CONST timep, const long offset, struct tm * CPP_CONST tmp) { const struct state * sp; const struct ttinfo * ttisp; @@ -991,15 +996,15 @@ localsub(const time_t * const timep, const long offset, struct tm * const tmp) while (sp->ttis[i].tt_isdst) if (++i >= sp->typecnt) { - i = 0; - break; + i = 0; + break; } } else { for (i = 1; i < sp->timecnt; ++i) if (t < sp->ats[i]) - break; + break; i = sp->types[i - 1]; } ttisp = &sp->ttis[i]; @@ -1016,7 +1021,7 @@ localsub(const time_t * const timep, const long offset, struct tm * const tmp) } struct tm * -localtime(const time_t * const timep) +localtime(const time_t * CPP_CONST timep) { static struct tm tm; @@ -1029,7 +1034,7 @@ localtime(const time_t * const timep) */ static void -gmtsub(const time_t * const timep, const long offset, struct tm * const tmp) +gmtsub(const time_t * CPP_CONST timep, const long offset, struct tm * CPP_CONST tmp) { if (!gmt_is_set) { @@ -1063,7 +1068,7 @@ gmtsub(const time_t * const timep, const long offset, struct tm * const tmp) } struct tm * -gmtime(const time_t * const timep) +gmtime(const time_t * CPP_CONST timep) { static struct tm tm; @@ -1072,7 +1077,7 @@ gmtime(const time_t * const timep) } static void -timesub(const time_t * const timep, const long offset, const struct state * const sp, struct tm * const tmp) +timesub(const time_t * CPP_CONST timep, const long offset, const struct state * CPP_CONST sp, struct tm * CPP_CONST tmp) { const struct lsinfo * lp; long days; @@ -1098,8 +1103,8 @@ timesub(const time_t * const timep, const long offset, const struct state * cons if (*timep >= lp->ls_trans) { if (*timep == lp->ls_trans) - hit = ((i == 0 && lp->ls_corr > 0) || - lp->ls_corr > sp->lsis[i - 1].ls_corr); + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); corr = lp->ls_corr; break; } @@ -1146,7 +1151,7 @@ timesub(const time_t * const timep, const long offset, const struct state * cons { yleap = isleap(y); if (days < (long) year_lengths[yleap]) - break; + break; ++y; days = days - (long) year_lengths[yleap]; } @@ -1183,63 +1188,35 @@ asctime(const struct tm *timeptr) static char result[26]; (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n", - wday_name[timeptr->tm_wday], - mon_name[timeptr->tm_mon], - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - return result; -} - -wchar_t * -_wasctime(const struct tm *timeptr) -{ - static const wchar_t wday_name[DAYSPERWEEK][3] = { - L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" - }; - static const wchar_t mon_name[MONSPERYEAR][3] = { - L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", - L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" - }; - static wchar_t result[26]; - - (void)swprintf(result, L"%.3s %.3s%3d %02d:%02d:%02d %d\n", - wday_name[timeptr->tm_wday], - mon_name[timeptr->tm_mon], - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); + wday_name[timeptr->tm_wday], + mon_name[timeptr->tm_mon], + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + TM_YEAR_BASE + timeptr->tm_year); return result; } - char * -ctime(const time_t * const timep) +ctime(const time_t * CPP_CONST timep) { return asctime(localtime(timep)); } -wchar_t * -_wctime(const time_t * const timep) -{ - return _wasctime(localtime(timep)); -} - /* ** Adapted from code provided by Robert Elz, who writes: -** The "best" way to do mktime I think is based on an idea of Bob -** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now). -** It does a binary search of the time_t space. Since time_t's are -** just 32 bits, its a max of 32 iterations (even at 64 bits it -** would still be very reasonable). +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now). +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). */ #ifndef WRONG -#define WRONG (-1) +#define WRONG (-1) #endif /* !defined WRONG */ static void -normalize(int * const tensptr, int * const unitsptr, const int base) +normalize(int * CPP_CONST tensptr, int * CPP_CONST unitsptr, const int base) { if (*unitsptr >= base) { @@ -1259,7 +1236,7 @@ normalize(int * const tensptr, int * const unitsptr, const int base) } static int -tmcomp(const struct tm * const atmp, const struct tm * const btmp) +tmcomp(const struct tm * CPP_CONST atmp, const struct tm * CPP_CONST btmp) { int result; @@ -1273,7 +1250,7 @@ tmcomp(const struct tm * const atmp, const struct tm * const btmp) } static time_t -time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct tm *), const long offset, int * const okayp) +time2(struct tm *tmp, void (*const funcp)(const time_t * CPP_CONST, const long, struct tm *), const long offset, int * CPP_CONST okayp) { const struct state * sp; int dir; @@ -1300,7 +1277,7 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct for ( ; ; ) { i = mon_lengths[isleap(yourtm.tm_year + - TM_YEAR_BASE)][yourtm.tm_mon]; + TM_YEAR_BASE)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) break; yourtm.tm_mday -= i; @@ -1323,7 +1300,12 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct ** If time_t is signed, then 0 is the median value, ** if time_t is unsigned, then 1 << bits is median. */ +#ifdef _MSVCRT_LIB_ t = (time_t) ((1 << bits) - 1); +#else // TODO: FIXME: review which is correct + t = (time_t) 1 << bits; +#endif /*_MSVCRT_LIB_*/ + for ( ; ; ) { (*funcp)(&t, offset, &mytm); @@ -1331,11 +1313,11 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct if (dir != 0) { if (bits-- < 0) - return WRONG; + return WRONG; if (bits < 0) - --t; + --t; else if (dir > 0) - t -= (time_t) 1 << bits; + t -= (time_t) 1 << bits; else t += (time_t) 1 << bits; continue; } @@ -1356,23 +1338,23 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct for (i = 0; i < sp->typecnt; ++i) { if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) - continue; + continue; for (j = 0; j < sp->typecnt; ++j) { - if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) - continue; - newt = t + sp->ttis[j].tt_gmtoff - - sp->ttis[i].tt_gmtoff; - (*funcp)(&newt, offset, &mytm); - if (tmcomp(&mytm, &yourtm) != 0) - continue; - if (mytm.tm_isdst != yourtm.tm_isdst) - continue; - /* - ** We have a match. - */ - t = newt; - goto label; + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; + (*funcp)(&newt, offset, &mytm); + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; } } return WRONG; @@ -1385,7 +1367,7 @@ time2(struct tm *tmp, void (*const funcp)(const time_t *const,const long,struct } static time_t -time1(struct tm * const tmp, void (*const funcp)(const time_t * const, const long, struct tm *), const long offset) +time1(struct tm * CPP_CONST tmp, void (*const funcp)(const time_t * CPP_CONST, const long, struct tm *), const long offset) { time_t t; const struct state * sp; @@ -1415,15 +1397,15 @@ time1(struct tm * const tmp, void (*const funcp)(const time_t * const, const lon for (otheri = 0; otheri < sp->typecnt; ++otheri) { if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) - continue; + continue; tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; + sp->ttis[samei].tt_gmtoff; tmp->tm_isdst = !tmp->tm_isdst; t = time2(tmp, funcp, offset, &okay); if (okay) - return t; + return t; tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; + sp->ttis[samei].tt_gmtoff; tmp->tm_isdst = !tmp->tm_isdst; } } @@ -1435,7 +1417,3 @@ mktime(struct tm * tmp) { return time1(tmp, localsub, 0L); } - - - - diff --git a/lib/msvcrt/time/strdate.c b/lib/msvcrt/time/strdate.c index 91ff36c..52f6ad5 100644 --- a/lib/msvcrt/time/strdate.c +++ b/lib/msvcrt/time/strdate.c @@ -12,36 +12,19 @@ #include #include -char *_strdate( const char *datestr ) -{ - time_t t; - struct tm *d; - char *dt = (char *)datestr; - - if ( datestr == NULL ) - { - __set_errno(EINVAL); - return NULL; - } - t = time(NULL); - d = localtime(&t); - sprintf(dt,"%d/%d/%d",d->tm_mday,d->tm_mon+1,d->tm_year); - return dt; -} -wchar_t *_wstrdate( const wchar_t *datestr ) +char* _strdate(const char* datestr) { - time_t t; - struct tm *d; - wchar_t *dt = (wchar_t *)datestr; + time_t t; + struct tm* d; + char* dt = (char*)datestr; - if ( datestr == NULL ) - { - __set_errno(EINVAL); - return NULL; + if (datestr == NULL) { + __set_errno(EINVAL); + return NULL; } - t = time(NULL); - d = localtime(&t); - swprintf(dt,L"%d/%d/%d",d->tm_mday,d->tm_mon+1,d->tm_year); - return dt; + t = time(NULL); + d = localtime(&t); + sprintf(dt,"%d/%d/%d",d->tm_mday,d->tm_mon+1,d->tm_year); + return dt; } diff --git a/lib/msvcrt/time/strftime.c b/lib/msvcrt/time/strftime.c index 96831ed..7a39f63 100644 --- a/lib/msvcrt/time/strftime.c +++ b/lib/msvcrt/time/strftime.c @@ -4,6 +4,7 @@ #include #include + #define TM_YEAR_BASE 1900 static const char *afmt[] = { @@ -25,8 +26,8 @@ static const char *Bfmt[] = { static size_t gsize; static char *pt; -static int -_add(const char *str) + +static int _add(const char* str) { for (;; ++pt, --gsize) { @@ -37,8 +38,7 @@ _add(const char *str) } } -static int -_conv(int n, int digits, char pad) +static int _conv(int n, int digits, char pad) { static char buf[10]; char *p; @@ -50,16 +50,14 @@ _conv(int n, int digits, char pad) return _add(++p); } -static size_t -_fmt(const char *format, const struct tm *t) +static size_t _fmt(const char* format, const struct tm* t) { for (; *format; ++format) { if (*format == '%') { if (*(format+1) == '#' ) {format++;} - switch(*++format) - { + switch(*++format) { case '\0': --format; break; @@ -113,8 +111,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'I': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, '0')) + if (!_conv(t->tm_hour % 12 ? t->tm_hour % 12 : 12, 2, '0')) return 0; continue; case 'j': @@ -126,8 +123,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'l': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, ' ')) + if (!_conv(t->tm_hour % 12 ? t->tm_hour % 12 : 12, 2, ' ')) return 0; continue; case 'M': @@ -168,14 +164,11 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'U': - if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, - 2, '0')) + if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, 2, '0')) return 0; continue; case 'W': - if (!_conv((t->tm_yday + 7 - - (t->tm_wday ? (t->tm_wday - 1) : 6)) - / 7, 2, '0')) + if (!_conv((t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, 2, '0')) return 0; continue; case 'w': @@ -187,8 +180,7 @@ _fmt(const char *format, const struct tm *t) return 0; continue; case 'y': - if (!_conv((t->tm_year + TM_YEAR_BASE) - % 100, 2, '0')) + if (!_conv((t->tm_year + TM_YEAR_BASE) % 100, 2, '0')) return 0; continue; case 'Y': @@ -230,8 +222,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *t) return 0; } -size_t -wcsftime(wchar_t *s, size_t maxsize, const wchar_t *format, const struct tm *t) +size_t wcsftime(wchar_t* s, size_t maxsize, const wchar_t* format, const struct tm* t) { char *x; char *f; @@ -245,8 +236,7 @@ wcsftime(wchar_t *s, size_t maxsize, const wchar_t *format, const struct tm *t) pt = x; if ((gsize = maxsize) < 1) return 0; - if (_fmt(f, t)) - { + if (_fmt(f, t)) { *pt = '\0'; free(f); for(i=0;i #include -char *_strtime(char* buf) -{ - time_t t; - struct tm *d; - char *dt = (char *)buf; - - if ( buf == NULL ) - { - __set_errno(EINVAL); - return NULL; - } - t = time(NULL); - d = localtime(&t); - sprintf(dt,"%d:%d:%d",d->tm_hour,d->tm_min,d->tm_sec); - return dt; -} -wchar_t *_wstrtime(wchar_t* buf) +char* _strtime(char* buf) { - time_t t; - struct tm *d; - wchar_t *dt = (wchar_t *)buf; + time_t t; + struct tm *d; + char* dt = (char*)buf; - if ( buf == NULL ) - { - __set_errno(EINVAL); - return NULL; + if ( buf == NULL ) { + __set_errno(EINVAL); + return NULL; } - t = time(NULL); - d = localtime(&t); - swprintf(dt,L"%d:%d:%d",d->tm_hour,d->tm_min,d->tm_sec); - return dt; + t = time(NULL); + d = localtime(&t); + sprintf(dt,"%d:%d:%d",d->tm_hour,d->tm_min,d->tm_sec); + return dt; } diff --git a/lib/msvcrt/time/time.c b/lib/msvcrt/time/time.c index 6b0da0b..f24c9f1 100644 --- a/lib/msvcrt/time/time.c +++ b/lib/msvcrt/time/time.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crtdll/conio/time.c + * FILE: lib/msvcrt/time/time.c * PURPOSE: Get system time * PROGRAMER: Boudewijn Dekker * UPDATE HISTORY: @@ -19,16 +19,16 @@ #include #include -VOID STDCALL GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime ); -time_t -time(time_t *t) +VOID STDCALL GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime); + +time_t time(time_t* t) { FILETIME SystemTime; DWORD Remainder; time_t tt; GetSystemTimeAsFileTime(&SystemTime); - tt = FileTimeToUnixTime( &SystemTime,&Remainder ); + tt = FileTimeToUnixTime(&SystemTime,&Remainder); if (t) *t = tt; return tt; diff --git a/lib/msvcrt/time/tz_vars.c b/lib/msvcrt/time/tz_vars.c new file mode 100644 index 0000000..aad68dc --- /dev/null +++ b/lib/msvcrt/time/tz_vars.c @@ -0,0 +1,21 @@ +#include +#include +#include + + +int _daylight; +int _timezone; + + +void _set_daylight_export(int value) +{ + _daylight = value; +} + +void _set_timezone_export(int value) +{ + _timezone = value; +} + + + diff --git a/lib/msvcrt/time/wctime.c b/lib/msvcrt/time/wctime.c new file mode 100644 index 0000000..08ad9cd --- /dev/null +++ b/lib/msvcrt/time/wctime.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ +/* This file has been modified by DJ Delorie. These modifications are +** Copyright (C) 1995 DJ Delorie, 24 Kirsten Ave, Rochester NH, +** 03867-2954, USA. +*/ + +/* + * Copyright (c) 1987, 1989 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Arthur David Olson of the National Cancer Institute. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include "tzfile.h" + + +wchar_t* _wasctime(const struct tm* timeptr) +{ +#ifdef __GNUC__ + static const wchar_t wday_name[DAYSPERWEEK][3] = { + L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" + }; + static const wchar_t mon_name[MONSPERYEAR][3] = { + L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", + L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" + }; +#else + static const wchar_t wday_name[DAYSPERWEEK][4] = { + L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" + }; + static const wchar_t mon_name[MONSPERYEAR][4] = { + L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", + L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" + }; +#endif + static wchar_t result[26]; + + (void)swprintf(result, L"%.3s %.3s%3d %02d:%02d:%02d %d\n", + wday_name[timeptr->tm_wday], + mon_name[timeptr->tm_mon], + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + TM_YEAR_BASE + timeptr->tm_year); + return result; +} + + +wchar_t* _wctime(const time_t* const timep) +{ + return _wasctime(localtime(timep)); +} diff --git a/lib/msvcrt/time/wstrdate.c b/lib/msvcrt/time/wstrdate.c new file mode 100644 index 0000000..3d5a3ba --- /dev/null +++ b/lib/msvcrt/time/wstrdate.c @@ -0,0 +1,30 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/time/strtime.c + * PURPOSE: Fills a buffer with a formatted date representation + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include +#include +#include + + +wchar_t* _wstrdate(const wchar_t* datestr) +{ + time_t t; + struct tm* d; + wchar_t* dt = (wchar_t*)datestr; + + if (datestr == NULL) { + __set_errno(EINVAL); + return NULL; + } + t = time(NULL); + d = localtime(&t); + swprintf(dt,L"%d/%d/%d",d->tm_mday,d->tm_mon+1,d->tm_year); + return dt; +} diff --git a/lib/msvcrt/time/wstrtime.c b/lib/msvcrt/time/wstrtime.c new file mode 100644 index 0000000..8af7e56 --- /dev/null +++ b/lib/msvcrt/time/wstrtime.c @@ -0,0 +1,30 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/time/strtime.c + * PURPOSE: Fills a buffer with a formatted time representation + * PROGRAMER: Boudewijn Dekker + * UPDATE HISTORY: + * 28/12/98: Created + */ +#include +#include +#include +#include + + +wchar_t* _wstrtime(wchar_t* buf) +{ + time_t t; + struct tm* d; + wchar_t* dt = (wchar_t*)buf; + + if ( buf == NULL ) { + __set_errno(EINVAL); + return NULL; + } + t = time(NULL); + d = localtime(&t); + swprintf(dt,L"%d:%d:%d",d->tm_hour,d->tm_min,d->tm_sec); + return dt; +} diff --git a/lib/msvcrt/wstring/wcsdup.c b/lib/msvcrt/wstring/wcsdup.c index c3e646a..84bac88 100644 --- a/lib/msvcrt/wstring/wcsdup.c +++ b/lib/msvcrt/wstring/wcsdup.c @@ -1,16 +1,18 @@ #include #include #include +#include -wchar_t *_wcsdup(const wchar_t *ptr) +wchar_t* _wcsdup(const wchar_t* ptr) { - wchar_t *dup; - dup = malloc((wcslen(ptr) + 1)*sizeof(wchar_t)); - if( dup == NULL ) { - __set_errno(ENOMEM); - return NULL; - } - wcscpy(dup,ptr); - return dup; + wchar_t* dup; + + dup = malloc((wcslen(ptr) + 1) * sizeof(wchar_t)); + if (dup == NULL) { + __set_errno(ENOMEM); + return NULL; + } + wcscpy(dup, ptr); + return dup; } diff --git a/lib/msvcrt/wstring/wcsncmp.c b/lib/msvcrt/wstring/wcsncmp.c index e661043..a3e0746 100644 --- a/lib/msvcrt/wstring/wcsncmp.c +++ b/lib/msvcrt/wstring/wcsncmp.c @@ -1,9 +1,10 @@ #include -int wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t count) +#if 0 + +int wcsncmp(const wchar_t* cs, const wchar_t* ct, size_t count) { - while ((*cs) == (*ct) && count > 0) - { + while ((*cs) == (*ct) && count > 0) { if (*cs == 0) return 0; cs++; @@ -11,6 +12,22 @@ int wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t count) count--; } return (*cs) - (*ct); - } +#else + +int wcsncmp(const wchar_t* cs, const wchar_t* ct, size_t count) +{ + if (count == 0) + return 0; + do { + if (*cs != *ct++) + //return *(unsigned const char *)cs - *(unsigned const char *)--ct; + return (*cs) - (*(--ct)); + if (*cs++ == 0) + break; + } while (--count != 0); + return 0; +} + +#endif diff --git a/lib/msvcrt/wstring/wcsncpy.c b/lib/msvcrt/wstring/wcsncpy.c index 07d0000..cd40d65 100644 --- a/lib/msvcrt/wstring/wcsncpy.c +++ b/lib/msvcrt/wstring/wcsncpy.c @@ -12,7 +12,6 @@ wchar_t * wcsncpy(wchar_t * dest,const wchar_t *src,size_t count) return(dest); } } - dest[i]=0; return(dest); } diff --git a/lib/msvcrt/wstring/wcspbrk.c b/lib/msvcrt/wstring/wcspbrk.c index 7ab4b91..6bf0030 100644 --- a/lib/msvcrt/wstring/wcspbrk.c +++ b/lib/msvcrt/wstring/wcspbrk.c @@ -13,4 +13,4 @@ wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2) } } return 0; -} \ No newline at end of file +} diff --git a/lib/msvcrt/wstring/wcsupr.c b/lib/msvcrt/wstring/wcsupr.c index 27db416..1eeef91 100644 --- a/lib/msvcrt/wstring/wcsupr.c +++ b/lib/msvcrt/wstring/wcsupr.c @@ -1,11 +1,12 @@ +#include #include wchar_t *_wcsupr(wchar_t *x) { - wchar_t *y=x; + wchar_t *y = x; while (*y) { - *y=towupper(*y); + *y = towupper(*y); y++; } return x; diff --git a/lib/ntdll/.cvsignore b/lib/ntdll/.cvsignore index 20b8edc..79f29e2 100644 --- a/lib/ntdll/.cvsignore +++ b/lib/ntdll/.cvsignore @@ -3,7 +3,9 @@ junk.tmp napi.asm napi.c ntdll.lib +ntdll.sym ntdll.coff ntdll.dll ntdll.nostrip.dll temp.exp +*.o diff --git a/lib/ntdll/def/ntdll.def b/lib/ntdll/def/ntdll.def index bb4eba9..02dc323 100644 --- a/lib/ntdll/def/ntdll.def +++ b/lib/ntdll/def/ntdll.def @@ -935,12 +935,12 @@ wcsstr wcstol wcstombs wcstoul -wine_dbgstr_an -wine_dbgstr_wn -wine_dbgstr_guid -wine_dbg_vprintf -wine_dbg_printf -wine_dbg_log +;wine_dbgstr_an +;wine_dbgstr_wn +;wine_dbgstr_guid +;wine_dbg_vprintf +;wine_dbg_printf +;wine_dbg_log InterlockedIncrement@4 InterlockedDecrement@4 InterlockedExchange@8 diff --git a/lib/ntdll/def/ntdll.edf b/lib/ntdll/def/ntdll.edf index e43cd21..d88ec47 100644 --- a/lib/ntdll/def/ntdll.edf +++ b/lib/ntdll/def/ntdll.edf @@ -938,10 +938,10 @@ wcsstr wcstol wcstombs wcstoul -wine_dbgstr_an -wine_dbgstr_wn -wine_dbgstr_guid -wine_dbg_vprintf -wine_dbg_printf -wine_dbg_log +;wine_dbgstr_an +;wine_dbgstr_wn +;wine_dbgstr_guid +;wine_dbg_vprintf +;wine_dbg_printf +;wine_dbg_log ;EOF diff --git a/lib/ntdll/ldr/res.c b/lib/ntdll/ldr/res.c new file mode 100644 index 0000000..f3f7f35 --- /dev/null +++ b/lib/ntdll/ldr/res.c @@ -0,0 +1,268 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: lib/ntdll/ldr/res.c + * PURPOSE: Resource access for PE executables + * PROGRAMMERS: Jean Michault + * Rex Jolliff (rex@lvcablemodem.com) + * Robert Dickenson (robd@mok.lvcm.com) + */ + +/* + * TODO: + * - any comments ?? + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* PROTOTYPES ****************************************************************/ + + + +/* FUNCTIONS *****************************************************************/ + +/* + Status = LdrFindResource_U (hModule, + &ResourceInfo, + RESOURCE_DATA_LEVEL, + &ResourceDataEntry); + */ +NTSTATUS STDCALL +LdrFindResource_U(PVOID BaseAddress, + PLDR_RESOURCE_INFO ResourceInfo, + ULONG Level, + PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry) +{ + PIMAGE_RESOURCE_DIRECTORY ResDir; + PIMAGE_RESOURCE_DIRECTORY ResBase; + PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry; + NTSTATUS Status = STATUS_SUCCESS; + ULONG EntryCount; + PWCHAR ws; + ULONG i; + ULONG Id; + + //DPRINT("LdrFindResource_U()\n"); + DPRINT("LdrFindResource_U(%08x, %08x, %d, %08x)\n", BaseAddress, ResourceInfo, Level, ResourceDataEntry); + + /* Get the pointer to the resource directory */ + ResDir = (PIMAGE_RESOURCE_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress, + TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &i); + if (ResDir == NULL) { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + + DPRINT("ResourceDirectory: %x Size: %d\n", (ULONG)ResDir, (int)i); + + ResBase = ResDir; + + /* Let's go into resource tree */ + for (i = 0; i < Level; i++) { + DPRINT("ResDir: %x Level: %d\n", (ULONG)ResDir, i); + + Id = ((PULONG)ResourceInfo)[i]; +// ResourceInfo.Type = (ULONG)lpType; +// ResourceInfo.Name = (ULONG)lpName; +// ResourceInfo.Language = (ULONG)wLanguage; + + EntryCount = ResDir->NumberOfNamedEntries; + DPRINT(" Id: %d NumberOfNamedEntries: %d\n", Id, EntryCount); + ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); + //DPRINT("ResEntry %x\n", (ULONG)ResEntry); + if (Id & 0xFFFF0000) { + /* Resource name is a unicode string */ + DPRINT("ResEntry %x - Resource name is a unicode string\n", (ULONG)ResEntry); + DPRINT("EntryCount %d\n", (ULONG)EntryCount); + for (; EntryCount--; ResEntry++) { + /* Scan entries for equal name */ + if (ResEntry->Name & 0x80000000) { + ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); + if (!wcsncmp((PWCHAR)Id, ws + 1, *ws) && + wcslen((PWCHAR)Id) == (int)*ws) { + goto found; + } + } + } + } else { + /* We use ID number instead of string */ + DPRINT("ResEntry %x - Resource ID number instead of string\n", (ULONG)ResEntry); + DPRINT("EntryCount %d\n", (ULONG)EntryCount); + ResEntry += EntryCount; + EntryCount = ResDir->NumberOfIdEntries; + DPRINT("EntryCount %d\n", (ULONG)EntryCount); + for (; EntryCount--; ResEntry++) { + /* Scan entries for equal name */ + DPRINT("EntryCount %d ResEntry %x\n", (ULONG)EntryCount, ResEntry); + DPRINT("ResEntry->Name %x Id %x\n", (ULONG)ResEntry->Name, Id); + if (ResEntry->Name == Id) { + DPRINT("ID entry found %x\n", Id); + goto found; + } + } + } + + //DPRINT("Error %lu\n", i); + + switch (i) { + case 0: + DPRINT("Error %lu - STATUS_RESOURCE_TYPE_NOT_FOUND\n", i); + return STATUS_RESOURCE_TYPE_NOT_FOUND; + case 1: + DPRINT("Error %lu - STATUS_RESOURCE_NAME_NOT_FOUND\n", i); + return STATUS_RESOURCE_NAME_NOT_FOUND; + case 2: + if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) { + /* Use the first available language */ + ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); + break; + } + DPRINT("Error %lu - STATUS_RESOURCE_LANG_NOT_FOUND\n", i); + return STATUS_RESOURCE_LANG_NOT_FOUND; + case 3: + DPRINT("Error %lu - STATUS_RESOURCE_DATA_NOT_FOUND\n", i); + return STATUS_RESOURCE_DATA_NOT_FOUND; + default: + DPRINT("Error %lu - STATUS_INVALID_PARAMETER\n", i); + return STATUS_INVALID_PARAMETER; + } +found:; + ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase + + (ResEntry->OffsetToData & 0x7FFFFFFF)); + } + DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir); + + if (ResourceDataEntry) { + *ResourceDataEntry = (PVOID)ResDir; + } + return Status; +} + + +NTSTATUS STDCALL +LdrAccessResource(IN PVOID BaseAddress, + IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, + OUT PVOID* Resource OPTIONAL, + OUT PULONG Size OPTIONAL) +{ + PIMAGE_SECTION_HEADER Section; + PIMAGE_NT_HEADERS NtHeader; + ULONG SectionRva; + ULONG SectionVa; + ULONG DataSize; + ULONG Offset = 0; + ULONG Data; + + Data = (ULONG)RtlImageDirectoryEntryToData(BaseAddress, + TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &DataSize); + if (Data == 0) { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + if ((ULONG)BaseAddress & 1) { + /* loaded as ordinary file */ + NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL)); + Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; + Section = RtlImageRvaToSection(NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); + if (Section == NULL) { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData) { + SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress; + SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL); + Offset = SectionRva - SectionVa + Data - Section->VirtualAddress; + } + } + if (Resource) { + *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress); + } + if (Size) { + *Size = ResourceDataEntry->Size; + } + return STATUS_SUCCESS; +} + + +NTSTATUS STDCALL +LdrFindResourceDirectory_U(IN PVOID BaseAddress, + WCHAR** name, + DWORD level, + OUT PVOID* addr) +{ + PIMAGE_RESOURCE_DIRECTORY ResDir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry; + ULONG EntryCount; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + WCHAR* ws; + + /* Get the pointer to the resource directory */ + ResDir = (PIMAGE_RESOURCE_DIRECTORY) + RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &i); + if (ResDir == NULL) { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + + /* Let's go into resource tree */ + for (i = 0; i < level; i++, name++) { + EntryCount = ResDir->NumberOfNamedEntries; + ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); + if ((ULONG)(*name) & 0xFFFF0000) { + /* Resource name is a unicode string */ + for (; EntryCount--; ResEntry++) { + /* Scan entries for equal name */ + if (ResEntry->Name & 0x80000000) { + ws = (WCHAR*)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); + if (!wcsncmp(*name, ws + 1, *ws) && wcslen(*name) == (int)*ws) { + goto found; + } + } + } + } else { + /* We use ID number instead of string */ + ResEntry += EntryCount; + EntryCount = ResDir->NumberOfIdEntries; + for (; EntryCount--; ResEntry++) { + /* Scan entries for equal name */ + if (ResEntry->Name == (ULONG)(*name)) + goto found; + } + } + switch (i) { + case 0: + return STATUS_RESOURCE_TYPE_NOT_FOUND; + case 1: + return STATUS_RESOURCE_NAME_NOT_FOUND; + case 2: + Status = STATUS_RESOURCE_LANG_NOT_FOUND; + /* Just use first language entry */ + if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) { + ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); + break; + } + return Status; + case 3: + return STATUS_RESOURCE_DATA_NOT_FOUND; + default: + return STATUS_INVALID_PARAMETER; + } +found:; + ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResDir + ResEntry->OffsetToData); + } + if (addr) { + *addr = (PVOID)ResDir; + } + return Status; +} + +/* EOF */ diff --git a/lib/ntdll/ldr/startup.c b/lib/ntdll/ldr/startup.c index d897e55..845a334 100644 --- a/lib/ntdll/ldr/startup.c +++ b/lib/ntdll/ldr/startup.c @@ -64,20 +64,20 @@ LdrInitializeThunk (ULONG Unknown1, RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); current_entry = - NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink; + NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink; while (current_entry != - &NtCurrentPeb()->Ldr->InInitializationOrderModuleList) - { - current = CONTAINING_RECORD(current_entry, LDR_MODULE, - InInitializationOrderModuleList); - Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint; - if (Entrypoint != NULL && - current->BaseAddress != NtCurrentPeb()->ImageBaseAddress) - { - (VOID)Entrypoint(current->BaseAddress, DLL_THREAD_ATTACH, NULL); - } - current_entry = current_entry->Flink; - } + &NtCurrentPeb()->Ldr->InInitializationOrderModuleList) + { + current = CONTAINING_RECORD(current_entry, LDR_MODULE, + InInitializationOrderModuleList); + Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint; + if (Entrypoint != NULL && + current->BaseAddress != NtCurrentPeb()->ImageBaseAddress) + { + (VOID)Entrypoint(current->BaseAddress, DLL_THREAD_ATTACH, NULL); + } + current_entry = current_entry->Flink; + } RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); return; } @@ -88,8 +88,8 @@ LdrInitializeThunk (ULONG Unknown1, DPRINT("ImageBase %x\n", ImageBase); if (ImageBase <= (PVOID)0x1000) { - DPRINT("ImageBase is null\n"); - ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); + DPRINT("ImageBase is null\n"); + ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); } NtGlobalFlag = Peb->NtGlobalFlag; @@ -101,8 +101,8 @@ LdrInitializeThunk (ULONG Unknown1, PEDosHeader->e_lfanew == 0L || *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC) { - DbgPrint("Image has bad header\n"); - ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); + DbgPrint("Image has bad header\n"); + ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); } /* normalize process parameters */ @@ -121,16 +121,16 @@ LdrInitializeThunk (ULONG Unknown1, /* create process heap */ RtlInitializeHeapManager(); - Peb->ProcessHeap = RtlCreateHeap(0, - (PVOID)HEAP_BASE, - NTHeaders->OptionalHeader.SizeOfHeapCommit, - NTHeaders->OptionalHeader.SizeOfHeapReserve, - NULL, - NULL); + Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, + (PVOID)HEAP_BASE, + NTHeaders->OptionalHeader.SizeOfHeapReserve, + NTHeaders->OptionalHeader.SizeOfHeapCommit, + NULL, + NULL); if (Peb->ProcessHeap == 0) { - DbgPrint("Failed to create process heap\n"); - ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + DbgPrint("Failed to create process heap\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } /* initalize peb lock support */ @@ -141,16 +141,16 @@ LdrInitializeThunk (ULONG Unknown1, /* initialize tls bitmap */ RtlInitializeBitMap (&TlsBitMap, - Peb->TlsBitmapBits, - TLS_MINIMUM_AVAILABLE); + Peb->TlsBitmapBits, + TLS_MINIMUM_AVAILABLE); Peb->TlsBitmap = &TlsBitMap; Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE; /* Initialize table of callbacks for the kernel. */ Peb->KernelCallbackTable = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - sizeof(PVOID) * USER32_CALLBACK_MAXIMUM); + 0, + sizeof(PVOID) * USER32_CALLBACK_MAXIMUM); /* initalize loader lock */ RtlInitializeCriticalSection (&LoaderLock); @@ -158,12 +158,12 @@ LdrInitializeThunk (ULONG Unknown1, /* create loader information */ Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap, - 0, - sizeof(PEB_LDR_DATA)); + 0, + sizeof(PEB_LDR_DATA)); if (Peb->Ldr == NULL) { - DbgPrint("Failed to create loader data\n"); - ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + DbgPrint("Failed to create loader data\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } Peb->Ldr->Length = sizeof(PEB_LDR_DATA); Peb->Ldr->Initialized = FALSE; @@ -178,21 +178,21 @@ LdrInitializeThunk (ULONG Unknown1, /* add entry for ntdll */ NtModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap, - 0, - sizeof(LDR_MODULE)); + 0, + sizeof(LDR_MODULE)); if (NtModule == NULL) { - DbgPrint("Failed to create loader module entry (NTDLL)\n"); - ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + DbgPrint("Failed to create loader module entry (NTDLL)\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } memset(NtModule, 0, sizeof(LDR_MODULE)); NtModule->BaseAddress = (PVOID)&_image_base__; NtModule->EntryPoint = 0; /* no entry point */ RtlCreateUnicodeString (&NtModule->FullDllName, - FullNtDllPath); + FullNtDllPath); RtlCreateUnicodeString (&NtModule->BaseDllName, - L"ntdll.dll"); + L"ntdll.dll"); NtModule->Flags = 0; NtModule->LoadCount = -1; /* don't unload */ NtModule->TlsIndex = 0; @@ -204,9 +204,9 @@ LdrInitializeThunk (ULONG Unknown1, NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; InsertTailList(&Peb->Ldr->InLoadOrderModuleList, - &NtModule->InLoadOrderModuleList); + &NtModule->InLoadOrderModuleList); InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, - &NtModule->InInitializationOrderModuleList); + &NtModule->InInitializationOrderModuleList); #ifdef DBG @@ -216,33 +216,30 @@ LdrInitializeThunk (ULONG Unknown1, /* add entry for executable (becomes first list entry) */ ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap, - 0, - sizeof(LDR_MODULE)); + 0, + sizeof(LDR_MODULE)); if (ExeModule == NULL) { - DbgPrint("Failed to create loader module infomation\n"); - ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + DbgPrint("Failed to create loader module infomation\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } ExeModule->BaseAddress = Peb->ImageBaseAddress; - if ((Peb->ProcessParameters != NULL) && - (Peb->ProcessParameters->ImagePathName.Length != 0)) - { - RtlCreateUnicodeString (&ExeModule->FullDllName, - Peb->ProcessParameters->ImagePathName.Buffer); - RtlCreateUnicodeString (&ExeModule->BaseDllName, - wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1); - } - else - { - /* FIXME(???): smss.exe doesn't have a process parameter block */ - wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot); - wcscat (FullNtDllPath, L"\\system32\\smss.exe"); - RtlCreateUnicodeString (&ExeModule->BaseDllName, - L"smss.exe"); - RtlCreateUnicodeString (&ExeModule->FullDllName, - FullNtDllPath); - } + if ((Peb->ProcessParameters == NULL) || + (Peb->ProcessParameters->ImagePathName.Length == 0)) + { + DbgPrint("Failed to access the process parameter block\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + } + + RtlCreateUnicodeString(&ExeModule->FullDllName, + Peb->ProcessParameters->ImagePathName.Buffer); + RtlCreateUnicodeString(&ExeModule->BaseDllName, + wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1); + + DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", + &ExeModule->BaseDllName, + &ExeModule->FullDllName); ExeModule->Flags = 0; ExeModule->LoadCount = -1; /* don't unload */ @@ -255,7 +252,7 @@ LdrInitializeThunk (ULONG Unknown1, ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; InsertHeadList(&Peb->Ldr->InLoadOrderModuleList, - &ExeModule->InLoadOrderModuleList); + &ExeModule->InLoadOrderModuleList); #ifdef DBG @@ -272,8 +269,8 @@ LdrInitializeThunk (ULONG Unknown1, /* Check before returning that we can run the image safely. */ if (EntryPoint == NULL) { - DbgPrint("Failed to initialize image\n"); - ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); + DbgPrint("Failed to initialize image\n"); + ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); } } diff --git a/lib/ntdll/ldr/utils.c b/lib/ntdll/ldr/utils.c index dc21967..e9cb9ea 100644 --- a/lib/ntdll/ldr/utils.c +++ b/lib/ntdll/ldr/utils.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: lib/ntdll/ldr/startup.c + * FILE: lib/ntdll/ldr/utils.c * PURPOSE: Process startup for PE executables * PROGRAMMERS: Jean Michault * Rex Jolliff (rex@lvcablemodem.com) @@ -10,9 +10,9 @@ /* * TODO: - * - Fix calling of entry points - * - Handle loading flags correctly - * - any more ?? + * - Fix calling of entry points + * - Handle loading flags correctly + * - any more ?? */ /* INCLUDES *****************************************************************/ @@ -59,36 +59,36 @@ LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule) /*************************************************************************** - * NAME LOCAL - * LdrAdjustDllName + * NAME LOCAL + * LdrAdjustDllName * * DESCRIPTION - * Adjusts the name of a dll to a fully qualified name. + * Adjusts the name of a dll to a fully qualified name. * * ARGUMENTS - * FullDllName: Pointer to caller supplied storage for the fully - * qualified dll name. - * DllName: Pointer to the dll name. - * BaseName: TRUE: Only the file name is passed to FullDllName - * FALSE: The full path is preserved in FullDllName + * FullDllName: Pointer to caller supplied storage for the fully + * qualified dll name. + * DllName: Pointer to the dll name. + * BaseName: TRUE: Only the file name is passed to FullDllName + * FALSE: The full path is preserved in FullDllName * * RETURN VALUE - * None + * None * * REVISIONS * * NOTE - * A given path is not affected by the adjustment, but the file - * name only: - * ntdll --> ntdll.dll - * ntdll. --> ntdll - * ntdll.xyz --> ntdll.xyz + * A given path is not affected by the adjustment, but the file + * name only: + * ntdll --> ntdll.dll + * ntdll. --> ntdll + * ntdll.xyz --> ntdll.xyz */ static VOID LdrAdjustDllName (PUNICODE_STRING FullDllName, - PUNICODE_STRING DllName, - BOOLEAN BaseName) + PUNICODE_STRING DllName, + BOOLEAN BaseName) { WCHAR Buffer[MAX_PATH]; ULONG Length; @@ -99,55 +99,52 @@ LdrAdjustDllName (PUNICODE_STRING FullDllName, if (BaseName == TRUE) { - /* get the base dll name */ - Pointer = DllName->Buffer + Length; - Extension = Pointer; - - do - { - --Pointer; - } - while (Pointer >= DllName->Buffer && *Pointer != L'\\' && *Pointer != L'/'); - - Pointer++; - Length = Extension - Pointer; - memmove (Buffer, Pointer, Length * sizeof(WCHAR)); - Buffer[Length] = L'\0'; + /* get the base dll name */ + Pointer = DllName->Buffer + Length; + Extension = Pointer; + + do + { + --Pointer; + } + while (Pointer >= DllName->Buffer && *Pointer != L'\\' && *Pointer != L'/'); + + Pointer++; + Length = Extension - Pointer; + memmove (Buffer, Pointer, Length * sizeof(WCHAR)); + Buffer[Length] = L'\0'; } else { - /* get the full dll name */ - memmove (Buffer, DllName->Buffer, DllName->Length); - Buffer[DllName->Length / sizeof(WCHAR)] = L'\0'; + /* get the full dll name */ + memmove (Buffer, DllName->Buffer, DllName->Length); + Buffer[DllName->Length / sizeof(WCHAR)] = L'\0'; } /* Build the DLL's absolute name */ Extension = wcsrchr (Buffer, L'.'); if ((Extension != NULL) && (*Extension == L'.')) { - /* with extension - remove dot if it's the last character */ - if (Buffer[Length - 1] == L'.') - Length--; - Buffer[Length] = 0; + /* with extension - remove dot if it's the last character */ + if (Buffer[Length - 1] == L'.') + Length--; + Buffer[Length] = 0; } else { - /* name without extension - assume that it is .dll */ - memmove (Buffer + Length, L".dll", 10); + /* name without extension - assume that it is .dll */ + memmove (Buffer + Length, L".dll", 10); } - RtlCreateUnicodeString (FullDllName, - Buffer); + RtlCreateUnicodeString(FullDllName, Buffer); } PLDR_MODULE LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders, - PWSTR FullDosName) + PWSTR FullDosName) { - PLDR_MODULE Module; - Module = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - sizeof (LDR_MODULE)); + PLDR_MODULE Module; + Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE)); assert(Module); Module->BaseAddress = (PVOID)ImageBase; Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint; @@ -158,9 +155,7 @@ LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders, { /* loading while app is running */ Module->LoadCount = 1; - } - else - { + } else { /* * loading while app is initializing * dll must not be unloaded @@ -173,24 +168,24 @@ LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders, Module->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; RtlCreateUnicodeString (&Module->FullDllName, - FullDosName); + FullDosName); RtlCreateUnicodeString (&Module->BaseDllName, - wcsrchr(FullDosName, L'\\') + 1); + wcsrchr(FullDosName, L'\\') + 1); DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName); /* FIXME: aquire loader lock */ InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList, - &Module->InLoadOrderModuleList); + &Module->InLoadOrderModuleList); InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, - &Module->InInitializationOrderModuleList); + &Module->InInitializationOrderModuleList); /* FIXME: release loader lock */ return(Module); } /*************************************************************************** - * NAME EXPORTED - * LdrLoadDll + * NAME EXPORTED + * LdrLoadDll * * DESCRIPTION * @@ -206,26 +201,26 @@ LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders, NTSTATUS STDCALL LdrLoadDll (IN PWSTR SearchPath OPTIONAL, - IN ULONG LoadFlags, - IN PUNICODE_STRING Name, - OUT PVOID *BaseAddress OPTIONAL) + IN ULONG LoadFlags, + IN PUNICODE_STRING Name, + OUT PVOID *BaseAddress OPTIONAL) { - WCHAR SearchPathBuffer[MAX_PATH]; - WCHAR FullDosName[MAX_PATH]; - UNICODE_STRING AdjustedName; - UNICODE_STRING FullNtFileName; - OBJECT_ATTRIBUTES FileObjectAttributes; - char BlockBuffer [1024]; - PIMAGE_DOS_HEADER DosHeader; - NTSTATUS Status; - PIMAGE_NT_HEADERS NTHeaders; - ULONG ImageSize; - ULONG InitialViewSize; - PVOID ImageBase; - HANDLE FileHandle; - HANDLE SectionHandle; - PDLLMAIN_FUNC Entrypoint = NULL; - PLDR_MODULE Module; + WCHAR SearchPathBuffer[MAX_PATH]; + WCHAR FullDosName[MAX_PATH]; + UNICODE_STRING AdjustedName; + UNICODE_STRING FullNtFileName; + OBJECT_ATTRIBUTES FileObjectAttributes; + char BlockBuffer [1024]; + PIMAGE_DOS_HEADER DosHeader; + NTSTATUS Status; + PIMAGE_NT_HEADERS NTHeaders; + ULONG ImageSize; + ULONG InitialViewSize; + PVOID ImageBase; + HANDLE FileHandle; + HANDLE SectionHandle; + PDLLMAIN_FUNC Entrypoint = NULL; + PLDR_MODULE Module; if (Name == NULL) { @@ -236,12 +231,12 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, *BaseAddress = NULL; DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n", - Name, BaseAddress); + Name, BaseAddress); /* adjust the full dll name */ LdrAdjustDllName (&AdjustedName, - Name, - FALSE); + Name, + FALSE); DPRINT("AdjustedName: %wZ\n", &AdjustedName); /* @@ -251,12 +246,12 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, { DPRINT("DLL %wZ already loaded.\n", &AdjustedName); if (Module->LoadCount != -1) - Module->LoadCount++; + Module->LoadCount++; *BaseAddress = Module->BaseAddress; return STATUS_SUCCESS; } DPRINT("Loading \"%wZ\"\n", Name); - + if (SearchPath == NULL) { SearchPath = SearchPathBuffer; @@ -269,11 +264,11 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, DPRINT("SearchPath %S\n", SearchPath); if (RtlDosSearchPath_U (SearchPath, - AdjustedName.Buffer, - NULL, - MAX_PATH, - FullDosName, - NULL) == 0) + AdjustedName.Buffer, + NULL, + MAX_PATH, + FullDosName, + NULL) == 0) return STATUS_DLL_NOT_FOUND; DPRINT("FullDosName %S\n", FullDosName); @@ -281,45 +276,45 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, RtlFreeUnicodeString (&AdjustedName); if (!RtlDosPathNameToNtPathName_U (FullDosName, - &FullNtFileName, - NULL, - NULL)) + &FullNtFileName, + NULL, + NULL)) return STATUS_DLL_NOT_FOUND; DPRINT("FullNtFileName %wZ\n", &FullNtFileName); InitializeObjectAttributes(&FileObjectAttributes, - &FullNtFileName, - 0, - NULL, - NULL); + &FullNtFileName, + 0, + NULL, + NULL); DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName); Status = ZwOpenFile(&FileHandle, - FILE_ALL_ACCESS, - &FileObjectAttributes, - NULL, - 0, - 0); + FILE_ALL_ACCESS, + &FileObjectAttributes, + NULL, + 0, + 0); if (!NT_SUCCESS(Status)) { DbgPrint("Dll open of %wZ failed: Status = 0x%08x\n", - &FullNtFileName, Status); + &FullNtFileName, Status); RtlFreeUnicodeString (&FullNtFileName); return Status; } RtlFreeUnicodeString (&FullNtFileName); Status = ZwReadFile(FileHandle, - 0, - 0, - 0, - 0, - BlockBuffer, - sizeof(BlockBuffer), - 0, - 0); + 0, + 0, + 0, + 0, + BlockBuffer, + sizeof(BlockBuffer), + 0, + 0); if (!NT_SUCCESS(Status)) { DPRINT("Dll header read failed: Status = 0x%08x\n", Status); @@ -349,17 +344,17 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, ImageSize = NTHeaders->OptionalHeader.SizeOfImage; DPRINT("ImageBase 0x%08x\n", ImageBase); - + /* * Create a section for dll. */ Status = ZwCreateSection(&SectionHandle, - SECTION_ALL_ACCESS, - NULL, - NULL, - PAGE_READWRITE, - SEC_COMMIT | SEC_IMAGE, - FileHandle); + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_READWRITE, + SEC_COMMIT | SEC_IMAGE, + FileHandle); if (!NT_SUCCESS(Status)) { DPRINT("NTDLL create section failed: Status = 0x%08x\n", Status); @@ -373,21 +368,20 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, InitialViewSize = 0; ImageBase = 0; Status = ZwMapViewOfSection(SectionHandle, - NtCurrentProcess(), - &ImageBase, - 0, - InitialViewSize, - NULL, - &InitialViewSize, - 0, - MEM_COMMIT, - PAGE_READWRITE); + NtCurrentProcess(), + &ImageBase, + 0, + InitialViewSize, + NULL, + &InitialViewSize, + 0, + MEM_COMMIT, + PAGE_READWRITE); if (!NT_SUCCESS(Status)) { - DbgPrint("NTDLL.LDR: map view of section failed (Status %x)\n", - Status); + DbgPrint("NTDLL.LDR: map view of section failed (Status %x)\n", Status); ZwClose(FileHandle); - return(Status); + return(Status); } ZwClose(FileHandle); @@ -396,12 +390,12 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, IMAGE_FILE_DLL) { Entrypoint = - (PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module, - FullDosName); + (PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module, + FullDosName); if (Entrypoint == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } } #ifdef DBG @@ -415,29 +409,29 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, IMAGE_FILE_DLL) { if (Module->EntryPoint != 0) - { - Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; - - DPRINT("Calling entry point at 0x%08x\n", Entrypoint); - if (FALSE == Entrypoint(Module->BaseAddress, - DLL_PROCESS_ATTACH, - NULL)) - { - DPRINT("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n", - &Module->BaseDllName); - /* FIXME: should clean up and fail */ - } - else - { - DPRINT("NTDLL.LDR: DLL \"%wZ\" initialized successfully\n", - &Module->BaseDllName); - } - } + { + Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; + + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + if (FALSE == Entrypoint(Module->BaseAddress, + DLL_PROCESS_ATTACH, + NULL)) + { + DPRINT("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n", + &Module->BaseDllName); + /* FIXME: should clean up and fail */ + } + else + { + DPRINT("NTDLL.LDR: DLL \"%wZ\" initialized successfully\n", + &Module->BaseDllName); + } + } else - { - DPRINT("NTDLL.LDR: Entrypoint is NULL for \"%wZ\"\n", - &Module->BaseDllName); - } + { + DPRINT("NTDLL.LDR: Entrypoint is NULL for \"%wZ\"\n", + &Module->BaseDllName); + } } *BaseAddress = Module->BaseAddress; @@ -446,8 +440,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, /*************************************************************************** - * NAME EXPORTED - * LdrFindEntryForAddress + * NAME EXPORTED + * LdrFindEntryForAddress * * DESCRIPTION * @@ -462,7 +456,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, */ NTSTATUS STDCALL LdrFindEntryForAddress(PVOID Address, - PLDR_MODULE *Module) + PLDR_MODULE *Module) { PLIST_ENTRY ModuleListHead; PLIST_ENTRY Entry; @@ -485,11 +479,11 @@ LdrFindEntryForAddress(PVOID Address, DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->BaseAddress); if ((Address >= ModulePtr->BaseAddress) && - (Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage))) - { - *Module = ModulePtr; - return(STATUS_SUCCESS); - } + (Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage))) + { + *Module = ModulePtr; + return(STATUS_SUCCESS); + } Entry = Entry->Flink; } @@ -501,8 +495,8 @@ LdrFindEntryForAddress(PVOID Address, /*************************************************************************** - * NAME LOCAL - * LdrFindEntryForName + * NAME LOCAL + * LdrFindEntryForName * * DESCRIPTION * @@ -517,7 +511,7 @@ LdrFindEntryForAddress(PVOID Address, */ static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, - PLDR_MODULE *Module) + PLDR_MODULE *Module) { PLIST_ENTRY ModuleListHead; PLIST_ENTRY Entry; @@ -547,10 +541,10 @@ LdrFindEntryForName(PUNICODE_STRING Name, DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, Name); if (RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE) == 0) - { - *Module = ModulePtr; - return(STATUS_SUCCESS); - } + { + *Module = ModulePtr; + return(STATUS_SUCCESS); + } Entry = Entry->Flink; } @@ -561,8 +555,8 @@ LdrFindEntryForName(PUNICODE_STRING Name, } /********************************************************************** - * NAME LOCAL - * LdrFixupForward + * NAME LOCAL + * LdrFixupForward * * DESCRIPTION * @@ -589,31 +583,31 @@ LdrFixupForward(PCHAR ForwardName) p = strchr(NameBuffer, '.'); if (p != NULL) { - *p = 0; - - DPRINT("Dll: %s Function: %s\n", NameBuffer, p+1); - RtlCreateUnicodeStringFromAsciiz (&DllName, - NameBuffer); - - Status = LdrGetDllHandle (0, 0, &DllName, &BaseAddress); - if (!NT_SUCCESS(Status)) - { - Status = LdrLoadDll(NULL, - 0, - &DllName, - &BaseAddress); - if (!NT_SUCCESS(Status)) - { - DbgPrint("LdrFixupForward: failed to load %wZ\n", &DllName); - RtlFreeUnicodeString (&DllName); - return NULL; - } - } - - RtlFreeUnicodeString (&DllName); - DPRINT("BaseAddress: %p\n", BaseAddress); - - return LdrGetExportByName(BaseAddress, p+1, -1); + *p = 0; + + DPRINT("Dll: %s Function: %s\n", NameBuffer, p+1); + RtlCreateUnicodeStringFromAsciiz (&DllName, + NameBuffer); + + Status = LdrGetDllHandle (0, 0, &DllName, &BaseAddress); + if (!NT_SUCCESS(Status)) + { + Status = LdrLoadDll(NULL, + 0, + &DllName, + &BaseAddress); + if (!NT_SUCCESS(Status)) + { + DbgPrint("LdrFixupForward: failed to load %wZ\n", &DllName); + RtlFreeUnicodeString (&DllName); + return NULL; + } + } + + RtlFreeUnicodeString (&DllName); + DPRINT("BaseAddress: %p\n", BaseAddress); + + return LdrGetExportByName(BaseAddress, p+1, -1); } return NULL; @@ -621,9 +615,9 @@ LdrFixupForward(PCHAR ForwardName) /********************************************************************** - * NAME LOCAL - * LdrGetExportByOrdinal - * + * NAME LOCAL + * LdrGetExportByOrdinal + * * DESCRIPTION * * ARGUMENTS @@ -637,44 +631,44 @@ LdrFixupForward(PCHAR ForwardName) */ static PVOID LdrGetExportByOrdinal ( - PVOID BaseAddress, - ULONG Ordinal - ) + PVOID BaseAddress, + ULONG Ordinal + ) { - PIMAGE_EXPORT_DIRECTORY ExportDir; - PDWORD * ExFunctions; - USHORT * ExOrdinals; - - ExportDir = (PIMAGE_EXPORT_DIRECTORY) - RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - NULL); - - - ExOrdinals = (USHORT *) - RVA( - BaseAddress, - ExportDir->AddressOfNameOrdinals - ); - ExFunctions = (PDWORD *) - RVA( - BaseAddress, - ExportDir->AddressOfFunctions - ); - DbgPrint( - "LdrGetExportByOrdinal(Ordinal %d) = %x\n", - Ordinal, - ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]] - ); - return(ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]]); + PIMAGE_EXPORT_DIRECTORY ExportDir; + PDWORD * ExFunctions; + USHORT * ExOrdinals; + + ExportDir = (PIMAGE_EXPORT_DIRECTORY) + RtlImageDirectoryEntryToData (BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + NULL); + + + ExOrdinals = (USHORT *) + RVA( + BaseAddress, + ExportDir->AddressOfNameOrdinals + ); + ExFunctions = (PDWORD *) + RVA( + BaseAddress, + ExportDir->AddressOfFunctions + ); + DbgPrint( + "LdrGetExportByOrdinal(Ordinal %d) = %x\n", + Ordinal, + ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]] + ); + return(ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]]); } /********************************************************************** - * NAME LOCAL - * LdrGetExportByName - * + * NAME LOCAL + * LdrGetExportByName + * * DESCRIPTION * * ARGUMENTS @@ -688,17 +682,17 @@ LdrGetExportByOrdinal ( */ static PVOID LdrGetExportByName(PVOID BaseAddress, - PUCHAR SymbolName, - WORD Hint) + PUCHAR SymbolName, + WORD Hint) { - PIMAGE_EXPORT_DIRECTORY ExportDir; - PDWORD * ExFunctions; - PDWORD * ExNames; - USHORT * ExOrdinals; - ULONG i; - PVOID ExName; - ULONG Ordinal; - PVOID Function; + PIMAGE_EXPORT_DIRECTORY ExportDir; + PDWORD * ExFunctions; + PDWORD * ExNames; + USHORT * ExOrdinals; + ULONG i; + PVOID ExName; + ULONG Ordinal; + PVOID Function; ULONG minn, maxn; ULONG ExportDirSize; @@ -706,44 +700,44 @@ LdrGetExportByName(PVOID BaseAddress, ExportDir = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData(BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - &ExportDirSize); + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportDirSize); if (ExportDir == NULL) { - DbgPrint("LdrGetExportByName(): no export directory!\n"); - return NULL; + DbgPrint("LdrGetExportByName(): no export directory!\n"); + return NULL; } /* * Get header pointers */ ExNames = (PDWORD *)RVA(BaseAddress, - ExportDir->AddressOfNames); + ExportDir->AddressOfNames); ExOrdinals = (USHORT *)RVA(BaseAddress, - ExportDir->AddressOfNameOrdinals); + ExportDir->AddressOfNameOrdinals); ExFunctions = (PDWORD *)RVA(BaseAddress, - ExportDir->AddressOfFunctions); + ExportDir->AddressOfFunctions); /* * Check the hint first */ if (Hint < ExportDir->NumberOfFunctions) { - ExName = RVA(BaseAddress, ExNames[Hint]); - if (strcmp(ExName, SymbolName) == 0) - { - Ordinal = ExOrdinals[Hint]; - Function = RVA(BaseAddress, ExFunctions[Ordinal]); - if (((ULONG)Function >= (ULONG)ExportDir) && - ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) - { - DPRINT("Forward: %s\n", (PCHAR)Function); - Function = LdrFixupForward((PCHAR)Function); - } - if (Function != NULL) - return Function; - } + ExName = RVA(BaseAddress, ExNames[Hint]); + if (strcmp(ExName, SymbolName) == 0) + { + Ordinal = ExOrdinals[Hint]; + Function = RVA(BaseAddress, ExFunctions[Ordinal]); + if (((ULONG)Function >= (ULONG)ExportDir) && + ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) + { + DPRINT("Forward: %s\n", (PCHAR)Function); + Function = LdrFixupForward((PCHAR)Function); + } + if (Function != NULL) + return Function; + } } /* @@ -753,39 +747,39 @@ LdrGetExportByName(PVOID BaseAddress, maxn = ExportDir->NumberOfFunctions; while (minn <= maxn) { - ULONG mid; - LONG res; - - mid = (minn + maxn) / 2; - - ExName = RVA(BaseAddress, ExNames[mid]); - res = strcmp(ExName, SymbolName); - if (res == 0) - { - Ordinal = ExOrdinals[mid]; - Function = RVA(BaseAddress, ExFunctions[Ordinal]); - if (((ULONG)Function >= (ULONG)ExportDir) && - ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) - { - DPRINT("Forward: %s\n", (PCHAR)Function); - Function = LdrFixupForward((PCHAR)Function); - } - if (Function != NULL) - return Function; - } - else if (minn == maxn) - { - DPRINT("LdrGetExportByName(): binary search failed\n"); - break; - } - else if (res > 0) - { - maxn = mid - 1; - } - else - { - minn = mid + 1; - } + ULONG mid; + LONG res; + + mid = (minn + maxn) / 2; + + ExName = RVA(BaseAddress, ExNames[mid]); + res = strcmp(ExName, SymbolName); + if (res == 0) + { + Ordinal = ExOrdinals[mid]; + Function = RVA(BaseAddress, ExFunctions[Ordinal]); + if (((ULONG)Function >= (ULONG)ExportDir) && + ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) + { + DPRINT("Forward: %s\n", (PCHAR)Function); + Function = LdrFixupForward((PCHAR)Function); + } + if (Function != NULL) + return Function; + } + else if (minn == maxn) + { + DPRINT("LdrGetExportByName(): binary search failed\n"); + break; + } + else if (res > 0) + { + maxn = mid - 1; + } + else + { + minn = mid + 1; + } } /* @@ -794,20 +788,20 @@ LdrGetExportByName(PVOID BaseAddress, DPRINT("LdrGetExportByName(): Falling back on a linear search of export table\n"); for (i = 0; i < ExportDir->NumberOfFunctions; i++) { - ExName = RVA(BaseAddress, ExNames[i]); - if (strcmp(ExName,SymbolName) == 0) - { - Ordinal = ExOrdinals[i]; - Function = RVA(BaseAddress, ExFunctions[Ordinal]); - DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize); - if (((ULONG)Function >= (ULONG)ExportDir) && - ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) - { - DPRINT("Forward: %s\n", (PCHAR)Function); - Function = LdrFixupForward((PCHAR)Function); - } - return Function; - } + ExName = RVA(BaseAddress, ExNames[i]); + if (strcmp(ExName,SymbolName) == 0) + { + Ordinal = ExOrdinals[i]; + Function = RVA(BaseAddress, ExFunctions[Ordinal]); + DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize); + if (((ULONG)Function >= (ULONG)ExportDir) && + ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize)) + { + DPRINT("Forward: %s\n", (PCHAR)Function); + Function = LdrFixupForward((PCHAR)Function); + } + return Function; + } } DbgPrint("LdrGetExportByName(): failed to find %s\n",SymbolName); return NULL; @@ -815,12 +809,12 @@ LdrGetExportByName(PVOID BaseAddress, /********************************************************************** - * NAME LOCAL - * LdrPerformRelocations - * + * NAME LOCAL + * LdrPerformRelocations + * * DESCRIPTION - * Relocate a DLL's memory image. - * + * Relocate a DLL's memory image. + * * ARGUMENTS * * RETURN VALUE @@ -830,18 +824,18 @@ LdrGetExportByName(PVOID BaseAddress, * NOTE * */ -static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, - PVOID ImageBase) +static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, + PVOID ImageBase) { - USHORT NumberOfEntries; - PUSHORT pValue16; - ULONG RelocationRVA; - ULONG Delta32; - ULONG Offset; - PULONG pValue32; - PRELOCATION_DIRECTORY RelocationDir; - PRELOCATION_ENTRY RelocationBlock; - int i; + USHORT NumberOfEntries; + PUSHORT pValue16; + ULONG RelocationRVA; + ULONG Delta32; + ULONG Offset; + PULONG pValue32; + PRELOCATION_DIRECTORY RelocationDir; + PRELOCATION_ENTRY RelocationBlock; + int i; PIMAGE_DATA_DIRECTORY RelocationDDir; ULONG OldProtect; NTSTATUS Status; @@ -855,12 +849,12 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++) { if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD)) - { - ULONG Extend; - Extend = - (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize); - MaxExtend = max(MaxExtend, Extend); - } + { + ULONG Extend; + Extend = + (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize); + MaxExtend = max(MaxExtend, Extend); + } } RelocationDDir = @@ -870,106 +864,106 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, if (RelocationRVA) { RelocationDir = - (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA); + (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA); while (RelocationDir->SizeOfBlock) - { - if (RelocationDir->VirtualAddress > MaxExtend) - { - RelocationRVA += RelocationDir->SizeOfBlock; - RelocationDir = - (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); - continue; - } - - Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase); - RelocationBlock = - (PRELOCATION_ENTRY) (RelocationRVA + ImageBase + - sizeof (RELOCATION_DIRECTORY)); - NumberOfEntries = - RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY); - NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY); - - Status = NtProtectVirtualMemory(NtCurrentProcess(), - ImageBase + - RelocationDir->VirtualAddress, - PAGE_SIZE, - PAGE_READWRITE, - &OldProtect); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to unprotect relocation target.\n"); - return(Status); - } - - for (i = 0; i < NumberOfEntries; i++) - { - Offset = (RelocationBlock[i].TypeOffset & 0xfff); - Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase); - - /* - * What kind of relocations should we perform - * for the current entry? - */ - switch (RelocationBlock[i].TypeOffset >> 12) - { - case TYPE_RELOC_ABSOLUTE: - break; - - case TYPE_RELOC_HIGH: - pValue16 = (PUSHORT)Offset; - *pValue16 += Delta32 >> 16; - break; - - case TYPE_RELOC_LOW: - pValue16 = (PUSHORT)Offset; - *pValue16 += Delta32 & 0xffff; - break; - - case TYPE_RELOC_HIGHLOW: - pValue32 = (PULONG)Offset; - *pValue32 += Delta32; - break; - - case TYPE_RELOC_HIGHADJ: - /* FIXME: do the highadjust fixup */ - DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n"); - return(STATUS_UNSUCCESSFUL); - - default: - DPRINT("unexpected fixup type\n"); - return STATUS_UNSUCCESSFUL; - } - } - - Status = NtProtectVirtualMemory(NtCurrentProcess(), - ImageBase + - RelocationDir->VirtualAddress, - PAGE_SIZE, - OldProtect, - &OldProtect); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to protect relocation target.\n"); - return(Status); - } - - RelocationRVA += RelocationDir->SizeOfBlock; - RelocationDir = - (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); - } + { + if (RelocationDir->VirtualAddress > MaxExtend) + { + RelocationRVA += RelocationDir->SizeOfBlock; + RelocationDir = + (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); + continue; + } + + Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase); + RelocationBlock = + (PRELOCATION_ENTRY) (RelocationRVA + ImageBase + + sizeof (RELOCATION_DIRECTORY)); + NumberOfEntries = + RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY); + NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY); + + Status = NtProtectVirtualMemory(NtCurrentProcess(), + ImageBase + + RelocationDir->VirtualAddress, + PAGE_SIZE, + PAGE_READWRITE, + &OldProtect); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to unprotect relocation target.\n"); + return(Status); + } + + for (i = 0; i < NumberOfEntries; i++) + { + Offset = (RelocationBlock[i].TypeOffset & 0xfff); + Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase); + + /* + * What kind of relocations should we perform + * for the current entry? + */ + switch (RelocationBlock[i].TypeOffset >> 12) + { + case TYPE_RELOC_ABSOLUTE: + break; + + case TYPE_RELOC_HIGH: + pValue16 = (PUSHORT)Offset; + *pValue16 += Delta32 >> 16; + break; + + case TYPE_RELOC_LOW: + pValue16 = (PUSHORT)Offset; + *pValue16 += Delta32 & 0xffff; + break; + + case TYPE_RELOC_HIGHLOW: + pValue32 = (PULONG)Offset; + *pValue32 += Delta32; + break; + + case TYPE_RELOC_HIGHADJ: + /* FIXME: do the highadjust fixup */ + DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n"); + return(STATUS_UNSUCCESSFUL); + + default: + DPRINT("unexpected fixup type\n"); + return STATUS_UNSUCCESSFUL; + } + } + + Status = NtProtectVirtualMemory(NtCurrentProcess(), + ImageBase + + RelocationDir->VirtualAddress, + PAGE_SIZE, + OldProtect, + &OldProtect); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to protect relocation target.\n"); + return(Status); + } + + RelocationRVA += RelocationDir->SizeOfBlock; + RelocationDir = + (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); + } } return STATUS_SUCCESS; } /********************************************************************** - * NAME LOCAL - * LdrFixupImports - * + * NAME LOCAL + * LdrFixupImports + * * DESCRIPTION - * Compute the entry point for every symbol the DLL imports - * from other modules. + * Compute the entry point for every symbol the DLL imports + * from other modules. * * ARGUMENTS * @@ -980,8 +974,8 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, * NOTE * */ -static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, - PVOID ImageBase) +static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, + PVOID ImageBase) { PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; ULONG Ordinal; @@ -990,142 +984,142 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, ULONG IATSize; DPRINT("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders, - ImageBase); + ImageBase); /* * Process each import module. */ ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)( - ImageBase + NTHeaders->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - .VirtualAddress); + ImageBase + NTHeaders->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] + .VirtualAddress); DPRINT("ImportModuleDirectory %x\n", ImportModuleDirectory); while (ImportModuleDirectory->dwRVAModuleName) { - PVOID * ImportAddressList; - PULONG FunctionNameList; - UNICODE_STRING DllName; - DWORD pName; - WORD pHint; - PVOID IATBase; - ULONG OldProtect; - - DPRINT("ImportModule->Directory->dwRVAModuleName %s\n", - (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); - - RtlCreateUnicodeStringFromAsciiz (&DllName, - (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); - - Status = LdrGetDllHandle (0, 0, &DllName, &BaseAddress); - if (!NT_SUCCESS(Status)) - { - Status = LdrLoadDll(NULL, - 0, - &DllName, - &BaseAddress); - RtlFreeUnicodeString (&DllName); - if (!NT_SUCCESS(Status)) - { - DbgPrint("LdrFixupImports:failed to load %s\n" - ,(PCHAR)(ImageBase - + ImportModuleDirectory->dwRVAModuleName)); - - return Status; - } - } - - /* - * Get the import address list. - */ - ImportAddressList = (PVOID *)(NTHeaders->OptionalHeader.ImageBase - + ImportModuleDirectory->dwRVAFunctionAddressList); - - /* - * Get the list of functions to import. - */ - if (ImportModuleDirectory->dwRVAFunctionNameList != 0) - { - FunctionNameList = (PULONG) ( - ImageBase - + ImportModuleDirectory->dwRVAFunctionNameList - ); - } - else - { - FunctionNameList = - (PULONG)(ImageBase - + ImportModuleDirectory->dwRVAFunctionAddressList); - } - - /* - * Get the size of IAT. - */ - IATSize = 0; - while (FunctionNameList[IATSize] != 0L) - { - IATSize++; - } - - /* - * Unprotect the region we are about to write into. - */ - IATBase = (PVOID)ImportAddressList; - Status = NtProtectVirtualMemory(NtCurrentProcess(), - IATBase, - IATSize * sizeof(PVOID*), - PAGE_READWRITE, - &OldProtect); - if (!NT_SUCCESS(Status)) - { - DbgPrint("LDR: Failed to unprotect IAT.\n"); - return(Status); - } - - /* - * Walk through function list and fixup addresses. - */ - while (*FunctionNameList != 0L) - { - if ((*FunctionNameList) & 0x80000000) - { - Ordinal = (*FunctionNameList) & 0x7fffffff; - *ImportAddressList = - LdrGetExportByOrdinal(BaseAddress, - Ordinal); - } - else - { - pName = (DWORD) (ImageBase + *FunctionNameList + 2); - pHint = *(PWORD)(ImageBase + *FunctionNameList); - - *ImportAddressList = - LdrGetExportByName(BaseAddress, (PUCHAR)pName, pHint); - if ((*ImportAddressList) == NULL) - { - DbgPrint("Failed to import %s\n", pName); - return STATUS_UNSUCCESSFUL; - } - } - ImportAddressList++; - FunctionNameList++; - } - - /* - * Protect the region we are about to write into. - */ - Status = NtProtectVirtualMemory(NtCurrentProcess(), - IATBase, - IATSize * sizeof(PVOID*), - OldProtect, - &OldProtect); - if (!NT_SUCCESS(Status)) - { - DbgPrint("LDR: Failed to protect IAT.\n"); - return(Status); - } - - ImportModuleDirectory++; + PVOID * ImportAddressList; + PULONG FunctionNameList; + UNICODE_STRING DllName; + DWORD pName; + WORD pHint; + PVOID IATBase; + ULONG OldProtect; + + DPRINT("ImportModule->Directory->dwRVAModuleName %s\n", + (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); + + RtlCreateUnicodeStringFromAsciiz (&DllName, + (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); + + Status = LdrGetDllHandle (0, 0, &DllName, &BaseAddress); + if (!NT_SUCCESS(Status)) + { + Status = LdrLoadDll(NULL, + 0, + &DllName, + &BaseAddress); + RtlFreeUnicodeString (&DllName); + if (!NT_SUCCESS(Status)) + { + DbgPrint("LdrFixupImports:failed to load %s\n" + ,(PCHAR)(ImageBase + + ImportModuleDirectory->dwRVAModuleName)); + + return Status; + } + } + + /* + * Get the import address list. + */ + ImportAddressList = (PVOID *)(NTHeaders->OptionalHeader.ImageBase + + ImportModuleDirectory->dwRVAFunctionAddressList); + + /* + * Get the list of functions to import. + */ + if (ImportModuleDirectory->dwRVAFunctionNameList != 0) + { + FunctionNameList = (PULONG) ( + ImageBase + + ImportModuleDirectory->dwRVAFunctionNameList + ); + } + else + { + FunctionNameList = + (PULONG)(ImageBase + + ImportModuleDirectory->dwRVAFunctionAddressList); + } + + /* + * Get the size of IAT. + */ + IATSize = 0; + while (FunctionNameList[IATSize] != 0L) + { + IATSize++; + } + + /* + * Unprotect the region we are about to write into. + */ + IATBase = (PVOID)ImportAddressList; + Status = NtProtectVirtualMemory(NtCurrentProcess(), + IATBase, + IATSize * sizeof(PVOID*), + PAGE_READWRITE, + &OldProtect); + if (!NT_SUCCESS(Status)) + { + DbgPrint("LDR: Failed to unprotect IAT.\n"); + return(Status); + } + + /* + * Walk through function list and fixup addresses. + */ + while (*FunctionNameList != 0L) + { + if ((*FunctionNameList) & 0x80000000) + { + Ordinal = (*FunctionNameList) & 0x7fffffff; + *ImportAddressList = + LdrGetExportByOrdinal(BaseAddress, + Ordinal); + } + else + { + pName = (DWORD) (ImageBase + *FunctionNameList + 2); + pHint = *(PWORD)(ImageBase + *FunctionNameList); + + *ImportAddressList = + LdrGetExportByName(BaseAddress, (PUCHAR)pName, pHint); + if ((*ImportAddressList) == NULL) + { + DbgPrint("Failed to import %s\n", pName); + return STATUS_UNSUCCESSFUL; + } + } + ImportAddressList++; + FunctionNameList++; + } + + /* + * Protect the region we are about to write into. + */ + Status = NtProtectVirtualMemory(NtCurrentProcess(), + IATBase, + IATSize * sizeof(PVOID*), + OldProtect, + &OldProtect); + if (!NT_SUCCESS(Status)) + { + DbgPrint("LDR: Failed to protect IAT.\n"); + return(Status); + } + + ImportModuleDirectory++; } return STATUS_SUCCESS; } @@ -1133,26 +1127,26 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, /********************************************************************** * NAME - * LdrPEStartup + * LdrPEStartup * * DESCRIPTION - * 1. Map the DLL's sections into memory. - * 2. Relocate, if needed the DLL. - * 3. Fixup any imported symbol. - * 4. Compute the DLL's entry point. + * 1. Map the DLL's sections into memory. + * 2. Relocate, if needed the DLL. + * 3. Fixup any imported symbol. + * 4. Compute the DLL's entry point. * * ARGUMENTS - * ImageBase - * Address at which the DLL's image - * is loaded. - * - * SectionHandle - * Handle of the section that contains - * the DLL's image. + * ImageBase + * Address at which the DLL's image + * is loaded. + * + * SectionHandle + * Handle of the section that contains + * the DLL's image. * * RETURN VALUE - * NULL on error; otherwise the entry point - * to call for initializing the DLL. + * NULL on error; otherwise the entry point + * to call for initializing the DLL. * * REVISIONS * @@ -1160,14 +1154,14 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, * */ PEPFUNC LdrPEStartup (PVOID ImageBase, - HANDLE SectionHandle, - PLDR_MODULE* Module, - PWSTR FullDosName) + HANDLE SectionHandle, + PLDR_MODULE* Module, + PWSTR FullDosName) { - NTSTATUS Status; - PEPFUNC EntryPoint = NULL; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS NTHeaders; + NTSTATUS Status; + PEPFUNC EntryPoint = NULL; + PIMAGE_DOS_HEADER DosHeader; + PIMAGE_NT_HEADERS NTHeaders; DPRINT("LdrPEStartup(ImageBase %x SectionHandle %x)\n", ImageBase, (ULONG)SectionHandle); @@ -1189,10 +1183,10 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, DbgPrint("LDR: Performing relocations\n"); Status = LdrPerformRelocations(NTHeaders, ImageBase); if (!NT_SUCCESS(Status)) - { - DbgPrint("LdrPerformRelocations() failed\n"); - return NULL; - } + { + DbgPrint("LdrPerformRelocations() failed\n"); + return NULL; + } } if (Module != NULL) @@ -1207,14 +1201,14 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, if (NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] .VirtualAddress != 0) { - DPRINT("About to fixup imports\n"); - Status = LdrFixupImports(NTHeaders, ImageBase); - if (!NT_SUCCESS(Status)) - { - DbgPrint("LdrFixupImports() failed\n"); - return NULL; - } - DPRINT("Fixup done\n"); + DPRINT("About to fixup imports\n"); + Status = LdrFixupImports(NTHeaders, ImageBase); + if (!NT_SUCCESS(Status)) + { + DbgPrint("LdrFixupImports() failed\n"); + return NULL; + } + DPRINT("Fixup done\n"); } /* @@ -1224,8 +1218,8 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, DPRINT("AddressOfEntryPoint = %x\n",(ULONG)NTHeaders->OptionalHeader.AddressOfEntryPoint); if (NTHeaders->OptionalHeader.AddressOfEntryPoint != 0) { - EntryPoint = (PEPFUNC) (ImageBase - + NTHeaders->OptionalHeader.AddressOfEntryPoint); + EntryPoint = (PEPFUNC) (ImageBase + + NTHeaders->OptionalHeader.AddressOfEntryPoint); } DPRINT("LdrPEStartup() = %x\n",EntryPoint); return EntryPoint; @@ -1250,50 +1244,50 @@ LdrUnloadDll (IN PVOID BaseAddress) while (Entry != ModuleListHead) { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - if (Module->BaseAddress == BaseAddress) - { - if (Module->LoadCount == -1) - { - /* never unload this dll */ - return STATUS_SUCCESS; - } - else if (Module->LoadCount > 1) - { - Module->LoadCount--; - return STATUS_SUCCESS; - } - - NtHeaders = RtlImageNtHeader (Module->BaseAddress); - if ((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL) - { - if (Module->EntryPoint != 0) - { - Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; - DPRINT("Calling entry point at 0x%08x\n", Entrypoint); - Entrypoint(Module->BaseAddress, - DLL_PROCESS_DETACH, - NULL); - } - else - { - DPRINT("NTDLL.LDR: Entrypoint is NULL for \n"); - } - } - Status = ZwUnmapViewOfSection (NtCurrentProcess (), - Module->BaseAddress); - ZwClose (Module->SectionHandle); - - /* remove the module entry from the list */ - RtlFreeUnicodeString (&Module->FullDllName); - RtlFreeUnicodeString (&Module->BaseDllName); - RemoveEntryList (Entry); - RtlFreeHeap (RtlGetProcessHeap (), 0, Module); - - return Status; - } - - Entry = Entry->Flink; + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + if (Module->BaseAddress == BaseAddress) + { + if (Module->LoadCount == -1) + { + /* never unload this dll */ + return STATUS_SUCCESS; + } + else if (Module->LoadCount > 1) + { + Module->LoadCount--; + return STATUS_SUCCESS; + } + + NtHeaders = RtlImageNtHeader (Module->BaseAddress); + if ((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL) + { + if (Module->EntryPoint != 0) + { + Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + Entrypoint(Module->BaseAddress, + DLL_PROCESS_DETACH, + NULL); + } + else + { + DPRINT("NTDLL.LDR: Entrypoint is NULL for \n"); + } + } + Status = ZwUnmapViewOfSection (NtCurrentProcess (), + Module->BaseAddress); + ZwClose (Module->SectionHandle); + + /* remove the module entry from the list */ + RtlFreeUnicodeString (&Module->FullDllName); + RtlFreeUnicodeString (&Module->BaseDllName); + RemoveEntryList (Entry); + RtlFreeHeap (RtlGetProcessHeap (), 0, Module); + + return Status; + } + + Entry = Entry->Flink; } DPRINT("NTDLL.LDR: Dll not found\n") @@ -1301,6 +1295,7 @@ LdrUnloadDll (IN PVOID BaseAddress) return STATUS_UNSUCCESSFUL; } +#if 0 /*MOVED_TO_FILE_RES_C*/ NTSTATUS STDCALL LdrFindResource_U(PVOID BaseAddress, @@ -1321,13 +1316,13 @@ LdrFindResource_U(PVOID BaseAddress, /* Get the pointer to the resource directory */ ResDir = (PIMAGE_RESOURCE_DIRECTORY) - RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_RESOURCE, - &i); + RtlImageDirectoryEntryToData (BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_RESOURCE, + &i); if (ResDir == NULL) { - return STATUS_RESOURCE_DATA_NOT_FOUND; + return STATUS_RESOURCE_DATA_NOT_FOUND; } DPRINT("ResourceDirectory: %x\n", (ULONG)ResDir); @@ -1337,77 +1332,77 @@ LdrFindResource_U(PVOID BaseAddress, /* Let's go into resource tree */ for (i = 0; i < Level; i++) { - DPRINT("ResDir: %x\n", (ULONG)ResDir); - Id = ((PULONG)ResourceInfo)[i]; - EntryCount = ResDir->NumberOfNamedEntries; - ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); - DPRINT("ResEntry %x\n", (ULONG)ResEntry); - if (Id & 0xFFFF0000) - { - /* Resource name is a unicode string */ - for (; EntryCount--; ResEntry++) - { - /* Scan entries for equal name */ - if (ResEntry->Name & 0x80000000) - { - ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); - if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) && - wcslen((PWCHAR)Id) == (int)*ws ) - { - goto found; - } - } - } - } - else - { - /* We use ID number instead of string */ - ResEntry += EntryCount; - EntryCount = ResDir->NumberOfIdEntries; - for (; EntryCount--; ResEntry++) - { - /* Scan entries for equal name */ - if (ResEntry->Name == Id) - { - DPRINT("ID entry found %x\n", Id); - goto found; - } - } - } - DPRINT("Error %lu\n", i); - - switch (i) - { - case 0: - return STATUS_RESOURCE_TYPE_NOT_FOUND; - - case 1: - return STATUS_RESOURCE_NAME_NOT_FOUND; - - case 2: - if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) - { - /* Use the first available language */ - ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); - break; - } - return STATUS_RESOURCE_LANG_NOT_FOUND; - - case 3: - return STATUS_RESOURCE_DATA_NOT_FOUND; - - default: - return STATUS_INVALID_PARAMETER; - } + DPRINT("ResDir: %x\n", (ULONG)ResDir); + Id = ((PULONG)ResourceInfo)[i]; + EntryCount = ResDir->NumberOfNamedEntries; + ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); + DPRINT("ResEntry %x\n", (ULONG)ResEntry); + if (Id & 0xFFFF0000) + { + /* Resource name is a unicode string */ + for (; EntryCount--; ResEntry++) + { + /* Scan entries for equal name */ + if (ResEntry->Name & 0x80000000) + { + ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); + if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) && + wcslen((PWCHAR)Id) == (int)*ws ) + { + goto found; + } + } + } + } + else + { + /* We use ID number instead of string */ + ResEntry += EntryCount; + EntryCount = ResDir->NumberOfIdEntries; + for (; EntryCount--; ResEntry++) + { + /* Scan entries for equal name */ + if (ResEntry->Name == Id) + { + DPRINT("ID entry found %x\n", Id); + goto found; + } + } + } + DPRINT("Error %lu\n", i); + + switch (i) + { + case 0: + return STATUS_RESOURCE_TYPE_NOT_FOUND; + + case 1: + return STATUS_RESOURCE_NAME_NOT_FOUND; + + case 2: + if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) + { + /* Use the first available language */ + ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); + break; + } + return STATUS_RESOURCE_LANG_NOT_FOUND; + + case 3: + return STATUS_RESOURCE_DATA_NOT_FOUND; + + default: + return STATUS_INVALID_PARAMETER; + } found:; - ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase + - (ResEntry->OffsetToData & 0x7FFFFFFF)); + ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase + + (ResEntry->OffsetToData & 0x7FFFFFFF)); } DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir); if (ResourceDataEntry) { - *ResourceDataEntry = (PVOID)ResDir; + *ResourceDataEntry = (PVOID)ResDir; } return Status; @@ -1429,85 +1424,77 @@ LdrAccessResource(IN PVOID BaseAddress, ULONG Data; Data = (ULONG)RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_RESOURCE, - &DataSize); + TRUE, + IMAGE_DIRECTORY_ENTRY_RESOURCE, + &DataSize); if (Data == 0) - return STATUS_RESOURCE_DATA_NOT_FOUND; + return STATUS_RESOURCE_DATA_NOT_FOUND; if ((ULONG)BaseAddress & 1) { - /* loaded as ordinary file */ - NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL)); - Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - Section = RtlImageRvaToSection (NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); - if (Section == NULL) - { - return STATUS_RESOURCE_DATA_NOT_FOUND; - } - - if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData) - { - SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress; - SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL); - Offset = SectionRva - SectionVa + Data - Section->VirtualAddress; - } + /* loaded as ordinary file */ + NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL)); + Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; + Section = RtlImageRvaToSection (NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); + if (Section == NULL) + { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + + if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData) + { + SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress; + SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL); + Offset = SectionRva - SectionVa + Data - Section->VirtualAddress; + } } if (Resource) { - *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress); + *Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress); } if (Size) { - *Size = ResourceDataEntry->Size; + *Size = ResourceDataEntry->Size; } return STATUS_SUCCESS; } +#endif /*MOVED_TO_FILE_RES_C*/ NTSTATUS STDCALL -LdrDisableThreadCalloutsForDll (IN PVOID BaseAddress) +LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress) { - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_MODULE Module; - NTSTATUS Status; - - DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %x)\n", - BaseAddress); - - Status = STATUS_DLL_NOT_FOUND; - - ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; - Entry = ModuleListHead->Flink; - - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - - DPRINT("BaseDllName %wZ BaseAddress %x\n", - &Module->BaseDllName, - Module->BaseAddress); - - if (Module->BaseAddress == BaseAddress) - { - if (Module->TlsIndex == 0) - { - Module->Flags |= 0x00040000; - Status = STATUS_SUCCESS; - } - return Status; - } - - Entry = Entry->Flink; - } - - return Status; + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE Module; + NTSTATUS Status; + + DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %x)\n", BaseAddress); + + Status = STATUS_DLL_NOT_FOUND; + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + while (Entry != ModuleListHead) { + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + + DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->BaseAddress); + + if (Module->BaseAddress == BaseAddress) { + if (Module->TlsIndex == 0) { + Module->Flags |= 0x00040000; + Status = STATUS_SUCCESS; + } + return Status; + } + Entry = Entry->Flink; + } + return Status; } +#if 0 /*MOVED_TO_FILE_RES_C*/ NTSTATUS STDCALL LdrFindResourceDirectory_U (IN PVOID BaseAddress, @@ -1524,142 +1511,134 @@ LdrFindResourceDirectory_U (IN PVOID BaseAddress, /* Get the pointer to the resource directory */ ResDir = (PIMAGE_RESOURCE_DIRECTORY) - RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_RESOURCE, - &i); + RtlImageDirectoryEntryToData (BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_RESOURCE, + &i); if (ResDir == NULL) { - return STATUS_RESOURCE_DATA_NOT_FOUND; + return STATUS_RESOURCE_DATA_NOT_FOUND; } /* Let's go into resource tree */ for (i = 0; i < level; i++, name++) { - EntryCount = ResDir->NumberOfNamedEntries; - ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); - if ((ULONG)(*name) & 0xFFFF0000) - { - /* Resource name is a unicode string */ - for (; EntryCount--; ResEntry++) - { - /* Scan entries for equal name */ - if (ResEntry->Name & 0x80000000) - { - ws = (WCHAR*)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); - if (!wcsncmp( *name, ws + 1, *ws ) && wcslen( *name ) == (int)*ws ) - { - goto found; - } - } - } - } - else - { - /* We use ID number instead of string */ - ResEntry += EntryCount; - EntryCount = ResDir->NumberOfIdEntries; - for (; EntryCount--; ResEntry++) - { - /* Scan entries for equal name */ - if (ResEntry->Name == (ULONG)(*name)) - goto found; - } - } - - switch (i) - { - case 0: - return STATUS_RESOURCE_TYPE_NOT_FOUND; - - case 1: - return STATUS_RESOURCE_NAME_NOT_FOUND; - - case 2: - Status = STATUS_RESOURCE_LANG_NOT_FOUND; - /* Just use first language entry */ - if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) - { - ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); - break; - } - return Status; - - case 3: - return STATUS_RESOURCE_DATA_NOT_FOUND; - - default: - return STATUS_INVALID_PARAMETER; - } + EntryCount = ResDir->NumberOfNamedEntries; + ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1); + if ((ULONG)(*name) & 0xFFFF0000) + { + /* Resource name is a unicode string */ + for (; EntryCount--; ResEntry++) + { + /* Scan entries for equal name */ + if (ResEntry->Name & 0x80000000) + { + ws = (WCHAR*)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); + if (!wcsncmp( *name, ws + 1, *ws ) && wcslen( *name ) == (int)*ws ) + { + goto found; + } + } + } + } + else + { + /* We use ID number instead of string */ + ResEntry += EntryCount; + EntryCount = ResDir->NumberOfIdEntries; + for (; EntryCount--; ResEntry++) + { + /* Scan entries for equal name */ + if (ResEntry->Name == (ULONG)(*name)) + goto found; + } + } + + switch (i) + { + case 0: + return STATUS_RESOURCE_TYPE_NOT_FOUND; + + case 1: + return STATUS_RESOURCE_NAME_NOT_FOUND; + + case 2: + Status = STATUS_RESOURCE_LANG_NOT_FOUND; + /* Just use first language entry */ + if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries) + { + ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1); + break; + } + return Status; + + case 3: + return STATUS_RESOURCE_DATA_NOT_FOUND; + + default: + return STATUS_INVALID_PARAMETER; + } found:; - ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResDir + ResEntry->OffsetToData); + ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResDir + ResEntry->OffsetToData); } if (addr) { - *addr = (PVOID)ResDir; + *addr = (PVOID)ResDir; } return Status; } +#endif /*MOVED_TO_FILE_RES_C*/ -NTSTATUS STDCALL -LdrGetDllHandle (IN ULONG Unknown1, - IN ULONG Unknown2, - IN PUNICODE_STRING DllName, - OUT PVOID *BaseAddress) +NTSTATUS +STDCALL +LdrGetDllHandle(IN ULONG Unknown1, + IN ULONG Unknown2, + IN PUNICODE_STRING DllName, + OUT PVOID* BaseAddress) { - UNICODE_STRING FullDllName; - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_MODULE Module; + UNICODE_STRING FullDllName; + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE Module; + + DPRINT("LdrGetDllHandle (Unknown1 %x Unknown2 %x DllName %wZ BaseAddress %p)\n", + Unknown1, Unknown2, DllName, BaseAddress); + + /* NULL is the current executable */ + if (DllName == NULL) { + *BaseAddress = NtCurrentPeb()->ImageBaseAddress; + DPRINT("BaseAddress %x\n", *BaseAddress); + return STATUS_SUCCESS; + } + LdrAdjustDllName(&FullDllName, DllName, TRUE); - DPRINT("LdrGetDllHandle (Unknown1 %x Unknown2 %x DllName %wZ BaseAddress %p)\n", - Unknown1, Unknown2, DllName, BaseAddress); + DPRINT("FullDllName %wZ\n", &FullDllName); - /* NULL is the current executable */ - if ( DllName == NULL ) - { - *BaseAddress = NtCurrentPeb()->ImageBaseAddress; - DPRINT("BaseAddress %x\n", *BaseAddress); - return STATUS_SUCCESS; - } + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + while (Entry != ModuleListHead) { + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - LdrAdjustDllName (&FullDllName, - DllName, - TRUE); + DPRINT("EntryPoint %x\n", Module->EntryPoint); + DPRINT("Comparing %wZ and %wZ\n", &Module->BaseDllName, &FullDllName); - DPRINT("FullDllName %wZ\n", - &FullDllName); - - ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; - Entry = ModuleListHead->Flink; + if (!RtlCompareUnicodeString(&Module->BaseDllName, &FullDllName, TRUE)) { + RtlFreeUnicodeString(&FullDllName); + *BaseAddress = Module->BaseAddress; + DPRINT("BaseAddress %x\n", *BaseAddress); + return STATUS_SUCCESS; + } + Entry = Entry->Flink; + } - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - - DPRINT("EntryPoint %x\n", Module->EntryPoint); - DPRINT("Comparing %wZ and %wZ\n", - &Module->BaseDllName, - &FullDllName); - - if (!RtlCompareUnicodeString(&Module->BaseDllName, &FullDllName, TRUE)) - { - RtlFreeUnicodeString (&FullDllName); - *BaseAddress = Module->BaseAddress; - DPRINT("BaseAddress %x\n", *BaseAddress); - return STATUS_SUCCESS; - } - - Entry = Entry->Flink; - } + DPRINT("Failed to find dll %wZ\n", &FullDllName); - DPRINT("Failed to find dll %wZ\n", &FullDllName); - RtlFreeUnicodeString (&FullDllName); - *BaseAddress = NULL; - return STATUS_DLL_NOT_FOUND; + RtlFreeUnicodeString(&FullDllName); + *BaseAddress = NULL; + return STATUS_DLL_NOT_FOUND; } @@ -1680,44 +1659,44 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, /* Get the pointer to the export directory */ ExportDir = (PIMAGE_EXPORT_DIRECTORY) - RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - &i); + RtlImageDirectoryEntryToData (BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &i); DPRINT("ExportDir %x i %lu\n", ExportDir, i); if (!ExportDir || !i || !ProcedureAddress) { - return STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; } AddressPtr = (PULONG)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfFunctions); if (Name && Name->Length) { - /* by name */ - OrdinalPtr = (PUSHORT)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals); - NamePtr = (PULONG)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNames); - for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) - { - if (!_strnicmp(Name->Buffer, (char*)(BaseAddress + *NamePtr), Name->Length)) - { - *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]); - return STATUS_SUCCESS; - } - } - DbgPrint("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name); + /* by name */ + OrdinalPtr = (PUSHORT)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals); + NamePtr = (PULONG)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNames); + for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) + { + if (!_strnicmp(Name->Buffer, (char*)(BaseAddress + *NamePtr), Name->Length)) + { + *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]); + return STATUS_SUCCESS; + } + } + DbgPrint("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name); } else { - /* by ordinal */ - Ordinal &= 0x0000FFFF; - if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions) - { - *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]); - return STATUS_SUCCESS; - } - DbgPrint("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal); + /* by ordinal */ + Ordinal &= 0x0000FFFF; + if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions) + { + *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]); + return STATUS_SUCCESS; + } + DbgPrint("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal); } return STATUS_PROCEDURE_NOT_FOUND; @@ -1740,24 +1719,24 @@ LdrShutdownProcess (VOID) while (Entry != ModuleListHead) { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); - - DPRINT(" Unloading %S\n", - &Module->BaseDllName); - // PJS: only detach from static dlls, they should FreeLibrary() any dlls that - // they loaded dynamically, and when the last reference is gone, that lib will - // be detached. - if (Module->EntryPoint != 0 && Module->LoadCount == -1) - { - PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; - - DPRINT("Calling entry point at 0x%08x\n", Entrypoint); - Entrypoint (Module->BaseAddress, - DLL_PROCESS_DETACH, - NULL); - } - - Entry = Entry->Blink; + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); + + DPRINT(" Unloading %wZ\n", + &Module->BaseDllName); + // PJS: only detach from static dlls, they should FreeLibrary() any dlls that + // they loaded dynamically, and when the last reference is gone, that lib will + // be detached. + if (Module->EntryPoint != 0 && Module->LoadCount == -1) + { + PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; + + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + Entrypoint (Module->BaseAddress, + DLL_PROCESS_DETACH, + NULL); + } + + Entry = Entry->Blink; } RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); @@ -1784,22 +1763,22 @@ LdrShutdownThread (VOID) while (Entry != ModuleListHead) { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); - DPRINT(" Unloading %wZ\n", - &Module->BaseDllName); + DPRINT(" Unloading %wZ\n", + &Module->BaseDllName); - if (Module->EntryPoint != 0) - { - PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; + if (Module->EntryPoint != 0) + { + PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; - DPRINT("Calling entry point at 0x%08x\n", Entrypoint); - Entrypoint (Module->BaseAddress, - DLL_THREAD_DETACH, - NULL); - } + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + Entrypoint (Module->BaseAddress, + DLL_THREAD_DETACH, + NULL); + } - Entry = Entry->Blink; + Entry = Entry->Blink; } RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); @@ -1811,8 +1790,8 @@ LdrShutdownThread (VOID) /*************************************************************************** - * NAME EXPORTED - * LdrQueryProcessModuleInformation + * NAME EXPORTED + * LdrQueryProcessModuleInformation * * DESCRIPTION * @@ -1826,8 +1805,8 @@ LdrShutdownThread (VOID) */ NTSTATUS STDCALL LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL, - IN ULONG Size OPTIONAL, - OUT PULONG ReturnedSize) + IN ULONG Size OPTIONAL, + OUT PULONG ReturnedSize) { PLIST_ENTRY ModuleListHead; @@ -1862,38 +1841,38 @@ LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTION Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); DPRINT(" Module %wZ\n", - &Module->FullDllName); + &Module->FullDllName); if (UsedSize > Size) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } else if (ModuleInformation != NULL) - { - ModulePtr->Unknown0 = 0; // FIXME: ?? - ModulePtr->Unknown1 = 0; // FIXME: ?? - ModulePtr->BaseAddress = Module->BaseAddress; - ModulePtr->SizeOfImage = Module->SizeOfImage; - ModulePtr->Flags = Module->Flags; - ModulePtr->Unknown2 = 0; // FIXME: load order index ?? - ModulePtr->Unknown3 = 0; // FIXME: ?? - ModulePtr->LoadCount = Module->LoadCount; - - AnsiString.Length = 0; - AnsiString.MaximumLength = 256; - AnsiString.Buffer = ModulePtr->ModuleName; - RtlUnicodeStringToAnsiString(&AnsiString, - &Module->FullDllName, - FALSE); - p = strrchr(ModulePtr->ModuleName, '\\'); - if (p != NULL) - ModulePtr->PathLength = p - ModulePtr->ModuleName + 1; - else - ModulePtr->PathLength = 0; - - ModulePtr++; - ModuleInformation->ModuleCount++; - } + { + ModulePtr->Unknown0 = 0; // FIXME: ?? + ModulePtr->Unknown1 = 0; // FIXME: ?? + ModulePtr->BaseAddress = Module->BaseAddress; + ModulePtr->SizeOfImage = Module->SizeOfImage; + ModulePtr->Flags = Module->Flags; + ModulePtr->Unknown2 = 0; // FIXME: load order index ?? + ModulePtr->Unknown3 = 0; // FIXME: ?? + ModulePtr->LoadCount = Module->LoadCount; + + AnsiString.Length = 0; + AnsiString.MaximumLength = 256; + AnsiString.Buffer = ModulePtr->ModuleName; + RtlUnicodeStringToAnsiString(&AnsiString, + &Module->FullDllName, + FALSE); + p = strrchr(ModulePtr->ModuleName, '\\'); + if (p != NULL) + ModulePtr->PathLength = p - ModulePtr->ModuleName + 1; + else + ModulePtr->PathLength = 0; + + ModulePtr++; + ModuleInformation->ModuleCount++; + } UsedSize += sizeof(MODULE_ENTRY); Entry = Entry->Flink; diff --git a/lib/ntdll/makefile b/lib/ntdll/makefile index 84279cb..65de6e7 100644 --- a/lib/ntdll/makefile +++ b/lib/ntdll/makefile @@ -22,7 +22,7 @@ TARGET_ENTRY = _LdrInitializeThunk@16 CSR_OBJECTS = csr/lpc.o csr/capture.o csr/probe.o csr/thread.o -DBG_OBJECTS = dbg/brkpoint.o dbg/debug.o dbg/print.o dbg/winedbg.o +DBG_OBJECTS = dbg/brkpoint.o dbg/debug.o dbg/print.o #dbg/winedbg.o RTL_I386_OBJECTS = \ rtl/i386/exception.o \ @@ -68,6 +68,7 @@ TARGET_OBJECTS = \ $(STDLIB_OBJECTS) \ $(STRING_OBJECTS) \ stubs/stubs.o \ + ldr/res.o \ ldr/utils.o \ $(CSR_OBJECTS) diff --git a/lib/ntdll/rtl/error.c b/lib/ntdll/rtl/error.c index 6eb801e..475a10f 100644 --- a/lib/ntdll/rtl/error.c +++ b/lib/ntdll/rtl/error.c @@ -826,12 +826,10 @@ RPC_NT_SS_CONTEXT_MISMATCH ERROR_INVALID_HANDLE VOID STDCALL -RtlAssert ( - PVOID FailedAssertion, +RtlAssert(PVOID FailedAssertion, PVOID FileName, ULONG LineNumber, - PCHAR Message - ) + PCHAR Message) { DbgPrint ("Assertion \'%s\' failed at %s line %d: %s\n", (PCHAR)FailedAssertion, @@ -881,9 +879,9 @@ RtlNtStatusToDosErrorNoTeb(NTSTATUS Status) if (!ret) ret = Status; /* 0 means 1:1 mapping */ else if (ret == ERROR_MR_MID_NOT_FOUND) - { + { DbgPrint("RTL: RtlNtStatusToDosErrorNoTeb(0x%lx): no valid W32 error mapping\n", Status); - } + } return ret; } Table++; diff --git a/lib/ntdll/rtl/heap.c b/lib/ntdll/rtl/heap.c index a2f5d36..dba78de 100644 --- a/lib/ntdll/rtl/heap.c +++ b/lib/ntdll/rtl/heap.c @@ -625,7 +625,7 @@ static SUBHEAP *HEAP_CreateSubHeap(PVOID BaseAddress, { ULONG dummySize = 0; ZwFreeVirtualMemory(NtCurrentProcess(), - address, + &address, &dummySize, MEM_RELEASE); return NULL; @@ -1001,8 +1001,8 @@ static BOOL HEAP_IsRealArena( HANDLE STDCALL RtlCreateHeap(ULONG flags, PVOID BaseAddress, - ULONG initialSize, ULONG maxSize, + ULONG initialSize, PVOID Unknown, PRTL_HEAP_DEFINITION Definition) { diff --git a/lib/ntdll/rtl/i386/.cvsignore b/lib/ntdll/rtl/i386/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/ntdll/rtl/i386/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/ntdll/rtl/largeint.c b/lib/ntdll/rtl/largeint.c index 3cc9e5f..9350908 100644 --- a/lib/ntdll/rtl/largeint.c +++ b/lib/ntdll/rtl/largeint.c @@ -121,11 +121,9 @@ RtlExtendedLargeIntegerDivide ( LARGE_INTEGER STDCALL -RtlExtendedMagicDivide ( - LARGE_INTEGER Dividend, +RtlExtendedMagicDivide(LARGE_INTEGER Dividend, LARGE_INTEGER MagicDivisor, - CCHAR ShiftCount - ) + CCHAR ShiftCount) { UNIMPLEMENTED; } diff --git a/lib/ntdll/rtl/mem.c b/lib/ntdll/rtl/mem.c index d117b28..393f2d6 100644 --- a/lib/ntdll/rtl/mem.c +++ b/lib/ntdll/rtl/mem.c @@ -18,7 +18,9 @@ ULONG STDCALL -RtlCompareMemory(PVOID Source1, PVOID Source2, ULONG Length) +RtlCompareMemory(PVOID Source1, + PVOID Source2, + ULONG Length) /* * FUNCTION: Compares blocks of memory and returns the number of equal bytes * ARGUMENTS: @@ -95,11 +97,7 @@ RtlFillMemory ( UCHAR Fill ) { - memset ( - Destination, - Fill, - Length - ); + memset(Destination, Fill, Length); } VOID @@ -124,31 +122,31 @@ RtlFillMemoryUlong ( VOID STDCALL -RtlZeroMemory ( - PVOID Destination, - ULONG Length +RtlMoveMemory ( + PVOID Destination, + CONST VOID * Source, + ULONG Length ) { - RtlFillMemory ( + memmove ( Destination, - Length, - 0 + Source, + Length ); } VOID STDCALL -RtlMoveMemory ( - PVOID Destination, - CONST VOID * Source, - ULONG Length +RtlZeroMemory ( + PVOID Destination, + ULONG Length ) { - memmove ( + RtlFillMemory ( Destination, - Source, - Length + Length, + 0 ); } diff --git a/lib/ntdll/rtl/ppb.c b/lib/ntdll/rtl/ppb.c index 50feb7b..99243a9 100644 --- a/lib/ntdll/rtl/ppb.c +++ b/lib/ntdll/rtl/ppb.c @@ -97,10 +97,10 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, if (Environment == NULL) Environment = NtCurrentPeb()->ProcessParameters->Environment; if (CurrentDirectory == NULL) - CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectoryName; - CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectoryHandle; - ConsoleHandle = NtCurrentPeb()->ProcessParameters->hConsole; - ConsoleFlags = NtCurrentPeb()->ProcessParameters->ProcessGroup; + CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectoryName; + CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectoryHandle; + ConsoleHandle = NtCurrentPeb()->ProcessParameters->hConsole; + ConsoleFlags = NtCurrentPeb()->ProcessParameters->ProcessGroup; } else { @@ -156,33 +156,33 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, DPRINT ("Process parameters allocated\n"); - Param->AllocationSize = RegionSize; - Param->Size = Length; + Param->AllocationSize = RegionSize; + Param->Size = Length; Param->Flags = PPF_NORMALIZED; Param->Environment = Environment; - Param->CurrentDirectoryHandle = CurrentDirectoryHandle; - Param->hConsole = ConsoleHandle; - Param->ProcessGroup = ConsoleFlags; + Param->CurrentDirectoryHandle = CurrentDirectoryHandle; + Param->hConsole = ConsoleHandle; + Param->ProcessGroup = ConsoleFlags; Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS)); /* copy current directory */ RtlpCopyParameterString(&Dest, - &Param->CurrentDirectoryName, + &Param->CurrentDirectoryName, CurrentDirectory, MAX_PATH * sizeof(WCHAR)); /* make sure the current directory has a trailing backslash */ - if (Param->CurrentDirectoryName.Length > 0) + if (Param->CurrentDirectoryName.Length > 0) { ULONG Length; - Length = Param->CurrentDirectoryName.Length / sizeof(WCHAR); - if (Param->CurrentDirectoryName.Buffer[Length-1] != L'\\') + Length = Param->CurrentDirectoryName.Length / sizeof(WCHAR); + if (Param->CurrentDirectoryName.Buffer[Length-1] != L'\\') { - Param->CurrentDirectoryName.Buffer[Length] = L'\\'; - Param->CurrentDirectoryName.Buffer[Length + 1] = 0; - Param->CurrentDirectoryName.Length += sizeof(WCHAR); + Param->CurrentDirectoryName.Buffer[Length] = L'\\'; + Param->CurrentDirectoryName.Buffer[Length + 1] = 0; + Param->CurrentDirectoryName.Length += sizeof(WCHAR); } } @@ -235,12 +235,12 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, return STATUS_SUCCESS; } -VOID STDCALL +NTSTATUS STDCALL RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters) { ULONG RegionSize = 0; - NtFreeVirtualMemory (NtCurrentProcess (), + return NtFreeVirtualMemory (NtCurrentProcess (), (PVOID)ProcessParameters, &RegionSize, MEM_RELEASE); @@ -254,7 +254,7 @@ RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params) { if (Params && (Params->Flags & PPF_NORMALIZED)) { - DENORMALIZE(Params->CurrentDirectoryName.Buffer, Params); + DENORMALIZE(Params->CurrentDirectoryName.Buffer, Params); DENORMALIZE(Params->DllPath.Buffer, Params); DENORMALIZE(Params->ImagePathName.Buffer, Params); DENORMALIZE(Params->CommandLine.Buffer, Params); @@ -277,7 +277,7 @@ RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params) { if (Params && !(Params->Flags & PPF_NORMALIZED)) { - NORMALIZE(Params->CurrentDirectoryName.Buffer, Params); + NORMALIZE(Params->CurrentDirectoryName.Buffer, Params); NORMALIZE(Params->DllPath.Buffer, Params); NORMALIZE(Params->ImagePathName.Buffer, Params); NORMALIZE(Params->CommandLine.Buffer, Params); diff --git a/lib/ntdll/rtl/time.c b/lib/ntdll/rtl/time.c index 4c7cbb8..d0d8a7e 100644 --- a/lib/ntdll/rtl/time.c +++ b/lib/ntdll/rtl/time.c @@ -55,43 +55,11 @@ static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize, /* FUNCTIONS *****************************************************************/ -VOID STDCALL -RtlTimeToElapsedTimeFields(IN PLARGE_INTEGER Time, - OUT PTIME_FIELDS TimeFields) -{ - ULONGLONG ElapsedSeconds; - ULONG SecondsInDay; - ULONG SecondsInMinute; - - /* Extract millisecond from time */ - TimeFields->Milliseconds = (CSHORT)((Time->QuadPart % TICKSPERSEC) / TICKSPERMSEC); - - /* Compute elapsed seconds */ - ElapsedSeconds = (ULONGLONG)Time->QuadPart / TICKSPERSEC; - - /* Compute seconds within the day */ - SecondsInDay = ElapsedSeconds % SECSPERDAY; - - /* Compute elapsed minutes within the day */ - SecondsInMinute = SecondsInDay % SECSPERHOUR; - - /* Compute elapsed time of day */ - TimeFields->Hour = (CSHORT)(SecondsInDay / SECSPERHOUR); - TimeFields->Minute = (CSHORT)(SecondsInMinute / SECSPERMIN); - TimeFields->Second = (CSHORT)(SecondsInMinute % SECSPERMIN); - - /* Compute elapsed days */ - TimeFields->Day = (CSHORT)(ElapsedSeconds / SECSPERDAY); - - /* The elapsed number of months and days cannot be calculated */ - TimeFields->Month = 0; - TimeFields->Year = 0; -} - - -VOID STDCALL -RtlTimeToTimeFields(PLARGE_INTEGER liTime, - PTIME_FIELDS TimeFields) +VOID +STDCALL +RtlTimeToTimeFields( + PLARGE_INTEGER liTime, + PTIME_FIELDS TimeFields) { const int *Months; int LeapSecondCorrections, SecondsInDay, CurYear; @@ -169,11 +137,14 @@ RtlTimeToTimeFields(PLARGE_INTEGER liTime, } -BOOLEAN STDCALL -RtlTimeFieldsToTime(PTIME_FIELDS tfTimeFields, - PLARGE_INTEGER Time) +BOOLEAN +STDCALL +RtlTimeFieldsToTime( + PTIME_FIELDS tfTimeFields, + PLARGE_INTEGER Time) { - int CurYear, CurMonth; + int CurYear; + int CurMonth; long long int rcTime; TIME_FIELDS TimeFields = *tfTimeFields; @@ -233,9 +204,11 @@ RtlTimeFieldsToTime(PTIME_FIELDS tfTimeFields, } -VOID STDCALL -RtlSecondsSince1970ToTime(ULONG SecondsSince1970, - PLARGE_INTEGER Time) +VOID +STDCALL +RtlSecondsSince1970ToTime( + ULONG SecondsSince1970, + PLARGE_INTEGER Time) { LONGLONG llTime; @@ -245,9 +218,11 @@ RtlSecondsSince1970ToTime(ULONG SecondsSince1970, } -VOID STDCALL -RtlSecondsSince1980ToTime(ULONG SecondsSince1980, - PLARGE_INTEGER Time) +VOID +STDCALL +RtlSecondsSince1980ToTime( + ULONG SecondsSince1980, + PLARGE_INTEGER Time) { LONGLONG llTime; @@ -257,9 +232,11 @@ RtlSecondsSince1980ToTime(ULONG SecondsSince1980, } -BOOLEAN STDCALL -RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, - PULONG SecondsSince1970) +BOOLEAN +STDCALL +RtlTimeToSecondsSince1970( + PLARGE_INTEGER Time, + PULONG SecondsSince1970) { LARGE_INTEGER liTime; @@ -267,17 +244,19 @@ RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, liTime.QuadPart = liTime.QuadPart / TICKSPERSEC; if (liTime.u.HighPart != 0) - return(FALSE); + return FALSE; *SecondsSince1970 = liTime.u.LowPart; - return(TRUE); + return TRUE; } -BOOLEAN STDCALL -RtlTimeToSecondsSince1980(PLARGE_INTEGER Time, - PULONG SecondsSince1980) +BOOLEAN +STDCALL +RtlTimeToSecondsSince1980( + PLARGE_INTEGER Time, + PULONG SecondsSince1980) { LARGE_INTEGER liTime; @@ -285,15 +264,16 @@ RtlTimeToSecondsSince1980(PLARGE_INTEGER Time, liTime.QuadPart = liTime.QuadPart / TICKSPERSEC; if (liTime.u.HighPart != 0) - return(FALSE); + return FALSE; *SecondsSince1980 = liTime.u.LowPart; - return(TRUE); + return TRUE; } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlLocalTimeToSystemTime(PLARGE_INTEGER LocalTime, PLARGE_INTEGER SystemTime) { @@ -314,7 +294,8 @@ RtlLocalTimeToSystemTime(PLARGE_INTEGER LocalTime, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlSystemTimeToLocalTime(PLARGE_INTEGER SystemTime, PLARGE_INTEGER LocalTime) { @@ -334,4 +315,40 @@ RtlSystemTimeToLocalTime(PLARGE_INTEGER SystemTime, return(STATUS_SUCCESS); } + +VOID +STDCALL +RtlTimeToElapsedTimeFields(IN PLARGE_INTEGER Time, + OUT PTIME_FIELDS TimeFields) +{ + ULONGLONG ElapsedSeconds; + ULONG SecondsInDay; + ULONG SecondsInMinute; + + /* Extract millisecond from time */ + TimeFields->Milliseconds = (CSHORT)((Time->QuadPart % TICKSPERSEC) / TICKSPERMSEC); + + /* Compute elapsed seconds */ + ElapsedSeconds = (ULONGLONG)Time->QuadPart / TICKSPERSEC; + + /* Compute seconds within the day */ + SecondsInDay = ElapsedSeconds % SECSPERDAY; + + /* Compute elapsed minutes within the day */ + SecondsInMinute = SecondsInDay % SECSPERHOUR; + + /* Compute elapsed time of day */ + TimeFields->Hour = (CSHORT)(SecondsInDay / SECSPERHOUR); + TimeFields->Minute = (CSHORT)(SecondsInMinute / SECSPERMIN); + TimeFields->Second = (CSHORT)(SecondsInMinute % SECSPERMIN); + + /* Compute elapsed days */ + TimeFields->Day = (CSHORT)(ElapsedSeconds / SECSPERDAY); + + /* The elapsed number of months and days cannot be calculated */ + TimeFields->Month = 0; + TimeFields->Year = 0; +} + + /* EOF */ diff --git a/lib/ntdll/rtl/unicode.c b/lib/ntdll/rtl/unicode.c index 3bff31e..fa0512a 100644 --- a/lib/ntdll/rtl/unicode.c +++ b/lib/ntdll/rtl/unicode.c @@ -21,9 +21,8 @@ WCHAR STDCALL -RtlAnsiCharToUnicodeChar ( - IN CHAR AnsiChar - ) +RtlAnsiCharToUnicodeChar( + IN CHAR AnsiChar) { ULONG Size; WCHAR UnicodeChar; @@ -45,9 +44,8 @@ RtlAnsiCharToUnicodeChar ( ULONG STDCALL -RtlAnsiStringToUnicodeSize ( - IN PANSI_STRING AnsiString - ) +RtlAnsiStringToUnicodeSize( + IN PANSI_STRING AnsiString) { ULONG Size; @@ -64,8 +62,7 @@ STDCALL RtlAnsiStringToUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PANSI_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -125,10 +122,9 @@ RtlAnsiStringToUnicodeString( NTSTATUS STDCALL -RtlAppendAsciizToString ( +RtlAppendAsciizToString( IN OUT PSTRING Destination, - IN PCSZ Source - ) + IN PCSZ Source) { ULONG Length; PCHAR Ptr; @@ -155,10 +151,9 @@ RtlAppendAsciizToString ( NTSTATUS STDCALL -RtlAppendStringToString ( +RtlAppendStringToString( IN OUT PSTRING Destination, - IN PSTRING Source - ) + IN PSTRING Source) { PCHAR Ptr; @@ -183,10 +178,9 @@ RtlAppendStringToString ( NTSTATUS STDCALL -RtlAppendUnicodeStringToString ( +RtlAppendUnicodeStringToString( IN OUT PUNICODE_STRING Destination, - IN PUNICODE_STRING Source - ) + IN PUNICODE_STRING Source) { PWCHAR Src; PWCHAR Dest; @@ -244,7 +238,7 @@ RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination, NTSTATUS STDCALL -RtlCharToInteger ( +RtlCharToInteger( IN PCSZ String, IN ULONG Base, IN OUT PULONG Value) @@ -285,11 +279,10 @@ RtlCharToInteger ( LONG STDCALL -RtlCompareString ( +RtlCompareString( IN PSTRING String1, IN PSTRING String2, - IN BOOLEAN CaseInsensitive - ) + IN BOOLEAN CaseInsensitive) { ULONG len1, len2; PCHAR s1, s2; @@ -333,11 +326,10 @@ RtlCompareString ( LONG STDCALL -RtlCompareUnicodeString ( +RtlCompareUnicodeString( IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, - IN BOOLEAN CaseInsensitive - ) + IN BOOLEAN CaseInsensitive) { ULONG len1, len2; PWCHAR s1, s2; @@ -381,10 +373,9 @@ RtlCompareUnicodeString ( VOID STDCALL -RtlCopyString ( +RtlCopyString( IN OUT PSTRING DestinationString, - IN PSTRING SourceString - ) + IN PSTRING SourceString) { ULONG copylen, i; PCHAR Src, Dest; @@ -414,10 +405,9 @@ RtlCopyString ( VOID STDCALL -RtlCopyUnicodeString ( +RtlCopyUnicodeString( IN OUT PUNICODE_STRING DestinationString, - IN PUNICODE_STRING SourceString - ) + IN PUNICODE_STRING SourceString) { ULONG copylen, i; PWCHAR Src, Dest; @@ -447,10 +437,9 @@ RtlCopyUnicodeString ( BOOLEAN STDCALL -RtlCreateUnicodeString ( +RtlCreateUnicodeString( IN OUT PUNICODE_STRING Destination, - IN PWSTR Source - ) + IN PWSTR Source) { ULONG Length; @@ -473,8 +462,10 @@ RtlCreateUnicodeString ( } -BOOLEAN STDCALL -RtlCreateUnicodeStringFromAsciiz (OUT PUNICODE_STRING Destination, +BOOLEAN +STDCALL +RtlCreateUnicodeStringFromAsciiz( + OUT PUNICODE_STRING Destination, IN PCSZ Source) { ANSI_STRING AnsiString; @@ -493,11 +484,10 @@ RtlCreateUnicodeStringFromAsciiz (OUT PUNICODE_STRING Destination, NTSTATUS STDCALL -RtlDowncaseUnicodeString ( +RtlDowncaseUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { ULONG i; PWCHAR Src, Dest; @@ -545,10 +535,9 @@ RtlDowncaseUnicodeString ( BOOLEAN STDCALL -RtlEqualComputerName ( +RtlEqualComputerName( IN PUNICODE_STRING ComputerName1, - IN PUNICODE_STRING ComputerName2 - ) + IN PUNICODE_STRING ComputerName2) { return RtlEqualDomainName (ComputerName1, ComputerName2); @@ -586,11 +575,10 @@ RtlEqualDomainName ( BOOLEAN STDCALL -RtlEqualString ( +RtlEqualString( IN PSTRING String1, IN PSTRING String2, - IN BOOLEAN CaseInsensitive - ) + IN BOOLEAN CaseInsensitive) { ULONG i; CHAR c1, c2; @@ -627,11 +615,10 @@ RtlEqualString ( BOOLEAN STDCALL -RtlEqualUnicodeString ( +RtlEqualUnicodeString( IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, - IN BOOLEAN CaseInsensitive - ) + IN BOOLEAN CaseInsensitive) { ULONG i; WCHAR wc1, wc2; @@ -669,9 +656,8 @@ RtlEqualUnicodeString ( VOID STDCALL -RtlEraseUnicodeString ( - IN PUNICODE_STRING String - ) +RtlEraseUnicodeString( + IN PUNICODE_STRING String) { if (String->Buffer == NULL) return; @@ -689,9 +675,8 @@ RtlEraseUnicodeString ( VOID STDCALL -RtlFreeAnsiString ( - IN PANSI_STRING AnsiString - ) +RtlFreeAnsiString( + IN PANSI_STRING AnsiString) { if (AnsiString->Buffer == NULL) return; @@ -708,9 +693,8 @@ RtlFreeAnsiString ( VOID STDCALL -RtlFreeOemString ( - IN POEM_STRING OemString - ) +RtlFreeOemString( + IN POEM_STRING OemString) { if (OemString->Buffer == NULL) return; @@ -727,9 +711,8 @@ RtlFreeOemString ( VOID STDCALL -RtlFreeUnicodeString ( - IN PUNICODE_STRING UnicodeString - ) +RtlFreeUnicodeString( + IN PUNICODE_STRING UnicodeString) { if (UnicodeString->Buffer == NULL) return; @@ -746,10 +729,9 @@ RtlFreeUnicodeString ( VOID STDCALL -RtlInitAnsiString ( +RtlInitAnsiString( IN OUT PANSI_STRING DestinationString, - IN PCSZ SourceString - ) + IN PCSZ SourceString) { ULONG DestSize; @@ -770,10 +752,9 @@ RtlInitAnsiString ( VOID STDCALL -RtlInitString ( +RtlInitString( IN OUT PSTRING DestinationString, - IN PCSZ SourceString - ) + IN PCSZ SourceString) { ULONG DestSize; @@ -794,10 +775,9 @@ RtlInitString ( VOID STDCALL -RtlInitUnicodeString ( +RtlInitUnicodeString( IN OUT PUNICODE_STRING DestinationString, - IN PCWSTR SourceString - ) + IN PCWSTR SourceString) { ULONG DestSize; @@ -818,12 +798,11 @@ RtlInitUnicodeString ( NTSTATUS STDCALL -RtlIntegerToChar ( +RtlIntegerToChar( IN ULONG Value, IN ULONG Base, IN ULONG Length, - IN OUT PCHAR String - ) + IN OUT PCHAR String) { ULONG Radix; CHAR temp[33]; @@ -866,11 +845,10 @@ RtlIntegerToChar ( NTSTATUS STDCALL -RtlIntegerToUnicodeString ( +RtlIntegerToUnicodeString( IN ULONG Value, IN ULONG Base, /* optional */ - IN OUT PUNICODE_STRING String - ) + IN OUT PUNICODE_STRING String) { ANSI_STRING AnsiString; CHAR Buffer[33]; @@ -897,12 +875,11 @@ RtlIntegerToUnicodeString ( NTSTATUS STDCALL -RtlLargeIntegerToChar ( +RtlLargeIntegerToChar( IN PLARGE_INTEGER Value, IN ULONG Base, IN ULONG Length, - IN OUT PCHAR String - ) + IN OUT PCHAR String) { ULONG Radix; CHAR temp[65]; @@ -945,9 +922,8 @@ RtlLargeIntegerToChar ( ULONG STDCALL -RtlOemStringToUnicodeSize ( - IN POEM_STRING OemString - ) +RtlOemStringToUnicodeSize( + IN POEM_STRING OemString) { ULONG Size; @@ -961,11 +937,10 @@ RtlOemStringToUnicodeSize ( NTSTATUS STDCALL -RtlOemStringToUnicodeString ( +RtlOemStringToUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN POEM_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1025,11 +1000,10 @@ RtlOemStringToUnicodeString ( BOOLEAN STDCALL -RtlPrefixString ( +RtlPrefixString( PANSI_STRING String1, PANSI_STRING String2, - BOOLEAN CaseInsensitive - ) + BOOLEAN CaseInsensitive) { PCHAR pc1; PCHAR pc2; @@ -1068,11 +1042,10 @@ RtlPrefixString ( BOOLEAN STDCALL -RtlPrefixUnicodeString ( +RtlPrefixUnicodeString( PUNICODE_STRING String1, PUNICODE_STRING String2, - BOOLEAN CaseInsensitive - ) + BOOLEAN CaseInsensitive) { PWCHAR pc1; PWCHAR pc2; @@ -1112,9 +1085,8 @@ RtlPrefixUnicodeString ( ULONG STDCALL -RtlUnicodeStringToAnsiSize ( - IN PUNICODE_STRING UnicodeString - ) +RtlUnicodeStringToAnsiSize( + IN PUNICODE_STRING UnicodeString) { ULONG Size; @@ -1128,11 +1100,10 @@ RtlUnicodeStringToAnsiSize ( NTSTATUS STDCALL -RtlUnicodeStringToAnsiString ( +RtlUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1186,11 +1157,10 @@ RtlUnicodeStringToAnsiString ( NTSTATUS STDCALL -RtlUnicodeStringToInteger ( +RtlUnicodeStringToInteger( IN PUNICODE_STRING String, IN ULONG Base, - OUT PULONG Value - ) + OUT PULONG Value) { PWCHAR Str; ULONG lenmin = 0; @@ -1276,9 +1246,8 @@ RtlUnicodeStringToInteger ( ULONG STDCALL -RtlUnicodeStringToOemSize ( - IN PUNICODE_STRING UnicodeString - ) +RtlUnicodeStringToOemSize( + IN PUNICODE_STRING UnicodeString) { ULONG Size; @@ -1292,11 +1261,10 @@ RtlUnicodeStringToOemSize ( NTSTATUS STDCALL -RtlUnicodeStringToCountedOemString ( +RtlUnicodeStringToCountedOemString( IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1359,11 +1327,10 @@ RtlUnicodeStringToCountedOemString ( NTSTATUS STDCALL -RtlUnicodeStringToOemString ( +RtlUnicodeStringToOemString( IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1426,9 +1393,7 @@ RtlUnicodeStringToOemString ( WCHAR STDCALL -RtlUpcaseUnicodeChar ( - IN WCHAR Source - ) +RtlUpcaseUnicodeChar(IN WCHAR Source) { if (Source < L'a') return Source; @@ -1444,11 +1409,10 @@ RtlUpcaseUnicodeChar ( NTSTATUS STDCALL -RtlUpcaseUnicodeString ( +RtlUpcaseUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { ULONG i; PWCHAR Src, Dest; @@ -1485,11 +1449,10 @@ RtlUpcaseUnicodeString ( NTSTATUS STDCALL -RtlUpcaseUnicodeStringToAnsiString ( +RtlUpcaseUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1552,11 +1515,10 @@ RtlUpcaseUnicodeStringToAnsiString ( NTSTATUS STDCALL -RtlUpcaseUnicodeStringToCountedOemString ( +RtlUpcaseUnicodeStringToCountedOemString( IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString - ) + IN BOOLEAN AllocateDestinationString) { NTSTATUS Status; ULONG Length; @@ -1724,10 +1686,9 @@ RtlUpperChar ( VOID STDCALL -RtlUpperString ( +RtlUpperString( IN OUT PSTRING DestinationString, - IN PSTRING SourceString - ) + IN PSTRING SourceString) { ULONG Length; ULONG i; @@ -1752,41 +1713,33 @@ RtlUpperString ( ULONG STDCALL -RtlxAnsiStringToUnicodeSize ( - IN PANSI_STRING AnsiString - ) +RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString) { - return RtlAnsiStringToUnicodeSize (AnsiString); + return RtlAnsiStringToUnicodeSize(AnsiString); } ULONG STDCALL -RtlxOemStringToUnicodeSize ( - IN POEM_STRING OemString - ) +RtlxOemStringToUnicodeSize(IN POEM_STRING OemString) { - return RtlAnsiStringToUnicodeSize ((PANSI_STRING)OemString); + return RtlAnsiStringToUnicodeSize((PANSI_STRING)OemString); } ULONG STDCALL -RtlxUnicodeStringToAnsiSize ( - IN PUNICODE_STRING UnicodeString - ) +RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString) { - return RtlUnicodeStringToAnsiSize (UnicodeString); + return RtlUnicodeStringToAnsiSize(UnicodeString); } ULONG STDCALL -RtlxUnicodeStringToOemSize ( - IN PUNICODE_STRING UnicodeString - ) +RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) { - return RtlUnicodeStringToAnsiSize (UnicodeString); + return RtlUnicodeStringToAnsiSize(UnicodeString); } /* EOF */ diff --git a/lib/ntdll/stdlib/abs.c b/lib/ntdll/stdlib/abs.c index 2863888..3bd28bd 100644 --- a/lib/ntdll/stdlib/abs.c +++ b/lib/ntdll/stdlib/abs.c @@ -1,5 +1,5 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include +#include int abs(int j) diff --git a/lib/ntdll/string/stricmp.c b/lib/ntdll/string/stricmp.c index 913ceef..dce78e3 100644 --- a/lib/ntdll/string/stricmp.c +++ b/lib/ntdll/string/stricmp.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ -#include -#include +#include +#include int _stricmp(const char *s1, const char *s2) diff --git a/lib/ntdll/string/wstring.c b/lib/ntdll/string/wstring.c index 592a55a..d2c18ec 100644 --- a/lib/ntdll/string/wstring.c +++ b/lib/ntdll/string/wstring.c @@ -200,7 +200,6 @@ wchar_t* wcsncpy(wchar_t *dest, const wchar_t *src, size_t count) return dest; } } - dest[i] = 0; return dest; } diff --git a/lib/ole32/ole32.def b/lib/ole32/ole32.def index 9dd86d2..9bbdbf6 100644 --- a/lib/ole32/ole32.def +++ b/lib/ole32/ole32.def @@ -1,307 +1,307 @@ LIBRARY ole32.dll EXPORTS -;BindMoniker @ 9 -;CLIPFORMAT_UserFree @ 10 -;CLIPFORMAT_UserMarshal @ 11 -;CLIPFORMAT_UserSize @ 12 -;CLIPFORMAT_UserUnmarshal @ 13 -CLSIDFromProgID@8 @ 14 -;CLSIDFromProgIDEx @ 15 -CLSIDFromString@8 @ 16 -CoAddRefServerProcess@0 @ 17 -CoAllowSetForegroundWindow@8 @ 18 -CoBuildVersion@0 @ 19 -CoCancelCall@8 @ 20 -CoCopyProxy@8 @ 21 -CoCreateFreeThreadedMarshaler@8 @ 22 -CoCreateGuid@4 @ 23 -CoCreateInstance@20 @ 24 -CoCreateInstanceEx@24 @ 25 -;CoCreateObjectInContext @ 26 -;CoDeactivateObject @ 27 -CoDisableCallCancellation@4 @ 28 -CoDisconnectObject@8 @ 29 -CoDosDateTimeToFileTime@12 @ 30 -CoEnableCallCancellation@4 @ 31 -CoFileTimeNow@4 @ 32 -CoFileTimeToDosDateTime@12 @ 33 -CoFreeAllLibraries@0 @ 34 -CoFreeLibrary@4 @ 35 -CoFreeUnusedLibraries@0 @ 36 -;CoGetApartmentID @ 37 -CoGetCallContext@8 @ 38 -;CoGetCallerTID @ 39 -CoGetCancelObject@12 @ 40 -CoGetClassObject@20 @ 41 -;CoGetClassVersion @ 42 -;CoGetCurrentLogicalThreadId @ 43 -CoGetCurrentProcess@0 @ 44 -CoGetInstanceFromFile@32 @ 45 -CoGetInstanceFromIStorage@28 @ 46 -CoGetInterfaceAndReleaseStream@12 @ 47 -CoGetMalloc@8 @ 48 -CoGetMarshalSizeMax@24 @ 49 -CoGetObject@16 @ 50 -CoGetObjectContext@8 @ 51 -CoGetPSClsid@8 @ 52 -CoGetStandardMarshal@24 @ 53 -;CoGetState @ 54 -CoGetStdMarshalEx@12 @ 55 -CoGetTreatAsClass@8 @ 56 -CoImpersonateClient@0 @ 57 -CoInitialize@4 @ 58 -CoInitializeEx@8 @ 59 -CoInitializeSecurity@36 @ 60 -CoInitializeWOW@8 @ 61 -;CoInstall @ 62 -CoIsHandlerConnected@4 @ 63 -;CoIsOle1Class @ 64 -CoLoadLibrary@8 @ 65 -CoLockObjectExternal@12 @ 66 -CoMarshalHresult@8 @ 67 -CoMarshalInterThreadInterfaceInStream@12 @ 68 -CoMarshalInterface@24 @ 69 -CoQueryAuthenticationServices@8 @ 70 -CoQueryClientBlanket@28 @ 71 -CoQueryProxyBlanket@32 @ 72 -;CoQueryReleaseObject @ 73 -;CoReactivateObject @ 74 -;CoRegisterChannelHook @ 75 -CoRegisterClassObject@20 @ 76 -CoRegisterMallocSpy@4 @ 77 -CoRegisterMessageFilter@8 @ 78 -CoRegisterPSClsid@8 @ 79 -;CoRegisterSurrogate @ 80 -;CoRegisterSurrogateEx @ 81 -CoReleaseMarshalData@4 @ 82 -CoReleaseServerProcess@0 @ 83 -CoResumeClassObjects@0 @ 84 -CoRevertToSelf@0 @ 85 -CoRevokeClassObject@4 @ 86 -CoRevokeMallocSpy@0 @ 87 -CoSetCancelObject@4 @ 88 -CoSetProxyBlanket@32 @ 89 -CoSetState@4 @ 90 -CoSuspendClassObjects@0 @ 91 -CoSwitchCallContext@8 @ 92 -CoTaskMemAlloc@4 @ 93 -CoTaskMemFree@4 @ 94 -CoTaskMemRealloc@8 @ 95 -CoTestCancel@0 @ 96 -CoTreatAsClass@8 @ 97 -CoUninitialize@0 @ 98 -;CoUnloadingWOW @ 99 -CoUnmarshalHresult@8 @ 100 -CoUnmarshalInterface@12 @ 101 -CoWaitForMultipleHandles@20 @ 102 -CreateAntiMoniker@4 @ 103 -CreateBindCtx@8 @ 104 -;CreateClassMoniker @ 105 -;CreateDataAdviseHolder @ 106 -CreateDataCache@16 @ 107 -;CreateErrorInfo @ 108 -CreateFileMoniker@8 @ 109 -CreateGenericComposite@12 @ 110 -CreateILockBytesOnHGlobal@12 @ 111 -CreateItemMoniker@12 @ 112 -;CreateObjrefMoniker @ 113 -;CreateOleAdviseHolder @ 114 -;CreatePointerMoniker @ 115 -;CreateStdProgressIndicator @ 116 -;CreateStreamOnHGlobal @ 117 -;DcomChannelSetHResult @ 118 -;DllDebugObjectRPCHook @ 119 -;DllGetClassObject @ 120 -;DllGetClassObjectWOW @ 121 -;DllRegisterServer @ 122 -;DoDragDrop @ 123 -;EnableHookObject @ 124 -;FmtIdToPropStgName @ 125 -;FreePropVariantArray @ 126 -GetClassFile@8 @ 127 -GetConvertStg@4 @ 128 -;GetDocumentBitStg @ 129 -;GetErrorInfo @ 130 -GetHGlobalFromILockBytes@8 @ 131 -;GetHGlobalFromStream @ 132 -;GetHookInterface @ 133 -GetRunningObjectTable@8 @ 134 -;HACCEL_UserFree @ 135 -;HACCEL_UserMarshal @ 136 -;HACCEL_UserSize @ 137 -;HACCEL_UserUnmarshal @ 138 -;HBITMAP_UserFree @ 139 -;HBITMAP_UserMarshal @ 140 -;HBITMAP_UserSize @ 141 -;HBITMAP_UserUnmarshal @ 142 -;HBRUSH_UserFree @ 143 -;HBRUSH_UserMarshal @ 144 -;HBRUSH_UserSize @ 145 -;HBRUSH_UserUnmarshal @ 146 -;HDC_UserFree @ 147 -;HDC_UserMarshal @ 148 -;HDC_UserSize @ 149 -;HDC_UserUnmarshal @ 150 -;HENHMETAFILE_UserFree @ 151 -;HENHMETAFILE_UserMarshal @ 152 -;HENHMETAFILE_UserSize @ 153 -;HENHMETAFILE_UserUnmarshal @ 154 -;HGLOBAL_UserFree @ 155 -;HGLOBAL_UserMarshal @ 156 -;HGLOBAL_UserSize @ 157 -;HGLOBAL_UserUnmarshal @ 158 -;HICON_UserFree @ 159 -;HICON_UserMarshal @ 160 -;HICON_UserSize @ 161 -;HICON_UserUnmarshal @ 162 -;HMENU_UserFree @ 163 -;HMENU_UserMarshal @ 164 -;HMENU_UserSize @ 165 -;HMENU_UserUnmarshal @ 166 -;HMETAFILEPICT_UserFree @ 167 -;HMETAFILEPICT_UserMarshal @ 168 -;HMETAFILEPICT_UserSize @ 169 -;HMETAFILEPICT_UserUnmarshal @ 170 -;HMETAFILE_UserFree @ 171 -;HMETAFILE_UserMarshal @ 172 -;HMETAFILE_UserSize @ 173 -;HMETAFILE_UserUnmarshal @ 174 -;HPALETTE_UserFree @ 175 -;HPALETTE_UserMarshal @ 176 -;HPALETTE_UserSize @ 177 -;HPALETTE_UserUnmarshal @ 178 -;HWND_UserFree @ 179 -;HWND_UserMarshal @ 180 -;HWND_UserSize @ 181 -;HWND_UserUnmarshal @ 182 -;HkOleRegisterObject @ 183 -;IIDFromString @ 184 -;IsAccelerator @ 185 -IsEqualGUID@8 @ 186 -;IsValidIid @ 187 -IsValidInterface@4 @ 188 -;IsValidPtrIn @ 189 -;IsValidPtrOut @ 190 -MkParseDisplayName@16 @ 191 -MonikerCommonPrefixWith@12 @ 192 -;MonikerRelativePathTo @ 193 -;OleBuildVersion @ 194 -OleConvertIStorageToOLESTREAM@8 @ 195 -;OleConvertIStorageToOLESTREAMEx @ 196 -OleConvertOLESTREAMToIStorage@12 @ 197 -;OleConvertOLESTREAMToIStorageEx @ 198 -;OleCreate @ 199 -;OleCreateDefaultHandler @ 200 -;OleCreateEmbeddingHelper @ 201 -;OleCreateEx @ 202 -;OleCreateFromData @ 203 -;OleCreateFromDataEx @ 204 -;OleCreateFromFile @ 205 -;OleCreateFromFileEx @ 206 -;OleCreateLink @ 207 -;OleCreateLinkEx @ 208 -;OleCreateLinkFromData @ 209 -;OleCreateLinkFromDataEx @ 210 -;OleCreateLinkToFile @211 -;OleCreateLinkToFileEx @ 212 -;OleCreateMenuDescriptor @ 213 -;OleCreateStaticFromData @ 214 -;OleDestroyMenuDescriptor @215 -;OleDoAutoConvert @ 216 -;OleDraw @ 217 -;OleDuplicateData @ 218 -;OleFlushClipboard @ 219 -OleGetAutoConvert@8 @ 220 -;OleGetClipboard @ 221 -;OleGetIconOfClass @ 222 -;OleGetIconOfFile @ 223 -;OleInitialize @ 224 -;OleInitializeWOW @ 225 -;OleIsCurrentClipboard @ 226 -;OleIsRunning @ 227 -;OleLoad @ 228 -OleLoadFromStream@12 @ 229 -;OleLockRunning @ 230 -;OleMetafilePictFromIconAndLabel @ 231 -;OleNoteObjectVisible @ 232 -;OleQueryCreateFromData @ 233 -;OleQueryLinkFromData @ 234 -;OleRegEnumFormatEtc @ 235 -;OleRegEnumVerbs @ 236 -;OleRegGetMiscStatus @ 237 -;OleRegGetUserType @ 238 -OleRun@4 @ 239 -;OleSave @ 240 -OleSaveToStream@8 @ 241 -OleSetAutoConvert@8 @ 242 -;OleSetClipboard @ 243 -;OleSetContainedObject @ 244 -;OleSetMenuDescriptor @ 245 -;OleTranslateAccelerator @ 246 -;OleUninitialize @ 247 -;OpenOrCreateStream @ 248 -ProgIDFromCLSID@8 @ 249 -;PropStgNameToFmtId @ 250 -;PropSysAllocString @ 251 -;PropSysFreeString @ 252 -;PropVariantChangeType @ 1 -;PropVariantClear @ 253 -;PropVariantCopy @ 254 -ReadClassStg@8 @ 255 -ReadClassStm@8 @ 256 -;ReadFmtUserTypeStg @ 257 -;ReadOleStg @ 258 -;ReadStringStream @ 259 -;RegisterDragDrop @ 260 -;ReleaseStgMedium @ 261 -;RevokeDragDrop @ 262 -;SNB_UserFree @ 263 -;SNB_UserMarshal @ 264 -;SNB_UserSize @ 265 -;SNB_UserUnmarshal @ 266 -;STGMEDIUM_UserFree @ 267 -;STGMEDIUM_UserMarshal @ 268 -;STGMEDIUM_UserSize @ 269 -;STGMEDIUM_UserUnmarshal @ 270 -;SetConvertStg @ 271 -;SetDocumentBitStg @ 272 -;SetErrorInfo @ 273 -;StgConvertPropertyToVariant @ 2 -;StgConvertVariantToProperty @ 3 -StgCreateDocfile@16 @ 274 -StgCreateDocfileOnILockBytes@16 @ 275 -;StgCreatePropSetStg @ 276 -;StgCreatePropStg @ 277 -;StgCreateStorageEx @ 278 -;StgGetIFillLockBytesOnFile @ 279 -;StgGetIFillLockBytesOnILockBytes @ 280 -StgIsStorageFile@4 @ 281 -StgIsStorageILockBytes@4 @ 282 -;StgOpenAsyncDocfileOnIFillLockBytes @ 283 -;StgOpenPropStg @ 284 -StgOpenStorage@24 @ 285 -;StgOpenStorageEx @ 286 -;StgOpenStorageOnHandle @ 287 -StgOpenStorageOnILockBytes@24 @ 288 -;StgPropertyLengthAsVariant @ 4 -StgSetTimes@16 @ 289 -StringFromCLSID@8 @ 290 -StringFromGUID2@12 @ 291 -;StringFromIID @ 292 -;UpdateDCOMSettings @ 293 -;UtConvertDvtd16toDvtd32 @ 294 -;UtConvertDvtd32toDvtd16 @ 295 -;UtGetDvtd16Info @ 296 -;UtGetDvtd32Info @ 297 -;WdtpInterfacePointer_UserFree @ 5 -;WdtpInterfacePointer_UserMarshal @ 6 -;WdtpInterfacePointer_UserSize @ 7 -;WdtpInterfacePointer_UserUnmarshal @ 8 -WriteClassStg@8 @ 298 -WriteClassStm@8 @ 299 -;WriteFmtUserTypeStg @ 300 -;WriteOleStg @ 301 -;WriteStringStream @ 302 +; BindMoniker @9 +; CLIPFORMAT_UserFree @10 +; CLIPFORMAT_UserMarshal @11 +; CLIPFORMAT_UserSize @12 +; CLIPFORMAT_UserUnmarshal @13 + CLSIDFromProgID@8 @14 +; CLSIDFromProgIDEx @15 + CLSIDFromString@8 @16 + CoAddRefServerProcess@0 @17 + CoAllowSetForegroundWindow@8 @18 + CoBuildVersion@0 @19 + CoCancelCall@8 @20 + CoCopyProxy@8 @21 + CoCreateFreeThreadedMarshaler@8 @22 + CoCreateGuid@4 @23 + CoCreateInstance@20 @24 + CoCreateInstanceEx@24 @25 +; CoCreateObjectInContext @26 +; CoDeactivateObject @27 + CoDisableCallCancellation@4 @28 + CoDisconnectObject@8 @29 + CoDosDateTimeToFileTime@12 @30 + CoEnableCallCancellation@4 @31 + CoFileTimeNow@4 @32 + CoFileTimeToDosDateTime@12 @33 + CoFreeAllLibraries@0 @34 + CoFreeLibrary@4 @35 + CoFreeUnusedLibraries@0 @36 +; CoGetApartmentID @37 + CoGetCallContext@8 @38 +; CoGetCallerTID @39 + CoGetCancelObject@12 @40 + CoGetClassObject@20 @41 +; CoGetClassVersion @42 +; CoGetCurrentLogicalThreadId @43 + CoGetCurrentProcess@0 @44 + CoGetInstanceFromFile@32 @45 + CoGetInstanceFromIStorage@28 @46 + CoGetInterfaceAndReleaseStream@12 @47 + CoGetMalloc@8 @48 + CoGetMarshalSizeMax@24 @49 + CoGetObject@16 @50 + CoGetObjectContext@8 @51 + CoGetPSClsid@8 @52 + CoGetStandardMarshal@24 @53 +; CoGetState @54 + CoGetStdMarshalEx@12 @55 + CoGetTreatAsClass@8 @56 + CoImpersonateClient@0 @57 + CoInitialize@4 @58 + CoInitializeEx@8 @59 + CoInitializeSecurity@36 @60 + CoInitializeWOW@8 @61 +; CoInstall @62 + CoIsHandlerConnected@4 @63 +; CoIsOle1Class @64 + CoLoadLibrary@8 @65 + CoLockObjectExternal@12 @66 + CoMarshalHresult@8 @67 + CoMarshalInterThreadInterfaceInStream@12 @68 + CoMarshalInterface@24 @69 + CoQueryAuthenticationServices@8 @70 + CoQueryClientBlanket@28 @71 + CoQueryProxyBlanket@32 @72 +; CoQueryReleaseObject @73 +; CoReactivateObject @74 +; CoRegisterChannelHook @75 + CoRegisterClassObject@20 @76 + CoRegisterMallocSpy@4 @77 + CoRegisterMessageFilter@8 @78 + CoRegisterPSClsid@8 @79 +; CoRegisterSurrogate @80 +; CoRegisterSurrogateEx @81 + CoReleaseMarshalData@4 @82 + CoReleaseServerProcess@0 @83 + CoResumeClassObjects@0 @84 + CoRevertToSelf@0 @85 + CoRevokeClassObject@4 @86 + CoRevokeMallocSpy@0 @87 + CoSetCancelObject@4 @88 + CoSetProxyBlanket@32 @89 + CoSetState@4 @90 + CoSuspendClassObjects@0 @91 + CoSwitchCallContext@8 @92 + CoTaskMemAlloc@4 @93 + CoTaskMemFree@4 @94 + CoTaskMemRealloc@8 @95 + CoTestCancel@0 @96 + CoTreatAsClass@8 @97 + CoUninitialize@0 @98 +; CoUnloadingWOW @99 + CoUnmarshalHresult@8 @100 + CoUnmarshalInterface@12 @101 + CoWaitForMultipleHandles@20 @102 + CreateAntiMoniker@4 @103 + CreateBindCtx@8 @104 +; CreateClassMoniker @105 +; CreateDataAdviseHolder @106 + CreateDataCache@16 @107 +; CreateErrorInfo @108 + CreateFileMoniker@8 @109 + CreateGenericComposite@12 @110 + CreateILockBytesOnHGlobal@12 @111 + CreateItemMoniker@12 @112 +; CreateObjrefMoniker @113 +; CreateOleAdviseHolder @114 +; CreatePointerMoniker @115 +; CreateStdProgressIndicator @116 + CreateStreamOnHGlobal@12 @117 +; DcomChannelSetHResult @118 +; DllDebugObjectRPCHook @119 +; DllGetClassObject @120 +; DllGetClassObjectWOW @121 +; DllRegisterServer @122 +; DoDragDrop @123 +; EnableHookObject @124 +; FmtIdToPropStgName @125 +; FreePropVariantArray @126 + GetClassFile@8 @127 + GetConvertStg@4 @128 +; GetDocumentBitStg @129 +; GetErrorInfo @130 + GetHGlobalFromILockBytes@8 @131 +; GetHGlobalFromStream @132 +; GetHookInterface @133 + GetRunningObjectTable@8 @134 +; HACCEL_UserFree @135 +; HACCEL_UserMarshal @136 +; HACCEL_UserSize @137 +; HACCEL_UserUnmarshal @138 +; HBITMAP_UserFree @139 +; HBITMAP_UserMarshal @140 +; HBITMAP_UserSize @141 +; HBITMAP_UserUnmarshal @142 +; HBRUSH_UserFree @143 +; HBRUSH_UserMarshal @144 +; HBRUSH_UserSize @145 +; HBRUSH_UserUnmarshal @146 +; HDC_UserFree @147 +; HDC_UserMarshal @148 +; HDC_UserSize @149 +; HDC_UserUnmarshal @150 +; HENHMETAFILE_UserFree @151 +; HENHMETAFILE_UserMarshal @152 +; HENHMETAFILE_UserSize @153 +; HENHMETAFILE_UserUnmarshal @154 +; HGLOBAL_UserFree @155 +; HGLOBAL_UserMarshal @156 +; HGLOBAL_UserSize @157 +; HGLOBAL_UserUnmarshal @158 +; HICON_UserFree @159 +; HICON_UserMarshal @160 +; HICON_UserSize @161 +; HICON_UserUnmarshal @162 +; HMENU_UserFree @163 +; HMENU_UserMarshal @164 +; HMENU_UserSize @165 +; HMENU_UserUnmarshal @166 +; HMETAFILEPICT_UserFree @167 +; HMETAFILEPICT_UserMarshal @168 +; HMETAFILEPICT_UserSize @169 +; HMETAFILEPICT_UserUnmarshal @170 +; HMETAFILE_UserFree @171 +; HMETAFILE_UserMarshal @172 +; HMETAFILE_UserSize @173 +; HMETAFILE_UserUnmarshal @174 +; HPALETTE_UserFree @175 +; HPALETTE_UserMarshal @176 +; HPALETTE_UserSize @177 +; HPALETTE_UserUnmarshal @178 +; HWND_UserFree @179 +; HWND_UserMarshal @180 +; HWND_UserSize @181 +; HWND_UserUnmarshal @182 +; HkOleRegisterObject @183 +; IIDFromString @184 +; IsAccelerator @185 + IsEqualGUID@8 @186 +; IsValidIid @187 + IsValidInterface@4 @188 +; IsValidPtrIn @189 +; IsValidPtrOut @190 + MkParseDisplayName@16 @191 + MonikerCommonPrefixWith@12 @192 +; MonikerRelativePathTo @193 +; OleBuildVersion @194 + OleConvertIStorageToOLESTREAM@8 @195 +; OleConvertIStorageToOLESTREAMEx @196 + OleConvertOLESTREAMToIStorage@12 @197 +; OleConvertOLESTREAMToIStorageEx @198 +; OleCreate @199 +; OleCreateDefaultHandler @200 +; OleCreateEmbeddingHelper @201 +; OleCreateEx @202 +; OleCreateFromData @203 +; OleCreateFromDataEx @204 +; OleCreateFromFile @205 +; OleCreateFromFileEx @206 +; OleCreateLink @207 +; OleCreateLinkEx @208 +; OleCreateLinkFromData @209 +; OleCreateLinkFromDataEx @210 +; OleCreateLinkToFile @211 +; OleCreateLinkToFileEx @212 +; OleCreateMenuDescriptor @213 +; OleCreateStaticFromData @214 +; OleDestroyMenuDescriptor @215 +; OleDoAutoConvert @216 +; OleDraw @217 +; OleDuplicateData @218 +; OleFlushClipboard @219 + OleGetAutoConvert@8 @220 +; OleGetClipboard @221 +; OleGetIconOfClass @222 +; OleGetIconOfFile @223 +; OleInitialize @224 +; OleInitializeWOW @225 +; OleIsCurrentClipboard @226 +; OleIsRunning @227 +; OleLoad @228 + OleLoadFromStream@12 @229 +; OleLockRunning @230 +; OleMetafilePictFromIconAndLabel @231 +; OleNoteObjectVisible @232 +; OleQueryCreateFromData @233 +; OleQueryLinkFromData @234 +; OleRegEnumFormatEtc @235 +; OleRegEnumVerbs @236 +; OleRegGetMiscStatus @237 +; OleRegGetUserType @238 + OleRun@4 @239 +; OleSave @240 + OleSaveToStream@8 @241 + OleSetAutoConvert@8 @242 +; OleSetClipboard @243 +; OleSetContainedObject @244 +; OleSetMenuDescriptor @245 +; OleTranslateAccelerator @246 +; OleUninitialize @247 +; OpenOrCreateStream @248 + ProgIDFromCLSID@8 @249 +; PropStgNameToFmtId @250 +; PropSysAllocString @251 +; PropSysFreeString @252 +; PropVariantChangeType @1 +; PropVariantClear @253 +; PropVariantCopy @254 + ReadClassStg@8 @255 + ReadClassStm@8 @256 +; ReadFmtUserTypeStg @257 +; ReadOleStg @258 +; ReadStringStream @259 +; RegisterDragDrop @260 +; ReleaseStgMedium @261 +; RevokeDragDrop @262 +; SNB_UserFree @263 +; SNB_UserMarshal @264 +; SNB_UserSize @265 +; SNB_UserUnmarshal @266 +; STGMEDIUM_UserFree @267 +; STGMEDIUM_UserMarshal @268 +; STGMEDIUM_UserSize @269 +; STGMEDIUM_UserUnmarshal @270 +; SetConvertStg @271 +; SetDocumentBitStg @272 +; SetErrorInfo @273 +; StgConvertPropertyToVariant @2 +; StgConvertVariantToProperty @3 + StgCreateDocfile@16 @274 + StgCreateDocfileOnILockBytes@16 @275 +; StgCreatePropSetStg @276 +; StgCreatePropStg @277 +; StgCreateStorageEx @278 +; StgGetIFillLockBytesOnFile @279 +; StgGetIFillLockBytesOnILockBytes @280 + StgIsStorageFile@4 @281 + StgIsStorageILockBytes@4 @282 +; StgOpenAsyncDocfileOnIFillLockBytes @283 +; StgOpenPropStg @284 + StgOpenStorage@24 @285 +; StgOpenStorageEx @286 +; StgOpenStorageOnHandle @287 + StgOpenStorageOnILockBytes@24 @288 +; StgPropertyLengthAsVariant @4 + StgSetTimes@16 @289 + StringFromCLSID@8 @290 + StringFromGUID2@12 @291 +; StringFromIID @292 +; UpdateDCOMSettings @293 +; UtConvertDvtd16toDvtd32 @294 +; UtConvertDvtd32toDvtd16 @295 +; UtGetDvtd16Info @296 +; UtGetDvtd32Info @297 +; WdtpInterfacePointer_UserFree @5 +; WdtpInterfacePointer_UserMarshal @6 +; WdtpInterfacePointer_UserSize @7 +; WdtpInterfacePointer_UserUnmarshal @8 + WriteClassStg@8 @298 + WriteClassStm@8 @299 +; WriteFmtUserTypeStg @300 +; WriteOleStg @301 +; WriteStringStream @302 ; EOF diff --git a/lib/packet/Packet32.c b/lib/packet/Packet32.c index 5f0a06d..8f0264b 100644 --- a/lib/packet/Packet32.c +++ b/lib/packet/Packet32.c @@ -21,11 +21,10 @@ #define UNICODE 1 -#include #include -//#include -#include +#include +#include #include "trace.h" diff --git a/lib/packet/include/devioctl.h b/lib/packet/include/devioctl.h deleted file mode 100644 index 661fda0..0000000 --- a/lib/packet/include/devioctl.h +++ /dev/null @@ -1,90 +0,0 @@ -/*++ BUILD Version: 0004 // Increment this if a change has global effects - Copyright (c) 1992-1993 Microsoft Corporation - Module Name: - devioctl.h - Revision History: - -- */ -// begin_winioctl -#ifndef _DEVIOCTL_ -#define _DEVIOCTL_ -// begin_ntddk begin_nthal begin_ntifs -// -// Define the various device type values. Note that values used by Microsoft -// Corporation are in the range 0-32767, and 32768-65535 are reserved for use -// by customers. -// -#define DEVICE_TYPE ULONG -#define FILE_DEVICE_BEEP 0x00000001 -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_DATALINK 0x00000005 -#define FILE_DEVICE_DFS 0x00000006 -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#define FILE_DEVICE_INPORT_PORT 0x0000000a -#define FILE_DEVICE_KEYBOARD 0x0000000b -#define FILE_DEVICE_MAILSLOT 0x0000000c -#define FILE_DEVICE_MIDI_IN 0x0000000d -#define FILE_DEVICE_MIDI_OUT 0x0000000e -#define FILE_DEVICE_MOUSE 0x0000000f -#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 -#define FILE_DEVICE_NAMED_PIPE 0x00000011 -#define FILE_DEVICE_NETWORK 0x00000012 -#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 -#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 -#define FILE_DEVICE_NULL 0x00000015 -#define FILE_DEVICE_PARALLEL_PORT 0x00000016 -#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 -#define FILE_DEVICE_PRINTER 0x00000018 -#define FILE_DEVICE_SCANNER 0x00000019 -#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a -#define FILE_DEVICE_SERIAL_PORT 0x0000001b -#define FILE_DEVICE_SCREEN 0x0000001c -#define FILE_DEVICE_SOUND 0x0000001d -#define FILE_DEVICE_STREAMS 0x0000001e -#define FILE_DEVICE_TAPE 0x0000001f -#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 -#define FILE_DEVICE_TRANSPORT 0x00000021 -#define FILE_DEVICE_UNKNOWN 0x00000022 -#define FILE_DEVICE_VIDEO 0x00000023 -#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 -#define FILE_DEVICE_WAVE_IN 0x00000025 -#define FILE_DEVICE_WAVE_OUT 0x00000026 -#define FILE_DEVICE_8042_PORT 0x00000027 -#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 -#define FILE_DEVICE_BATTERY 0x00000029 -#define FILE_DEVICE_BUS_EXTENDER 0x0000002a -#define FILE_DEVICE_MODEM 0x0000002b -#define FILE_DEVICE_VDM 0x0000002c -#define FILE_DEVICE_MASS_STORAGE 0x0000002d -// -// Macro definition for defining IOCTL and FSCTL function control codes. Note -// that function codes 0-2047 are reserved for Microsoft Corporation, and -// 2048-4095 are reserved for customers. -// -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) -// -// Define the method codes for how buffers are passed for I/O and FS controls -// -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 -// -// Define the access check value for any access -// -// -// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in -// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these -// constants *MUST* always be in sync. -// -#define FILE_ANY_ACCESS 0 -#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe -#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe -// end_ntddk end_nthal end_ntifs -#endif // _DEVIOCTL_ -// end_winioctl diff --git a/lib/packet/include/ntddndis.h b/lib/packet/include/ntddndis.h deleted file mode 100644 index 77a53d7..0000000 --- a/lib/packet/include/ntddndis.h +++ /dev/null @@ -1,1400 +0,0 @@ -/*++ BUILD Version: 0001 // Increment this if a change has global effects - Copyright (c) 1990-1993 Microsoft Corporation - Module Name: - ntddndis.h - Abstract: - This is the include file that defines all constants and types for - accessing the Network driver interface device. - Author: - Steve Wood (stevewo) 27-May-1990 - Revision History: - Adam Barr (adamba) 04-Nov-1992 added the correct values for NDIS 3.0. - Jameel Hyder (jameelh) 01-Aug-95 added Pnp IoCTLs and structures - Kyle Brandon (kyleb) 09/24/96 added general co ndis oids. - -- */ -#ifndef _NTDDNDIS_ -#define _NTDDNDIS_ -// -// Device Name - this string is the name of the device. It is the name -// that should be passed to NtOpenFile when accessing the device. -// -// Note: For devices that support multiple units, it should be suffixed -// with the Ascii representation of the unit number. -// -#define DD_NDIS_DEVICE_NAME "\\Device\\UNKNOWN" -// -// NtDeviceIoControlFile IoControlCode values for this device. -// -// Warning: Remember that the low two bits of the code specify how the -// buffers are passed to the driver! -// -#define _NDIS_CONTROL_CODE(request,method) \ - CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS) -#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT ) -#define IOCTL_NDIS_QUERY_ALL_STATS _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT ) -#define IOCTL_NDIS_ADD_DEVICE _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED ) -#define IOCTL_NDIS_DELETE_DEVICE _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED ) -#define IOCTL_NDIS_TRANSLATE_NAME _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED ) -#define IOCTL_NDIS_ADD_TDI_DEVICE _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED ) -#define IOCTL_NDIS_NOTIFY_PROTOCOL _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED ) -#define IOCTL_NDIS_GET_LOG_DATA _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT ) -// -// NtDeviceIoControlFile InputBuffer/OutputBuffer record structures for -// this device. -// -// -// This is the type of an NDIS OID value. -// -typedef ULONG NDIS_OID, *PNDIS_OID; -// -// IOCTL_NDIS_QUERY_ALL_STATS returns a sequence of these, packed -// together (no padding is required since statistics all have -// four or eight bytes of data). -// -typedef struct _NDIS_STATISTICS_VALUE { - NDIS_OID Oid; - ULONG DataLength; - UCHAR Data[1]; // variable length - -} NDIS_STATISTICS_VALUE, *PNDIS_STATISTICS_VALUE; - -// -// Structure used by TRANSLATE_NAME IOCTL -// -typedef struct _NET_PNP_ID { - ULONG ClassId; - ULONG Token; -} NET_PNP_ID, *PNET_PNP_ID; - -typedef struct _NET_PNP_TRANSLATE_LIST { - ULONG BytesNeeded; - NET_PNP_ID IdArray[ANYSIZE_ARRAY]; -} NET_PNP_TRANSLATE_LIST, *PNET_PNP_TRANSLATE_LIST; - -// -// Structure used to define a self-contained variable data structure -// -typedef struct _NDIS_VAR_DATA_DESC { - USHORT Length; // # of octects of data - - USHORT MaximumLength; // # of octects available - - LONG Offset; // Offset of data relative to the descriptor - -} NDIS_VAR_DATA_DESC, *PNDIS_VAR_DATA_DESC; - -// -// Object Identifiers used by NdisRequest Query/Set Information -// -// -// General Objects -// -#define OID_GEN_SUPPORTED_LIST 0x00010101 -#define OID_GEN_HARDWARE_STATUS 0x00010102 -#define OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define OID_GEN_MEDIA_IN_USE 0x00010104 -#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define OID_GEN_LINK_SPEED 0x00010107 -#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define OID_GEN_VENDOR_ID 0x0001010C -#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define OID_GEN_DRIVER_VERSION 0x00010110 -#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define OID_GEN_MAC_OPTIONS 0x00010113 -#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 -#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D -#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E -#define OID_GEN_GET_TIME_CAPS 0x0002020F -#define OID_GEN_GET_NETCARD_TIME 0x00020210 -// -// These are connection-oriented general OIDs. -// These replace the above OIDs for connection-oriented media. -// -#define OID_GEN_CO_SUPPORTED_LIST 0x00010101 -#define OID_GEN_CO_HARDWARE_STATUS 0x00010102 -#define OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 -#define OID_GEN_CO_MEDIA_IN_USE 0x00010104 -#define OID_GEN_CO_LINK_SPEED 0x00010105 -#define OID_GEN_CO_VENDOR_ID 0x00010106 -#define OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 -#define OID_GEN_CO_DRIVER_VERSION 0x00010108 -#define OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 -#define OID_GEN_CO_MAC_OPTIONS 0x0001010A -#define OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B -#define OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C -#define OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D -#define OID_GEN_CO_GET_TIME_CAPS 0x00010201 -#define OID_GEN_CO_GET_NETCARD_TIME 0x00010202 -// -// These are connection-oriented statistics OIDs. -// -#define OID_GEN_CO_XMIT_PDUS_OK 0x00020101 -#define OID_GEN_CO_RCV_PDUS_OK 0x00020102 -#define OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 -#define OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 -#define OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 -#define OID_GEN_CO_RCV_CRC_ERROR 0x00020201 -#define OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 -#define OID_GEN_CO_BYTES_XMIT 0x00020203 -#define OID_GEN_CO_BYTES_RCV 0x00020204 -#define OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 -#define OID_GEN_CO_NETCARD_LOAD 0x00020206 -// -// These are objects for Connection-oriented media call-managers and are not -// valid for ndis drivers. Under construction. -// -#define OID_CO_ADD_PVC 0xFF000001 -#define OID_CO_DELETE_PVC 0xFF000002 -#define OID_CO_GET_CALL_INFORMATION 0xFF000003 -#define OID_CO_ADD_ADDRESS 0xFF000004 -#define OID_CO_DELETE_ADDRESS 0xFF000005 -#define OID_CO_GET_ADDRESSES 0xFF000006 -#define OID_CO_ADDRESS_CHANGE 0xFF000007 -#define OID_CO_SIGNALING_ENABLED 0xFF000008 -#define OID_CO_SIGNALING_DISABLED 0xFF000009 -// -// 802.3 Objects (Ethernet) -// -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 -#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define OID_802_3_MAC_OPTIONS 0x01010105 -// -// -#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 -// -// 802.5 Objects (Token-Ring) -// -#define OID_802_5_PERMANENT_ADDRESS 0x02010101 -#define OID_802_5_CURRENT_ADDRESS 0x02010102 -#define OID_802_5_CURRENT_FUNCTIONAL 0x02010103 -#define OID_802_5_CURRENT_GROUP 0x02010104 -#define OID_802_5_LAST_OPEN_STATUS 0x02010105 -#define OID_802_5_CURRENT_RING_STATUS 0x02010106 -#define OID_802_5_CURRENT_RING_STATE 0x02010107 -#define OID_802_5_LINE_ERRORS 0x02020101 -#define OID_802_5_LOST_FRAMES 0x02020102 -#define OID_802_5_BURST_ERRORS 0x02020201 -#define OID_802_5_AC_ERRORS 0x02020202 -#define OID_802_5_ABORT_DELIMETERS 0x02020203 -#define OID_802_5_FRAME_COPIED_ERRORS 0x02020204 -#define OID_802_5_FREQUENCY_ERRORS 0x02020205 -#define OID_802_5_TOKEN_ERRORS 0x02020206 -#define OID_802_5_INTERNAL_ERRORS 0x02020207 -// -// FDDI Objects -// -#define OID_FDDI_LONG_PERMANENT_ADDR 0x03010101 -#define OID_FDDI_LONG_CURRENT_ADDR 0x03010102 -#define OID_FDDI_LONG_MULTICAST_LIST 0x03010103 -#define OID_FDDI_LONG_MAX_LIST_SIZE 0x03010104 -#define OID_FDDI_SHORT_PERMANENT_ADDR 0x03010105 -#define OID_FDDI_SHORT_CURRENT_ADDR 0x03010106 -#define OID_FDDI_SHORT_MULTICAST_LIST 0x03010107 -#define OID_FDDI_SHORT_MAX_LIST_SIZE 0x03010108 -#define OID_FDDI_ATTACHMENT_TYPE 0x03020101 -#define OID_FDDI_UPSTREAM_NODE_LONG 0x03020102 -#define OID_FDDI_DOWNSTREAM_NODE_LONG 0x03020103 -#define OID_FDDI_FRAME_ERRORS 0x03020104 -#define OID_FDDI_FRAMES_LOST 0x03020105 -#define OID_FDDI_RING_MGT_STATE 0x03020106 -#define OID_FDDI_LCT_FAILURES 0x03020107 -#define OID_FDDI_LEM_REJECTS 0x03020108 -#define OID_FDDI_LCONNECTION_STATE 0x03020109 -#define OID_FDDI_SMT_STATION_ID 0x03030201 -#define OID_FDDI_SMT_OP_VERSION_ID 0x03030202 -#define OID_FDDI_SMT_HI_VERSION_ID 0x03030203 -#define OID_FDDI_SMT_LO_VERSION_ID 0x03030204 -#define OID_FDDI_SMT_MANUFACTURER_DATA 0x03030205 -#define OID_FDDI_SMT_USER_DATA 0x03030206 -#define OID_FDDI_SMT_MIB_VERSION_ID 0x03030207 -#define OID_FDDI_SMT_MAC_CT 0x03030208 -#define OID_FDDI_SMT_NON_MASTER_CT 0x03030209 -#define OID_FDDI_SMT_MASTER_CT 0x0303020A -#define OID_FDDI_SMT_AVAILABLE_PATHS 0x0303020B -#define OID_FDDI_SMT_CONFIG_CAPABILITIES 0x0303020C -#define OID_FDDI_SMT_CONFIG_POLICY 0x0303020D -#define OID_FDDI_SMT_CONNECTION_POLICY 0x0303020E -#define OID_FDDI_SMT_T_NOTIFY 0x0303020F -#define OID_FDDI_SMT_STAT_RPT_POLICY 0x03030210 -#define OID_FDDI_SMT_TRACE_MAX_EXPIRATION 0x03030211 -#define OID_FDDI_SMT_PORT_INDEXES 0x03030212 -#define OID_FDDI_SMT_MAC_INDEXES 0x03030213 -#define OID_FDDI_SMT_BYPASS_PRESENT 0x03030214 -#define OID_FDDI_SMT_ECM_STATE 0x03030215 -#define OID_FDDI_SMT_CF_STATE 0x03030216 -#define OID_FDDI_SMT_HOLD_STATE 0x03030217 -#define OID_FDDI_SMT_REMOTE_DISCONNECT_FLAG 0x03030218 -#define OID_FDDI_SMT_STATION_STATUS 0x03030219 -#define OID_FDDI_SMT_PEER_WRAP_FLAG 0x0303021A -#define OID_FDDI_SMT_MSG_TIME_STAMP 0x0303021B -#define OID_FDDI_SMT_TRANSITION_TIME_STAMP 0x0303021C -#define OID_FDDI_SMT_SET_COUNT 0x0303021D -#define OID_FDDI_SMT_LAST_SET_STATION_ID 0x0303021E -#define OID_FDDI_MAC_FRAME_STATUS_FUNCTIONS 0x0303021F -#define OID_FDDI_MAC_BRIDGE_FUNCTIONS 0x03030220 -#define OID_FDDI_MAC_T_MAX_CAPABILITY 0x03030221 -#define OID_FDDI_MAC_TVX_CAPABILITY 0x03030222 -#define OID_FDDI_MAC_AVAILABLE_PATHS 0x03030223 -#define OID_FDDI_MAC_CURRENT_PATH 0x03030224 -#define OID_FDDI_MAC_UPSTREAM_NBR 0x03030225 -#define OID_FDDI_MAC_DOWNSTREAM_NBR 0x03030226 -#define OID_FDDI_MAC_OLD_UPSTREAM_NBR 0x03030227 -#define OID_FDDI_MAC_OLD_DOWNSTREAM_NBR 0x03030228 -#define OID_FDDI_MAC_DUP_ADDRESS_TEST 0x03030229 -#define OID_FDDI_MAC_REQUESTED_PATHS 0x0303022A -#define OID_FDDI_MAC_DOWNSTREAM_PORT_TYPE 0x0303022B -#define OID_FDDI_MAC_INDEX 0x0303022C -#define OID_FDDI_MAC_SMT_ADDRESS 0x0303022D -#define OID_FDDI_MAC_LONG_GRP_ADDRESS 0x0303022E -#define OID_FDDI_MAC_SHORT_GRP_ADDRESS 0x0303022F -#define OID_FDDI_MAC_T_REQ 0x03030230 -#define OID_FDDI_MAC_T_NEG 0x03030231 -#define OID_FDDI_MAC_T_MAX 0x03030232 -#define OID_FDDI_MAC_TVX_VALUE 0x03030233 -#define OID_FDDI_MAC_T_PRI0 0x03030234 -#define OID_FDDI_MAC_T_PRI1 0x03030235 -#define OID_FDDI_MAC_T_PRI2 0x03030236 -#define OID_FDDI_MAC_T_PRI3 0x03030237 -#define OID_FDDI_MAC_T_PRI4 0x03030238 -#define OID_FDDI_MAC_T_PRI5 0x03030239 -#define OID_FDDI_MAC_T_PRI6 0x0303023A -#define OID_FDDI_MAC_FRAME_CT 0x0303023B -#define OID_FDDI_MAC_COPIED_CT 0x0303023C -#define OID_FDDI_MAC_TRANSMIT_CT 0x0303023D -#define OID_FDDI_MAC_TOKEN_CT 0x0303023E -#define OID_FDDI_MAC_ERROR_CT 0x0303023F -#define OID_FDDI_MAC_LOST_CT 0x03030240 -#define OID_FDDI_MAC_TVX_EXPIRED_CT 0x03030241 -#define OID_FDDI_MAC_NOT_COPIED_CT 0x03030242 -#define OID_FDDI_MAC_LATE_CT 0x03030243 -#define OID_FDDI_MAC_RING_OP_CT 0x03030244 -#define OID_FDDI_MAC_FRAME_ERROR_THRESHOLD 0x03030245 -#define OID_FDDI_MAC_FRAME_ERROR_RATIO 0x03030246 -#define OID_FDDI_MAC_NOT_COPIED_THRESHOLD 0x03030247 -#define OID_FDDI_MAC_NOT_COPIED_RATIO 0x03030248 -#define OID_FDDI_MAC_RMT_STATE 0x03030249 -#define OID_FDDI_MAC_DA_FLAG 0x0303024A -#define OID_FDDI_MAC_UNDA_FLAG 0x0303024B -#define OID_FDDI_MAC_FRAME_ERROR_FLAG 0x0303024C -#define OID_FDDI_MAC_NOT_COPIED_FLAG 0x0303024D -#define OID_FDDI_MAC_MA_UNITDATA_AVAILABLE 0x0303024E -#define OID_FDDI_MAC_HARDWARE_PRESENT 0x0303024F -#define OID_FDDI_MAC_MA_UNITDATA_ENABLE 0x03030250 -#define OID_FDDI_PATH_INDEX 0x03030251 -#define OID_FDDI_PATH_RING_LATENCY 0x03030252 -#define OID_FDDI_PATH_TRACE_STATUS 0x03030253 -#define OID_FDDI_PATH_SBA_PAYLOAD 0x03030254 -#define OID_FDDI_PATH_SBA_OVERHEAD 0x03030255 -#define OID_FDDI_PATH_CONFIGURATION 0x03030256 -#define OID_FDDI_PATH_T_R_MODE 0x03030257 -#define OID_FDDI_PATH_SBA_AVAILABLE 0x03030258 -#define OID_FDDI_PATH_TVX_LOWER_BOUND 0x03030259 -#define OID_FDDI_PATH_T_MAX_LOWER_BOUND 0x0303025A -#define OID_FDDI_PATH_MAX_T_REQ 0x0303025B -#define OID_FDDI_PORT_MY_TYPE 0x0303025C -#define OID_FDDI_PORT_NEIGHBOR_TYPE 0x0303025D -#define OID_FDDI_PORT_CONNECTION_POLICIES 0x0303025E -#define OID_FDDI_PORT_MAC_INDICATED 0x0303025F -#define OID_FDDI_PORT_CURRENT_PATH 0x03030260 -#define OID_FDDI_PORT_REQUESTED_PATHS 0x03030261 -#define OID_FDDI_PORT_MAC_PLACEMENT 0x03030262 -#define OID_FDDI_PORT_AVAILABLE_PATHS 0x03030263 -#define OID_FDDI_PORT_MAC_LOOP_TIME 0x03030264 -#define OID_FDDI_PORT_PMD_CLASS 0x03030265 -#define OID_FDDI_PORT_CONNECTION_CAPABILITIES 0x03030266 -#define OID_FDDI_PORT_INDEX 0x03030267 -#define OID_FDDI_PORT_MAINT_LS 0x03030268 -#define OID_FDDI_PORT_BS_FLAG 0x03030269 -#define OID_FDDI_PORT_PC_LS 0x0303026A -#define OID_FDDI_PORT_EB_ERROR_CT 0x0303026B -#define OID_FDDI_PORT_LCT_FAIL_CT 0x0303026C -#define OID_FDDI_PORT_LER_ESTIMATE 0x0303026D -#define OID_FDDI_PORT_LEM_REJECT_CT 0x0303026E -#define OID_FDDI_PORT_LEM_CT 0x0303026F -#define OID_FDDI_PORT_LER_CUTOFF 0x03030270 -#define OID_FDDI_PORT_LER_ALARM 0x03030271 -#define OID_FDDI_PORT_CONNNECT_STATE 0x03030272 -#define OID_FDDI_PORT_PCM_STATE 0x03030273 -#define OID_FDDI_PORT_PC_WITHHOLD 0x03030274 -#define OID_FDDI_PORT_LER_FLAG 0x03030275 -#define OID_FDDI_PORT_HARDWARE_PRESENT 0x03030276 -#define OID_FDDI_SMT_STATION_ACTION 0x03030277 -#define OID_FDDI_PORT_ACTION 0x03030278 -#define OID_FDDI_IF_DESCR 0x03030279 -#define OID_FDDI_IF_TYPE 0x0303027A -#define OID_FDDI_IF_MTU 0x0303027B -#define OID_FDDI_IF_SPEED 0x0303027C -#define OID_FDDI_IF_PHYS_ADDRESS 0x0303027D -#define OID_FDDI_IF_ADMIN_STATUS 0x0303027E -#define OID_FDDI_IF_OPER_STATUS 0x0303027F -#define OID_FDDI_IF_LAST_CHANGE 0x03030280 -#define OID_FDDI_IF_IN_OCTETS 0x03030281 -#define OID_FDDI_IF_IN_UCAST_PKTS 0x03030282 -#define OID_FDDI_IF_IN_NUCAST_PKTS 0x03030283 -#define OID_FDDI_IF_IN_DISCARDS 0x03030284 -#define OID_FDDI_IF_IN_ERRORS 0x03030285 -#define OID_FDDI_IF_IN_UNKNOWN_PROTOS 0x03030286 -#define OID_FDDI_IF_OUT_OCTETS 0x03030287 -#define OID_FDDI_IF_OUT_UCAST_PKTS 0x03030288 -#define OID_FDDI_IF_OUT_NUCAST_PKTS 0x03030289 -#define OID_FDDI_IF_OUT_DISCARDS 0x0303028A -#define OID_FDDI_IF_OUT_ERRORS 0x0303028B -#define OID_FDDI_IF_OUT_QLEN 0x0303028C -#define OID_FDDI_IF_SPECIFIC 0x0303028D -// -// WAN objects -// -#define OID_WAN_PERMANENT_ADDRESS 0x04010101 -#define OID_WAN_CURRENT_ADDRESS 0x04010102 -#define OID_WAN_QUALITY_OF_SERVICE 0x04010103 -#define OID_WAN_PROTOCOL_TYPE 0x04010104 -#define OID_WAN_MEDIUM_SUBTYPE 0x04010105 -#define OID_WAN_HEADER_FORMAT 0x04010106 -#define OID_WAN_GET_INFO 0x04010107 -#define OID_WAN_SET_LINK_INFO 0x04010108 -#define OID_WAN_GET_LINK_INFO 0x04010109 -#define OID_WAN_LINE_COUNT 0x0401010A -#define OID_WAN_GET_BRIDGE_INFO 0x0401020A -#define OID_WAN_SET_BRIDGE_INFO 0x0401020B -#define OID_WAN_GET_COMP_INFO 0x0401020C -#define OID_WAN_SET_COMP_INFO 0x0401020D -#define OID_WAN_GET_STATS_INFO 0x0401020E -// -// LocalTalk objects -// -#define OID_LTALK_CURRENT_NODE_ID 0x05010102 -#define OID_LTALK_IN_BROADCASTS 0x05020101 -#define OID_LTALK_IN_LENGTH_ERRORS 0x05020102 -#define OID_LTALK_OUT_NO_HANDLERS 0x05020201 -#define OID_LTALK_COLLISIONS 0x05020202 -#define OID_LTALK_DEFERS 0x05020203 -#define OID_LTALK_NO_DATA_ERRORS 0x05020204 -#define OID_LTALK_RANDOM_CTS_ERRORS 0x05020205 -#define OID_LTALK_FCS_ERRORS 0x05020206 -// -// Arcnet objects -// -#define OID_ARCNET_PERMANENT_ADDRESS 0x06010101 -#define OID_ARCNET_CURRENT_ADDRESS 0x06010102 -#define OID_ARCNET_RECONFIGURATIONS 0x06020201 -// -// TAPI objects -// -#define OID_TAPI_ACCEPT 0x07030101 -#define OID_TAPI_ANSWER 0x07030102 -#define OID_TAPI_CLOSE 0x07030103 -#define OID_TAPI_CLOSE_CALL 0x07030104 -#define OID_TAPI_CONDITIONAL_MEDIA_DETECTION 0x07030105 -#define OID_TAPI_CONFIG_DIALOG 0x07030106 -#define OID_TAPI_DEV_SPECIFIC 0x07030107 -#define OID_TAPI_DIAL 0x07030108 -#define OID_TAPI_DROP 0x07030109 -#define OID_TAPI_GET_ADDRESS_CAPS 0x0703010A -#define OID_TAPI_GET_ADDRESS_ID 0x0703010B -#define OID_TAPI_GET_ADDRESS_STATUS 0x0703010C -#define OID_TAPI_GET_CALL_ADDRESS_ID 0x0703010D -#define OID_TAPI_GET_CALL_INFO 0x0703010E -#define OID_TAPI_GET_CALL_STATUS 0x0703010F -#define OID_TAPI_GET_DEV_CAPS 0x07030110 -#define OID_TAPI_GET_DEV_CONFIG 0x07030111 -#define OID_TAPI_GET_EXTENSION_ID 0x07030112 -#define OID_TAPI_GET_ID 0x07030113 -#define OID_TAPI_GET_LINE_DEV_STATUS 0x07030114 -#define OID_TAPI_MAKE_CALL 0x07030115 -#define OID_TAPI_NEGOTIATE_EXT_VERSION 0x07030116 -#define OID_TAPI_OPEN 0x07030117 -#define OID_TAPI_PROVIDER_INITIALIZE 0x07030118 -#define OID_TAPI_PROVIDER_SHUTDOWN 0x07030119 -#define OID_TAPI_SECURE_CALL 0x0703011A -#define OID_TAPI_SELECT_EXT_VERSION 0x0703011B -#define OID_TAPI_SEND_USER_USER_INFO 0x0703011C -#define OID_TAPI_SET_APP_SPECIFIC 0x0703011D -#define OID_TAPI_SET_CALL_PARAMS 0x0703011E -#define OID_TAPI_SET_DEFAULT_MEDIA_DETECTION 0x0703011F -#define OID_TAPI_SET_DEV_CONFIG 0x07030120 -#define OID_TAPI_SET_MEDIA_MODE 0x07030121 -#define OID_TAPI_SET_STATUS_MESSAGES 0x07030122 -// -// ATM Connection Oriented Ndis -// -#define OID_ATM_SUPPORTED_VC_RATES 0x08010101 -#define OID_ATM_SUPPORTED_SERVICE_CATEGORY 0x08010102 -#define OID_ATM_SUPPORTED_AAL_TYPES 0x08010103 -#define OID_ATM_HW_CURRENT_ADDRESS 0x08010104 -#define OID_ATM_MAX_ACTIVE_VCS 0x08010105 -#define OID_ATM_MAX_ACTIVE_VCI_BITS 0x08010106 -#define OID_ATM_MAX_ACTIVE_VPI_BITS 0x08010107 -#define OID_ATM_MAX_AAL0_PACKET_SIZE 0x08010108 -#define OID_ATM_MAX_AAL1_PACKET_SIZE 0x08010109 -#define OID_ATM_MAX_AAL34_PACKET_SIZE 0x0801010A -#define OID_ATM_MAX_AAL5_PACKET_SIZE 0x0801010B -#define OID_ATM_SIGNALING_VPIVCI 0x08010201 -#define OID_ATM_ASSIGNED_VPI 0x08010202 -#define OID_ATM_ACQUIRE_ACCESS_NET_RESOURCES 0x08010203 -#define OID_ATM_RELEASE_ACCESS_NET_RESOURCES 0x08010204 -#define OID_ATM_ILMI_VPIVCI 0x08010205 -#define OID_ATM_DIGITAL_BROADCAST_VPIVCI 0x08010206 -#define OID_ATM_GET_NEAREST_FLOW 0x08010207 -#define OID_ATM_ALIGNMENT_REQUIRED 0x08010208 -// -// ATM specific statistics OIDs. -// -#define OID_ATM_RCV_CELLS_OK 0x08020101 -#define OID_ATM_XMIT_CELLS_OK 0x08020102 -#define OID_ATM_RCV_CELLS_DROPPED 0x08020103 -#define OID_ATM_RCV_INVALID_VPI_VCI 0x08020201 -#define OID_ATM_CELLS_HEC_ERROR 0x08020202 -#define OID_ATM_RCV_REASSEMBLY_ERROR 0x08020203 -// -// PCCA (Wireless) object -// -// -// All WirelessWAN devices must support the following OIDs -// -#define OID_WW_GEN_NETWORK_TYPES_SUPPORTED 0x09010101 -#define OID_WW_GEN_NETWORK_TYPE_IN_USE 0x09010102 -#define OID_WW_GEN_HEADER_FORMATS_SUPPORTED 0x09010103 -#define OID_WW_GEN_HEADER_FORMAT_IN_USE 0x09010104 -#define OID_WW_GEN_INDICATION_REQUEST 0x09010105 -#define OID_WW_GEN_DEVICE_INFO 0x09010106 -#define OID_WW_GEN_OPERATION_MODE 0x09010107 -#define OID_WW_GEN_LOCK_STATUS 0x09010108 -#define OID_WW_GEN_DISABLE_TRANSMITTER 0x09010109 -#define OID_WW_GEN_NETWORK_ID 0x0901010A -#define OID_WW_GEN_PERMANENT_ADDRESS 0x0901010B -#define OID_WW_GEN_CURRENT_ADDRESS 0x0901010C -#define OID_WW_GEN_SUSPEND_DRIVER 0x0901010D -#define OID_WW_GEN_BASESTATION_ID 0x0901010E -#define OID_WW_GEN_CHANNEL_ID 0x0901010F -#define OID_WW_GEN_ENCRYPTION_SUPPORTED 0x09010110 -#define OID_WW_GEN_ENCRYPTION_IN_USE 0x09010111 -#define OID_WW_GEN_ENCRYPTION_STATE 0x09010112 -#define OID_WW_GEN_CHANNEL_QUALITY 0x09010113 -#define OID_WW_GEN_REGISTRATION_STATUS 0x09010114 -#define OID_WW_GEN_RADIO_LINK_SPEED 0x09010115 -#define OID_WW_GEN_LATENCY 0x09010116 -#define OID_WW_GEN_BATTERY_LEVEL 0x09010117 -#define OID_WW_GEN_EXTERNAL_POWER 0x09010118 -// -// Network Dependent OIDs - Mobitex: -// -#define OID_WW_MBX_SUBADDR 0x09050101 -// OID 0x09050102 is reserved and may not be used -#define OID_WW_MBX_FLEXLIST 0x09050103 -#define OID_WW_MBX_GROUPLIST 0x09050104 -#define OID_WW_MBX_TRAFFIC_AREA 0x09050105 -#define OID_WW_MBX_LIVE_DIE 0x09050106 -#define OID_WW_MBX_TEMP_DEFAULTLIST 0x09050107 -// -// Network Dependent OIDs - Pinpoint: -// -#define OID_WW_PIN_LOC_AUTHORIZE 0x09090101 -#define OID_WW_PIN_LAST_LOCATION 0x09090102 -#define OID_WW_PIN_LOC_FIX 0x09090103 -// -// Network Dependent - CDPD: -// -#define OID_WW_CDPD_SPNI 0x090D0101 -#define OID_WW_CDPD_WASI 0x090D0102 -#define OID_WW_CDPD_AREA_COLOR 0x090D0103 -#define OID_WW_CDPD_TX_POWER_LEVEL 0x090D0104 -#define OID_WW_CDPD_EID 0x090D0105 -#define OID_WW_CDPD_HEADER_COMPRESSION 0x090D0106 -#define OID_WW_CDPD_DATA_COMPRESSION 0x090D0107 -#define OID_WW_CDPD_CHANNEL_SELECT 0x090D0108 -#define OID_WW_CDPD_CHANNEL_STATE 0x090D0109 -#define OID_WW_CDPD_NEI 0x090D010A -#define OID_WW_CDPD_NEI_STATE 0x090D010B -#define OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER 0x090D010C -#define OID_WW_CDPD_SLEEP_MODE 0x090D010D -#define OID_WW_CDPD_CIRCUIT_SWITCHED 0x090D010E -#define OID_WW_CDPD_TEI 0x090D010F -#define OID_WW_CDPD_RSSI 0x090D0110 -// -// Network Dependent - Ardis: -// -#define OID_WW_ARD_SNDCP 0x09110101 -#define OID_WW_ARD_TMLY_MSG 0x09110102 -#define OID_WW_ARD_DATAGRAM 0x09110103 -// -// Network Dependent - DataTac: -// -#define OID_WW_TAC_COMPRESSION 0x09150101 -#define OID_WW_TAC_SET_CONFIG 0x09150102 -#define OID_WW_TAC_GET_STATUS 0x09150103 -#define OID_WW_TAC_USER_HEADER 0x09150104 -// -// Network Dependent - Metricom: -// -#define OID_WW_MET_FUNCTION 0x09190101 -// -// IRDA objects -// -#define OID_IRDA_RECEIVING 0x0A010100 -#define OID_IRDA_TURNAROUND_TIME 0x0A010101 -#define OID_IRDA_SUPPORTED_SPEEDS 0x0A010102 -#define OID_IRDA_LINK_SPEED 0x0A010103 -#define OID_IRDA_MEDIA_BUSY 0x0A010104 -#define OID_IRDA_EXTRA_RCV_BOFS 0x0A010200 -#define OID_IRDA_RATE_SNIFF 0x0A010201 -#define OID_IRDA_UNICAST_LIST 0x0A010202 -#define OID_IRDA_MAX_UNICAST_LIST_SIZE 0x0A010203 -#define OID_IRDA_MAX_RECEIVE_WINDOW_SIZE 0x0A010204 -#define OID_IRDA_MAX_SEND_WINDOW_SIZE 0x0A010205 -// -// Medium the Ndis Driver is running on (OID_GEN_MEDIA_SUPPORTED/ -// OID_GEN_MEDIA_IN_USE). -// -typedef enum _NDIS_MEDIUM { - NdisMedium802_3, - NdisMedium802_5, - NdisMediumFddi, - NdisMediumWan, - NdisMediumLocalTalk, - NdisMediumDix, // defined for convenience, not a real medium - NdisMediumArcnetRaw, - NdisMediumArcnet878_2, - NdisMediumAtm, - NdisMediumWirelessWan, - NdisMediumIrda, - NdisMediumMax // Not a real medium, defined as an upper-bound -} NDIS_MEDIUM, *PNDIS_MEDIUM; - -// -// Hardware status codes (OID_GEN_HARDWARE_STATUS). -// -typedef enum _NDIS_HARDWARE_STATUS { - NdisHardwareStatusReady, - NdisHardwareStatusInitializing, - NdisHardwareStatusReset, - NdisHardwareStatusClosing, - NdisHardwareStatusNotReady -} NDIS_HARDWARE_STATUS, *PNDIS_HARDWARE_STATUS; - -// -// this is the type passed in the OID_GEN_GET_TIME_CAPS request -// -typedef struct _GEN_GET_TIME_CAPS { - ULONG Flags; // Bits defined below - - ULONG ClockPrecision; -} GEN_GET_TIME_CAPS, *PGEN_GET_TIME_CAPS; - -#define READABLE_LOCAL_CLOCK 0x000000001 -#define CLOCK_NETWORK_DERIVED 0x000000002 -#define CLOCK_PRECISION 0x000000004 -#define RECEIVE_TIME_INDICATION_CAPABLE 0x000000008 -#define TIMED_SEND_CAPABLE 0x000000010 -#define TIME_STAMP_CAPABLE 0x000000020 -// -// -// this is the type passed in the OID_GEN_GET_NETCARD_TIME request -// -typedef struct _GEN_GET_NETCARD_TIME { - ULONG ReadTime; -} GEN_GET_NETCARD_TIME, *PGEN_GET_NETCARD_TIME; - -// -// Defines the attachment types for FDDI (OID_FDDI_ATTACHMENT_TYPE). -// -typedef enum _NDIS_FDDI_ATTACHMENT_TYPE { - NdisFddiTypeIsolated = 1, - NdisFddiTypeLocalA, - NdisFddiTypeLocalB, - NdisFddiTypeLocalAB, - NdisFddiTypeLocalS, - NdisFddiTypeWrapA, - NdisFddiTypeWrapB, - NdisFddiTypeWrapAB, - NdisFddiTypeWrapS, - NdisFddiTypeCWrapA, - NdisFddiTypeCWrapB, - NdisFddiTypeCWrapS, - NdisFddiTypeThrough -} NDIS_FDDI_ATTACHMENT_TYPE, *PNDIS_FDDI_ATTACHMENT_TYPE; - -// -// Defines the ring management states for FDDI (OID_FDDI_RING_MGT_STATE). -// -typedef enum _NDIS_FDDI_RING_MGT_STATE { - NdisFddiRingIsolated = 1, - NdisFddiRingNonOperational, - NdisFddiRingOperational, - NdisFddiRingDetect, - NdisFddiRingNonOperationalDup, - NdisFddiRingOperationalDup, - NdisFddiRingDirected, - NdisFddiRingTrace -} NDIS_FDDI_RING_MGT_STATE, *PNDIS_FDDI_RING_MGT_STATE; - -// -// Defines the Lconnection state for FDDI (OID_FDDI_LCONNECTION_STATE). -// -typedef enum _NDIS_FDDI_LCONNECTION_STATE { - NdisFddiStateOff = 1, - NdisFddiStateBreak, - NdisFddiStateTrace, - NdisFddiStateConnect, - NdisFddiStateNext, - NdisFddiStateSignal, - NdisFddiStateJoin, - NdisFddiStateVerify, - NdisFddiStateActive, - NdisFddiStateMaintenance -} NDIS_FDDI_LCONNECTION_STATE, *PNDIS_FDDI_LCONNECTION_STATE; - -// -// Defines the medium subtypes for WAN medium (OID_WAN_MEDIUM_SUBTYPE). -// -typedef enum _NDIS_WAN_MEDIUM_SUBTYPE { - NdisWanMediumHub, - NdisWanMediumX_25, - NdisWanMediumIsdn, - NdisWanMediumSerial, - NdisWanMediumFrameRelay, - NdisWanMediumAtm, - NdisWanMediumSonet, - NdisWanMediumSW56K -} NDIS_WAN_MEDIUM_SUBTYPE, *PNDIS_WAN_MEDIUM_SUBTYPE; - -// -// Defines the header format for WAN medium (OID_WAN_HEADER_FORMAT). -// -typedef enum _NDIS_WAN_HEADER_FORMAT { - NdisWanHeaderNative, // src/dest based on subtype, followed by NLPID - NdisWanHeaderEthernet // emulation of ethernet header -} NDIS_WAN_HEADER_FORMAT, *PNDIS_WAN_HEADER_FORMAT; - -// -// Defines the line quality on a WAN line (OID_WAN_QUALITY_OF_SERVICE). -// -typedef enum _NDIS_WAN_QUALITY { - NdisWanRaw, - NdisWanErrorControl, - NdisWanReliable -} NDIS_WAN_QUALITY, *PNDIS_WAN_QUALITY; - -// -// Defines the state of a token-ring adapter (OID_802_5_CURRENT_RING_STATE). -// -typedef enum _NDIS_802_5_RING_STATE { - NdisRingStateOpened = 1, - NdisRingStateClosed, - NdisRingStateOpening, - NdisRingStateClosing, - NdisRingStateOpenFailure, - NdisRingStateRingFailure -} NDIS_802_5_RING_STATE, *PNDIS_802_5_RING_STATE; - -// -// Defines the state of the LAN media -// -typedef enum _NDIS_MEDIA_STATE { - NdisMediaStateConnected, - NdisMediaStateDisconnected -} NDIS_MEDIA_STATE, *PNDIS_MEDIA_STATE; - -// -// The following is set on a per-packet basis as OOB data with NdisClass802_3Priority -// -typedef ULONG Priority_802_3; // 0-7 priority levels -// -// The following structure is used to query OID_GEN_CO_LINK_SPEED and -// OID_GEN_CO_MINIMUM_LINK_SPEED. The first OID will return the current -// link speed of the adapter. The second will return the minimum link speed -// the adapter is capable of. -// - -typedef struct _NDIS_CO_LINK_SPEED { - ULONG Outbound; - ULONG Inbound; -} NDIS_CO_LINK_SPEED, - -*PNDIS_CO_LINK_SPEED; -// -// Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER). -// -#define NDIS_PACKET_TYPE_DIRECTED 0x0001 -#define NDIS_PACKET_TYPE_MULTICAST 0x0002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x0004 -#define NDIS_PACKET_TYPE_BROADCAST 0x0008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x0010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x0020 -#define NDIS_PACKET_TYPE_SMT 0x0040 -#define NDIS_PACKET_TYPE_ALL_LOCAL 0x0080 -#define NDIS_PACKET_TYPE_MAC_FRAME 0x8000 -#define NDIS_PACKET_TYPE_FUNCTIONAL 0x4000 -#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x2000 -#define NDIS_PACKET_TYPE_GROUP 0x1000 -// -// Ndis Token-Ring Ring Status Codes (OID_802_5_CURRENT_RING_STATUS). -// -#define NDIS_RING_SIGNAL_LOSS 0x00008000 -#define NDIS_RING_HARD_ERROR 0x00004000 -#define NDIS_RING_SOFT_ERROR 0x00002000 -#define NDIS_RING_TRANSMIT_BEACON 0x00001000 -#define NDIS_RING_LOBE_WIRE_FAULT 0x00000800 -#define NDIS_RING_AUTO_REMOVAL_ERROR 0x00000400 -#define NDIS_RING_REMOVE_RECEIVED 0x00000200 -#define NDIS_RING_COUNTER_OVERFLOW 0x00000100 -#define NDIS_RING_SINGLE_STATION 0x00000080 -#define NDIS_RING_RING_RECOVERY 0x00000040 -// -// Ndis protocol option bits (OID_GEN_PROTOCOL_OPTIONS). -// -#define NDIS_PROT_OPTION_ESTIMATED_LENGTH 0x00000001 -#define NDIS_PROT_OPTION_NO_LOOPBACK 0x00000002 -#define NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT 0x00000004 -// -// Ndis MAC option bits (OID_GEN_MAC_OPTIONS). -// -#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 -#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 -#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 -#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 -#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 -#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 -#define NDIS_MAC_OPTION_RESERVED 0x80000000 -// -// NDIS MAC option bits for OID_GEN_CO_MAC_OPTIONS. -// -#define NDIS_CO_MAC_OPTION_DYNAMIC_LINK_SPEED 0x00000001 -#ifdef IRDA -// -// The following is set on a per-packet basis as OOB data with NdisClassIrdaPacketInfo -// This is the per-packet info specified on a per-packet basis -// -typedef struct _NDIS_IRDA_PACKET_INFO { - UINT ExtraBOFs; - UINT MinTurnAroundTime; -} NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO; - -#endif -#ifdef WIRELESS_WAN -// -// Wireless WAN structure definitions -// -// -// currently defined Wireless network subtypes -// -typedef enum _NDIS_WW_NETWORK_TYPE { - NdisWWGeneric, - NdisWWMobitex, - NdisWWPinpoint, - NdisWWCDPD, - NdisWWArdis, - NdisWWDataTAC, - NdisWWMetricom, - NdisWWGSM, - NdisWWCDMA, - NdisWWTDMA, - NdisWWAMPS, - NdisWWInmarsat, - NdisWWpACT -} NDIS_WW_NETWORK_TYPE; - -// -// currently defined header formats -// -typedef enum _NDIS_WW_HEADER_FORMAT { - NdisWWDIXEthernetFrames, - NdisWWMPAKFrames, - NdisWWRDLAPFrames, - NdisWWMDC4800Frames -} NDIS_WW_HEADER_FORMAT; - -// -// currently defined encryption types -// -typedef enum _NDIS_WW_ENCRYPTION_TYPE { - NdisWWUnknownEncryption = -1, - NdisWWNoEncryption, - NdisWWDefaultEncryption -} NDIS_WW_ENCRYPTION_TYPE, *PNDIS_WW_ENCRYPTION_TYPE; - -// -// OID_WW_GEN_INDICATION_REQUEST -// -typedef struct _NDIS_WW_INDICATION_REQUEST { - NDIS_OID Oid; // IN - - UINT uIndicationFlag; // IN - - UINT uApplicationToken; // IN OUT - - HANDLE hIndicationHandle; // IN OUT - - INT iPollingInterval; // IN OUT - - NDIS_VAR_DATA_DESC InitialValue; // IN OUT - - NDIS_VAR_DATA_DESC OIDIndicationValue; // OUT - only valid after indication - - NDIS_VAR_DATA_DESC TriggerValue; // IN - -} NDIS_WW_INDICATION_REQUEST, *PNDIS_WW_INDICATION_REQUEST; - -#define OID_INDICATION_REQUEST_ENABLE 0x0000 -#define OID_INDICATION_REQUEST_CANCEL 0x0001 -// -// OID_WW_GEN_DEVICE_INFO -// -typedef struct _WW_DEVICE_INFO { - NDIS_VAR_DATA_DESC Manufacturer; - NDIS_VAR_DATA_DESC ModelNum; - NDIS_VAR_DATA_DESC SWVersionNum; - NDIS_VAR_DATA_DESC SerialNum; -} WW_DEVICE_INFO, *PWW_DEVICE_INFO; - -// -// OID_WW_GEN_OPERATION_MODE -// -typedef INT WW_OPERATION_MODE; // 0 = Normal mode - // 1 = Power saving mode - // -1 = mode unknown -// -// OID_WW_GEN_LOCK_STATUS -// - -typedef INT WW_LOCK_STATUS; // 0 = unlocked - // 1 = locked - // -1 = unknown lock status -// -// OID_WW_GEN_DISABLE_TRANSMITTER -// - -typedef INT WW_DISABLE_TRANSMITTER; // 0 = transmitter enabled - // 1 = transmitter disabled - // -1 = unknown value -// -// OID_WW_GEN_NETWORK_ID -// - -typedef NDIS_VAR_DATA_DESC WW_NETWORK_ID; -// -// OID_WW_GEN_PERMANENT_ADDRESS -// -typedef NDIS_VAR_DATA_DESC WW_PERMANENT_ADDRESS; -// -// OID_WW_GEN_CURRENT_ADDRESS -// -typedef struct _WW_CURRENT_ADDRESS { - NDIS_WW_HEADER_FORMAT Format; - NDIS_VAR_DATA_DESC Address; -} WW_CURRENT_ADDRESS, *PWW_CURRENT_ADDRESS; - -// -// OID_WW_GEN_SUSPEND_DRIVER -// -typedef BOOLEAN WW_SUSPEND_DRIVER; // 0 = driver operational - // 1 = driver suspended -// -// OID_WW_GEN_BASESTATION_ID -// - -typedef NDIS_VAR_DATA_DESC WW_BASESTATION_ID; -// -// OID_WW_GEN_CHANNEL_ID -// -typedef NDIS_VAR_DATA_DESC WW_CHANNEL_ID; -// -// OID_WW_GEN_ENCRYPTION_STATE -// -typedef BOOLEAN WW_ENCRYPTION_STATE; // 0 = if encryption is disabled - // 1 = if encryption is enabled -// -// OID_WW_GEN_CHANNEL_QUALITY -// - -typedef INT WW_CHANNEL_QUALITY; // 0 = Not in network contact, - // 1-100 = Quality of Channel (100 is highest quality). - // -1 = channel quality is unknown -// -// OID_WW_GEN_REGISTRATION_STATUS -// - -typedef INT WW_REGISTRATION_STATUS; // 0 = Registration denied - // 1 = Registration pending - // 2 = Registered - // -1 = unknown registration status -// -// OID_WW_GEN_RADIO_LINK_SPEED -// - -typedef UINT WW_RADIO_LINK_SPEED; // Bits per second. -// -// OID_WW_GEN_LATENCY -// - -typedef UINT WW_LATENCY; // milliseconds -// -// OID_WW_GEN_BATTERY_LEVEL -// - -typedef INT WW_BATTERY_LEVEL; // 0-100 = battery level in percentage - // (100=fully charged) - // -1 = unknown battery level. -// -// OID_WW_GEN_EXTERNAL_POWER -// - -typedef INT WW_EXTERNAL_POWER; // 0 = no external power connected - // 1 = external power connected - // -1 = unknown -// -// OID_WW_MET_FUNCTION -// - -typedef NDIS_VAR_DATA_DESC WW_MET_FUNCTION; -// -// OID_WW_TAC_COMPRESSION -// -typedef BOOLEAN WW_TAC_COMPRESSION; // Determines whether or not network level compression - // is being used. -// -// OID_WW_TAC_SET_CONFIG -// - -typedef struct _WW_TAC_SETCONFIG { - NDIS_VAR_DATA_DESC RCV_MODE; - NDIS_VAR_DATA_DESC TX_CONTROL; - NDIS_VAR_DATA_DESC RX_CONTROL; - NDIS_VAR_DATA_DESC FLOW_CONTROL; - NDIS_VAR_DATA_DESC RESET_CNF; - NDIS_VAR_DATA_DESC READ_CNF; -} WW_TAC_SETCONFIG, *PWW_TAC_SETCONFIG; - -// -// OID_WW_TAC_GET_STATUS -// -typedef struct _WW_TAC_GETSTATUS { - BOOLEAN Action; // Set = Execute command. - - NDIS_VAR_DATA_DESC Command; - NDIS_VAR_DATA_DESC Option; - NDIS_VAR_DATA_DESC Response; // The response to the requested command - // - max. length of string is 256 octets. - -} WW_TAC_GETSTATUS, *PWW_TAC_GETSTATUS; - -// -// OID_WW_TAC_USER_HEADER -// -typedef NDIS_VAR_DATA_DESC WW_TAC_USERHEADER; // This will hold the user header - Max. 64 octets. -// -// OID_WW_ARD_SNDCP -// - -typedef struct _WW_ARD_SNDCP { - NDIS_VAR_DATA_DESC Version; // The version of SNDCP protocol supported. - - INT BlockSize; // The block size used for SNDCP - - INT Window; // The window size used in SNDCP - -} WW_ARD_SNDCP, *PWW_ARD_SNDCP; - -// -// OID_WW_ARD_TMLY_MSG -// -typedef BOOLEAN WW_ARD_CHANNEL_STATUS; // The current status of the inbound RF Channel. -// -// OID_WW_ARD_DATAGRAM -// - -typedef struct _WW_ARD_DATAGRAM { - BOOLEAN LoadLevel; // Byte that contains the load level info. - - INT SessionTime; // Datagram session time remaining. - - NDIS_VAR_DATA_DESC HostAddr; // Host address. - - NDIS_VAR_DATA_DESC THostAddr; // Test host address. - -} WW_ARD_DATAGRAM, *PWW_ARD_DATAGRAM; - -// -// OID_WW_CDPD_SPNI -// -typedef struct _WW_CDPD_SPNI { - UINT SPNI[10]; //10 16-bit service provider network IDs - - INT OperatingMode; // 0 = ignore SPNI, - // 1 = require SPNI from list, - // 2 = prefer SPNI from list. - // 3 = exclude SPNI from list. - -} WW_CDPD_SPNI, *PWW_CDPD_SPNI; - -// -// OID_WW_CDPD_WASI -// -typedef struct _WW_CDPD_WIDE_AREA_SERVICE_ID { - UINT WASI[10]; //10 16-bit wide area service IDs - - INT OperatingMode; // 0 = ignore WASI, - // 1 = Require WASI from list, - // 2 = prefer WASI from list - // 3 = exclude WASI from list. - -} WW_CDPD_WIDE_AREA_SERVICE_ID, *PWW_CDPD_WIDE_AREA_SERVICE_ID; - -// -// OID_WW_CDPD_AREA_COLOR -// -typedef INT WW_CDPD_AREA_COLOR; -// -// OID_WW_CDPD_TX_POWER_LEVEL -// -typedef UINT WW_CDPD_TX_POWER_LEVEL; -// -// OID_WW_CDPD_EID -// -typedef NDIS_VAR_DATA_DESC WW_CDPD_EID; -// -// OID_WW_CDPD_HEADER_COMPRESSION -// -typedef INT WW_CDPD_HEADER_COMPRESSION; // 0 = no header compression, - // 1 = always compress headers, - // 2 = compress headers if MD-IS does - // -1 = unknown -// -// OID_WW_CDPD_DATA_COMPRESSION -// - -typedef INT WW_CDPD_DATA_COMPRESSION; // 0 = no data compression, - // 1 = data compression enabled - // -1 = unknown -// -// OID_WW_CDPD_CHANNEL_SELECT -// - -typedef struct _WW_CDPD_CHANNEL_SELECT { - UINT ChannelID; // channel number - - UINT fixedDuration; // duration in seconds - -} WW_CDPD_CHANNEL_SELECT, *PWW_CDPD_CHANNEL_SELECT; - -// -// OID_WW_CDPD_CHANNEL_STATE -// -typedef enum _WW_CDPD_CHANNEL_STATE { - CDPDChannelNotAvail, - CDPDChannelScanning, - CDPDChannelInitAcquired, - CDPDChannelAcquired, - CDPDChannelSleeping, - CDPDChannelWaking, - CDPDChannelCSDialing, - CDPDChannelCSRedial, - CDPDChannelCSAnswering, - CDPDChannelCSConnected, - CDPDChannelCSSuspended -} WW_CDPD_CHANNEL_STATE, *PWW_CDPD_CHANNEL_STATE; - -// -// OID_WW_CDPD_NEI -// -typedef enum _WW_CDPD_NEI_FORMAT { - CDPDNeiIPv4, - CDPDNeiCLNP, - CDPDNeiIPv6 -} WW_CDPD_NEI_FORMAT, *PWW_CDPD_NEI_FORMAT; -typedef enum _WW_CDPD_NEI_TYPE { - CDPDNeiIndividual, - CDPDNeiMulticast, - CDPDNeiBroadcast -} WW_CDPD_NEI_TYPE; -typedef struct _WW_CDPD_NEI { - UINT uNeiIndex; - WW_CDPD_NEI_FORMAT NeiFormat; - WW_CDPD_NEI_TYPE NeiType; - WORD NeiGmid; // group member identifier, only - // meaningful if NeiType == - // CDPDNeiMulticast - - NDIS_VAR_DATA_DESC NeiAddress; -} WW_CDPD_NEI; - -// -// OID_WW_CDPD_NEI_STATE -// -typedef enum _WW_CDPD_NEI_STATE { - CDPDUnknown, - CDPDRegistered, - CDPDDeregistered -} WW_CDPD_NEI_STATE, *PWW_CDPD_NEI_STATE; -typedef enum _WW_CDPD_NEI_SUB_STATE { - CDPDPending, // Registration pending - CDPDNoReason, // Registration denied - no reason given - CDPDMDISNotCapable, // Registration denied - MD-IS not capable of - // handling M-ES at this time - CDPDNEINotAuthorized, // Registration denied - NEI is not authorized to - // use this subnetwork - CDPDInsufficientAuth, // Registration denied - M-ES gave insufficient - // authentication credentials - CDPDUnsupportedAuth, // Registration denied - M-ES gave unsupported - // authentication credentials - CDPDUsageExceeded, // Registration denied - NEI has exceeded usage - // limitations - CDPDDeniedThisNetwork // Registration denied on this network, service - // may be obtained on alternate Service Provider - // network -} WW_CDPD_NEI_SUB_STATE; -typedef struct _WW_CDPD_NEI_REG_STATE { - UINT uNeiIndex; - WW_CDPD_NEI_STATE NeiState; - WW_CDPD_NEI_SUB_STATE NeiSubState; -} WW_CDPD_NEI_REG_STATE, *PWW_CDPD_NEI_REG_STATE; - -// -// OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER -// -typedef struct _WW_CDPD_SERVICE_PROVIDER_ID { - UINT SPI[10]; //10 16-bit service provider IDs - - INT OperatingMode; // 0 = ignore SPI, - // 1 = require SPI from list, - // 2 = prefer SPI from list. - // 3 = exclude SPI from list. - -} WW_CDPD_SERVICE_PROVIDER_ID, *PWW_CDPD_SERVICE_PROVIDER_ID; - -// -// OID_WW_CDPD_SLEEP_MODE -// -typedef INT WW_CDPD_SLEEP_MODE; -// -// OID_WW_CDPD_TEI -// -typedef ULONG WW_CDPD_TEI; -// -// OID_WW_CDPD_CIRCUIT_SWITCHED -// -typedef struct _WW_CDPD_CIRCUIT_SWITCHED { - INT service_preference; // -1 = unknown, - // 0 = always use packet switched CDPD, - // 1 = always use CS CDPD via AMPS, - // 2 = always use CS CDPD via PSTN, - // 3 = use circuit switched via AMPS only - // when packet switched is not available. - // 4 = use packet switched only when circuit - // switched via AMPS is not available. - // 5 = device manuf. defined service - // preference. - // 6 = device manuf. defined service - // preference. - - INT service_status; // -1 = unknown, - // 0 = packet switched CDPD, - // 1 = circuit switched CDPD via AMPS, - // 2 = circuit switched CDPD via PSTN. - - INT connect_rate; // CS connection bit rate (bits per second). - // 0 = no active connection, - // -1 = unknown - // Dial code last used to dial. - - NDIS_VAR_DATA_DESC dial_code[20]; - - UINT sid; // Current AMPS system ID - - INT a_b_side_selection; // -1 = unknown, - // 0 = no AMPS service - // 1 = AMPS "A" side channels selected - // 2 = AMPS "B" side channels selected - - INT AMPS_channel; // -1= unknown - // 0 = no AMPS service. - // 1-1023 = AMPS channel number in use - - UINT action; // 0 = no action - // 1 = suspend (hangup) - // 2 = dial - - // Default dial code for CS CDPD service - // encoded as specified in the CS CDPD - // implementor guidelines. - NDIS_VAR_DATA_DESC default_dial[20]; - - // Number for the CS CDPD network to call - // back the mobile, encoded as specified in - // the CS CDPD implementor guidelines. - NDIS_VAR_DATA_DESC call_back[20]; - - UINT sid_list[10]; // List of 10 16-bit preferred AMPS - // system IDs for CS CDPD. - - UINT inactivity_timer; // Wait time after last data before dropping - // call. - // 0-65535 = inactivity time limit (seconds). - - UINT receive_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT conn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT reconn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT disconn_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT NEI_reg_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT reconn_retry_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT link_reset_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT link_reset_ack_timer; // secs. per CS-CDPD Implementor Guidelines. - - UINT n401_retry_limit; // per CS-CDPD Implementor Guidelines. - - UINT n402_retry_limit; // per CS-CDPD Implementor Guidelines. - - UINT n404_retry_limit; // per CS-CDPD Implementor Guidelines. - - UINT n405_retry_limit; // per CS-CDPD Implementor Guidelines. - -} WW_CDPD_CIRCUIT_SWITCHED, *WW_PCDPD_CIRCUIT_SWITCHED; -typedef UINT WW_CDPD_RSSI; -// -// OID_WW_PIN_LOC_AUTHORIZE -// -typedef INT WW_PIN_AUTHORIZED; // 0 = unauthorized - // 1 = authorized - // -1 = unknown -// -// OID_WW_PIN_LAST_LOCATION -// OID_WW_PIN_LOC_FIX -// - -typedef struct _WW_PIN_LOCATION { - INT Latitude; // Latitude in hundredths of a second - - INT Longitude; // Longitude in hundredths of a second - - INT Altitude; // Altitude in feet - - INT FixTime; // Time of the location fix, since midnight, local time (of the - // current day), in tenths of a second - - INT NetTime; // Current local network time of the current day, since midnight, - // in tenths of a second - - INT LocQuality; // 0-100 = location quality - - INT LatReg; // Latitude registration offset, in hundredths of a second - - INT LongReg; // Longitude registration offset, in hundredths of a second - - INT GMTOffset; // Offset in minutes of the local time zone from GMT - -} WW_PIN_LOCATION, *PWW_PIN_LOCATION; - -// -// The following is set on a per-packet basis as OOB data with NdisClassWirelessWanMbxMailbox -// -typedef ULONG WW_MBX_MAILBOX_FLAG; // 1 = set mailbox flag, 0 = do not set mailbox flag -// -// OID_WW_MBX_SUBADDR -// - -typedef struct _WW_MBX_PMAN { - BOOLEAN ACTION; // 0 = Login PMAN, 1 = Logout PMAN - - UINT MAN; - UCHAR PASSWORD[8]; // Password should be null for Logout and indications. - // Maximum length of password is 8 chars. - -} WW_MBX_PMAN, *PWW_MBX_PMAN; - -// -// OID_WW_MBX_FLEXLIST -// -typedef struct _WW_MBX_FLEXLIST { - INT count; // Number of MAN entries used. - // -1=unknown. - - UINT MAN[7]; // List of MANs. - -} WW_MBX_FLEXLIST; - -// -// OID_WW_MBX_GROUPLIST -// -typedef struct _WW_MBX_GROUPLIST { - INT count; // Number of MAN entries used. - // -1=unknown. - - UINT MAN[15]; // List of MANs. - -} WW_MBX_GROUPLIST; - -// -// OID_WW_MBX_TRAFFIC_AREA -// -typedef enum _WW_MBX_TRAFFIC_AREA { - unknown_traffic_area, // The driver has no information about the current traffic area. - in_traffic_area, // Mobile unit has entered a subscribed traffic area. - in_auth_traffic_area, // Mobile unit is outside traffic area but is authorized. - unauth_traffic_area // Mobile unit is outside traffic area but is un-authorized. -} WW_MBX_TRAFFIC_AREA; - -// -// OID_WW_MBX_LIVE_DIE -// -typedef INT WW_MBX_LIVE_DIE; // 0 = DIE last received - // 1 = LIVE last received - // -1 = unknown -// -// OID_WW_MBX_TEMP_DEFAULTLIST -// - -typedef struct _WW_MBX_CHANNEL_PAIR { - UINT Mobile_Tx; - UINT Mobile_Rx; -} WW_MBX_CHANNEL_PAIR, *PWW_MBX_CHANNEL_PAIR; -typedef struct _WW_MBX_TEMPDEFAULTLIST { - UINT Length; - WW_MBX_CHANNEL_PAIR ChannelPair[1]; -} WW_MBX_TEMPDEFAULTLIST, *WW_PMBX_TEMPDEFAULTLIST; - -#endif // WIRELESS_WAN -#endif // _NTDDNDIS_ diff --git a/lib/packet/include/packet32.h b/lib/packet/include/packet32.h index bcb167a..862cc37 100644 --- a/lib/packet/include/packet32.h +++ b/lib/packet/include/packet32.h @@ -34,7 +34,6 @@ #define __PACKET32 #include -#include "devioctl.h" // Working modes #define PACKET_MODE_CAPT 0x0 ///< Capture mode diff --git a/lib/packet/makefile b/lib/packet/makefile index 3682663..09a4748 100644 --- a/lib/packet/makefile +++ b/lib/packet/makefile @@ -16,8 +16,6 @@ TARGET_OBJECTS = \ Packet32.o \ trace.o -TARGET_CLEAN = $(TARGET_OBJECTS) - include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk diff --git a/lib/psapi/misc/win32.c b/lib/psapi/misc/win32.c index edb9a0c..c19bdc3 100644 --- a/lib/psapi/misc/win32.c +++ b/lib/psapi/misc/win32.c @@ -165,6 +165,15 @@ NTSTATUS STDCALL EnumProcessesCallback } /* exported interface */ +/* + @brief Enumerate the process identifiers of the currently active processes + + @param lpidProcess Array that receives the list of process identifiers + @param cb Size of the @p lpidProcess array, in bytes + @param lpcbNeeded Number of bytes returned in the @p lpidProcess array + + @return [standard] + */ BOOL STDCALL EnumProcesses ( DWORD *lpidProcess, diff --git a/lib/secur32/.cvsignore b/lib/secur32/.cvsignore index 5cd856a..7774f30 100644 --- a/lib/secur32/.cvsignore +++ b/lib/secur32/.cvsignore @@ -1,3 +1,5 @@ secur32.dll secur32.nostrip.dll secur32.coff +secur32.sym +*.o diff --git a/lib/secur32/Makefile b/lib/secur32/Makefile index b7ae93d..dbdfebb 100644 --- a/lib/secur32/Makefile +++ b/lib/secur32/Makefile @@ -11,7 +11,14 @@ TARGET_BASE = 0x10000000 TARGET_SDKLIBS = ntdll.a -TARGET_CFLAGS = -I./include -D__SECUR32__ +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -D__SECUR32__ + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_OBJECTS = lsa.o dllmain.o diff --git a/lib/secur32/dllmain.c b/lib/secur32/dllmain.c index b52cd67..5913432 100644 --- a/lib/secur32/dllmain.c +++ b/lib/secur32/dllmain.c @@ -24,7 +24,7 @@ WINBOOL STDCALL DllMain(HINSTANCE hInstance, ULONG Reason, PVOID Reserved) switch (Reason) { case DLL_PROCESS_ATTACH: - Secur32Heap = RtlCreateHeap(0, NULL, 4096, 0, NULL, NULL); + Secur32Heap = RtlCreateHeap(0, NULL, 0, 4096, NULL, NULL); if (Secur32Heap == 0) { return(FALSE); diff --git a/lib/shell32/control/.cvsignore b/lib/shell32/control/.cvsignore new file mode 100644 index 0000000..33df5bf --- /dev/null +++ b/lib/shell32/control/.cvsignore @@ -0,0 +1,6 @@ +control.exe +control.coff +control.sym +control.dsp +control.dsw +*.o diff --git a/lib/shell32/control/makefile b/lib/shell32/control/makefile new file mode 100644 index 0000000..f25a88f --- /dev/null +++ b/lib/shell32/control/makefile @@ -0,0 +1,64 @@ +# +# ReactOS control +# +# Makefile +# +# Copyright (C) 2002 Robert Dickenson +# +# 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. +# + +PATH_TO_TOP = .. + +TARGET = control + +BASE_CFLAGS = -DGCC -D_WIN32_IE=0x0400 -DUNICODE -D_UNICODE + +RCFLAGS = -DGCC -D_WIN32_IE=0x0400 + + +OBJS = framewnd.o \ + listview.o \ + main.o + +LIBS = -lgdi32 -luser32 -lkernel32 -lcomctl32 + +all: $(TARGET).exe + +$(TARGET).res: $(TARGET).rc + +$(TARGET).exe: $(OBJS) $(TARGET).coff + $(CC) -Wl,--subsystem,windows -o $(TARGET).exe $(OBJS) $(TARGET).coff $(LIBS) + $(NM) --numeric-sort $(TARGET).exe > $(TARGET).sym + + +main.h: resource.h + +main.o: main.c main.h framewnd.h + +framewnd.o: framewnd.c framewnd.h listview.h main.h + +listview.o: listview.c listview.h main.h + +about.o: about.c about.h main.h + + +clean: + - $(RM) $(OBJS) + - $(RM) $(TARGET).exe + - $(RM) $(TARGET).sym + - $(RM) $(TARGET).coff + +include $(PATH_TO_TOP)/rules.mak diff --git a/lib/shell32/misc/stubs.c b/lib/shell32/misc/stubs.c index 461e363..1f2f057 100644 --- a/lib/shell32/misc/stubs.c +++ b/lib/shell32/misc/stubs.c @@ -44,6 +44,8 @@ #ifdef __GNUC__ void* _alloca(size_t); +#else +#define __FUNCTION__ "unknown" #endif #define NO_SHLWAPI_STREAM @@ -99,6 +101,7 @@ typedef struct _browseinfo { } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; +#define DbgPrint(a,b,c,d) #undef DragQueryFile #undef ShellExecute diff --git a/lib/user32/Makefile b/lib/user32/Makefile index 8bf5b11..3769634 100644 --- a/lib/user32/Makefile +++ b/lib/user32/Makefile @@ -10,11 +10,18 @@ TARGET_BASE = 0x77e70000 TARGET_SDKLIBS = ntdll.a kernel32.a gdi32.a -TARGET_CFLAGS = -I./include -DUNICODE -Wall -Werror +TARGET_CFLAGS = \ + -I./include \ + -DUNICODE \ + -Wall \ + -Werror \ + -fno-builtin + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_OBJECTS = $(TARGET_NAME).o -TARGET_CLEAN = misc/*.o windows/*.o +TARGET_CLEAN = controls/*.o misc/*.o windows/*.o include $(PATH_TO_TOP)/rules.mak diff --git a/lib/user32/controls/scrollbar.c b/lib/user32/controls/scrollbar.c index 45caa32..393c56c 100644 --- a/lib/user32/controls/scrollbar.c +++ b/lib/user32/controls/scrollbar.c @@ -1,30 +1,14 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ /* $Id$ * - * PROJECT: ReactOS user32.dll - * FILE: lib/user32/controls/scrollbar.c - * PURPOSE: Scroll bar - * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 09-05-2001 CSH Created + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Windows + * FILE: subsys/win32k/ntuser/window.c + * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISION HISTORY: + * 06-06-2001 CSH Created */ +/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/ @@ -32,72 +16,371 @@ #include #include +/* GLOBAL VARIABLES **********************************************************/ +/* +static HBITMAP hUpArrow; +static HBITMAP hDnArrow; +static HBITMAP hLfArrow; +static HBITMAP hRgArrow; +static HBITMAP hUpArrowD; +static HBITMAP hDnArrowD; +static HBITMAP hLfArrowD; +static HBITMAP hRgArrowD; +static HBITMAP hUpArrowI; +static HBITMAP hDnArrowI; +static HBITMAP hLfArrowI; +static HBITMAP hRgArrowI; +*/ +#define TOP_ARROW(flags,pressed) \ + (((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow)) +#define BOTTOM_ARROW(flags,pressed) \ + (((flags)&ESB_DISABLE_DOWN) ? hDnArrowI : ((pressed) ? hDnArrowD:hDnArrow)) +#define LEFT_ARROW(flags,pressed) \ + (((flags)&ESB_DISABLE_LEFT) ? hLfArrowI : ((pressed) ? hLfArrowD:hLfArrow)) +#define RIGHT_ARROW(flags,pressed) \ + (((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow)) + +#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */ +#define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */ +#define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */ +#define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */ +#define SCROLL_TIMER 0 /* Scroll timer id */ + + /* What to do after SCROLL_SetScrollInfo() */ +#define SA_SSI_HIDE 0x0001 +#define SA_SSI_SHOW 0x0002 +#define SA_SSI_REFRESH 0x0004 +#define SA_SSI_REPAINT_ARROWS 0x0008 + + /* Scroll-bar hit testing */ +enum SCROLL_HITTEST +{ + SCROLL_NOWHERE, /* Outside the scroll bar */ + SCROLL_TOP_ARROW, /* Top or left arrow */ + SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */ + SCROLL_THUMB, /* Thumb rectangle */ + SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */ + SCROLL_BOTTOM_ARROW /* Bottom or right arrow */ +}; + +static BOOL SCROLL_MovingThumb = FALSE; /* Is the moving thumb being displayed? */ + +/* Thumb-tracking info */ +static HWND SCROLL_TrackingWin = 0; +static INT SCROLL_TrackingBar = 0; +static INT SCROLL_TrackingPos = 0; +/* static INT SCROLL_TrackingVal = 0; */ +static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */ +static BOOL SCROLL_trackVertical; + /* FUNCTIONS *****************************************************************/ +HBRUSH DefWndControlColor (HDC hDC, UINT ctlType); +HPEN STDCALL GetSysColorPen (int nIndex); + + + WINBOOL STDCALL -GetScrollBarInfo(HWND hwnd, - LONG idObject, - PSCROLLBARINFO psbi) +GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi) { - return FALSE; + int ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi); + + return ret; +} + +/* Ported from WINE20020904 */ +/* Draw the scroll bar interior (everything except the arrows). */ +static void +SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, INT arrowSize, PSCROLLBARINFO psbi) +{ + INT thumbSize = psbi->xyThumbBottom - psbi->xyThumbTop; + HPEN hSavePen; + HBRUSH hSaveBrush, hBrush; + BOOLEAN top_selected = FALSE, bottom_selected = FALSE; +DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); + if(psbi->rgstate[2] & STATE_SYSTEM_PRESSED) + { + top_selected = TRUE; + } + if(psbi->rgstate[4] & STATE_SYSTEM_PRESSED) + { + bottom_selected = TRUE; + } + + /* Only scrollbar controls send WM_CTLCOLORSCROLLBAR. + * The window-owned scrollbars need to call DefWndControlColor + * to correctly setup default scrollbar colors + */ + if (nBar == SB_CTL) + { + hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, + (WPARAM) hdc, (LPARAM) hwnd); + } + else + { +/* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME */ /* DefWndControlColor */ + hBrush = GetSysColorBrush(COLOR_SCROLLBAR); + } + + hSavePen = SelectObject (hdc, GetSysColorPen (COLOR_WINDOWFRAME)); + hSaveBrush = SelectObject (hdc, hBrush); + + /* Calculate the scroll rectangle */ + if (nBar == SB_VERT) + { + psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; + psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + } + else if (nBar == SB_HORZ) + { + psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; + psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + } + + /* Draw the scroll rectangles and thumb */ + if (!psbi->dxyLineButton) /* No thumb to draw */ + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + PATCOPY); + + /* cleanup and return */ + SelectObject (hdc, hSavePen); + SelectObject (hdc, hSaveBrush); + return; + } + + if (nBar == SB_VERT) + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), + top_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top + thumbSize, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize, + bottom_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize; + } + else if (nBar == SB_HORZ) + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + top_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + PatBlt (hdc, + psbi->rcScrollBar.left + thumbSize, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + bottom_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize; + } + + /* Draw the thumb */ + DrawEdge (hdc, &psbi->rcScrollBar, EDGE_RAISED, BF_RECT | BF_MIDDLE); + + /* cleanup */ + SelectObject (hdc, hSavePen); + SelectObject (hdc, hSaveBrush); +} + +/* Ported from WINE20020904 */ +static void +SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumbSize, PSCROLLBARINFO psbi) +{ + INT pos = SCROLL_TrackingPos; + INT max_size; + + if (nBar == SB_VERT) + max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top; + else if (nBar == SB_HORZ) + max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left; + + max_size -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) + thumbSize; + + if (pos < (arrowSize - SCROLL_ARROW_THUMB_OVERLAP)) + pos = (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + else if (pos > max_size) + pos = max_size; + + SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, arrowSize, psbi); + + SCROLL_MovingThumb = !SCROLL_MovingThumb; +} + +/* Ported from WINE20020904 */ +/* Draw the scroll bar arrows. */ +static void +SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info, + RECT * rect, INT arrowSize, int nBar, + BOOL top_pressed, BOOL bottom_pressed) +{ + RECT r; + int scrollDirFlag1, scrollDirFlag2; + + if (nBar == SB_VERT) + { + scrollDirFlag1 = DFCS_SCROLLUP; + scrollDirFlag2 = DFCS_SCROLLDOWN; + } + else if (nBar == SB_HORZ) + { + scrollDirFlag1 = DFCS_SCROLLLEFT; + scrollDirFlag2 = DFCS_SCROLLRIGHT; + } + + r = *rect; + if (nBar == SB_VERT) + r.bottom = r.top + arrowSize; + else if (nBar == SB_HORZ) + r.right = r.left + arrowSize; + + DrawFrameControl (hdc, &r, DFC_SCROLL, + scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */ + ); + r = *rect; + if (nBar == SB_VERT) + r.top = r.bottom - arrowSize; + else if (nBar == SB_HORZ) + r.left = r.right - arrowSize; + DrawFrameControl (hdc, &r, DFC_SCROLL, + scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */ + ); +} + +/* Ported from WINE20020904 */ +/* Redraw the whole scrollbar. */ +void +SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, + BOOL arrows, BOOL interior) +{ + INT arrowSize = 0; + INT thumbSize; + SCROLLBARINFO info; + BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb; + + info.cbSize = sizeof(SCROLLBARINFO); + GetScrollBarInfo (hwnd, nBar, &info); + + thumbSize = info.xyThumbBottom - info.xyThumbTop; + + if (nBar == SB_HORZ) + { + arrowSize = GetSystemMetrics(SM_CYHSCROLL); + } else + if (nBar == SB_VERT) + { + arrowSize = GetSystemMetrics(SM_CXVSCROLL); + } + + if (IsRectEmpty (&(info.rcScrollBar))) goto END; + + if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) + { + SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), nBar, arrowSize, thumbSize, &info); + } + + /* Draw the arrows */ + if (arrows && arrowSize) + { + if (SCROLL_trackVertical == TRUE /* && GetCapture () == hwnd */) + { + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, + (SCROLL_trackHitTest == SCROLL_TOP_ARROW), + (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW)); + } + else + { + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, FALSE, FALSE); + } + } + + if (interior) + { + SCROLL_DrawInterior (hwnd, hdc, nBar, arrowSize, &info); + } + + if (Save_SCROLL_MovingThumb && + (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) + SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, nBar, arrowSize, thumbSize, &info); + /* if scroll bar has focus, reposition the caret */ + +/* if (hwnd == GetFocus () && (nBar == SB_CTL)) + { + if (nBar == SB_HORZ) + { + SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1); + } + else if (nBAR == SB_VERT) + { + SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1); + } + } */ +END:; +/* WIN_ReleaseWndPtr(wndPtr); */ } WINBOOL STDCALL -GetScrollInfo(HWND hwnd, - int fnBar, - LPSCROLLINFO lpsi) +GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi) { + UNIMPLEMENTED; return FALSE; } int STDCALL -GetScrollPos(HWND hWnd, - int nBar) +GetScrollPos (HWND hWnd, int nBar) { + UNIMPLEMENTED; return 0; } WINBOOL STDCALL -GetScrollRange(HWND hWnd, - int nBar, - LPINT lpMinPos, - LPINT lpMaxPos) +GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) { + UNIMPLEMENTED; return FALSE; } int STDCALL -SetScrollInfo(HWND hwnd, - int fnBar, - LPCSCROLLINFO lpsi, - WINBOOL fRedraw) +SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw) { + UNIMPLEMENTED; return 0; } int STDCALL -SetScrollPos(HWND hWnd, - int nBar, - int nPos, - WINBOOL bRedraw) +SetScrollPos (HWND hWnd, int nBar, int nPos, WINBOOL bRedraw) { + UNIMPLEMENTED; return 0; } WINBOOL STDCALL -SetScrollRange(HWND hWnd, - int nBar, - int nMinPos, - int nMaxPos, - WINBOOL bRedraw) +SetScrollRange (HWND hWnd, + int nBar, int nMinPos, int nMaxPos, WINBOOL bRedraw) { + UNIMPLEMENTED; return FALSE; } +/* Ported from WINE20020904 */ WINBOOL STDCALL -ShowScrollBar(HWND hWnd, - int wBar, - WINBOOL bShow) +ShowScrollBar (HWND hWnd, int wBar, WINBOOL bShow) { - return FALSE; + NtUserShowScrollBar (hWnd, wBar, bShow); + return TRUE; } diff --git a/lib/user32/misc/resources.c b/lib/user32/misc/resources.c index 47e5e54..0e35d36 100644 --- a/lib/user32/misc/resources.c +++ b/lib/user32/misc/resources.c @@ -3,57 +3,189 @@ #include #include -int -STDCALL -LoadStringA( HINSTANCE hInstance, - UINT uID, - LPSTR lpBuffer, - int nBufferMax) +BOOL STDCALL _InternalLoadString +( + HINSTANCE hInstance, + UINT uID, + PUNICODE_STRING pwstrDest +) { - HRSRC rsc; - PBYTE ptr; - int len; - int count, dest = uID % 16; - PWSTR pwstr; - UNICODE_STRING UString; - ANSI_STRING AString; - NTSTATUS Status; - - rsc = FindResource( (HMODULE)hInstance, - MAKEINTRESOURCE( (uID / 16) + 1 ), - RT_STRING ); - if( rsc == NULL ) - return 0; - // get pointer to string table - ptr = (PBYTE)LoadResource( (HMODULE)hInstance, rsc ); - if( ptr == NULL ) - return 0; - for( count = 0; count <= dest; count++ ) - { - // walk each of the 16 string slots in the string table - len = (*(USHORT *)ptr) * 2; // length is in unicode chars, convert to bytes - ptr += 2; // first 2 bytes are length, string follows - pwstr = (PWSTR)ptr; - ptr += len; - } - if( !len ) - return 0; // zero means no string is there - // convert unitocde to ansi, and copy string to caller buffer - UString.Length = UString.MaximumLength = len; - UString.Buffer = pwstr; - memset( &AString, 0, sizeof AString ); - Status = RtlUnicodeStringToAnsiString( &AString, &UString, TRUE ); - if( !NT_SUCCESS( Status ) ) - { - SetLastErrorByStatus( Status ); - return 0; - } - nBufferMax--; // save room for the null - if( nBufferMax > AString.Length ) - nBufferMax = AString.Length; - memcpy( lpBuffer, AString.Buffer, nBufferMax ); - lpBuffer[nBufferMax] = 0; - RtlFreeAnsiString( &AString ); - return nBufferMax; + HRSRC hrsStringTable; + PWCHAR pStringTable; + unsigned i; + unsigned l = uID % 16; /* (1) */ + + /* parameter validation */ + if(IsBadWritePtr(pwstrDest, sizeof(UNICODE_STRING))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* + find the string table. String tables are created by grouping, 16 by 16, string + resources whose identifiers, divided by 16, have the same integer quotient. + Holes in the numbering are filled with zero-length strings. String table ids + (actual resource ids) start from 1. See (1) and (2) + */ + /* TODO: some sort of cache, here, would be great */ + hrsStringTable = FindResource + ( + (HMODULE)hInstance, + MAKEINTRESOURCE((uID / 16) + 1), /* (2) */ + RT_STRING + ); + + /* failure */ + if(hrsStringTable == NULL) return FALSE; + + /* load the string table into memory */ + pStringTable = LoadResource((HMODULE)hInstance, hrsStringTable); + + /* failure */ + if(pStringTable == NULL) return FALSE; + + /* + string tables are packed Unicode Pascal strings. The first WCHAR contains the + length, in characters, of the current string. Zero-length strings, if any, are + placeholders for unused slots, and should therefore be considered non-present. + See also (3). Here, we walk all the strings before that of interest + */ + for(i = 0; i < l; ++ i) + { + /* skip the length and the current string */ + pStringTable += 1 + (*pStringTable); + } + + /* we've reached the string of interest */ + if((*pStringTable) == 0) + { + /* the string is empty (unallocated) */ + SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + return FALSE; /* 3 */ + } + + /* string length */ + pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable); + + /* string */ + pwstrDest->Buffer = pStringTable + 1; + + /* success */ + return TRUE; +} + +int STDCALL LoadStringA +( + HINSTANCE hInstance, + UINT uID, + LPSTR lpBuffer, + int nBufferMax +) +{ + UNICODE_STRING wstrResStr; + ANSI_STRING strBuf; + NTSTATUS nErrCode; + + /* parameter validation */ + if + ( + (nBufferMax < 1) || + (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0]))) + ) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* get the UNICODE_STRING descriptor of the in-memory image of the string */ + if(!_InternalLoadString(hInstance, uID, &wstrResStr)) + /* failure */ + return 0; + + /* + convert the string. The Unicode string may be in UTF-16 (multi-byte), so we + don't alter wstrResStr.Length, and let RtlUnicodeStringToAnsiString truncate + it, if necessary + */ + strBuf.Length = 0; + strBuf.MaximumLength = nBufferMax * sizeof(CHAR); + strBuf.Buffer = lpBuffer; + + nErrCode = RtlUnicodeStringToAnsiString(&strBuf, &wstrResStr, FALSE); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + SetLastErrorByStatus(nErrCode); + return 0; + } + + /* the ANSI string may not be null-terminated */ + if(strBuf.Length >= strBuf.MaximumLength) + { + /* length greater than the buffer? whatever */ + int nStringLen = strBuf.MaximumLength / sizeof(CHAR) - 1; + + /* zero the last character in the buffer */ + strBuf.Buffer[nStringLen] = 0; + + /* success */ + return nStringLen; + } + else + { + /* zero the last character in the string */ + strBuf.Buffer[strBuf.Length / sizeof(CHAR)] = 0; + + /* success */ + return strBuf.Length / sizeof(CHAR); + } } + +int STDCALL LoadStringW +( + HINSTANCE hInstance, + UINT uID, + LPWSTR lpBuffer, + int nBufferMax +) +{ + UNICODE_STRING wstrResStr; + int nStringLen; + + /* parameter validation */ + if + ( + (nBufferMax < 1) || + (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0]))) + ) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* get the UNICODE_STRING descriptor of the in-memory image of the string */ + if(!_InternalLoadString(hInstance, uID, &wstrResStr)) + /* failure */ + return 0; + + /* get the length in characters */ + nStringLen = wstrResStr.Length / sizeof(WCHAR); + + /* the buffer must be enough to contain the string and the null terminator */ + if(nBufferMax < (nStringLen + 1)) + /* otherwise, the string is truncated */ + nStringLen = nBufferMax - 1; + + /* copy the string */ + memcpy(lpBuffer, wstrResStr.Buffer, nStringLen * sizeof(WCHAR)); + + /* null-terminate it */ + lpBuffer[nStringLen] = 0; + /* success */ + return nStringLen; +} + +/* EOF */ diff --git a/lib/user32/misc/stubs.c b/lib/user32/misc/stubs.c index 4ca0484..ba49db1 100644 --- a/lib/user32/misc/stubs.c +++ b/lib/user32/misc/stubs.c @@ -242,19 +242,6 @@ IsWindowEnabled( - - -int -STDCALL -LoadStringW( - HINSTANCE hInstance, - UINT uID, - LPWSTR lpBuffer, - int nBufferMax) -{ - return 0; -} - WINBOOL STDCALL LockWindowUpdate( @@ -528,4 +515,28 @@ WaitForInputIdle( } + +HHOOK +STDCALL +SetWindowsHookExA( + int idHook, + HOOKPROC lpfn, + HINSTANCE hMod, + DWORD dwThreadId) +{ + return 0; +} + +HHOOK +STDCALL +SetWindowsHookExW( + int idHook, + HOOKPROC lpfn, + HINSTANCE hMod, + DWORD dwThreadId) +{ + return 0; +} + + /* EOF */ diff --git a/lib/user32/user32.def b/lib/user32/user32.def index 2600cd9..66eef33 100644 --- a/lib/user32/user32.def +++ b/lib/user32/user32.def @@ -617,8 +617,8 @@ SetWindowTextA@8 SetWindowTextW@8 ;SetWindowWord ;SetWindowsHookA -;SetWindowsHookExA -;SetWindowsHookExW +SetWindowsHookExA +SetWindowsHookExW ;SetWindowsHookW ShowCaret@4 ShowCursor@4 diff --git a/lib/user32/user32.edf b/lib/user32/user32.edf index ea23e7a..00d046b 100644 --- a/lib/user32/user32.edf +++ b/lib/user32/user32.edf @@ -617,8 +617,8 @@ SetWindowTextA=SetWindowTextA@8 SetWindowTextW=SetWindowTextW@8 ;SetWindowWord ;SetWindowsHookA -;SetWindowsHookExA -;SetWindowsHookExW +SetWindowsHookExA=SetWindowsHookExA@16 +SetWindowsHookExW=SetWindowsHookExW@16 ;SetWindowsHookW ShowCaret=ShowCaret@4 ShowCursor=ShowCursor@4 diff --git a/lib/user32/windows/bitmap.c b/lib/user32/windows/bitmap.c index 72a6977..ef95d34 100644 --- a/lib/user32/windows/bitmap.c +++ b/lib/user32/windows/bitmap.c @@ -242,7 +242,7 @@ LoadImageW(HINSTANCE hinst, } case IMAGE_CURSOR: { - DbgPrint("FIXME: Need support for loading cursors.\n"); + DbgPrint("FIXME: Need support for loading cursor images.\n"); return(NULL); } default: diff --git a/lib/user32/windows/defwnd.c b/lib/user32/windows/defwnd.c index de7d91b..d754e3c 100644 --- a/lib/user32/windows/defwnd.c +++ b/lib/user32/windows/defwnd.c @@ -107,10 +107,10 @@ DefFrameProcW(HWND hWnd, } -BOOL +BOOL DefWndRedrawIconTitle(HWND hWnd) { - PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, + PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos); if (lpPos != NULL) { @@ -152,7 +152,7 @@ UserHasThickFrameStyle(ULONG Style, ULONG ExStyle) (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))); } -ULONG +ULONG UserHasThinFrameStyle(ULONG Style, ULONG ExStyle) { return((Style & WS_BORDER) || @@ -166,7 +166,7 @@ UserHasBigFrameStyle(ULONG Style, ULONG ExStyle) (ExStyle & WS_EX_DLGMODALFRAME)); } -static void UserGetInsideRectNC( HWND hwnd, RECT *rect ) +void UserGetInsideRectNC( HWND hwnd, RECT *rect ) { RECT WindowRect; ULONG Style; @@ -178,8 +178,8 @@ static void UserGetInsideRectNC( HWND hwnd, RECT *rect ) rect->top = rect->left = 0; rect->right = WindowRect.right - WindowRect.left; rect->bottom = WindowRect.bottom - WindowRect.top; - - if (Style & WS_ICONIC) + + if (Style & WS_ICONIC) { return; } @@ -187,14 +187,14 @@ static void UserGetInsideRectNC( HWND hwnd, RECT *rect ) /* Remove frame from rectangle */ if (UserHasThickFrameStyle(Style, ExStyle )) { - InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), + InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) ); } else { if (UserHasDlgFrameStyle(Style, ExStyle )) { - InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), + InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME)); /* FIXME: this isn't in NC_AdjustRect? why not? */ if (ExStyle & WS_EX_DLGMODALFRAME) @@ -204,7 +204,7 @@ static void UserGetInsideRectNC( HWND hwnd, RECT *rect ) { if (UserHasThinFrameStyle(Style, ExStyle)) { - InflateRect(rect, -GetSystemMetrics(SM_CXBORDER), + InflateRect(rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER)); } } @@ -222,8 +222,8 @@ void UserDrawSysButton( HWND hwnd, HDC hdc, BOOL down ) UserGetInsideRectNC( hwnd, &rect ); hdcMem = CreateCompatibleDC( hdc ); hbitmap = SelectObject( hdcMem, hbitmapClose ); - BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), - GetSystemMetrics(SM_CYSIZE), hdcMem, + BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), + GetSystemMetrics(SM_CYSIZE), hdcMem, (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0, down ? NOTSRCCOPY : SRCCOPY ); SelectObject( hdcMem, hbitmap ); @@ -237,7 +237,7 @@ static void UserDrawMaxButton( HWND hwnd, HDC hdc, BOOL down ) UserGetInsideRectNC( hwnd, &rect ); hdcMem = CreateCompatibleDC( hdc ); - SelectObject( hdcMem, (IsZoomed(hwnd) + SelectObject( hdcMem, (IsZoomed(hwnd) ? (down ? hbitmapRestoreD : hbitmapRestore) : (down ? hbitmapMaximizeD : hbitmapMaximize)) ); BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top, @@ -250,16 +250,16 @@ static void UserDrawMinButton( HWND hwnd, HDC hdc, BOOL down) { RECT rect; HDC hdcMem; - + UserGetInsideRectNC(hwnd, &rect); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize)); - if (GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZEBOX) + if (GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZEBOX) { rect.right -= GetSystemMetrics(SM_CXSMSIZE)+1; } BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top, - GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE), + GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE), hdcMem, 0, 0, SRCCOPY ); DeleteDC( hdcMem ); @@ -272,7 +272,7 @@ static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd, char buffer[256]; if (!hbitmapClose) - { + { hbitmapClose = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_CLOSE)); hbitmapMinimize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCE) ); hbitmapMinimizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCED) ); @@ -281,7 +281,7 @@ static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd, hbitmapRestore = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORE) ); hbitmapRestoreD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORED) ); } - + if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME) { HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) ); @@ -313,10 +313,10 @@ static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd, UserDrawMinButton( hwnd, hdc, FALSE ); r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; } - + FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) ); - + if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) { NONCLIENTMETRICS nclm; @@ -344,7 +344,7 @@ VOID UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) { INT width, height; - + if (dlgFrame) { width = GetSystemMetrics(SM_CXDLGFRAME) - 1; @@ -359,7 +359,7 @@ UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER : COLOR_INACTIVEBORDER) ); } - + /* Draw frame */ PatBlt( hdc, rect->left, rect->top, rect->right - rect->left, height, PATCOPY ); @@ -373,22 +373,22 @@ UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) if (dlgFrame) { InflateRect( rect, -width, -height ); - } + } else { - INT decYOff = GetSystemMetrics(SM_CXFRAME) + + INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1; - INT decXOff = GetSystemMetrics(SM_CYFRAME) + + INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1; /* Draw inner rectangle */ - + SelectObject( hdc, GetStockObject(NULL_BRUSH) ); Rectangle( hdc, rect->left + width, rect->top + height, rect->right - width , rect->bottom - height ); - + /* Draw the decorations */ - + MoveToEx( hdc, rect->left, rect->top + decYOff, NULL ); LineTo( hdc, rect->left + width, rect->top + decYOff ); MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL ); @@ -397,7 +397,7 @@ UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) LineTo( hdc, rect->left + width, rect->bottom - decYOff ); MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL ); LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff ); - + MoveToEx( hdc, rect->left + decXOff, rect->top, NULL ); LineTo( hdc, rect->left + decXOff, rect->top + height); MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL ); @@ -406,11 +406,13 @@ UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) LineTo( hdc, rect->right - decXOff, rect->top + height ); MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL ); LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 ); - + InflateRect( rect, -width - 1, -height - 1 ); } } +void SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, BOOL arrows, BOOL interior); + VOID DefWndDoPaintNC(HWND hWnd, HRGN clip) { @@ -445,7 +447,7 @@ DefWndDoPaintNC(HWND hWnd, HRGN clip) Rectangle(hDc, 0, 0, rect.right, rect.bottom); InflateRect(&rect, -1, -1); } - + if (UserHasThickFrameStyle(Style, ExStyle)) { UserDrawFrameNC(hDc, &rect, FALSE, Active); @@ -454,22 +456,27 @@ DefWndDoPaintNC(HWND hWnd, HRGN clip) { UserDrawFrameNC(hDc, &rect, TRUE, Active); } - + if (Style & WS_CAPTION) { RECT r = rect; r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE); - rect.top += GetSystemMetrics(SM_CYSIZE) + + rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER); UserDrawCaptionNC(hDc, &r, hWnd, Style, Active); } /* FIXME: Draw menu bar. */ - /* FIXME: Draw scroll bars. */ +DbgPrint("drawing scrollbars..\n"); + /* Draw scrollbars */ + if (Style & WS_VSCROLL) + SCROLL_DrawScrollBar(hWnd, hDc, SB_VERT, TRUE, TRUE); + if (Style & WS_HSCROLL) + SCROLL_DrawScrollBar(hWnd, hDc, SB_HORZ, TRUE, TRUE); /* FIXME: Draw size box. */ - + ReleaseDC(hWnd, hDc); } @@ -561,9 +568,9 @@ DefWndHitTestNC(HWND hWnd, POINT Point) } return(HTRIGHT); } - } + } } - else + else { if (UserHasDlgFrameStyle(Style, ExStyle)) { @@ -583,7 +590,7 @@ DefWndHitTestNC(HWND hWnd, POINT Point) if ((Style & WS_CAPTION) == WS_CAPTION) { - WindowRect.top += GetSystemMetrics(SM_CYCAPTION) - + WindowRect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER); if (!PtInRect(&WindowRect, Point)) { @@ -679,7 +686,7 @@ DefWndTrackMinMaxBox(HWND hWnd, WPARAM wParam) for(;;) { - BOOL OldState = Pressed; + BOOL OldState = Pressed; GetMessageA(hWnd, &Msg, 0, 0); if (Msg.message == WM_LBUTTONUP) @@ -691,7 +698,7 @@ DefWndTrackMinMaxBox(HWND hWnd, WPARAM wParam) continue; } - Pressed = DefWndHitTestNC(hWnd, Msg.pt) == wParam; + Pressed = DefWndHitTestNC(hWnd, Msg.pt) == (LRESULT) wParam; if (Pressed != OldState) { if (wParam == HTMINBUTTON) @@ -727,13 +734,13 @@ DefWndTrackMinMaxBox(HWND hWnd, WPARAM wParam) if (wParam == HTMINBUTTON) { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(Msg.pt.x, Msg.pt.y)); } else { - SendMessageA(hWnd, WM_SYSCOMMAND, - IsZoomed(hWnd) ? SC_RESTORE : SC_MAXIMIZE, + SendMessageA(hWnd, WM_SYSCOMMAND, + IsZoomed(hWnd) ? SC_RESTORE : SC_MAXIMIZE, MAKELONG(Msg.pt.x, Msg.pt.y)); } } @@ -749,8 +756,8 @@ DefWndDrawSysButton(HWND hWnd, HDC hDC, BOOL Down) hDcMem = CreateCompatibleDC(hDC); hSavedBitmap = SelectObject(hDcMem, hbitmapClose); BitBlt(hDC, Rect.left, Rect.top, GetSystemMetrics(SM_CXSIZE), - GetSystemMetrics(SM_CYSIZE), hDcMem, - (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ? + GetSystemMetrics(SM_CYSIZE), hDcMem, + (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE): 0, 0, Down ? NOTSRCCOPY : SRCCOPY); SelectObject(hDcMem, hSavedBitmap); DeleteDC(hDcMem); @@ -780,7 +787,7 @@ DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam) DefWndDrawSysButton(hWnd, hDC, TRUE); ReleaseDC(hWnd, hDC); } - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam); } break; @@ -836,7 +843,7 @@ DefWndSetRedraw(HWND hWnd, WPARAM wParam) { } -LRESULT +LRESULT DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam) { /* Not for child windows. */ @@ -913,7 +920,7 @@ DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle) if (UserHasThickFrameStyle(Style, ExStyle)) { - InflateRect(Rect, GetSystemMetrics(SM_CXFRAME), + InflateRect(Rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME)); } else if (UserHasDlgFrameStyle(Style, ExStyle)) @@ -928,7 +935,7 @@ DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle) } if (Style & WS_CAPTION) { - Rect->top -= GetSystemMetrics(SM_CYCAPTION) - + Rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER); } if (Menu) @@ -1081,7 +1088,7 @@ User32DefWindowProc(HWND hWnd, Pt.x = SLOWORD(lParam); Pt.y = SHIWORD(lParam); - + if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) { ScreenToClient(GetParent(hWnd), &Pt); @@ -1128,9 +1135,9 @@ User32DefWindowProc(HWND hWnd, RECT WindowRect; INT x, y; GetWindowRect(hWnd, &WindowRect); - x = (WindowRect.right - WindowRect.left - + x = (WindowRect.right - WindowRect.left - GetSystemMetrics(SM_CXICON)) / 2; - y = (WindowRect.bottom - WindowRect.top - + y = (WindowRect.bottom - WindowRect.top - GetSystemMetrics(SM_CYICON)) / 2; DrawIcon(hDc, x, y, hIcon); } @@ -1145,7 +1152,7 @@ User32DefWindowProc(HWND hWnd, hRgn = CreateRectRgn(0, 0, 0, 0); if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION) { - RedrawWindow(hWnd, NULL, hRgn, + RedrawWindow(hWnd, NULL, hRgn, RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); } @@ -1243,12 +1250,12 @@ User32DefWindowProc(HWND hWnd, BOOL bResult; if (bUnicode) { - bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR, + bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR, wParam, lParam); } - else + else { - bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR, + bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR, wParam, lParam); } if (bResult) @@ -1257,7 +1264,7 @@ User32DefWindowProc(HWND hWnd, } } } - return(DefWndHandleSetCursor(hWnd, wParam, lParam)); + return(DefWndHandleSetCursor(hWnd, wParam, lParam)); } case WM_SYSCOMMAND: @@ -1281,7 +1288,7 @@ User32DefWindowProc(HWND hWnd, (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam)) { return(0); - } + } ShowWindow(hWnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE); break; } @@ -1352,7 +1359,7 @@ User32DefWindowProc(HWND hWnd, INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM; HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index); SetClassLongW(hWnd, Index, lParam); - SetWindowPos(hWnd, 0, 0, 0, 0, 0, + SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); return((LRESULT)hOldIcon); @@ -1397,7 +1404,7 @@ DefWindowProcA(HWND hWnd, CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam; if (HIWORD(Cs->lpszName)) { - WindowTextAtom = + WindowTextAtom = (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA"); WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(Cs->lpszName) * sizeof(CHAR)); @@ -1446,8 +1453,8 @@ DefWindowProcA(HWND hWnd, { if (WindowTextAtom != 0) { - WindowTextAtom = - (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomW"); + WindowTextAtom = + (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomW"); } if (WindowTextAtom != 0 && (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL) @@ -1500,7 +1507,7 @@ DefWindowProcW(HWND hWnd, CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam; if (HIWORD(Cs->lpszName)) { - WindowTextAtom = + WindowTextAtom = (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW"); WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0, wcslen(Cs->lpszName) * sizeof(WCHAR)); @@ -1549,8 +1556,8 @@ DefWindowProcW(HWND hWnd, { if (WindowTextAtom != 0) { - WindowTextAtom = - (LPWSTR)(DWORD)GlobalAddAtom(L"USER32!WindowTextAtomW"); + WindowTextAtom = + (LPWSTR)(DWORD)GlobalAddAtom(L"USER32!WindowTextAtomW"); } if (WindowTextAtom != 0 && (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL) @@ -1562,6 +1569,8 @@ DefWindowProcW(HWND hWnd, wcscpy(WindowText, (PWSTR)lParam); SetPropW(hWnd, WindowTextAtom, WindowText); } + //FIXME: return correct code + return TRUE; case WM_NCDESTROY: { diff --git a/lib/user32/windows/draw.c b/lib/user32/windows/draw.c index 806726f..c9a9aa1 100644 --- a/lib/user32/windows/draw.c +++ b/lib/user32/windows/draw.c @@ -36,8 +36,1334 @@ #define COLOR_MAX (28) +/* HPEN STDCALL W32kGetSysColorPen(int nIndex); */ + +static const WORD wPattern_AA55[8] = { 0xaaaa, 0x5555, 0xaaaa, 0x5555, + 0xaaaa, 0x5555, 0xaaaa, 0x5555 }; + +/* These tables are used in: + * UITOOLS_DrawDiagEdge() + * UITOOLS_DrawRectEdge() + */ +static const signed char LTInnerNormal[] = { + -1, -1, -1, -1, + -1, COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT, -1, + -1, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW, -1, + -1, -1, -1, -1 +}; + +static const signed char LTOuterNormal[] = { + -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + COLOR_3DDKSHADOW, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1 +}; + +static const signed char RBInnerNormal[] = { + -1, -1, -1, -1, + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, + -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, + -1, -1, -1, -1 +}; + +static const signed char RBOuterNormal[] = { + -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + COLOR_BTNSHADOW, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + COLOR_3DLIGHT, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1 +}; + +static const signed char LTInnerSoft[] = { + -1, -1, -1, -1, + -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, + -1, -1, -1, -1 +}; + +static const signed char LTOuterSoft[] = { + -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + COLOR_3DLIGHT, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + COLOR_BTNSHADOW, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1 +}; + +#define RBInnerSoft RBInnerNormal /* These are the same */ +#define RBOuterSoft RBOuterNormal + +static const signed char LTRBOuterMono[] = { + -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, +}; + +static const signed char LTRBInnerMono[] = { + -1, -1, -1, -1, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, +}; + +static const signed char LTRBOuterFlat[] = { + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, +}; + +static const signed char LTRBInnerFlat[] = { + -1, -1, -1, -1, + -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, + -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, + -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, +}; + /* FUNCTIONS *****************************************************************/ + +HPEN STDCALL GetSysColorPen(int nIndex); +HBRUSH STDCALL GetSysColorBrush(int nIndex); + +/* Ported from WINE20020904 */ +/* Same as DrawEdge invoked with BF_DIAGONAL */ +static BOOL UITOOLS95_DrawDiagEdge(HDC hdc, LPRECT rc, + UINT uType, UINT uFlags) +{ + POINT Points[4]; + signed char InnerI, OuterI; + HPEN InnerPen, OuterPen; + POINT SavePoint; + HPEN SavePen; + int spx, spy; + int epx, epy; + int Width = rc->right - rc->left; + int Height= rc->bottom - rc->top; + int SmallDiam = Width > Height ? Height : Width; + BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER + || (uType & BDR_OUTER) == BDR_OUTER) + && !(uFlags & (BF_FLAT|BF_MONO)) ); + int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) + + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); + + /* Init some vars */ + OuterPen = InnerPen = (HPEN)GetStockObject(NULL_PEN); + SavePen = (HPEN)SelectObject(hdc, InnerPen); + spx = spy = epx = epy = 0; /* Satisfy the compiler... */ + + /* Determine the colors of the edges */ + if(uFlags & BF_MONO) + { + InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_FLAT) + { + InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_SOFT) + { + if(uFlags & BF_BOTTOM) + { + InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + } + else + { + if(uFlags & BF_BOTTOM) + { + InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + } + + if(InnerI != -1) InnerPen = GetSysColorPen(InnerI); + if(OuterI != -1) OuterPen = GetSysColorPen(OuterI); + + MoveToEx(hdc, 0, 0, &SavePoint); + + /* Don't ask me why, but this is what is visible... */ + /* This must be possible to do much simpler, but I fail to */ + /* see the logic in the MS implementation (sigh...). */ + /* So, this might look a bit brute force here (and it is), but */ + /* it gets the job done;) */ + + switch(uFlags & BF_RECT) + { + case 0: + case BF_LEFT: + case BF_BOTTOM: + case BF_BOTTOMLEFT: + /* Left bottom endpoint */ + epx = rc->left-1; + spx = epx + SmallDiam; + epy = rc->bottom; + spy = epy - SmallDiam; + break; + + case BF_TOPLEFT: + case BF_BOTTOMRIGHT: + /* Left top endpoint */ + epx = rc->left-1; + spx = epx + SmallDiam; + epy = rc->top-1; + spy = epy + SmallDiam; + break; + + case BF_TOP: + case BF_RIGHT: + case BF_TOPRIGHT: + case BF_RIGHT|BF_LEFT: + case BF_RIGHT|BF_LEFT|BF_TOP: + case BF_BOTTOM|BF_TOP: + case BF_BOTTOM|BF_TOP|BF_LEFT: + case BF_BOTTOMRIGHT|BF_LEFT: + case BF_BOTTOMRIGHT|BF_TOP: + case BF_RECT: + /* Right top endpoint */ + spx = rc->left; + epx = spx + SmallDiam; + spy = rc->bottom-1; + epy = spy - SmallDiam; + break; + } + + MoveToEx(hdc, spx, spy, NULL); + SelectObject(hdc, OuterPen); + LineTo(hdc, epx, epy); + + SelectObject(hdc, InnerPen); + + switch(uFlags & (BF_RECT|BF_DIAGONAL)) + { + case BF_DIAGONAL_ENDBOTTOMLEFT: + case (BF_DIAGONAL|BF_BOTTOM): + case BF_DIAGONAL: + case (BF_DIAGONAL|BF_LEFT): + MoveToEx(hdc, spx-1, spy, NULL); + LineTo(hdc, epx, epy-1); + Points[0].x = spx-add; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->top; + Points[2].x = epx+1; + Points[2].y = epy-1-add; + Points[3] = Points[2]; + break; + + case BF_DIAGONAL_ENDBOTTOMRIGHT: + MoveToEx(hdc, spx-1, spy, NULL); + LineTo(hdc, epx, epy+1); + Points[0].x = spx-add; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->bottom-1; + Points[2].x = epx+1; + Points[2].y = epy+1+add; + Points[3] = Points[2]; + break; + + case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT): + case BF_DIAGONAL_ENDTOPRIGHT: + case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT): + MoveToEx(hdc, spx+1, spy, NULL); + LineTo(hdc, epx, epy+1); + Points[0].x = epx-1; + Points[0].y = epy+1+add; + Points[1].x = rc->right-1; + Points[1].y = rc->top+add; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1; + Points[3].x = spx+add; + Points[3].y = spy; + break; + + case BF_DIAGONAL_ENDTOPLEFT: + MoveToEx(hdc, spx, spy-1, NULL); + LineTo(hdc, epx+1, epy); + Points[0].x = epx+1+add; + Points[0].y = epy+1; + Points[1].x = rc->right-1; + Points[1].y = rc->top; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1-add; + Points[3].x = spx; + Points[3].y = spy-add; + break; + + case (BF_DIAGONAL|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT): + MoveToEx(hdc, spx+1, spy-1, NULL); + LineTo(hdc, epx, epy); + Points[0].x = epx-1; + Points[0].y = epy+1; + Points[1].x = rc->right-1; + Points[1].y = rc->top; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1-add; + Points[3].x = spx+add; + Points[3].y = spy-add; + break; + + case (BF_DIAGONAL|BF_RIGHT): + case (BF_DIAGONAL|BF_RIGHT|BF_LEFT): + case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM): + MoveToEx(hdc, spx, spy, NULL); + LineTo(hdc, epx-1, epy+1); + Points[0].x = spx; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->top+add; + Points[2].x = epx-1-add; + Points[2].y = epy+1+add; + Points[3] = Points[2]; + break; + } + + /* Fill the interior if asked */ + if((uFlags & BF_MIDDLE) && retval) + { + HBRUSH hbsave; + HBRUSH hb = GetSysColorBrush(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE); + HPEN hpsave; + HPEN hp = GetSysColorPen(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE); + hbsave = (HBRUSH)SelectObject(hdc, hb); + hpsave = (HPEN)SelectObject(hdc, hp); + Polygon(hdc, Points, 4); + SelectObject(hdc, hbsave); + SelectObject(hdc, hpsave); + } + + /* Adjust rectangle if asked */ + if(uFlags & BF_ADJUST) + { + if(uFlags & BF_LEFT) rc->left += add; + if(uFlags & BF_RIGHT) rc->right -= add; + if(uFlags & BF_TOP) rc->top += add; + if(uFlags & BF_BOTTOM) rc->bottom -= add; + } + + /* Cleanup */ + SelectObject(hdc, SavePen); + MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL); + + return retval; +} + +/* Ported from WINE20020904 */ +/* Same as DrawEdge invoked without BF_DIAGONAL + * + * 23-Nov-1997: Changed by Bertho Stultiens + * + * Well, I started testing this and found out that there are a few things + * that weren't quite as win95. The following rewrite should reproduce + * win95 results completely. + * The colorselection is table-driven to avoid awfull if-statements. + * The table below show the color settings. + * + * Pen selection table for uFlags = 0 + * + * uType | LTI | LTO | RBI | RBO + * ------+-------+-------+-------+------- + * 0000 | x | x | x | x + * 0001 | x | 22 | x | 21 + * 0010 | x | 16 | x | 20 + * 0011 | x | x | x | x + * ------+-------+-------+-------+------- + * 0100 | x | 20 | x | 16 + * 0101 | 20 | 22 | 16 | 21 + * 0110 | 20 | 16 | 16 | 20 + * 0111 | x | x | x | x + * ------+-------+-------+-------+------- + * 1000 | x | 21 | x | 22 + * 1001 | 21 | 22 | 22 | 21 + * 1010 | 21 | 16 | 22 | 20 + * 1011 | x | x | x | x + * ------+-------+-------+-------+------- + * 1100 | x | x | x | x + * 1101 | x | x (22)| x | x (21) + * 1110 | x | x (16)| x | x (20) + * 1111 | x | x | x | x + * + * Pen selection table for uFlags = BF_SOFT + * + * uType | LTI | LTO | RBI | RBO + * ------+-------+-------+-------+------- + * 0000 | x | x | x | x + * 0001 | x | 20 | x | 21 + * 0010 | x | 21 | x | 20 + * 0011 | x | x | x | x + * ------+-------+-------+-------+------- + * 0100 | x | 22 | x | 16 + * 0101 | 22 | 20 | 16 | 21 + * 0110 | 22 | 21 | 16 | 20 + * 0111 | x | x | x | x + * ------+-------+-------+-------+------- + * 1000 | x | 16 | x | 22 + * 1001 | 16 | 20 | 22 | 21 + * 1010 | 16 | 21 | 22 | 20 + * 1011 | x | x | x | x + * ------+-------+-------+-------+------- + * 1100 | x | x | x | x + * 1101 | x | x (20)| x | x (21) + * 1110 | x | x (21)| x | x (20) + * 1111 | x | x | x | x + * + * x = don't care; (n) = is what win95 actually uses + * LTI = left Top Inner line + * LTO = left Top Outer line + * RBI = Right Bottom Inner line + * RBO = Right Bottom Outer line + * 15 = COLOR_BTNFACE + * 16 = COLOR_BTNSHADOW + * 20 = COLOR_BTNHIGHLIGHT + * 21 = COLOR_3DDKSHADOW + * 22 = COLOR_3DLIGHT + */ +static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, + UINT uType, UINT uFlags) +{ + signed char LTInnerI, LTOuterI; + signed char RBInnerI, RBOuterI; + HPEN LTInnerPen, LTOuterPen; + HPEN RBInnerPen, RBOuterPen; + RECT InnerRect = *rc; + POINT SavePoint; + HPEN SavePen; + int LBpenplus = 0; + int LTpenplus = 0; + int RTpenplus = 0; + int RBpenplus = 0; + BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER + || (uType & BDR_OUTER) == BDR_OUTER) + && !(uFlags & (BF_FLAT|BF_MONO)) ); + + /* Init some vars */ + LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)GetStockObject(NULL_PEN); + SavePen = (HPEN)SelectObject(hdc, LTInnerPen); + + /* Determine the colors of the edges */ + if(uFlags & BF_MONO) + { + LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_FLAT) + { + LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; + + /* Bertho Stultiens states above that this function exactly matches win95 + * In win98 BF_FLAT rectangles have an inner border same color as the + * middle (COLOR_BTNFACE). I believe it's the same for win95 but since + * I don't know I go with Bertho and just sets it for win98 until proven + * otherwise. + * Dennis Björklund, 10 June, 99 + */ +/* if( TWEAK_WineLook == WIN98_LOOK && LTInnerI != -1 ) + LTInnerI = RBInnerI = COLOR_BTNFACE; */ + } + else if(uFlags & BF_SOFT) + { + LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + + if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) LBpenplus = 1; + if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) RTpenplus = 1; + if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1; + if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1; + + if(LTInnerI != -1) LTInnerPen = GetSysColorPen(LTInnerI); + if(LTOuterI != -1) LTOuterPen = GetSysColorPen(LTOuterI); + if(RBInnerI != -1) RBInnerPen = GetSysColorPen(RBInnerI); + if(RBOuterI != -1) RBOuterPen = GetSysColorPen(RBOuterI); + + MoveToEx(hdc, 0, 0, &SavePoint); + + /* Draw the outer edge */ + SelectObject(hdc, LTOuterPen); + if(uFlags & BF_TOP) + { + MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL); + LineTo(hdc, InnerRect.right, InnerRect.top); + } + if(uFlags & BF_LEFT) + { + MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL); + LineTo(hdc, InnerRect.left, InnerRect.bottom); + } + SelectObject(hdc, RBOuterPen); + if(uFlags & BF_BOTTOM) + { + MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); + LineTo(hdc, InnerRect.left-1, InnerRect.bottom-1); + } + if(uFlags & BF_RIGHT) + { + MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); + LineTo(hdc, InnerRect.right-1, InnerRect.top-1); + } + + /* Draw the inner edge */ + SelectObject(hdc, LTInnerPen); + if(uFlags & BF_TOP) + { + MoveToEx(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL); + LineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1); + } + if(uFlags & BF_LEFT) + { + MoveToEx(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL); + LineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus); + } + SelectObject(hdc, RBInnerPen); + if(uFlags & BF_BOTTOM) + { + MoveToEx(hdc, InnerRect.right-1-RBpenplus, InnerRect.bottom-2, NULL); + LineTo(hdc, InnerRect.left-1+LBpenplus, InnerRect.bottom-2); + } + if(uFlags & BF_RIGHT) + { + MoveToEx(hdc, InnerRect.right-2, InnerRect.bottom-1-RBpenplus, NULL); + LineTo(hdc, InnerRect.right-2, InnerRect.top-1+RTpenplus); + } + + if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) ) + { + int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) + + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); + + if(uFlags & BF_LEFT) InnerRect.left += add; + if(uFlags & BF_RIGHT) InnerRect.right -= add; + if(uFlags & BF_TOP) InnerRect.top += add; + if(uFlags & BF_BOTTOM) InnerRect.bottom -= add; + + if((uFlags & BF_MIDDLE) && retval) + { + FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ? + COLOR_WINDOW : COLOR_BTNFACE)); + } + + if(uFlags & BF_ADJUST) + *rc = InnerRect; + } + + /* Cleanup */ + SelectObject(hdc, SavePen); + MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL); + return retval; +} + +/* Ported from WINE20020904 */ +/* Utility to create a square rectangle and returning the width */ +static int UITOOLS_MakeSquareRect(LPRECT src, LPRECT dst) +{ + int Width = src->right - src->left; + int Height = src->bottom - src->top; + int SmallDiam = Width > Height ? Height : Width; + + *dst = *src; + + /* Make it a square box */ + if(Width < Height) /* SmallDiam == Width */ + { + dst->top += (Height-Width)/2; + dst->bottom = dst->top + SmallDiam; + } + else if(Width > Height) /* SmallDiam == Height */ + { + dst->left += (Width-Height)/2; + dst->right = dst->left + SmallDiam; + } + + return SmallDiam; +} + +/* Ported from WINE20020904 */ +static void UITOOLS_DrawCheckedRect( HDC dc, LPRECT rect ) +{ + if(GetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255)) + { + HBITMAP hbm = CreateBitmap(8, 8, 1, 1, wPattern_AA55); + HBRUSH hbsave; + HBRUSH hb = CreatePatternBrush(hbm); + COLORREF bg; + + FillRect(dc, rect, GetSysColorBrush(COLOR_BTNFACE)); + bg = SetBkColor(dc, RGB(255, 255, 255)); + hbsave = (HBRUSH)SelectObject(dc, hb); + PatBlt(dc, rect->left, rect->top, rect->right-rect->left, rect->bottom-rect->top, 0x00FA0089); + SelectObject(dc, hbsave); + SetBkColor(dc, bg); + DeleteObject(hb); + DeleteObject(hbm); + } + else + { + FillRect(dc, rect, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + } +} + +/* Ported from WINE20020904 */ +/* Draw a push button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +static BOOL UITOOLS95_DFC_ButtonPush(HDC dc, LPRECT r, UINT uFlags) +{ + UINT edge; + RECT myr = *r; + + if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT)) + edge = EDGE_SUNKEN; + else + edge = EDGE_RAISED; + + if(uFlags & DFCS_CHECKED) + { + if(uFlags & DFCS_MONO) + UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); + else + UITOOLS95_DrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST); + + UITOOLS_DrawCheckedRect( dc, &myr ); + } + else + { + if(uFlags & DFCS_MONO) + { + UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + } + else + { + UITOOLS95_DrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT); + } + } + + /* Adjust rectangle if asked */ + if(uFlags & DFCS_ADJUSTRECT) + { + r->left += 2; + r->right -= 2; + r->top += 2; + r->bottom -= 2; + } + + return TRUE; +} + +/* Ported from WINE20020904 */ +/* Draw a check/3state button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +static BOOL UITOOLS95_DFC_ButtonCheck(HDC dc, LPRECT r, UINT uFlags) +{ + RECT myr, bar; + UINT flags = BF_RECT | BF_ADJUST; + UITOOLS_MakeSquareRect(r, &myr); + + if(uFlags & DFCS_FLAT) flags |= BF_FLAT; + else if(uFlags & DFCS_MONO) flags |= BF_MONO; + + UITOOLS95_DrawRectEdge( dc, &myr, EDGE_SUNKEN, flags ); + + if(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + else if( (uFlags & DFCS_BUTTON3STATE) && (uFlags & DFCS_CHECKED) ) + UITOOLS_DrawCheckedRect( dc, &myr ); + else + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_WINDOW)); + } + + if(uFlags & DFCS_CHECKED) + { + int i, k; + i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ? + COLOR_BTNSHADOW : COLOR_WINDOWTEXT; + + /* draw 7 bars, with h=3w to form the check */ + bar.left = myr.left; + bar.top = myr.top + 2; + for (k = 0; k < 7; k++) { + bar.left = bar.left + 1; + bar.top = (k < 3) ? bar.top + 1 : bar.top - 1; + bar.bottom = bar.top + 3; + bar.right = bar.left + 1; + FillRect(dc, &bar, GetSysColorBrush(i)); + } + } + return TRUE; +} + +/* Ported from WINE20020904 */ +/* Draw a radio/radioimage/radiomask button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +static BOOL UITOOLS95_DFC_ButtonRadio(HDC dc, LPRECT r, UINT uFlags) +{ + RECT myr; + int i; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); + int BorderShrink = SmallDiam / 16; + HPEN hpsave; + HBRUSH hbsave; + int xc, yc; + + if(BorderShrink < 1) BorderShrink = 1; + + if((uFlags & 0xff) == DFCS_BUTTONRADIOIMAGE) + { + FillRect(dc, r, (HBRUSH)GetStockObject(BLACK_BRUSH)); + } + + xc = myr.left + SmallDiam - SmallDiam/2; + yc = myr.top + SmallDiam - SmallDiam/2; + + /* Define bounding box */ + i = 14*SmallDiam/16; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + + if((uFlags & 0xff) == DFCS_BUTTONRADIOMASK) + { + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH)); + Ellipse(dc, myr.left, myr.top, myr.right, myr.bottom); + SelectObject(dc, hbsave); + } + else + { + if(uFlags & (DFCS_FLAT|DFCS_MONO)) + { + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_WINDOWFRAME)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_WINDOWFRAME)); + Ellipse(dc, myr.left, myr.top, myr.right, myr.bottom); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + else + { + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + Pie(dc, myr.left, myr.top, myr.right+1, myr.bottom+1, myr.left-1, myr.bottom, myr.right+1, myr.top); + + SelectObject(dc, GetSysColorPen(COLOR_BTNSHADOW)); + SelectObject(dc, GetSysColorBrush(COLOR_BTNSHADOW)); + Pie(dc, myr.left, myr.top, myr.right+1, myr.bottom+1, myr.right+1, myr.top, myr.left-1, myr.bottom); + + myr.left += BorderShrink; + myr.right -= BorderShrink; + myr.top += BorderShrink; + myr.bottom -= BorderShrink; + + SelectObject(dc, GetSysColorPen(COLOR_3DLIGHT)); + SelectObject(dc, GetSysColorBrush(COLOR_3DLIGHT)); + Pie(dc, myr.left, myr.top, myr.right+1, myr.bottom+1, myr.left-1, myr.bottom, myr.right+1, myr.top); + + SelectObject(dc, GetSysColorPen(COLOR_3DDKSHADOW)); + SelectObject(dc, GetSysColorBrush(COLOR_3DDKSHADOW)); + Pie(dc, myr.left, myr.top, myr.right+1, myr.bottom+1, myr.right+1, myr.top, myr.left-1, myr.bottom); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + + i = 10*SmallDiam/16; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE; + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + Ellipse(dc, myr.left, myr.top, myr.right, myr.bottom); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + + if(uFlags & DFCS_CHECKED) + { + i = 6*SmallDiam/16; + i = i < 1 ? 1 : i; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + Ellipse(dc, myr.left, myr.top, myr.right, myr.bottom); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + /* FIXME: M$ has a Polygon in the center at relative points: */ + /* 0.476, 0.476 (times SmallDiam, SmallDiam) */ + /* 0.476, 0.525 */ + /* 0.500, 0.500 */ + /* 0.500, 0.499 */ + /* when the button is unchecked. The reason for it is unknown. The */ + /* color is COLOR_BTNHIGHLIGHT, although the Polygon gets painted at */ + /* least 3 times (it looks like a clip-region when you see it happen). */ + /* I do not really see a reason why this should be implemented. If you */ + /* have a good reason, let me know. Maybe this is a quirk in the Marlett */ + /* font. */ + + return TRUE; +} + +/* Ported from WINE20020904 */ +static BOOL UITOOLS95_DrawFrameButton(HDC hdc, LPRECT rc, UINT uState) +{ + switch(uState & 0xff) + { + case DFCS_BUTTONPUSH: + return UITOOLS95_DFC_ButtonPush(hdc, rc, uState); + + case DFCS_BUTTONCHECK: + case DFCS_BUTTON3STATE: + return UITOOLS95_DFC_ButtonCheck(hdc, rc, uState); + + case DFCS_BUTTONRADIOIMAGE: + case DFCS_BUTTONRADIOMASK: + case DFCS_BUTTONRADIO: + return UITOOLS95_DFC_ButtonRadio(hdc, rc, uState); + + default: + DbgPrint("Invalid button state=0x%04x\n", uState); + } + + return FALSE; +} + +/* Ported from WINE20020904 */ +/* Draw caption buttons (win95), coming from DrawFrameControl() */ +static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Line1[10]; + POINT Line2[10]; + int Line1N; + int Line2N; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2; + int i; + HBRUSH hbsave; + HPEN hpsave; + HFONT hfsave, hf; + int colorIdx = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + int xc = (myr.left+myr.right)/2; + int yc = (myr.top+myr.bottom)/2; + int edge, move; + char str[2] = "?"; + UINT alignsave; + int bksave; + COLORREF clrsave; + SIZE size; + + UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00); + + switch(uFlags & 0xff) + { + case DFCS_CAPTIONCLOSE: + { + /* The "X" is made by drawing a series of lines. + * The number of lines drawn depends on the size + * of the bounding rect. e.g. For a 6x5 inside rect, + * two lines are drawn from top-left to bottom-right, + * and two lines from top-right to bottom-left. + * + * 0 1 2 3 4 5 0 1 2 3 4 5 + * 1 * * * * + * 2 * * * * + * 3 * * * * + * 4 * * * * + * + * Drawing one line for every 6 pixels in width + * seems to provide the best proportions. + */ + + POINT start, oldPos; + INT width = myr.right - myr.left - 5; + INT height = myr.bottom - myr.top - 6; + INT numLines = (width / 6) + 1; + + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(colorIdx)); + + start.x = myr.left + 2; + start.y = myr.top + 2; + + if (width < 6) + height = width; + else + start.y++; + + if (uFlags & DFCS_PUSHED) + { + start.x++; + start.y++; + } + + /* now use the width of each line */ + width -= numLines - 1; + + for (i = 0; i < numLines; i++) + { + MoveToEx(dc, start.x + i, start.y, &oldPos); + LineTo(dc, start.x + i + width, start.y + height); + + MoveToEx(dc, start.x + i, start.y + height - 1, &oldPos); + LineTo(dc, start.x + i + width, start.y - 1); + } + + SelectObject(dc, hpsave); + return TRUE; + } + + case DFCS_CAPTIONHELP: + /* This one breaks the flow */ + /* FIXME: We need the Marlett font in order to get this right. */ + + hf = CreateFontA(-SmallDiam, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "System"); + alignsave = SetTextAlign(dc, TA_TOP|TA_LEFT); + bksave = SetBkMode(dc, TRANSPARENT); + clrsave = GetTextColor(dc); + hfsave = (HFONT)SelectObject(dc, hf); + GetTextExtentPoint32A(dc, str, 1, &size); + + if(uFlags & DFCS_INACTIVE) + { + SetTextColor(dc, GetSysColor(COLOR_BTNHIGHLIGHT)); + TextOutA(dc, xc-size.cx/2+1, yc-size.cy/2+1, str, 1); + } + SetTextColor(dc, GetSysColor(colorIdx)); + TextOutA(dc, xc-size.cx/2, yc-size.cy/2, str, 1); + + SelectObject(dc, hfsave); + SetTextColor(dc, clrsave); + SetBkMode(dc, bksave); + SetTextAlign(dc, alignsave); + DeleteObject(hf); + return TRUE; + + case DFCS_CAPTIONMIN: + Line1[0].x = Line1[3].x = myr.left + 96*SmallDiam/750+2; + Line1[1].x = Line1[2].x = Line1[0].x + 372*SmallDiam/750; + Line1[0].y = Line1[1].y = myr.top + 563*SmallDiam/750+1; + Line1[2].y = Line1[3].y = Line1[0].y + 92*SmallDiam/750; + Line1N = 4; + Line2N = 0; + break; + + case DFCS_CAPTIONMAX: + edge = 47*SmallDiam/750; + Line1[0].x = Line1[5].x = myr.left + 57*SmallDiam/750+3; + Line1[0].y = Line1[1].y = myr.top + 143*SmallDiam/750+1; + Line1[1].x = Line1[2].x = Line1[0].x + 562*SmallDiam/750; + Line1[5].y = Line1[4].y = Line1[0].y + 93*SmallDiam/750; + Line1[2].y = Line1[3].y = Line1[0].y + 513*SmallDiam/750; + Line1[3].x = Line1[4].x = Line1[1].x - edge; + + Line2[0].x = Line2[5].x = Line1[0].x; + Line2[3].x = Line2[4].x = Line1[1].x; + Line2[1].x = Line2[2].x = Line1[0].x + edge; + Line2[0].y = Line2[1].y = Line1[0].y; + Line2[4].y = Line2[5].y = Line1[2].y; + Line2[2].y = Line2[3].y = Line1[2].y - edge; + Line1N = 6; + Line2N = 6; + break; + + case DFCS_CAPTIONRESTORE: + /* FIXME: this one looks bad at small sizes < 15x15 :( */ + edge = 47*SmallDiam/750; + move = 420*SmallDiam/750; + Line1[0].x = Line1[9].x = myr.left + 198*SmallDiam/750+2; + Line1[0].y = Line1[1].y = myr.top + 169*SmallDiam/750+1; + Line1[6].y = Line1[7].y = Line1[0].y + 93*SmallDiam/750; + Line1[7].x = Line1[8].x = Line1[0].x + edge; + Line1[1].x = Line1[2].x = Line1[0].x + move; + Line1[5].x = Line1[6].x = Line1[1].x - edge; + Line1[9].y = Line1[8].y = Line1[0].y + 187*SmallDiam/750; + Line1[2].y = Line1[3].y = Line1[0].y + 327*SmallDiam/750; + Line1[4].y = Line1[5].y = Line1[2].y - edge; + Line1[3].x = Line1[4].x = Line1[2].x - 140*SmallDiam/750; + + Line2[1].x = Line2[2].x = Line1[3].x; + Line2[7].x = Line2[8].x = Line2[1].x - edge; + Line2[0].x = Line2[9].x = Line2[3].x = Line2[4].x = Line2[1].x - move; + Line2[5].x = Line2[6].x = Line2[0].x + edge; + Line2[0].y = Line2[1].y = Line1[9].y; + Line2[4].y = Line2[5].y = Line2[8].y = Line2[9].y = Line2[0].y + 93*SmallDiam/750; + Line2[2].y = Line2[3].y = Line2[0].y + 327*SmallDiam/750; + Line2[6].y = Line2[7].y = Line2[2].y - edge; + Line1N = 10; + Line2N = 10; + break; + + default: + DbgPrint("Invalid caption; flags=0x%04x\n", uFlags); + return FALSE; + } + + /* Here the drawing takes place */ + if(uFlags & DFCS_INACTIVE) + { + /* If we have an inactive button, then you see a shadow */ + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + Polygon(dc, Line1, Line1N); + if(Line2N > 0) + Polygon(dc, Line2, Line2N); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + /* Correct for the shadow shift */ + if (!(uFlags & DFCS_PUSHED)) + { + for(i = 0; i < Line1N; i++) + { + Line1[i].x--; + Line1[i].y--; + } + for(i = 0; i < Line2N; i++) + { + Line2[i].x--; + Line2[i].y--; + } + } + + /* Make the final picture */ + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(colorIdx)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(colorIdx)); + + Polygon(dc, Line1, Line1N); + if(Line2N > 0) + Polygon(dc, Line2, Line2N); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + + return TRUE; +} + +/* Ported from WINE20020904 */ +/* Draw a scroll-bar control coming from DrawFrameControl() */ +static BOOL UITOOLS95_DrawFrameScroll(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Line[4]; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr) - 2; + int i; + HBRUSH hbsave, hb, hb2; + HPEN hpsave, hp, hp2; + int tri = 290*SmallDiam/1000 - 1; + int d46, d93; + + /* + * This fixes a problem with really tiny "scroll" buttons. In particular + * with the updown control. + * Making sure that the arrow is as least 3 pixels wide (or high). + */ + if (tri == 0) + tri = 1; + + switch(uFlags & 0xff) + { + case DFCS_SCROLLCOMBOBOX: + case DFCS_SCROLLDOWN: + Line[2].x = myr.left + 470*SmallDiam/1000 + 2; + Line[2].y = myr.top + 687*SmallDiam/1000 + 1; + Line[0].x = Line[2].x - tri; + Line[1].x = Line[2].x + tri; + Line[0].y = Line[1].y = Line[2].y - tri; + break; + + case DFCS_SCROLLUP: + Line[2].x = myr.left + 470*SmallDiam/1000 + 2; + Line[2].y = myr.bottom - (687*SmallDiam/1000 + 1); + Line[0].x = Line[2].x - tri; + Line[1].x = Line[2].x + tri; + Line[0].y = Line[1].y = Line[2].y + tri; + break; + + case DFCS_SCROLLLEFT: + Line[2].x = myr.right - (687*SmallDiam/1000 + 1); + Line[2].y = myr.top + 470*SmallDiam/1000 + 2; + Line[0].y = Line[2].y - tri; + Line[1].y = Line[2].y + tri; + Line[0].x = Line[1].x = Line[2].x + tri; + break; + + case DFCS_SCROLLRIGHT: + Line[2].x = myr.left + 687*SmallDiam/1000 + 1; + Line[2].y = myr.top + 470*SmallDiam/1000 + 2; + Line[0].y = Line[2].y - tri; + Line[1].y = Line[2].y + tri; + Line[0].x = Line[1].x = Line[2].x - tri; + break; + + case DFCS_SCROLLSIZEGRIP: + /* This one breaks the flow... */ + UITOOLS95_DrawRectEdge(dc, r, EDGE_BUMP, BF_MIDDLE | ((uFlags&(DFCS_MONO|DFCS_FLAT)) ? BF_MONO : 0)); + hpsave = (HPEN)SelectObject(dc, GetStockObject(NULL_PEN)); + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH)); + if(uFlags & (DFCS_MONO|DFCS_FLAT)) + { + hp = hp2 = GetSysColorPen(COLOR_WINDOWFRAME); + hb = hb2 = GetSysColorBrush(COLOR_WINDOWFRAME); + } + else + { + hp = GetSysColorPen(COLOR_BTNHIGHLIGHT); + hp2 = GetSysColorPen(COLOR_BTNSHADOW); + hb = GetSysColorBrush(COLOR_BTNHIGHLIGHT); + hb2 = GetSysColorBrush(COLOR_BTNSHADOW); + } + Line[0].x = Line[1].x = r->right-1; + Line[2].y = Line[3].y = r->bottom-1; + d46 = 46*SmallDiam/750; + d93 = 93*SmallDiam/750; + + i = 586*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + i = 398*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + i = 210*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + return TRUE; + + default: + DbgPrint("Invalid scroll; flags=0x%04x\n", uFlags); + return FALSE; + } + + /* Here do the real scroll-bar controls end up */ + if( ! (uFlags & (0xff00 & ~DFCS_ADJUSTRECT)) ) + /* UITOOLS95_DFC_ButtonPush always uses BF_SOFT which we don't */ + /* want for the normal scroll-arrow button. */ + UITOOLS95_DrawRectEdge( dc, r, EDGE_RAISED, (uFlags&DFCS_ADJUSTRECT) | BF_MIDDLE | BF_RECT); + else + UITOOLS95_DFC_ButtonPush(dc, r, (uFlags & 0xff00) ); + + if(uFlags & DFCS_INACTIVE) + { + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + Polygon(dc, Line, 3); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + if( (uFlags & DFCS_INACTIVE) || !(uFlags & DFCS_PUSHED) ) + for(i = 0; i < 3; i++) + { + Line[i].x--; + Line[i].y--; + } + + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + Polygon(dc, Line, 3); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + + return TRUE; +} + +/* Ported from WINE20020904 */ +/* Draw a menu control coming from DrawFrameControl() */ +static BOOL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Points[6]; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); + int i; + HBRUSH hbsave; + HPEN hpsave; + int xe, ye; + int xc, yc; + BOOL retval = TRUE; + + /* Using black and white seems to be utterly wrong, but win95 doesn't */ + /* use anything else. I think I tried all sys-colors to change things */ + /* without luck. It seems as if this behavior is inherited from the */ + /* win31 DFC() implementation... (you remember, B/W menus). */ + + FillRect(dc, r, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH)); + hpsave = (HPEN)SelectObject(dc, GetStockObject(BLACK_PEN)); + + switch(uFlags & 0xff) + { + case DFCS_MENUARROW: + i = 187*SmallDiam/750; + Points[2].x = myr.left + 468*SmallDiam/750; + Points[2].y = myr.top + 352*SmallDiam/750+1; + Points[0].y = Points[2].y - i; + Points[1].y = Points[2].y + i; + Points[0].x = Points[1].x = Points[2].x - i; + Polygon(dc, Points, 3); + break; + + case DFCS_MENUBULLET: + xe = myr.left; + ye = myr.top + SmallDiam - SmallDiam/2; + xc = myr.left + SmallDiam - SmallDiam/2; + yc = myr.top + SmallDiam - SmallDiam/2; + i = 234*SmallDiam/750; + i = i < 1 ? 1 : i; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + break; + + case DFCS_MENUCHECK: + Points[0].x = myr.left + 253*SmallDiam/1000; + Points[0].y = myr.top + 445*SmallDiam/1000; + Points[1].x = myr.left + 409*SmallDiam/1000; + Points[1].y = Points[0].y + (Points[1].x-Points[0].x); + Points[2].x = myr.left + 690*SmallDiam/1000; + Points[2].y = Points[1].y - (Points[2].x-Points[1].x); + Points[3].x = Points[2].x; + Points[3].y = Points[2].y + 3*SmallDiam/16; + Points[4].x = Points[1].x; + Points[4].y = Points[1].y + 3*SmallDiam/16; + Points[5].x = Points[0].x; + Points[5].y = Points[0].y + 3*SmallDiam/16; + Polygon(dc, Points, 6); + break; + + default: + DbgPrint("Invalid menu; flags=0x%04x\n", uFlags); + retval = FALSE; + break; + } + + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + return retval; +} + +/* Ported from WINE20020904 */ +BOOL WINAPI DrawFrameControl( HDC hdc, LPRECT rc, UINT uType, + UINT uState ) +{ + /* Win95 doesn't support drawing in other mapping modes */ + if(GetMapMode(hdc) != MM_TEXT) + return FALSE; + + switch(uType) + { + case DFC_BUTTON: + return UITOOLS95_DrawFrameButton(hdc, rc, uState); + case DFC_CAPTION: + return UITOOLS95_DrawFrameCaption(hdc, rc, uState); + case DFC_MENU: + return UITOOLS95_DrawFrameMenu(hdc, rc, uState); + case DFC_SCROLL: + return UITOOLS95_DrawFrameScroll(hdc, rc, uState); + default: + DbgPrint("(%x,%p,%d,%x), bad type!\n", hdc,rc,uType,uState ); + } + return FALSE; +} + +/* Ported from WINE20020904 */ +BOOL WINAPI DrawEdge( HDC hdc, LPRECT rc, UINT edge, UINT flags ) +{ + DbgPrint("%04x %d,%d-%d,%d %04x %04x\n", + hdc, rc->left, rc->top, rc->right, rc->bottom, edge, flags ); + + if(flags & BF_DIAGONAL) + return UITOOLS95_DrawDiagEdge(hdc, rc, edge, flags); + else + return UITOOLS95_DrawRectEdge(hdc, rc, edge, flags); +} + WINBOOL STDCALL GrayStringA( @@ -174,17 +1500,6 @@ DrawCaption( WINBOOL STDCALL -DrawEdge( - HDC hdc, - LPRECT qrc, - UINT edge, - UINT grfFlags) -{ - return FALSE; -} - -WINBOOL -STDCALL DrawFocusRect( HDC hDC, CONST RECT *lprc) diff --git a/lib/user32/windows/text.c b/lib/user32/windows/text.c index 5ebd43a..ca2ea82 100644 --- a/lib/user32/windows/text.c +++ b/lib/user32/windows/text.c @@ -28,270 +28,389 @@ /* INCLUDES ******************************************************************/ +#define __NTAPP__ + #include #include + +//#include +#include + #include + +const unsigned short wctype_table[] = +{ +}; + +/* the character type contains the C1_* flags in the low 12 bits */ +/* and the C2_* type in the high 4 bits */ +static inline unsigned short get_char_typeW(WCHAR ch) +{ + extern const unsigned short wctype_table[]; + return wctype_table[wctype_table[ch >> 8] + (ch & 0xff)]; +} + + /* FUNCTIONS *****************************************************************/ +//LPSTR STDCALL CharLowerA(LPSTR lpsz) LPSTR -STDCALL -CharLowerA( - LPSTR lpsz) +WINAPI +CharLowerA(LPSTR x) { - return (LPSTR)NULL; + if (!HIWORD(x)) return (LPSTR)tolower((char)(int)x); +/* + __TRY + { + LPSTR s = x; + while (*s) + { + *s=tolower(*s); + s++; + } + } + __EXCEPT(page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + __ENDTRY + */ + return x; } +//DWORD STDCALL CharLowerBuffA(LPSTR lpsz, DWORD cchLength) DWORD -STDCALL -CharLowerBuffA( - LPSTR lpsz, - DWORD cchLength) +WINAPI +CharLowerBuffA(LPSTR str, DWORD len) { - return 0; + DWORD lenW; + WCHAR *strW; + if (!str) return 0; /* YES */ + + lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR)); + if (strW) { + MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW); + CharLowerBuffW(strW, lenW); + len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL); + HeapFree(GetProcessHeap(), 0, strW); + return len; + } + return 0; } +//DWORD STDCALL CharLowerBuffW(LPWSTR lpsz, DWORD cchLength) DWORD -STDCALL -CharLowerBuffW( - LPWSTR lpsz, - DWORD cchLength) +WINAPI +CharLowerBuffW(LPWSTR str, DWORD len) { - return 0; + DWORD ret = len; + if (!str) return 0; /* YES */ + for (; len; len--, str++) *str = towlower(*str); + return ret; } +//LPWSTR STDCALL CharLowerW(LPWSTR lpsz) LPWSTR -STDCALL -CharLowerW( - LPWSTR lpsz) +WINAPI +CharLowerW(LPWSTR x) { - return (LPWSTR)NULL; + if (HIWORD(x)) { + return _wcslwr(x); + } else { + return (LPWSTR)(INT)towlower((WORD)(((DWORD)(x)) & 0xFFFF)); + } } -LPSTR -STDCALL -CharNextA( - LPCSTR lpsz) +//LPWSTR STDCALL CharPrevW(LPCWSTR lpszStart, LPCWSTR lpszCurrent) +LPWSTR +WINAPI +CharPrevW(LPCWSTR start, LPCWSTR x) { - return (LPSTR)NULL; + if (x > start) return (LPWSTR)(x-1); + else return (LPWSTR)x; } +//LPSTR STDCALL CharNextA(LPCSTR lpsz) LPSTR -STDCALL -CharNextExA( - WORD CodePage, - LPCSTR lpCurrentChar, - DWORD dwFlags) -{ - return (LPSTR)NULL; -} - -LPWSTR -STDCALL -CharNextW( - LPCWSTR lpsz) +WINAPI +CharNextA(LPCSTR ptr) { - return (LPWSTR)NULL; + if (!*ptr) return (LPSTR)ptr; + if (IsDBCSLeadByte(ptr[0]) && ptr[1]) return (LPSTR)(ptr + 2); + return (LPSTR)(ptr + 1); } +//LPSTR STDCALL CharNextExA(WORD CodePage, LPCSTR lpCurrentChar, DWORD dwFlags) LPSTR -STDCALL -CharPrevA( - LPCSTR lpszStart, - LPCSTR lpszCurrent) +WINAPI +CharNextExA(WORD codepage, LPCSTR ptr, DWORD flags) { - return (LPSTR)NULL; + if (!*ptr) return (LPSTR)ptr; + if (IsDBCSLeadByteEx(codepage, ptr[0]) && ptr[1]) return (LPSTR)(ptr + 2); + return (LPSTR)(ptr + 1); } +//LPWSTR STDCALL CharNextW(LPCWSTR lpsz) LPWSTR -STDCALL -CharPrevW( - LPCWSTR lpszStart, - LPCWSTR lpszCurrent) +WINAPI +CharNextW(LPCWSTR x) { - return (LPWSTR)NULL; + if (*x) x++; + return (LPWSTR)x; } +//LPSTR STDCALL CharPrevA(LPCSTR lpszStart, LPCSTR lpszCurrent) LPSTR -STDCALL -CharPrevExA( - WORD CodePage, - LPCSTR lpStart, - LPCSTR lpCurrentChar, - DWORD dwFlags) +WINAPI +CharPrevA(LPCSTR start, LPCSTR ptr) { - return (LPSTR)NULL; + while (*start && (start < ptr)) { + LPCSTR next = CharNextA(start); + if (next >= ptr) break; + start = next; + } + return (LPSTR)start; } -WINBOOL -STDCALL -CharToOemA( - LPCSTR lpszSrc, - LPSTR lpszDst) +//LPSTR STDCALL CharPrevExA(WORD CodePage, LPCSTR lpStart, LPCSTR lpCurrentChar, DWORD dwFlags) +LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags ) { - return FALSE; + while (*start && (start < ptr)) + { + LPCSTR next = CharNextExA( codepage, start, flags ); + if (next > ptr) break; + start = next; + } + return (LPSTR)start; } -WINBOOL -STDCALL -CharToOemBuffA( - LPCSTR lpszSrc, - LPSTR lpszDst, - DWORD cchDstLength) +//WINBOOL STDCALL CharToOemA(LPCSTR lpszSrc, LPSTR lpszDst) +BOOL +WINAPI +CharToOemA(LPCSTR s, LPSTR d) { - return FALSE; + if (!s || !d) return TRUE; + return CharToOemBuffA(s, d, strlen(s) + 1); } -WINBOOL -STDCALL -CharToOemBuffW( - LPCWSTR lpszSrc, - LPSTR lpszDst, - DWORD cchDstLength) +//WINBOOL STDCALL CharToOemBuffA(LPCSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength) +BOOL +WINAPI +CharToOemBuffA(LPCSTR s, LPSTR d, DWORD len) { - return FALSE; + WCHAR* bufW; + + bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (bufW) { + MultiByteToWideChar(CP_ACP, 0, s, len, bufW, len); + WideCharToMultiByte(CP_OEMCP, 0, bufW, len, d, len, NULL, NULL); + HeapFree(GetProcessHeap(), 0, bufW); + } + return TRUE; } -WINBOOL -STDCALL -CharToOemW( - LPCWSTR lpszSrc, - LPSTR lpszDst) +//WINBOOL STDCALL CharToOemBuffW(LPCWSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength) +BOOL +WINAPI +CharToOemBuffW(LPCWSTR s, LPSTR d, DWORD len) { - return FALSE; + if (!s || !d) + return TRUE; + WideCharToMultiByte(CP_OEMCP, 0, s, len, d, len, NULL, NULL); + return TRUE; } -LPSTR -STDCALL -CharUpperA( - LPSTR lpsz) +//WINBOOL STDCALL CharToOemW(LPCWSTR lpszSrc, LPSTR lpszDst) +BOOL +WINAPI +CharToOemW(LPCWSTR s, LPSTR d) { + return CharToOemBuffW(s, d, wcslen(s) + 1); +} + +//LPSTR STDCALL CharUpperA(LPSTR lpsz) +LPSTR WINAPI CharUpperA(LPSTR x) +{ + if (!HIWORD(x)) return (LPSTR)toupper((char)(int)x); +/* + __TRY + { + LPSTR s = x; + while (*s) + { + *s=toupper(*s); + s++; + } + } + __EXCEPT(page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + __ENDTRY + return x; + */ return (LPSTR)NULL; } +//DWORD STDCALL CharUpperBuffA(LPSTR lpsz, DWORD cchLength) DWORD -STDCALL -CharUpperBuffA( - LPSTR lpsz, - DWORD cchLength) +WINAPI +CharUpperBuffA(LPSTR str, DWORD len) { - return 0; + DWORD lenW; + WCHAR* strW; + if (!str) return 0; /* YES */ + + lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR)); + if (strW) { + MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW); + CharUpperBuffW(strW, lenW); + len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL); + HeapFree(GetProcessHeap(), 0, strW); + return len; + } + return 0; } +//DWORD STDCALL CharUpperBuffW(LPWSTR lpsz, DWORD cchLength) DWORD -STDCALL -CharUpperBuffW( - LPWSTR lpsz, - DWORD cchLength) +WINAPI +CharUpperBuffW(LPWSTR str, DWORD len) { - return 0; + DWORD ret = len; + if (!str) return 0; /* YES */ + for (; len; len--, str++) *str = towupper(*str); + return ret; } +//LPWSTR STDCALL CharUpperW(LPWSTR lpsz) LPWSTR -STDCALL -CharUpperW( - LPWSTR lpsz) +WINAPI +CharUpperW(LPWSTR x) { - return (LPWSTR)NULL; + if (HIWORD(x)) return _wcsupr(x); + else return (LPWSTR)(UINT)towlower((WORD)(((DWORD)(x)) & 0xFFFF)); } -WINBOOL -STDCALL -IsCharAlphaA( - CHAR ch) + +//WINBOOL STDCALL IsCharAlphaA(CHAR ch) +BOOL +WINAPI +IsCharAlphaA(CHAR x) { - return FALSE; + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharAlphaW(wch); } +const char IsCharAlphaNumericA_lookup_table[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, + 0x08, 0x54, 0x00, 0xd4, 0x00, 0x00, 0x0c, 0x02, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff +}; + WINBOOL STDCALL -IsCharAlphaNumericA( - CHAR ch) +IsCharAlphaNumericA(CHAR ch) { - return FALSE; +// return (IsCharAlphaNumericA_lookup_table[ch / 8] & (1 << (ch % 8))) ? 1 : 0; + + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1); + return IsCharAlphaNumericW(wch); + //return FALSE; } WINBOOL STDCALL -IsCharAlphaNumericW( - WCHAR ch) +IsCharAlphaNumericW(WCHAR ch) { - return FALSE; + return (get_char_typeW(ch) & (C1_ALPHA|C1_DIGIT)) != 0; +// return FALSE; } -WINBOOL -STDCALL -IsCharAlphaW( - WCHAR ch) +//WINBOOL STDCALL IsCharAlphaW(WCHAR ch) +BOOL +WINAPI +IsCharAlphaW(WCHAR x) { - return FALSE; + return (get_char_typeW(x) & C1_ALPHA) != 0; } -WINBOOL -STDCALL -IsCharLowerA( - CHAR ch) +//WINBOOL STDCALL IsCharLowerA(CHAR ch) +BOOL +WINAPI +IsCharLowerA(CHAR x) { - return FALSE; + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharLowerW(wch); } -WINBOOL -STDCALL -IsCharLowerW( - WCHAR ch) +//WINBOOL STDCALL IsCharLowerW(WCHAR ch) +BOOL +WINAPI +IsCharLowerW(WCHAR x) { - return FALSE; + return (get_char_typeW(x) & C1_LOWER) != 0; } -WINBOOL -STDCALL -IsCharUpperA( - CHAR ch) +//WINBOOL STDCALL IsCharUpperA(CHAR ch) +BOOL +WINAPI +IsCharUpperA(CHAR x) { - return FALSE; + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharUpperW(wch); } -WINBOOL -STDCALL -IsCharUpperW( - WCHAR ch) +//WINBOOL STDCALL IsCharUpperW(WCHAR ch) +BOOL +WINAPI +IsCharUpperW(WCHAR x) { - return FALSE; + return (get_char_typeW(x) & C1_UPPER) != 0; } -WINBOOL -STDCALL -OemToCharA( - LPCSTR lpszSrc, - LPSTR lpszDst) +//WINBOOL STDCALL OemToCharA(LPCSTR lpszSrc, LPSTR lpszDst) +BOOL +WINAPI +OemToCharA(LPCSTR s, LPSTR d) { - return FALSE; + return OemToCharBuffA(s, d, strlen(s) + 1); } -WINBOOL -STDCALL -OemToCharBuffA( - LPCSTR lpszSrc, - LPSTR lpszDst, - DWORD cchDstLength) +//WINBOOL STDCALL OemToCharBuffA(LPCSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength) +BOOL WINAPI OemToCharBuffA(LPCSTR s, LPSTR d, DWORD len) { - return FALSE; + WCHAR* bufW; + + bufW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (bufW) { + MultiByteToWideChar(CP_OEMCP, 0, s, len, bufW, len); + WideCharToMultiByte(CP_ACP, 0, bufW, len, d, len, NULL, NULL); + HeapFree(GetProcessHeap(), 0, bufW); + } + return TRUE; } -WINBOOL -STDCALL -OemToCharBuffW( - LPCSTR lpszSrc, - LPWSTR lpszDst, - DWORD cchDstLength) +//WINBOOL STDCALL OemToCharBuffW(LPCSTR lpszSrc, LPWSTR lpszDst, DWORD cchDstLength) +BOOL +WINAPI +OemToCharBuffW(LPCSTR s, LPWSTR d, DWORD len) { - return FALSE; + MultiByteToWideChar(CP_OEMCP, 0, s, len, d, len); + return TRUE; } -WINBOOL -STDCALL -OemToCharW( - LPCSTR lpszSrc, - LPWSTR lpszDst) +//WINBOOL STDCALL OemToCharW(LPCSTR lpszSrc, LPWSTR lpszDst) +BOOL WINAPI OemToCharW(LPCSTR s, LPWSTR d) { - return FALSE; + return OemToCharBuffW(s, d, strlen(s) + 1); } diff --git a/lib/user32/windows/window.c b/lib/user32/windows/window.c index c15da5d..24d70e7 100644 --- a/lib/user32/windows/window.c +++ b/lib/user32/windows/window.c @@ -286,15 +286,15 @@ CreateWindowExA(DWORD dwExStyle, /* Fixup default coordinates. */ sw = SW_SHOW; - if (x == CW_USEDEFAULT || nWidth == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT) { if (dwStyle & (WS_CHILD | WS_POPUP)) { - if (x == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT) { x = y = 0; } - if (nWidth == CW_USEDEFAULT) + if (nWidth == (LONG) CW_USEDEFAULT) { nWidth = nHeight = 0; } @@ -305,9 +305,9 @@ CreateWindowExA(DWORD dwExStyle, GetStartupInfoA(&info); - if (x == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT) { - if (y != CW_USEDEFAULT) + if (y != (LONG) CW_USEDEFAULT) { sw = y; } @@ -315,7 +315,7 @@ CreateWindowExA(DWORD dwExStyle, y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0; } - if (nWidth == CW_USEDEFAULT) + if (nWidth == (LONG) CW_USEDEFAULT) { if (info.dwFlags & STARTF_USESIZE) { @@ -391,15 +391,15 @@ CreateWindowExW(DWORD dwExStyle, /* Fixup default coordinates. */ sw = SW_SHOW; - if (x == CW_USEDEFAULT || nWidth == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT) { if (dwStyle & (WS_CHILD | WS_POPUP)) { - if (x == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT) { x = y = 0; } - if (nWidth == CW_USEDEFAULT) + if (nWidth == (LONG) CW_USEDEFAULT) { nWidth = nHeight = 0; } @@ -410,9 +410,9 @@ CreateWindowExW(DWORD dwExStyle, GetStartupInfoW(&info); - if (x == CW_USEDEFAULT) + if (x == (LONG) CW_USEDEFAULT) { - if (y != CW_USEDEFAULT) + if (y != (LONG) CW_USEDEFAULT) { sw = y; } @@ -420,7 +420,7 @@ CreateWindowExW(DWORD dwExStyle, y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0; } - if (nWidth == CW_USEDEFAULT) + if (nWidth == (LONG) CW_USEDEFAULT) { if (info.dwFlags & STARTF_USESIZE) { diff --git a/lib/version/.cvsignore b/lib/version/.cvsignore index c189b50..b596370 100644 --- a/lib/version/.cvsignore +++ b/lib/version/.cvsignore @@ -1,3 +1,4 @@ version.coff version.nostrip.dll -version.dll \ No newline at end of file +version.dll +version.sym diff --git a/lib/version/makefile b/lib/version/makefile index 770c8ff..2c8b5e0 100644 --- a/lib/version/makefile +++ b/lib/version/makefile @@ -8,7 +8,11 @@ TARGET_NAME = version TARGET_BASE = 0x77a90000 -TARGET_SDKLIBS = kernel32.a +TARGET_CFLAGS = -fno-builtin + +TARGET_LFLAGS = -nostdlib -nostartfiles + +TARGET_SDKLIBS = kernel32.a ntdll.a TARGET_OBJECTS = misc/libmain.o misc/stubs.o diff --git a/lib/version/misc/.cvsignore b/lib/version/misc/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/version/misc/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/version/misc/libmain.c b/lib/version/misc/libmain.c index 530b679..268a754 100644 --- a/lib/version/misc/libmain.c +++ b/lib/version/misc/libmain.c @@ -1,23 +1,20 @@ + #include + + INT STDCALL -DllMain ( - PVOID hinstDll, - ULONG dwReason, - PVOID reserved - ) +DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - break; - } - return(1); + switch (dwReason) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } - diff --git a/lib/winedbgc/.cvsignore b/lib/winedbgc/.cvsignore new file mode 100644 index 0000000..08743c3 --- /dev/null +++ b/lib/winedbgc/.cvsignore @@ -0,0 +1,4 @@ +*.sym +*.coff +*.dll +*.o diff --git a/lib/winedbgc/Makefile b/lib/winedbgc/Makefile new file mode 100644 index 0000000..057066d --- /dev/null +++ b/lib/winedbgc/Makefile @@ -0,0 +1,35 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_DEFONLY = yes + +TARGET_TYPE = dynlink + +TARGET_NAME = winedbgc + +#TARGET_CFLAGS = -fno-rtti -D_ROS_ -D__WINE__ + +#TARGET_CFLAGS = -g -D__NTDLL__ +TARGET_CFLAGS = -D__NTDLL__ + +TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \ + -Wl,--section-alignment,0x1000 \ + -nostartfiles + +TARGET_BASE = 0x77a90000 + +TARGET_SDKLIBS = ntdll.a kernel32.a + +TARGET_OBJECTS = \ + debug.o \ + libmain.o \ + porting.o \ + winedbgc.o \ + winedbgc.dll.dbg.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/lib/winedbgc/debug.c b/lib/winedbgc/debug.c new file mode 100644 index 0000000..9dff056 --- /dev/null +++ b/lib/winedbgc/debug.c @@ -0,0 +1,436 @@ +/* + * Management of the debugging channels + * + * Copyright 2000 Alexandre Julliard + * + * 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 +#include +#include +#include +#include +#include +#include + */ +#include +#include +#include +#include "porting.h" +/* +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#include "wine/debug.h" +#include "wine/library.h" +#include "wine/unicode.h" + */ +struct dll +{ + struct dll *next; /* linked list of dlls */ + struct dll *prev; + char * const *channels; /* array of channels */ + int nb_channels; /* number of channels in array */ +}; + +static struct dll *first_dll; + +struct debug_option +{ + struct debug_option *next; /* next option in list */ + unsigned char set; /* bits to set */ + unsigned char clear; /* bits to clear */ + char name[14]; /* channel name, or empty for "all" */ +}; + +static struct debug_option *first_option; +static struct debug_option *last_option; + +static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" }; + +static int cmp_name( const void *p1, const void *p2 ) +{ + const char *name = p1; + const char * const *chan = p2; + return strcmp( name, *chan + 1 ); +} + +/* apply a debug option to the channels of a given dll */ +static void apply_option( struct dll *dll, const struct debug_option *opt ) +{ + if (opt->name[0]) + { + char **dbch = bsearch( opt->name, dll->channels, dll->nb_channels, + sizeof(*dll->channels), cmp_name ); + if (dbch) **dbch = (**dbch & ~opt->clear) | opt->set; + } + else /* all */ + { + int i; + for (i = 0; i < dll->nb_channels; i++) + dll->channels[i][0] = (dll->channels[i][0] & ~opt->clear) | opt->set; + } +} + +/* register a new set of channels for a dll */ +void *__wine_dbg_register( char * const *channels, int nb ) +{ + struct debug_option *opt = first_option; + struct dll *dll = malloc( sizeof(*dll) ); + if (dll) + { + dll->channels = channels; + dll->nb_channels = nb; + dll->prev = NULL; + if ((dll->next = first_dll)) dll->next->prev = dll; + first_dll = dll; + + /* apply existing options to this dll */ + while (opt) + { + apply_option( dll, opt ); + opt = opt->next; + } + } + return dll; +} + + +/* unregister a set of channels; must pass the pointer obtained from wine_dbg_register */ +void __wine_dbg_unregister( void *channel ) +{ + struct dll *dll = channel; + if (dll) + { + if (dll->next) dll->next->prev = dll->prev; + if (dll->prev) dll->prev->next = dll->next; + else first_dll = dll->next; + free( dll ); + } +} + + +/* add a new debug option at the end of the option list */ +void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear ) +{ + struct dll *dll = first_dll; + struct debug_option *opt; + + if (!(opt = malloc( sizeof(*opt) ))) return; + opt->next = NULL; + opt->set = set; + opt->clear = clear; + strncpy( opt->name, name, sizeof(opt->name) ); + opt->name[sizeof(opt->name)-1] = 0; + if (last_option) last_option->next = opt; + else first_option = opt; + last_option = opt; + + /* apply option to all existing dlls */ + while (dll) + { + apply_option( dll, opt ); + dll = dll->next; + } +} + +/* parse a set of debugging option specifications and add them to the option list */ +int wine_dbg_parse_options( const char *str ) +{ + char *p, *opt, *next, *options; + int i, errors = 0; + + if (!(options = strdup(str))) return -1; + for (opt = options; opt; opt = next) + { + unsigned char set = 0, clear = 0; + + if ((next = strchr( opt, ',' ))) *next++ = 0; + + p = opt + strcspn( opt, "+-" ); + if (!p[0] || !p[1]) /* bad option, skip it */ + { + errors++; + continue; + } + + if (p > opt) + { + for (i = 0; i < sizeof(debug_classes)/sizeof(debug_classes[0]); i++) + { + int len = strlen(debug_classes[i]); + if (len != (p - opt)) continue; + if (!memcmp( opt, debug_classes[i], len )) /* found it */ + { + if (*p == '+') set |= 1 << i; + else clear |= 1 << i; + break; + } + } + if (i == sizeof(debug_classes)/sizeof(debug_classes[0])) /* bad class name, skip it */ + { + errors++; + continue; + } + } + else + { + if (*p == '+') set = ~0; + else clear = ~0; + } + p++; + if (!strcmp( p, "all" )) p = ""; /* empty string means all */ + wine_dbg_add_option( p, set, clear ); + } + free( options ); + return errors; +} + +#ifdef __WINE__ + +/* varargs wrapper for __wine_dbg_vprintf */ +int wine_dbg_printf( const char *format, ... ) +{ + int ret; + va_list valist; + + va_start(valist, format); + ret = __wine_dbg_vprintf( format, valist ); + va_end(valist); + return ret; +} + + +/* varargs wrapper for __wine_dbg_vlog */ +int wine_dbg_log( int cls, const char *channel, const char *func, const char *format, ... ) +{ + int ret; + va_list valist; + + va_start(valist, format); + ret = __wine_dbg_vlog( cls, channel, func, format, valist ); + va_end(valist); + return ret; +} + +#endif /*__WINE__*/ + +/* allocate some tmp string space */ +/* FIXME: this is not 100% thread-safe */ +static char *get_tmp_space( int size ) +{ + static char *list[32]; + static long pos; + char *ret; + int idx; + + idx = interlocked_xchg_add( &pos, 1 ) % (sizeof(list)/sizeof(list[0])); + if ((ret = realloc( list[idx], size ))) list[idx] = ret; + return ret; +} + + +/* default implementation of wine_dbgstr_an */ +static const char *default_dbgstr_an( const char *str, int n ) +{ + char *dst, *res; + + if (!HIWORD(str)) + { + if (!str) return "(null)"; + res = get_tmp_space( 6 ); + sprintf( res, "#%04x", LOWORD(str) ); + return res; + } + if (n == -1) n = strlen(str); + if (n < 0) n = 0; + else if (n > 200) n = 200; + dst = res = get_tmp_space( n * 4 + 6 ); + *dst++ = '"'; + while (n-- > 0) + { + unsigned char c = *str++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c >= ' ' && c <= 126) + *dst++ = c; + else + { + *dst++ = '\\'; + *dst++ = '0' + ((c >> 6) & 7); + *dst++ = '0' + ((c >> 3) & 7); + *dst++ = '0' + ((c >> 0) & 7); + } + } + } + *dst++ = '"'; + if (*str) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst = 0; + return res; +} + + +/* default implementation of wine_dbgstr_wn */ +static const char *default_dbgstr_wn( const WCHAR *str, int n ) +{ + char *dst, *res; + + if (!HIWORD(str)) + { + if (!str) return "(null)"; + res = get_tmp_space( 6 ); + sprintf( res, "#%04x", LOWORD(str) ); + return res; + } + if (n == -1) n = strlenW(str); + if (n < 0) n = 0; + else if (n > 200) n = 200; + dst = res = get_tmp_space( n * 5 + 7 ); + *dst++ = 'L'; + *dst++ = '"'; + while (n-- > 0) + { + WCHAR c = *str++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c >= ' ' && c <= 126) + *dst++ = c; + else + { + *dst++ = '\\'; + sprintf(dst,"%04x",c); + dst+=4; + } + } + } + *dst++ = '"'; + if (*str) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst = 0; + return res; +} + + +/* default implementation of wine_dbgstr_guid */ +static const char *default_dbgstr_guid( const struct _GUID *id ) +{ + char *str; + + if (!id) return "(null)"; + if (!((int)id >> 16)) + { + str = get_tmp_space( 12 ); + sprintf( str, "", (int)id & 0xffff ); + } + else + { + str = get_tmp_space( 40 ); + sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], + id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); + } + return str; +} + + +/* default implementation of wine_dbg_vprintf */ +static int default_dbg_vprintf( const char *format, va_list args ) +{ + return vfprintf( stderr, format, args ); +} + + +/* default implementation of wine_dbg_vlog */ +static int default_dbg_vlog( int cls, const char *channel, const char *func, + const char *format, va_list args ) +{ + int ret = 0; + + if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) + ret += wine_dbg_printf( "%s:%s:%s ", debug_classes[cls], channel + 1, func ); + if (format) + ret += __wine_dbg_vprintf( format, args ); + return ret; +} + + +/* exported function pointers so that debugging functions can be redirected at run-time */ + +const char * (*__wine_dbgstr_an)( const char * s, int n ) = default_dbgstr_an; +const char * (*__wine_dbgstr_wn)( const WCHAR *s, int n ) = default_dbgstr_wn; +const char * (*__wine_dbgstr_guid)( const struct _GUID *id ) = default_dbgstr_guid; +int (*__wine_dbg_vprintf)( const char *format, va_list args ) = default_dbg_vprintf; +int (*__wine_dbg_vlog)( int cls, const char *channel, const char *function, + const char *format, va_list args ) = default_dbg_vlog; + +/* wrappers to use the function pointers */ + +#ifdef __WINE__ + +const char *wine_dbgstr_guid( const struct _GUID *id ) +{ + return __wine_dbgstr_guid(id); +} + +const char *wine_dbgstr_an( const char * s, int n ) +{ + return __wine_dbgstr_an(s, n); +} + +const char *wine_dbgstr_wn( const WCHAR *s, int n ) +{ + return __wine_dbgstr_wn(s, n); +} + +const char *wine_dbgstr_a( const char *s ) +{ + return __wine_dbgstr_an( s, -1 ); +} + +const char *wine_dbgstr_w( const WCHAR *s ) +{ + return __wine_dbgstr_wn( s, -1 ); +} + +#endif /*__WINE__*/ diff --git a/lib/winedbgc/libmain.c b/lib/winedbgc/libmain.c new file mode 100644 index 0000000..f9fd854 --- /dev/null +++ b/lib/winedbgc/libmain.c @@ -0,0 +1,97 @@ +/* + * Win32 winedbgc functions + * + * + * 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 +//#include +//#include +//#include +//#include +//#include +//#include +//#include +/* +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include + +#include "winbase.h" +#include "wine/debug.h" +#include "wine/library.h" + +#include "proxywinedbgc.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winedbgc); + */ + +/*********************************************************************** + * DllMain [Internal] Initializes the internal 'winedbgc32.DLL'. + * + * PARAMS + * hinstDLL [I] handle to the DLL's instance + * fdwReason [I] + * lpvReserved [I] reserved, must be NULL + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ +// TRACE("Initializing or Finalizing winedbgc: %p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved); + if (fdwReason == DLL_PROCESS_ATTACH) + { +// TRACE("Loading winedbgc...\n"); +/* +#ifndef __REACTOS__ + if (winedbgc_LoadDriverManager()) + winedbgc_LoadDMFunctions(); +#endif + */ + } + else if (fdwReason == DLL_PROCESS_DETACH) + { +// TRACE("Unloading winedbgc...\n"); +/* +#ifndef __REACTOS__ + if (gProxyHandle.bFunctionReady) + { + int i; + for ( i = 0; i < NUM_SQLFUNC; i ++ ) + { + gProxyHandle.functions[i].func = SQLDummyFunc; + } + } + if (gProxyHandle.dmHandle) + { + wine_dlclose(gProxyHandle.dmHandle,NULL,0); + gProxyHandle.dmHandle = NULL; + } +#endif + */ + } + return TRUE; +} + + +/* EOF */ diff --git a/lib/winedbgc/porting.c b/lib/winedbgc/porting.c new file mode 100644 index 0000000..18b84f6 --- /dev/null +++ b/lib/winedbgc/porting.c @@ -0,0 +1,38 @@ +/* + * Porting wine comtrl32 to ReactOS comctrl32 support functions + * + * Copyright 2002 Robert Dickenson + * + * 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 +#include "porting.h" + + +static int interlocked_mutex; +void _lwp_mutex_lock(int* interlocked_mutex) {} +void _lwp_mutex_unlock(int* interlocked_mutex) {} + +long interlocked_xchg_add( long *dest, long incr ) +{ + long retv; + _lwp_mutex_lock( &interlocked_mutex ); + retv = *dest; + *dest += incr; + _lwp_mutex_unlock( &interlocked_mutex ); + return retv; +} + diff --git a/lib/winedbgc/porting.h b/lib/winedbgc/porting.h new file mode 100644 index 0000000..bc03379 --- /dev/null +++ b/lib/winedbgc/porting.h @@ -0,0 +1,40 @@ +/* + * Porting from wine to ReactOS definitions + * + * Copyright 2002 Robert Dickenson + * + * 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 __PORTING_WINE2ROS_H +#define __PORTING_WINE2ROS_H + + +#ifndef __GNUC__ +#define inline _inline +#endif + +long interlocked_xchg_add(long *dest, long incr); + +#define strlenW wcslen + +#define strstrW wcsstr +#define strtolW wcstol +#define strncasecmp strncmp +#define snprintf _snprintf +#define strcasecmp _stricmp + + +#endif /* __PORTING_WINE2ROS_H */ diff --git a/lib/winedbgc/winedbgc.c b/lib/winedbgc/winedbgc.c new file mode 100644 index 0000000..f382f3d --- /dev/null +++ b/lib/winedbgc/winedbgc.c @@ -0,0 +1,258 @@ +/* + * Debugging channels functions for WINE + */ +#include +#include +#include +#include "porting.h" + +//#include +#include + +//DECLARE_DEBUG_CHANNEL(tid); +DECLARE_DEBUG_CHANNEL(winedbgc); + + +/* ---------------------------------------------------------------------- */ + +struct debug_info +{ + char *str_pos; /* current position in strings buffer */ + char *out_pos; /* current position in output buffer */ + char strings[1024]; /* buffer for temporary strings */ + char output[1024]; /* current output line */ +}; + +static struct debug_info tmp; + +/* get the debug info pointer for the current thread */ +static inline struct debug_info *get_info(void) +{ + struct debug_info *info = NtCurrentTeb()->WineDebugInfo; + if (!info) + { + if (!tmp.str_pos) + { + tmp.str_pos = tmp.strings; + tmp.out_pos = tmp.output; + } + if (!RtlGetProcessHeap()) return &tmp; + /* setup the temp structure in case HeapAlloc wants to print something */ + NtCurrentTeb()->WineDebugInfo = &tmp; + info = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(*info) ); + info->str_pos = info->strings; + info->out_pos = info->output; + NtCurrentTeb()->WineDebugInfo = info; + } + return info; +} + +/* allocate some tmp space for a string */ +static void *gimme1(int n) +{ + struct debug_info *info = get_info(); + char *res = info->str_pos; + + if (res + n >= &info->strings[sizeof(info->strings)]) res = info->strings; + info->str_pos = res + n; + return res; +} + +/* release extra space that we requested in gimme1() */ +static inline void release( void *ptr ) +{ + struct debug_info *info = NtCurrentTeb()->WineDebugInfo; + info->str_pos = ptr; +} + +/*********************************************************************** + * wine_dbgstr_an (NTDLL.@) + */ +const char *wine_dbgstr_an( const char *src, int n ) +{ + char *dst, *res; + + if (!((WORD)(DWORD)(src) >> 16)) + { + if (!src) return "(null)"; + res = gimme1(6); + sprintf(res, "#%04x", (WORD)(DWORD)(src) ); + return res; + } + if (n < 0) n = 0; + else if (n > 200) n = 200; + dst = res = gimme1 (n * 4 + 6); + *dst++ = '"'; + while (n-- > 0 && *src) + { + unsigned char c = *src++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c >= ' ' && c <= 126) + *dst++ = c; + else + { + *dst++ = '\\'; + *dst++ = '0' + ((c >> 6) & 7); + *dst++ = '0' + ((c >> 3) & 7); + *dst++ = '0' + ((c >> 0) & 7); + } + } + } + *dst++ = '"'; + if (*src) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst++ = '\0'; + release( dst ); + return res; +} + +/*********************************************************************** + * wine_dbgstr_wn (NTDLL.@) + */ +const char *wine_dbgstr_wn( const WCHAR *src, int n ) +{ + char *dst, *res; + + if (!((WORD)(DWORD)(src) >> 16)) + { + if (!src) return "(null)"; + res = gimme1(6); + sprintf(res, "#%04x", (WORD)(DWORD)(src) ); + return res; + } + if (n < 0) n = 0; + else if (n > 200) n = 200; + dst = res = gimme1 (n * 5 + 7); + *dst++ = 'L'; + *dst++ = '"'; + while (n-- > 0 && *src) + { + WCHAR c = *src++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c >= ' ' && c <= 126) + *dst++ = c; + else + { + *dst++ = '\\'; + sprintf(dst,"%04x",c); + dst+=4; + } + } + } + *dst++ = '"'; + if (*src) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst++ = '\0'; + release( dst ); + return res; +} + +/*********************************************************************** + * wine_dbgstr_guid (NTDLL.@) + */ +const char *wine_dbgstr_guid( const GUID *id ) +{ + char *str; + + if (!id) return "(null)"; + if (!((WORD)(DWORD)(id) >> 16)) + { + str = gimme1(12); + sprintf( str, "", (WORD)(DWORD)(id) ); + } + else + { + str = gimme1(40); + sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], + id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); + } + return str; +} + +/*********************************************************************** + * wine_dbg_vprintf (NTDLL.@) + */ +int wine_dbg_vprintf( const char *format, va_list args ) +{ + struct debug_info *info = get_info(); + char *p; + + int ret = _vsnprintf( info->out_pos, sizeof(info->output) - (info->out_pos - info->output), + format, args ); + + p = strrchr( info->out_pos, '\n' ); + if (!p) info->out_pos += ret; + else + { + char *pos = info->output; + char saved_ch; + p++; + saved_ch = *p; + *p = 0; + DbgPrint(pos); + *p = saved_ch; + /* move beginning of next line to start of buffer */ + while ((*pos = *p++)) pos++; + info->out_pos = pos; + } + return ret; +} + +/*********************************************************************** + * wine_dbg_printf (NTDLL.@) + */ +int wine_dbg_printf(const char *format, ...) +{ + int ret; + va_list valist; + + va_start(valist, format); + ret = wine_dbg_vprintf( format, valist ); + va_end(valist); + return ret; +} + +/*********************************************************************** + * wine_dbg_log (NTDLL.@) + */ +int wine_dbg_log(enum __DEBUG_CLASS cls, const char *channel, + const char *function, const char *format, ... ) +{ + static const char *classes[__DBCL_COUNT] = { "fixme", "err", "warn", "trace" }; + va_list valist; + int ret = 0; + + va_start(valist, format); + if (TRACE_ON(winedbgc)) + ret = wine_dbg_printf( "%08lx:", NtCurrentTeb()->Cid.UniqueThread); + if (cls < __DBCL_COUNT) + ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel + 1, function ); + if (format) + ret += wine_dbg_vprintf( format, valist ); + va_end(valist); + return ret; +} diff --git a/lib/winedbgc/winedbgc.def b/lib/winedbgc/winedbgc.def new file mode 100644 index 0000000..4b86134 --- /dev/null +++ b/lib/winedbgc/winedbgc.def @@ -0,0 +1,37 @@ +; $Id$ +; +; ReactOS Operating System +; +LIBRARY winedbgc.dll + +EXPORTS + +wine_dbg_log +wine_dbg_printf +wine_dbgstr_an +wine_dbgstr_guid +wine_dbgstr_wn +__wine_dbg_register +__wine_dbg_unregister +__wine_dbg_vlog DATA +__wine_dbg_vprintf DATA +__wine_dbgstr_an DATA +__wine_dbgstr_guid DATA +__wine_dbgstr_wn DATA + + +; +;wine_dbg_log @1 +;__wine_dbg_register @2 +;__wine_dbg_unregister @3 +;__wine_dbg_vlog @4 DATA +;__wine_dbg_vprintf @5 DATA +;__wine_dbgstr_an @6 DATA +;__wine_dbgstr_guid @7 DATA +;__wine_dbgstr_wn @8 DATA +; +;wine_dbg_printf @34 +;wine_dbgstr_an @36 +;wine_dbgstr_guid @37 +;wine_dbgstr_wn @39 +; \ No newline at end of file diff --git a/lib/winedbgc/winedbgc.dll.dbg.c b/lib/winedbgc/winedbgc.dll.dbg.c new file mode 100644 index 0000000..8273668 --- /dev/null +++ b/lib/winedbgc/winedbgc.dll.dbg.c @@ -0,0 +1,42 @@ +/* File generated automatically; do not edit! */ +/* This file can be copied, modified and distributed without restriction. */ + +char __wine_dbch_winedbgc[] = "\003winedbgc"; + +static char * const debug_channels[4] = +{ + __wine_dbch_winedbgc +}; + +static void *debug_registration; + +#ifdef __GNUC__ +static void __wine_dbg_winedbgc32_init(void) __attribute__((constructor)); +static void __wine_dbg_winedbgc32_fini(void) __attribute__((destructor)); +#else +static void __asm__dummy_dll_init(void) { +asm("\t.section\t\".init\" ,\"ax\"\n" + "\tcall ___wine_dbg_winedbgc32_init\n" + "\t.section\t\".fini\" ,\"ax\"\n" + "\tcall ___wine_dbg_winedbgc32_fini\n" + "\t.section\t\".text\"\n"); +} +#endif /* defined(__GNUC__) */ + +#ifdef __GNUC__ +static +#endif +void __wine_dbg_winedbgc32_init(void) +{ +// extern void *__wine_dbg_register( char * const *, int ); +// debug_registration = __wine_dbg_register( debug_channels, 4 ); +} + +#ifdef __GNUC__ +static +#endif +void __wine_dbg_winedbgc32_fini(void) +{ +// extern void __wine_dbg_unregister( void* ); +// __wine_dbg_unregister( debug_registration ); +} diff --git a/lib/winedbgc/winedbgc.edf b/lib/winedbgc/winedbgc.edf new file mode 100644 index 0000000..7f5eddb --- /dev/null +++ b/lib/winedbgc/winedbgc.edf @@ -0,0 +1,81 @@ +; $Id$ +; +; ReactOS Operating System +; +LIBRARY winedbgc.dll + +EXPORTS + +wine_dbg_log +wine_dbg_printf +wine_dbgstr_an +wine_dbgstr_guid +wine_dbgstr_wn +__wine_dbg_register +__wine_dbg_unregister +__wine_dbg_vlog DATA +__wine_dbg_vprintf DATA +__wine_dbgstr_an DATA +__wine_dbgstr_guid DATA +__wine_dbgstr_wn DATA + + + +;wine_dbgstr_an +;wine_dbgstr_wn +;wine_dbgstr_guid +;wine_dbg_vprintf +;wine_dbg_printf +;wine_dbg_log + +; wine_dbg_log @1 +; __wine_dbg_register @2 +; __wine_dbg_unregister @3 +; __wine_dbg_vlog @4 DATA +; __wine_dbg_vprintf @5 DATA +; __wine_dbgstr_an @6 DATA +; __wine_dbgstr_guid @7 DATA +; __wine_dbgstr_wn @8 DATA +;__wine_dll_register @9 +;__wine_main_argc @10 DATA +;__wine_main_argv @11 DATA +;__wine_main_wargv @12 DATA + + +;interlocked_cmpxchg @20 +;interlocked_cmpxchg_ptr @21 +;interlocked_xchg @22 +;interlocked_xchg_add @23 +;interlocked_xchg_ptr @24 +;wine_anon_mmap @30 +;wine_dbg_add_option @31 +;wine_dbg_parse_options @33 +; wine_dbg_printf @34 +;wine_dbgstr_a @35 +; wine_dbgstr_an @36 +; wine_dbgstr_guid @37 +;wine_dbgstr_w @38 +; wine_dbgstr_wn @39 +;wine_dlclose @40 +;wine_dll_load @41 +;wine_dll_load_main_exe @42 +;wine_dll_set_callback @43 +;wine_dll_unload @44 +;wine_dlopen @45 +;wine_dlsym @46 +;wine_errno_location @47 DATA +;wine_get_config_dir @48 +;wine_get_cs @49 +;wine_get_ds @50 +;wine_get_es @51 +;wine_get_fs @52 +;wine_get_gs @53 +;wine_get_server_dir @54 +;wine_get_ss @55 +;wine_h_errno_location @56 DATA +;wine_ldt_copy @57 DATA +;wine_ldt_get_entry @58 +;wine_ldt_set_entry @59 +;wine_rewrite_s4tos2 @60 +;wine_set_fs @61 +;wine_set_gs @62 diff --git a/lib/winedbgc/winedbgc.rc b/lib/winedbgc/winedbgc.rc new file mode 100644 index 0000000..061cc81 --- /dev/null +++ b/lib/winedbgc/winedbgc.rc @@ -0,0 +1,38 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "WINE debug channels for ReactOS\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "winedbgc\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "winedbgc.dll\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/lib/winmm/dllmain.c b/lib/winmm/dllmain.c index 2eb5093..98404da 100644 --- a/lib/winmm/dllmain.c +++ b/lib/winmm/dllmain.c @@ -11,7 +11,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include INT STDCALL diff --git a/lib/winmm/misc/.cvsignore b/lib/winmm/misc/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/winmm/misc/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/winmm/misc/stubs.c b/lib/winmm/misc/stubs.c index 9af5d8a..4744cb5 100644 --- a/lib/winmm/misc/stubs.c +++ b/lib/winmm/misc/stubs.c @@ -1,7 +1,11 @@ /* - The stubs here are totaly wrong so please help a brother out - and fix this shit. sedwards 9-24-02 -*/ + * The stubs here are totaly wrong so please help a brother out + * and fix this shit. sedwards 9-24-02 + * + * Added more stubs for bochs 1.3 once again still mostly wrong + * but bochs gets further now. 12-14-02 + * + */ #include @@ -11,15 +15,24 @@ UINT WINAPI waveOutReset(HWAVEOUT hWaveOut) { - DbgPrint("waveOutReset unimplemented\n"); + DbgPrint("waveOutReset stub\n"); return 1; } + +UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("waveOutWrite stub\n"); + return 1; +} + + WINBOOL STDCALL sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags) { - DbgPrint("waveOutReset unimplemented\n"); + DbgPrint("sndPlaySoundA stub\n"); return 1; } @@ -27,6 +40,95 @@ WINBOOL STDCALL sndPlaySoundW(LPCSTR pszSoundA, UINT uFlags) { - DbgPrint("waveOutReset unimplemented\n"); + DbgPrint("sndPlaySoundW stub\n"); + return 1; +} + +WINBOOL +STDCALL +midiOutReset(HWAVEOUT hWaveOut) +{ + DbgPrint("midiOutReset stub\n"); + return 1; +} + +WINBOOL +STDCALL +waveOutPrepareHeader(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("waveOutPrepareHeader stub\n"); + return 1; +} + +WINBOOL +STDCALL +waveOutGetErrorTextA(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("waveOutGetErrorTextA stub\n"); + return 1; +} + +WINBOOL +STDCALL +waveOutOpen(HWAVEOUT* lphWaveOut, UINT uDeviceID, + const lpFormat, DWORD dwCallback, + DWORD dwInstance, DWORD dwFlags) +{ + DbgPrint("waveOutOpen stub\n"); + return 1; +} + +UINT +WINAPI +waveOutClose(HWAVEOUT hWaveOut) +{ + DbgPrint("waveOutClose stub\n"); + return 1; +} + +WINBOOL +STDCALL +midiOutClose(HWAVEOUT hWaveOut) +{ + DbgPrint("midiOutClose stub\n"); + return 1; +} + +WINBOOL +STDCALL +midiOutUnprepareHeader(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("midiOutUnprepareHeader stub\n"); + return 1; +} + +WINBOOL +STDCALL +waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("waveOutUnprepareHeader stub\n"); + return 1; +} + + +WINBOOL +STDCALL +midiOutPrepareHeader(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("midiOutPrepareHeader stub\n"); + return 1; +} + +WINBOOL +STDCALL +midiOutLongMsg(HWAVEOUT hWaveOut, LPCSTR pszSoundA, + UINT uSize) +{ + DbgPrint("midiOutLongMsg stub\n"); return 1; } diff --git a/lib/winmm/winmm.def b/lib/winmm/winmm.def index 7d36f1f..d0a9cbb 100644 --- a/lib/winmm/winmm.def +++ b/lib/winmm/winmm.def @@ -1,6 +1,16 @@ LIBRARY WINMM.DLL EXPORTS -; add more exports as needed -waveOutReset@4 +midiOutReset@4 +midiOutClose@4 +midiOutUnprepareHeader@12 sndPlaySoundA@8 -sndPlaySoundW@8 \ No newline at end of file +sndPlaySoundW@8 +waveOutReset@4 +waveOutWrite@12 +waveOutPrepareHeader@12 +waveOutGetErrorTextA@12 +waveOutOpen@24 +waveOutClose@4 +waveOutUnprepareHeader@12 +midiOutPrepareHeader@12 +midiOutLongMsg@12 \ No newline at end of file diff --git a/lib/winmm/winmm.edf b/lib/winmm/winmm.edf index fee70d2..e53abcd 100644 --- a/lib/winmm/winmm.edf +++ b/lib/winmm/winmm.edf @@ -1,6 +1,16 @@ LIBRARY WINMM.DLL EXPORTS -; add more exports as needed -waveOutReset=waveOutReset@4 +midiOutReset=midiOutReset@4 +midiOutClose=midiOutClose@4 +midiOutUnprepareHeader=midiOutUnprepareHeader@12 sndPlaySoundA=sndPlaySoundA@8 -sndPlaySoundW=sndPlaySoundW@8 \ No newline at end of file +sndPlaySoundW=sndPlaySoundW@8 +waveOutReset=waveOutReset@4 +waveOutWrite=waveOutWrite@12 +waveOutPrepareHeader=waveOutPrepareHeader@12 +waveOutGetErrorTextA=waveOutGetErrorTextA@12 +waveOutOpen=waveOutOpen@24 +waveOutClose=waveOutClose@4 +waveOutUnprepareHeader=waveOutUnprepareHeader@12 +midiOutPrepareHeader=midiOutPrepareHeader@12 +midiOutLongMsg=midiOutLongMsg@12 \ No newline at end of file diff --git a/lib/ws2_32/.cvsignore b/lib/ws2_32/.cvsignore index 1e224b1..72affdb 100644 --- a/lib/ws2_32/.cvsignore +++ b/lib/ws2_32/.cvsignore @@ -2,6 +2,7 @@ ws2_32.a ws2_32.dll ws2_32.nostrip.dll ws2_32.coff +ws2_32.sym base.tmp junk.tmp temp.exp diff --git a/lib/ws2_32/makefile b/lib/ws2_32/makefile index 5525bbd..66a48ce 100644 --- a/lib/ws2_32/makefile +++ b/lib/ws2_32/makefile @@ -8,7 +8,16 @@ TARGET_NAME = ws2_32 TARGET_BASE = 0x77780000 -TARGET_CFLAGS = -I./include -DUNICODE -DLE -DDBG +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -DUNICODE \ + -DLE \ + -DDBG + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a diff --git a/lib/ws2_32/misc/.cvsignore b/lib/ws2_32/misc/.cvsignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/lib/ws2_32/misc/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/lib/ws2_32/misc/catalog.c b/lib/ws2_32/misc/catalog.c index da89f6e..ef077be 100644 --- a/lib/ws2_32/misc/catalog.c +++ b/lib/ws2_32/misc/catalog.c @@ -131,10 +131,10 @@ PCATALOG_ENTRY LocateProvider( ListEntry); for (i = 0; i < Provider->Mapping->Rows; i++) { - if ((lpProtocolInfo->iAddressFamily == Provider->Mapping->Mapping[i].AddressFamily) && - (lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) && - ((lpProtocolInfo->iProtocol == Provider->Mapping->Mapping[i].Protocol) || - (lpProtocolInfo->iSocketType == SOCK_RAW))) { + if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) && + (lpProtocolInfo->iSocketType == (INT) Provider->Mapping->Mapping[i].SocketType) && + ((lpProtocolInfo->iProtocol == (INT) Provider->Mapping->Mapping[i].Protocol) || + (lpProtocolInfo->iSocketType == SOCK_RAW))) { //LeaveCriticalSection(&CatalogLock); WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider)); return Provider; @@ -155,7 +155,6 @@ PCATALOG_ENTRY LocateProviderById( { PLIST_ENTRY CurrentEntry; PCATALOG_ENTRY Provider; - UINT i; WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId)); diff --git a/lib/ws2_32/misc/dllmain.c b/lib/ws2_32/misc/dllmain.c index ed6b181..d3d34b5 100644 --- a/lib/ws2_32/misc/dllmain.c +++ b/lib/ws2_32/misc/dllmain.c @@ -288,7 +288,6 @@ select( PCATALOG_ENTRY Provider; INT Count; INT Errno; - ULONG i; WS_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n", readfds, writefds, exceptfds)); diff --git a/lib/ws2_32/misc/event.c b/lib/ws2_32/misc/event.c index 671cdbd..d83c5a0 100644 --- a/lib/ws2_32/misc/event.c +++ b/lib/ws2_32/misc/event.c @@ -176,7 +176,6 @@ WSAEventSelect( PCATALOG_ENTRY Provider; INT Status; INT Errno; - LONG i; if (!WSAINITIALIZED) { WSASetLastError(WSANOTINITIALISED); diff --git a/lib/ws2_32/misc/sndrcv.c b/lib/ws2_32/misc/sndrcv.c index 3f64254..3cd3bbd 100644 --- a/lib/ws2_32/misc/sndrcv.c +++ b/lib/ws2_32/misc/sndrcv.c @@ -9,6 +9,7 @@ */ #include #include +#include INT EXPORT diff --git a/lib/ws2_32/misc/upcall.c b/lib/ws2_32/misc/upcall.c index 227f59e..c9e9fc8 100644 --- a/lib/ws2_32/misc/upcall.c +++ b/lib/ws2_32/misc/upcall.c @@ -9,6 +9,7 @@ */ #include #include +#include BOOL WSPAPI @@ -118,7 +119,7 @@ WPUModifyIFSHandle( } Socket = (SOCKET)CreateProviderHandle( - ProposedHandle, + (HANDLE)ProposedHandle, Provider); *lpErrno = NO_ERROR; diff --git a/lib/ws2help/makefile b/lib/ws2help/makefile index 3bb2aa4..0756122 100644 --- a/lib/ws2help/makefile +++ b/lib/ws2help/makefile @@ -8,7 +8,14 @@ TARGET_NAME = ws2help TARGET_BASE = 0x777c0000 -TARGET_CFLAGS = -DUNICODE +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -DUNICODE + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_SDKLIBS = ntdll.a kernel32.a ws2_32.a diff --git a/loaders/boot/boot.asm b/loaders/boot/boot.asm index 019ea01..525380e 100644 --- a/loaders/boot/boot.asm +++ b/loaders/boot/boot.asm @@ -30,8 +30,8 @@ ; $Header$ ; ; $Log$ -; Revision 1.3 2002/11/07 12:04:04 short -; update for HEAD-2002110701 +; Revision 1.4 2003/02/12 22:32:53 short +; update for HEAD-2003021201 ; ; Revision 1.4 2000/06/25 03:59:14 dwelch ; diff --git a/loaders/boot/boot.mak b/loaders/boot/boot.mak index 99fb0b9..9dbd842 100644 --- a/loaders/boot/boot.mak +++ b/loaders/boot/boot.mak @@ -4,8 +4,8 @@ # $Header$ # # $Log$ -# Revision 1.3 2002/11/07 12:04:04 short -# update for HEAD-2002110701 +# Revision 1.4 2003/02/12 22:32:53 short +# update for HEAD-2003021201 # # Revision 1.4 2000/06/25 03:59:14 dwelch # diff --git a/loaders/boot/bootbk.asm b/loaders/boot/bootbk.asm index aafff8c..d73d1a9 100644 --- a/loaders/boot/bootbk.asm +++ b/loaders/boot/bootbk.asm @@ -30,8 +30,8 @@ ; $Header$ ; ; $Log$ -; Revision 1.3 2002/11/07 12:04:04 short -; update for HEAD-2002110701 +; Revision 1.4 2003/02/12 22:32:53 short +; update for HEAD-2003021201 ; ; Revision 1.4 2000/06/25 03:59:14 dwelch ; diff --git a/loaders/dos/.cvsignore b/loaders/dos/.cvsignore new file mode 100644 index 0000000..ed6fe06 --- /dev/null +++ b/loaders/dos/.cvsignore @@ -0,0 +1 @@ +*.com diff --git a/loaders/dos/loadros.asm b/loaders/dos/loadros.asm index 99f00e6..720b050 100644 --- a/loaders/dos/loadros.asm +++ b/loaders/dos/loadros.asm @@ -843,7 +843,7 @@ pe_load_module: mov dx, _cpe_doshdr int 0x21 jnc .header_read - mov dx, error_file_read_failed + mov di, error_file_read_failed jmp error .header_read @@ -853,7 +853,7 @@ pe_load_module: mov ax, word [_cpe_doshdr + e_magic] cmp ax, 'MZ' je .mz_hdr_good - mov dx, error_bad_mz + mov di, error_bad_mz jmp error .mz_hdr_good @@ -871,7 +871,7 @@ pe_load_module: mov bx, [_current_filehandle] int 0x21 jnc .start_seek1 - mov dx, error_file_seek_failed + mov di, error_file_seek_failed jmp error .start_seek1: mov ah, 0x3F @@ -880,7 +880,7 @@ pe_load_module: mov dx, _mb_magic int 0x21 jnc .mb_header_read - mov dx, error_file_read_failed + mov di, error_file_read_failed jmp error .mb_header_read: jmp .first @@ -900,7 +900,7 @@ load_module1: mov ax, 0x3d00 int 0x21 jnc .file_opened - mov dx, error_file_open_failed + mov di, error_file_open_failed jmp error .file_opened: @@ -925,7 +925,7 @@ load_module1: mov dx, 0 int 0x21 jnc .seek_start - mov dx, error_file_seek_failed + mov di, error_file_seek_failed jmp error .seek_start: ret @@ -941,7 +941,7 @@ load_module2: mov bx, [_current_filehandle] int 0x21 jnc .start_end - mov dx, error_file_seek_failed + mov di, error_file_seek_failed jmp error .start_end shl edx, 16 @@ -956,7 +956,7 @@ load_module2: mov bx, [_current_filehandle] int 0x21 jnc .start_seek - mov dx, error_file_seek_failed + mov di, error_file_seek_failed jmp error .start_seek @@ -979,7 +979,7 @@ load_module2: int 0x21 jnc .read_data_succeeded pop ds - mov dx, error_file_read_failed + mov di, error_file_read_failed jmp error .read_data_succeeded: %ifndef NDEBUG @@ -1023,7 +1023,7 @@ load_module2: int 0x21 jnc .read_last_data_succeeded pop ds - mov dx, error_file_read_failed + mov di, error_file_read_failed jmp error .read_last_data_succeeded: ;; @@ -1088,10 +1088,9 @@ load_module3: ;; On error print a message and return zero ;; error: - mov ah, 0x9 - int 0x21 - mov eax, 0 - ret + call print_string + mov ax,04c00h + int 21h ;; ;; Copy to high memory @@ -1283,20 +1282,22 @@ _loader_data_base_16_23: dw 0x0000 error_pmode_already: + db 0xa, 0xd db 'Error: The processor is already in protected mode' - db 0xa, 0xd, '$' + db 0xa, 0xd, 0 error_file_open_failed: - db 'Error: Failed to open file' - db 0xa, 0xd, '$' + db 0xa, 0xd + db 'Error: Failed to open file (code 0x%a)' + db 0xa, 0xd, 0 error_file_seek_failed: - db 'Error: File seek failed' - db 0xa, 0xd, '$' + db 0xa, 0xd + db 'Error: File seek failed (code 0x%a)' + db 0xa, 0xd, 0 error_file_read_failed: - db 'Error: File read failed' - db 0xa, 0xd, '$' -error_coff_load_failed: - db 'Error: Failed to load COFF file' - db 0xa, 0xd, '$' + db 0xa, 0xd + db 'Error: File read failed (code 0x%a)' + db 0xa, 0xd, 0 error_bad_mz: + db 0xa, 0xd db 'Error: Bad DOS EXE magic' - db 0xa, 0xd, '$' + db 0xa, 0xd, 0 diff --git a/ntoskrnl/.cvsignore b/ntoskrnl/.cvsignore index 3eff845..b40c38a 100644 --- a/ntoskrnl/.cvsignore +++ b/ntoskrnl/.cvsignore @@ -1,11 +1,12 @@ +objects base.tmp junk.tmp -ntoskrnl.coff -objects temp.exp +ntoskrnl.coff +ntoskrnl.map ntoskrnl.dbg bugcodes.rc msg*.bin -ntoskrnl.map *.o *.sym +*.exe diff --git a/ntoskrnl/Makefile b/ntoskrnl/Makefile index b371e8e..e89e6b9 100644 --- a/ntoskrnl/Makefile +++ b/ntoskrnl/Makefile @@ -27,7 +27,7 @@ endif ifeq ($(KDBG), 1) OBJECTS_KDBG := dbg/kdb.o dbg/kdb_keyboard.o dbg/rdebug.o \ - dbg/i386/kdb_help.o dbg/kdb_stabs.o + dbg/i386/kdb_help.o dbg/kdb_stabs.o dbg/profile.o else OBJECTS_KDBG := endif @@ -89,6 +89,7 @@ OBJECTS_RTL = \ rtl/error.o \ rtl/handle.o \ rtl/largeint.o \ + rtl/math.o \ rtl/mem.o \ rtl/memchr.o \ rtl/memcpy.o \ @@ -336,7 +337,8 @@ OBJECTS_KD = \ kd/kdebug.o \ kd/service.o \ kd/dlog.o \ - kd/gdbstub.o kd/mda.o + kd/gdbstub.o \ + kd/mda.o DEP_OBJECTS := $(OBJECTS_NT) $(OBJECTS_MM) $(OBJECTS_ARCH) \ $(OBJECTS_IO) $(OBJECTS_KE) $(OBJECTS_OB) \ @@ -652,7 +654,7 @@ implib: $(DDK_PATH_LIB)/$(TARGETNAME).a clean: - $(RM) $(OBJECTS_PATH)/*.o cc/*.o cm/*.o dbg/*.o dbg/i386/*.o ex/*.o \ ex/i386/*.o io/*.o ke/*.o ldr/*.o mm/*.o nt/*.o ob/*.o ps/*.o \ - rtl/*.o se/*.o ke/i386/*.o mm/i386/*.o fs/*.o po/*.o nls/*.o \ + rtl/*.o rtl/i386/*.o se/*.o ke/i386/*.o mm/i386/*.o fs/*.o po/*.o nls/*.o \ lpc/*.o kd/*.o $(TARGETNAME).o junk.tmp base.tmp temp.exp \ $(TARGETNAME).exe $(TARGETNAME).nostrip.exe $(TARGETNAME).sym ntoskrnl.map \ $(TARGETNAME).coff bugcodes.rc msg?????.bin $(DEP_FILES) \ diff --git a/ntoskrnl/cc/misc.c b/ntoskrnl/cc/misc.c index 18bf9cf..0fbbbb9 100644 --- a/ntoskrnl/cc/misc.c +++ b/ntoskrnl/cc/misc.c @@ -82,6 +82,8 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, (ULONG)FileSizes->ValidDataLength.QuadPart); Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + + DPRINT("Bcb 0x%.08x\n", Bcb); KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); diff --git a/ntoskrnl/cc/pin.c b/ntoskrnl/cc/pin.c index c29c2b2..1df84da 100644 --- a/ntoskrnl/cc/pin.c +++ b/ntoskrnl/cc/pin.c @@ -26,14 +26,9 @@ #define ROUND_DOWN(N, S) ((N) - ((N) % (S))) -/* FUNCTIONS *****************************************************************/ +extern NPAGED_LOOKASIDE_LIST iBcbLookasideList; -typedef struct _INTERNAL_BCB -{ - PUBLIC_BCB PFCB; - PCACHE_SEGMENT CacheSegment; - BOOLEAN Dirty; -} INTERNAL_BCB, *PINTERNAL_BCB; +/* FUNCTIONS *****************************************************************/ BOOLEAN STDCALL CcMapData (IN PFILE_OBJECT FileObject, @@ -57,7 +52,8 @@ CcMapData (IN PFILE_OBJECT FileObject, ReadOffset = FileOffset->QuadPart; Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; - + assert(Bcb); + DPRINT("AllocationSize %d, FileSize %d\n", (ULONG)Bcb->AllocationSize.QuadPart, (ULONG)Bcb->FileSize.QuadPart); @@ -90,12 +86,13 @@ CcMapData (IN PFILE_OBJECT FileObject, } } *pBuffer += ReadOffset % Bcb->CacheSegmentSize; - iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB)); + iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList); if (iBcb == NULL) { CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); return FALSE; } + memset(iBcb, 0, sizeof(INTERNAL_BCB)); iBcb->CacheSegment = CacheSeg; iBcb->Dirty = FALSE; iBcb->PFCB.MappedLength = Length; @@ -110,7 +107,7 @@ CcUnpinData (IN PVOID Bcb) PINTERNAL_BCB iBcb = Bcb; CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, iBcb->Dirty, FALSE); - ExFreePool(iBcb); + ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); } VOID STDCALL @@ -118,10 +115,6 @@ CcSetDirtyPinnedData (IN PVOID Bcb, IN PLARGE_INTEGER Lsn) { PINTERNAL_BCB iBcb = Bcb; -#if 0 iBcb->Dirty = TRUE; -#else - WriteCacheSegment(iBcb->CacheSegment); -#endif } diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 7a91f81..8a346f3 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -63,21 +63,51 @@ /* GLOBALS *******************************************************************/ +/* + * If CACHE_BITMAP is defined, the cache manager uses one large memory region + * within the kernel address space and allocate/deallocate space from this block + * over a bitmap. If CACHE_BITMAP is used, the size of the mdl mapping region + * must be reduced (ntoskrnl\mm\mdl.c, MI_MDLMAPPING_REGION_SIZE). + */ +//#define CACHE_BITMAP + #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) #define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N) #define TAG_CSEG TAG('C', 'S', 'E', 'G') #define TAG_BCB TAG('B', 'C', 'B', ' ') +#define TAG_IBCB TAG('i', 'B', 'C', 'B') static LIST_ENTRY DirtySegmentListHead; static LIST_ENTRY CacheSegmentListHead; static LIST_ENTRY CacheSegmentLRUListHead; +static LIST_ENTRY ClosedListHead; +static ULONG DirtyPageCount=0; static FAST_MUTEX ViewLock; +#ifdef CACHE_BITMAP +#define CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024) + +static PVOID CiCacheSegMappingRegionBase = NULL; +static RTL_BITMAP CiCacheSegMappingRegionAllocMap; +static ULONG CiCacheSegMappingRegionHint; +static KSPIN_LOCK CiCacheSegMappingRegionLock; +#endif + +NPAGED_LOOKASIDE_LIST iBcbLookasideList; +static NPAGED_LOOKASIDE_LIST BcbLookasideList; +static NPAGED_LOOKASIDE_LIST CacheSegLookasideList; + +static ULONG CcTimeStamp; +static KEVENT LazyCloseThreadEvent; +static HANDLE LazyCloseThreadHandle; +static CLIENT_ID LazyCloseThreadId; +static volatile BOOLEAN LazyCloseThreadShouldTerminate; + void * alloca(size_t size); -NTSTATUS STDCALL +NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); /* FUNCTIONS *****************************************************************/ @@ -94,6 +124,7 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment) KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql); CacheSegment->Dirty = FALSE; RemoveEntryList(&CacheSegment->DirtySegmentListEntry); + DirtyPageCount -= CacheSegment->Bcb->CacheSegmentSize / PAGE_SIZE; CacheSegment->ReferenceCount--; KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql); ExReleaseFastMutex(&ViewLock); @@ -101,6 +132,9 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment) return(Status); } +VOID CcRosRemoveUnusedFiles(VOID); + + NTSTATUS CcRosFlushDirtyPages(ULONG Target, PULONG Count) { @@ -109,13 +143,40 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count) ULONG PagesPerSegment; BOOLEAN Locked; NTSTATUS Status; + static ULONG WriteCount[4] = {0, 0, 0, 0}; + ULONG NewTarget; DPRINT("CcRosFlushDirtyPages(Target %d)\n", Target); (*Count) = 0; ExAcquireFastMutex(&ViewLock); + + WriteCount[0] = WriteCount[1]; + WriteCount[1] = WriteCount[2]; + WriteCount[2] = WriteCount[3]; + WriteCount[3] = 0; + + NewTarget = WriteCount[0] + WriteCount[1] + WriteCount[2]; + + if (NewTarget < DirtyPageCount) + { + NewTarget = (DirtyPageCount - NewTarget + 3) / 4; + WriteCount[0] += NewTarget; + WriteCount[1] += NewTarget; + WriteCount[2] += NewTarget; + WriteCount[3] += NewTarget; + } + + NewTarget = WriteCount[0]; + + Target = max(NewTarget, Target); + current_entry = DirtySegmentListHead.Flink; + if (current_entry == &DirtySegmentListHead) + { + DPRINT("No Dirty pages\n"); + } while (current_entry != &DirtySegmentListHead && Target > 0) { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, @@ -148,8 +209,13 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count) ExAcquireFastMutex(&ViewLock); current_entry = DirtySegmentListHead.Flink; } + if (*Count < NewTarget) + { + WriteCount[1] += (NewTarget - *Count); + } ExReleaseFastMutex(&ViewLock); - DPRINT("CcRosTrimCache() finished\n"); + DPRINT("CcRosFlushDirtyPages() finished\n"); + return(STATUS_SUCCESS); } @@ -217,7 +283,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) return(STATUS_SUCCESS); } -NTSTATUS STDCALL +NTSTATUS CcRosReleaseCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg, BOOLEAN Valid, @@ -227,6 +293,8 @@ CcRosReleaseCacheSegment(PBCB Bcb, BOOLEAN WasDirty = CacheSeg->Dirty; KIRQL oldIrql; + assert(Bcb); + DPRINT("CcReleaseCacheSegment(Bcb %x, CacheSeg %x, Valid %d)\n", Bcb, CacheSeg, Valid); @@ -237,6 +305,7 @@ CcRosReleaseCacheSegment(PBCB Bcb, if (!WasDirty && CacheSeg->Dirty) { InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; } RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry); @@ -262,12 +331,15 @@ CcRosReleaseCacheSegment(PBCB Bcb, return(STATUS_SUCCESS); } -PCACHE_SEGMENT CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) +PCACHE_SEGMENT +CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) { PLIST_ENTRY current_entry; PCACHE_SEGMENT current; KIRQL oldIrql; + assert(Bcb); + DPRINT("CcRosLookupCacheSegment(Bcb %x, FileOffset %d)\n", Bcb, FileOffset); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); @@ -295,6 +367,8 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) PCACHE_SEGMENT CacheSeg; KIRQL oldIrql; + assert(Bcb); + DPRINT("CcRosMarkDirtyCacheSegment(Bcb %x, FileOffset %d)\n", Bcb, FileOffset); CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); @@ -307,6 +381,7 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) { ExAcquireFastMutex(&ViewLock); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; ExReleaseFastMutex(&ViewLock); } else @@ -330,6 +405,8 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) BOOLEAN WasDirty; KIRQL oldIrql; + assert(Bcb); + DPRINT("CcRosUnmapCacheSegment(Bcb %x, FileOffset %d, NowDirty %d)\n", Bcb, FileOffset, NowDirty); @@ -349,6 +426,7 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) { ExAcquireFastMutex(&ViewLock); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; ExReleaseFastMutex(&ViewLock); } @@ -379,11 +457,15 @@ CcRosCreateCacheSegment(PBCB Bcb, PLIST_ENTRY current_entry; NTSTATUS Status; KIRQL oldIrql; +#ifdef CACHE_BITMAP + ULONG StartingOffset; +#endif + + assert(Bcb); DPRINT("CcRosCreateCacheSegment()\n"); - current = ExAllocatePoolWithTag(NonPagedPool, sizeof(CACHE_SEGMENT), - TAG_CSEG); + current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList); current->Valid = FALSE; current->Dirty = FALSE; current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); @@ -415,7 +497,7 @@ CcRosCreateCacheSegment(PBCB Bcb, KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); ExReleaseFastMutex(&(*CacheSeg)->Lock); ExReleaseFastMutex(&ViewLock); - ExFreePool(*CacheSeg); + ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); *CacheSeg = current; if (Lock) { @@ -432,7 +514,26 @@ CcRosCreateCacheSegment(PBCB Bcb, InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); ExReleaseFastMutex(&ViewLock); +#ifdef CACHE_BITMAP + KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); + StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint); + + if (StartingOffset == 0xffffffff) + { + DPRINT1("Out of CacheSeg mapping space\n"); + KeBugCheck(0); + } + + current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE; + + if (CiCacheSegMappingRegionHint == StartingOffset) + { + CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE; + } + + KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); +#else MmLockAddressSpace(MmGetKernelAddressSpace()); current->BaseAddress = NULL; Status = MmCreateMemoryArea(NULL, @@ -448,6 +549,7 @@ CcRosCreateCacheSegment(PBCB Bcb, { KeBugCheck(0); } +#endif for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++) { PHYSICAL_ADDRESS Page; @@ -487,6 +589,8 @@ CcRosGetCacheSegmentChain(PBCB Bcb, PCACHE_SEGMENT* CacheSegList; PCACHE_SEGMENT Previous = NULL; + assert(Bcb); + DPRINT("CcRosGetCacheSegmentChain()\n"); Length = ROUND_UP(Length, Bcb->CacheSegmentSize); @@ -542,6 +646,8 @@ CcRosGetCacheSegment(PBCB Bcb, PCACHE_SEGMENT current; NTSTATUS Status; + assert(Bcb); + DPRINT("CcRosGetCacheSegment()\n"); /* @@ -582,6 +688,8 @@ CcRosRequestCacheSegment(PBCB Bcb, { ULONG BaseOffset; + assert(Bcb); + if ((FileOffset % Bcb->CacheSegmentSize) != 0) { CPRINT("Bad fileoffset %x should be multiple of %x", @@ -596,7 +704,8 @@ CcRosRequestCacheSegment(PBCB Bcb, UptoDate, CacheSeg)); } - +#ifdef CACHE_BITMAP +#else STATIC VOID CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty) @@ -607,16 +716,45 @@ CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, MmReleasePageMemoryConsumer(MC_CACHE, PhysAddr); } } - -NTSTATUS STDCALL +#endif +NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg) /* * FUNCTION: Releases a cache segment associated with a BCB */ { - +#ifdef CACHE_BITMAP + ULONG i; + ULONG RegionSize; + ULONG Base; + PHYSICAL_ADDRESS PhysicalAddr; + KIRQL oldIrql; +#endif DPRINT("Freeing cache segment %x\n", CacheSeg); +#ifdef CACHE_BITMAP + RegionSize = CacheSeg->Bcb->CacheSegmentSize / PAGE_SIZE; + + /* Unmap all the pages. */ + for (i = 0; i < RegionSize; i++) + { + MmDeleteVirtualMapping(NULL, + CacheSeg->BaseAddress + (i * PAGE_SIZE), + FALSE, + NULL, + &PhysicalAddr); + MmReleasePageMemoryConsumer(MC_CACHE, PhysicalAddr); + } + + KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); + /* Deallocate all the pages used. */ + Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE; + + RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize); + CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base); + + KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); +#else MmLockAddressSpace(MmGetKernelAddressSpace()); MmFreeMemoryArea(MmGetKernelAddressSpace(), CacheSeg->BaseAddress, @@ -624,16 +762,19 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg) CcFreeCachePage, NULL); MmUnlockAddressSpace(MmGetKernelAddressSpace()); - ExFreePool(CacheSeg); +#endif + ExFreeToNPagedLookasideList(&CacheSegLookasideList, CacheSeg); return(STATUS_SUCCESS); } -NTSTATUS STDCALL +NTSTATUS CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) { NTSTATUS Status; KIRQL oldIrql; + assert(Bcb); + DPRINT("CcRosFreeCacheSegment(Bcb %x, CacheSeg %x)\n", Bcb, CacheSeg); @@ -645,6 +786,8 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) if (CacheSeg->Dirty) { RemoveEntryList(&CacheSeg->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + } KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); ExReleaseFastMutex(&ViewLock); @@ -671,6 +814,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap) { Bcb = (PBCB)SectionObjectPointers->SharedCacheMap; + assert(Bcb); if (FileOffset) { Offset = *FileOffset; @@ -701,8 +845,8 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, IoStatus->Status = Status; } } - ExReleaseFastMutex(¤t->Lock); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + ExReleaseFastMutex(¤t->Lock); current->ReferenceCount--; KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); } @@ -727,7 +871,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, } } -NTSTATUS STDCALL +NTSTATUS CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) /* * FUNCTION: Releases the BCB associated with a file object @@ -738,26 +882,30 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) NTSTATUS Status; LIST_ENTRY FreeList; KIRQL oldIrql; - - DPRINT("CcRosDeleteFileCache(FileObject %x, Bcb %x)\n", - Bcb->FileObject, Bcb); + assert(Bcb); + + Bcb->RefCount++; ExReleaseFastMutex(&ViewLock); CcFlushCache(FileObject->SectionObjectPointers, NULL, 0, NULL); ExAcquireFastMutex(&ViewLock); - + Bcb->RefCount--; if (Bcb->RefCount == 0) { - MmFreeSectionSegments(Bcb->FileObject); + if (Bcb->BcbRemoveListEntry.Flink != NULL) + { + RemoveEntryList(&Bcb->BcbRemoveListEntry); + Bcb->BcbRemoveListEntry.Flink = NULL; + } + + FileObject->SectionObjectPointers->SharedCacheMap = NULL; /* * Release all cache segments. */ InitializeListHead(&FreeList); - - FileObject->SectionObjectPointers->SharedCacheMap = NULL; KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); current_entry = Bcb->BcbSegmentListHead.Flink; while (!IsListEmpty(&Bcb->BcbSegmentListHead)) @@ -769,20 +917,24 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) if (current->Dirty) { RemoveEntryList(¤t->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + DPRINT1("Freeing dirty segment\n"); } InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry); - } KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + + ExReleaseFastMutex(&ViewLock); + ObDereferenceObject (Bcb->FileObject); + while (!IsListEmpty(&FreeList)) { current_entry = RemoveTailList(&FreeList); current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); Status = CcRosInternalFreeCacheSegment(current); } - - ObDereferenceObject (Bcb->FileObject); - ExFreePool(Bcb); + ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb); + ExAcquireFastMutex(&ViewLock); } return(STATUS_SUCCESS); } @@ -792,19 +944,51 @@ VOID CcRosReferenceCache(PFILE_OBJECT FileObject) PBCB Bcb; ExAcquireFastMutex(&ViewLock); Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap; + assert(Bcb); Bcb->RefCount++; ExReleaseFastMutex(&ViewLock); } +VOID CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer) +{ + PBCB Bcb; +// DPRINT1("CcRosSetRemoveOnClose()\n"); + ExAcquireFastMutex(&ViewLock); + Bcb = (PBCB)SectionObjectPointer->SharedCacheMap; + if (Bcb) + { + Bcb->RemoveOnClose = TRUE; + if (Bcb->RefCount == 0) + { + CcRosDeleteFileCache(Bcb->FileObject, Bcb); + } + } + ExReleaseFastMutex(&ViewLock); +} + + VOID CcRosDereferenceCache(PFILE_OBJECT FileObject) { PBCB Bcb; ExAcquireFastMutex(&ViewLock); Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap; - Bcb->RefCount--; - if (Bcb->RefCount == 0) + assert(Bcb); + if (Bcb->RefCount > 0) { - CcRosDeleteFileCache(FileObject, Bcb); + Bcb->RefCount--; + if (Bcb->RefCount == 0) + { + MmFreeSectionSegments(Bcb->FileObject); + if (Bcb->RemoveOnClose) + { + CcRosDeleteFileCache(FileObject, Bcb); + } + else + { + Bcb->TimeStamp = CcTimeStamp; + InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry); + } + } } ExReleaseFastMutex(&ViewLock); } @@ -816,6 +1000,8 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb) * has been closed. */ { + assert(Bcb); + ExAcquireFastMutex(&ViewLock); if (FileObject->SectionObjectPointers->SharedCacheMap != NULL) @@ -823,11 +1009,22 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb) if (FileObject->PrivateCacheMap != NULL) { FileObject->PrivateCacheMap = NULL; - Bcb->RefCount--; - } - if (Bcb->RefCount == 0) - { - CcRosDeleteFileCache(FileObject, Bcb); + if (Bcb->RefCount > 0) + { + Bcb->RefCount--; + if (Bcb->RefCount == 0) + { + if (Bcb->RemoveOnClose) + { + CcRosDeleteFileCache(FileObject, Bcb); + } + else + { + Bcb->TimeStamp = CcTimeStamp; + InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry); + } + } + } } } ExReleaseFastMutex(&ViewLock); @@ -849,12 +1046,13 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, if (*Bcb == NULL) { - (*Bcb) = ExAllocatePoolWithTag(NonPagedPool, sizeof(BCB), TAG_BCB); + (*Bcb) = ExAllocateFromNPagedLookasideList(&BcbLookasideList); if ((*Bcb) == NULL) { + ExReleaseFastMutex(&ViewLock); return(STATUS_UNSUCCESSFUL); } - + memset((*Bcb), 0, sizeof(BCB)); ObReferenceObjectByPointer(FileObject, FILE_ALL_ACCESS, NULL, @@ -877,6 +1075,11 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, FileObject->PrivateCacheMap = *Bcb; (*Bcb)->RefCount++; } + if ((*Bcb)->BcbRemoveListEntry.Flink != NULL) + { + RemoveEntryList(&(*Bcb)->BcbRemoveListEntry); + (*Bcb)->BcbRemoveListEntry.Flink = NULL; + } ExReleaseFastMutex(&ViewLock); return(STATUS_SUCCESS); @@ -889,21 +1092,154 @@ CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap) { Bcb = (PBCB)SectionObjectPointers->SharedCacheMap; + assert(Bcb); return Bcb->FileObject; } return NULL; } +VOID STDCALL +CmLazyCloseThreadMain(PVOID Ignored) +{ + LARGE_INTEGER Timeout; + PLIST_ENTRY current_entry; + PBCB current; + ULONG RemoveTimeStamp; + NTSTATUS Status; + + KeQuerySystemTime (&Timeout); + + while (1) + { + Timeout.QuadPart += 100000000LL; // 10sec + Status = KeWaitForSingleObject(&LazyCloseThreadEvent, + 0, + KernelMode, + FALSE, + &Timeout); + + DPRINT("LazyCloseThreadMain %d\n", CcTimeStamp); + + if (!NT_SUCCESS(Status)) + { + DbgPrint("LazyCloseThread: Wait failed\n"); + KeBugCheck(0); + break; + } + if (LazyCloseThreadShouldTerminate) + { + DbgPrint("LazyCloseThread: Terminating\n"); + break; + } + + ExAcquireFastMutex(&ViewLock); + CcTimeStamp++; + if (CcTimeStamp >= 30) + { + RemoveTimeStamp = CcTimeStamp - 30; /* 5min = 10sec * 30 */ + while (!IsListEmpty(&ClosedListHead)) + { + current_entry = ClosedListHead.Blink; + current = CONTAINING_RECORD(current_entry, BCB, BcbRemoveListEntry); + if (current->TimeStamp >= RemoveTimeStamp) + { + break; + } + CcRosDeleteFileCache(current->FileObject, current); + } + } + ExReleaseFastMutex(&ViewLock); + } +} + VOID CcInitView(VOID) { +#ifdef CACHE_BITMAP + PMEMORY_AREA marea; + PVOID Buffer; +#endif + NTSTATUS Status; + KPRIORITY Priority; + DPRINT("CcInitView()\n"); +#ifdef CACHE_BITMAP + CiCacheSegMappingRegionHint = 0; + CiCacheSegMappingRegionBase = NULL; + + MmLockAddressSpace(MmGetKernelAddressSpace()); + + Status = MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_CACHE_SEGMENT, + &CiCacheSegMappingRegionBase, + CI_CACHESEG_MAPPING_REGION_SIZE, + 0, + &marea, + FALSE); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(0); + } + + Buffer = ExAllocatePool(NonPagedPool, CI_CACHESEG_MAPPING_REGION_SIZE / (PAGE_SIZE * 8)); + + RtlInitializeBitMap(&CiCacheSegMappingRegionAllocMap, Buffer, CI_CACHESEG_MAPPING_REGION_SIZE / PAGE_SIZE); + RtlClearAllBits(&CiCacheSegMappingRegionAllocMap); + + KeInitializeSpinLock(&CiCacheSegMappingRegionLock); +#endif InitializeListHead(&CacheSegmentListHead); InitializeListHead(&DirtySegmentListHead); InitializeListHead(&CacheSegmentLRUListHead); + InitializeListHead(&ClosedListHead); ExInitializeFastMutex(&ViewLock); + ExInitializeNPagedLookasideList (&iBcbLookasideList, + NULL, + NULL, + 0, + sizeof(INTERNAL_BCB), + TAG_IBCB, + 20); + ExInitializeNPagedLookasideList (&BcbLookasideList, + NULL, + NULL, + 0, + sizeof(BCB), + TAG_BCB, + 20); + ExInitializeNPagedLookasideList (&CacheSegLookasideList, + NULL, + NULL, + 0, + sizeof(CACHE_SEGMENT), + TAG_CSEG, + 20); + MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache); + CcInitCacheZeroPage(); + + CcTimeStamp = 0; + LazyCloseThreadShouldTerminate = FALSE; + KeInitializeEvent (&LazyCloseThreadEvent, SynchronizationEvent, FALSE); + Status = PsCreateSystemThread(&LazyCloseThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &LazyCloseThreadId, + (PKSTART_ROUTINE)CmLazyCloseThreadMain, + NULL); + if (NT_SUCCESS(Status)) + { + Priority = LOW_REALTIME_PRIORITY; + NtSetInformationThread(LazyCloseThreadHandle, + ThreadPriority, + &Priority, + sizeof(Priority)); + } + } /* EOF */ diff --git a/ntoskrnl/cm/cm.h b/ntoskrnl/cm/cm.h index 69a345d..394d5c4 100644 --- a/ntoskrnl/cm/cm.h +++ b/ntoskrnl/cm/cm.h @@ -26,6 +26,12 @@ #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM" #define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY" +#define REG_SYSTEM_FILE_NAME L"\\SYSTEM" +#define REG_SOFTWARE_FILE_NAME L"\\SOFTWARE" +#define REG_USER_FILE_NAME L"\\DEFAULT" +#define REG_SAM_FILE_NAME L"\\SAM" +#define REG_SEC_FILE_NAME L"\\SECURITY" + #define REG_BLOCK_SIZE 4096 #define REG_HBIN_DATA_OFFSET 32 #define REG_BIN_ID 0x6e696268 @@ -36,9 +42,6 @@ #define REG_KEY_CELL_ID 0x6b6e #define REG_HASH_TABLE_BLOCK_ID 0x666c #define REG_VALUE_CELL_ID 0x6b76 -#define REG_LINK_KEY_CELL_TYPE 0x10 -#define REG_KEY_CELL_TYPE 0x20 -#define REG_ROOT_KEY_CELL_TYPE 0x2c #define REG_HIVE_ID 0x66676572 #define REGISTRY_FILE_MAGIC "REGEDIT4" @@ -52,7 +55,7 @@ #define MAX_REG_STD_HANDLE_NAME 19 // BLOCK_OFFSET = offset in file after header block -typedef DWORD BLOCK_OFFSET; +typedef ULONG BLOCK_OFFSET; /* header for registry hive file : */ typedef struct _HIVE_HEADER @@ -185,6 +188,12 @@ typedef struct _KEY_CELL UCHAR Name[0]; } __attribute__((packed)) KEY_CELL, *PKEY_CELL; +/* KEY_CELL.Type constants */ +#define REG_LINK_KEY_CELL_TYPE 0x10 +#define REG_KEY_CELL_TYPE 0x20 +#define REG_ROOT_KEY_CELL_TYPE 0x2c + + // hash record : // HashValue=four letters of value's name typedef struct _HASH_RECORD @@ -220,6 +229,10 @@ typedef struct _VALUE_CELL UCHAR Name[0]; /* warning : not zero terminated */ } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL; +/* VALUE_CELL.Flags constants */ +#define REG_VALUE_NAME_PACKED 0x0001 + + typedef struct _DATA_CELL { LONG CellSize; @@ -228,6 +241,7 @@ typedef struct _DATA_CELL typedef struct _REGISTRY_HIVE { + LIST_ENTRY HiveList; ULONG Flags; UNICODE_STRING Filename; ULONG FileSize; @@ -240,8 +254,11 @@ typedef struct _REGISTRY_HIVE ULONG FreeListMax; PCELL_HEADER *FreeList; BLOCK_OFFSET *FreeListOffset; -// KSPIN_LOCK RegLock; - KSEMAPHORE RegSem; + ERESOURCE HiveResource; + + RTL_BITMAP DirtyBitMap; + BOOLEAN HiveDirty; + // NTSTATUS (*Extend)(ULONG NewSize); // PVOID (*Flush)(VOID); } REGISTRY_HIVE, *PREGISTRY_HIVE; @@ -314,6 +331,9 @@ extern PREGISTRY_HIVE CmiVolatileHive; extern POBJECT_TYPE CmiKeyType; extern KSPIN_LOCK CmiKeyListLock; +extern LIST_ENTRY CmiHiveListHead; +extern ERESOURCE CmiHiveListLock; + VOID CmiVerifyBinCell(PHBIN BinCell); @@ -376,6 +396,12 @@ CmiCreateRegistryHive(PWSTR Filename, PREGISTRY_HIVE *RegistryHive, BOOLEAN CreateNew); +NTSTATUS +CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive); + +NTSTATUS +CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive); + ULONG CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell); @@ -412,9 +438,14 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive, IN ULONG CreateOptions); NTSTATUS +CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive, + IN PKEY_OBJECT Parent, + IN PKEY_OBJECT SubKey); + +NTSTATUS CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, - IN PCHAR ValueName, + IN PUNICODE_STRING ValueName, OUT PVALUE_CELL *ValueCell, OUT BLOCK_OFFSET *VBOffset); @@ -427,14 +458,15 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, - IN PCHAR ValueNameBuf, - OUT PVALUE_CELL *pValueCell, - OUT BLOCK_OFFSET *pVBOffset); + IN PUNICODE_STRING ValueName, + OUT PVALUE_CELL *pValueCell, + OUT BLOCK_OFFSET *pVBOffset); NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN PCHAR ValueName); + IN PKEY_CELL KeyCell, + IN BLOCK_OFFSET KeyCellOffset, + IN PUNICODE_STRING ValueName); NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, @@ -454,10 +486,15 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, BLOCK_OFFSET NKBOffset); NTSTATUS +CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive, + PHASH_TABLE_CELL HashBlock, + BLOCK_OFFSET NKBOffset); + +NTSTATUS CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive, - OUT PVALUE_CELL *ValueCell, - OUT BLOCK_OFFSET *VBOffset, - IN PCHAR ValueNameBuf); + OUT PVALUE_CELL *ValueCell, + OUT BLOCK_OFFSET *VBOffset, + IN PUNICODE_STRING ValueName); NTSTATUS CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, @@ -477,8 +514,8 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive, PVOID CmiGetBlock(PREGISTRY_HIVE RegistryHive, - BLOCK_OFFSET BlockOffset, - OUT PHBIN * ppBin); + BLOCK_OFFSET BlockOffset, + OUT PHBIN * ppBin); VOID CmiLockBlock(PREGISTRY_HIVE RegistryHive, @@ -486,7 +523,11 @@ CmiLockBlock(PREGISTRY_HIVE RegistryHive, VOID CmiReleaseBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block); + PVOID Block); + +VOID +CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, + BLOCK_OFFSET BlockOffset); NTSTATUS CmiAddFree(PREGISTRY_HIVE RegistryHive, @@ -496,4 +537,22 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiInitHives(BOOLEAN SetUpBoot); +ULONG +CmiGetPackedNameLength(IN PUNICODE_STRING Name, + OUT PBOOLEAN Packable); + +BOOLEAN +CmiComparePackedNames(IN PUNICODE_STRING Name, + IN PCHAR NameBuffer, + IN USHORT NameBufferSize, + IN BOOLEAN NamePacked); + +VOID +CmiCopyPackedName(PWCHAR NameBuffer, + PCHAR PackedNameBuffer, + ULONG PackedNameSize); + +VOID +CmiSyncHives(VOID); + #endif /*__INCLUDE_CM_H*/ diff --git a/ntoskrnl/cm/import.c b/ntoskrnl/cm/import.c index 1221d19..3f693e0 100644 --- a/ntoskrnl/cm/import.c +++ b/ntoskrnl/cm/import.c @@ -7,6 +7,9 @@ * PROGRAMMERS: Rex Jolliff */ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include @@ -21,6 +24,7 @@ #include #include "cm.h" +#endif static PCHAR checkAndSkipMagic (PCHAR regChunk) diff --git a/ntoskrnl/cm/ntfunc.c b/ntoskrnl/cm/ntfunc.c index a419b74..8d0a316 100644 --- a/ntoskrnl/cm/ntfunc.c +++ b/ntoskrnl/cm/ntfunc.c @@ -8,6 +8,9 @@ /* INCLUDES *****************************************************************/ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include #include @@ -20,6 +23,7 @@ #include #include "cm.h" +#endif /* GLOBALS ******************************************************************/ @@ -34,12 +38,12 @@ static BOOLEAN CmiRegistryInitialized = FALSE; NTSTATUS STDCALL NtCreateKey(OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class, - IN ULONG CreateOptions, - OUT PULONG Disposition) + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class, + IN ULONG CreateOptions, + OUT PULONG Disposition) { UNICODE_STRING RemainingPath; PKEY_OBJECT KeyObject; @@ -48,17 +52,19 @@ NtCreateKey(OUT PHANDLE KeyHandle, PWSTR End; DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n", - ObjectAttributes->ObjectName, - KeyHandle, - ObjectAttributes->RootDirectory); + ObjectAttributes->ObjectName, + KeyHandle, + ObjectAttributes->RootDirectory); /* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */ - Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType); - + Status = ObFindObject(ObjectAttributes, + &Object, + &RemainingPath, + CmiKeyType); if (!NT_SUCCESS(Status)) { - return Status; + return(Status); } DPRINT("RemainingPath %wZ\n", &RemainingPath); @@ -69,7 +75,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE) { ObDereferenceObject(Object); - return STATUS_UNSUCCESSFUL; + return(STATUS_UNSUCCESSFUL); } if (Disposition) @@ -106,9 +112,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, NULL, CmiKeyType, (PVOID*)&KeyObject); - if (!NT_SUCCESS(Status)) - return(Status); + { + return(Status); + } KeyObject->ParentKey = Object; @@ -121,7 +128,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, KeyObject->NumberOfSubKeys = 0; KeyObject->SizeOfSubKeys = 0; KeyObject->SubKeys = NULL; -// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql); + + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + /* add key to subkeys of parent if needed */ Status = CmiAddSubKey(KeyObject->RegistryHive, KeyObject->ParentKey, @@ -131,9 +141,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, TitleIndex, Class, CreateOptions); - if (!NT_SUCCESS(Status)) { + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); ObDereferenceObject(Object); return STATUS_UNSUCCESSFUL; @@ -151,7 +162,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, { KeyObject->KeyCell->ParentKeyOffset = -1; KeyObject->KeyCell->SecurityKeyOffset = -1; - /* This key must rest in memory unless it is deleted + /* This key must remain in memory unless it is deleted or file is unloaded */ ObReferenceObjectByPointer(KeyObject, STANDARD_RIGHTS_REQUIRED, @@ -160,7 +171,11 @@ NtCreateKey(OUT PHANDLE KeyHandle, } CmiAddKeyToList(KeyObject->ParentKey, KeyObject); -// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql); + + VERIFY_KEY_OBJECT(KeyObject); + + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); ObDereferenceObject(Object); @@ -168,7 +183,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, if (Disposition) *Disposition = REG_CREATED_NEW_KEY; - VERIFY_KEY_OBJECT(KeyObject); + CmiSyncHives(); return Status; } @@ -183,33 +198,50 @@ NtDeleteKey(IN HANDLE KeyHandle) DPRINT("KeyHandle %x\n", KeyHandle); /* Verify that the handle is valid and is a registry key */ +CHECKPOINT1; Status = ObReferenceObjectByHandle(KeyHandle, - KEY_WRITE, - CmiKeyType, - UserMode, - (PVOID *) &KeyObject, - NULL); - + KEY_WRITE, + CmiKeyType, + UserMode, + (PVOID *)&KeyObject, + NULL); if (!NT_SUCCESS(Status)) { - return Status; +CHECKPOINT1; + return(Status); } +CHECKPOINT1; + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); +CHECKPOINT1; + VERIFY_KEY_OBJECT(KeyObject); /* Set the marked for delete bit in the key object */ KeyObject->Flags |= KO_MARKED_FOR_DELETE; +CHECKPOINT1; + + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + + DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); /* Dereference the object */ ObDereferenceObject(KeyObject); if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive) ObDereferenceObject(KeyObject); - /* Close the handle */ - ObDeleteHandle(PsGetCurrentProcess(), KeyHandle); - /* FIXME: I think that ObDeleteHandle should dereference the object */ - ObDereferenceObject(KeyObject); - return STATUS_SUCCESS; + DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); + + /* + * Note: + * Hive-Synchronization will not be triggered here. This is done in + * CmiObjectDelete() (in regobj.c) after all key-related structures + * have been released. + */ + + return(STATUS_SUCCESS); } @@ -234,13 +266,13 @@ NtEnumerateKey( PDATA_CELL pClassData; DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n", - KeyHandle, - Index, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); - + KeyHandle, + Index, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_ENUMERATE_SUB_KEYS, @@ -251,62 +283,68 @@ NtEnumerateKey( if (!NT_SUCCESS(Status)) { DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status); - return Status; + return(Status); } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - + /* Get pointer to SubKey */ if (Index >= KeyCell->NumberOfSubKeys) - { - if (RegistryHive == CmiVolatileHive) - { - ObDereferenceObject (KeyObject); - DPRINT("No more volatile entries\n"); - return STATUS_NO_MORE_ENTRIES; - } - else - { - ULONG i; - PKEY_OBJECT CurKey = NULL; - - /* Search volatile keys */ - for (i = 0; i < KeyObject->NumberOfSubKeys; i++) - { - CurKey = KeyObject->SubKeys[i]; - if (CurKey->RegistryHive == CmiVolatileHive) - { - if (Index-- == KeyObject->NumberOfSubKeys) - break; - } - } - if(Index >= KeyCell->NumberOfSubKeys) - { - ObDereferenceObject (KeyObject); - DPRINT("No more non-volatile entries\n"); - return STATUS_NO_MORE_ENTRIES; - } - SubKeyCell = CurKey->KeyCell; - } - } + { + if (RegistryHive == CmiVolatileHive) + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more volatile entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } + else + { + ULONG i; + PKEY_OBJECT CurKey = NULL; + + /* Search volatile keys */ + for (i = 0; i < KeyObject->NumberOfSubKeys; i++) + { + CurKey = KeyObject->SubKeys[i]; + if (CurKey->RegistryHive == CmiVolatileHive) + { + if (Index-- == KeyObject->NumberOfSubKeys) + break; + } + } + if (Index >= KeyCell->NumberOfSubKeys) + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more non-volatile entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } + SubKeyCell = CurKey->KeyCell; + } + } else - { - HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); - SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive, - HashTableBlock, - Index); - } + { + HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); + SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive, + HashTableBlock, + Index); + } if (SubKeyCell == NULL) - { - ObDereferenceObject (KeyObject); - DPRINT("No more entries\n"); - return STATUS_NO_MORE_ENTRIES; - } + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } Status = STATUS_SUCCESS; switch (KeyInformationClass) @@ -413,11 +451,13 @@ NtEnumerateKey( break; } CmiReleaseBlock(RegistryHive, SubKeyCell); - ObDereferenceObject (KeyObject); + + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); DPRINT("Returning status %x\n", Status); - return Status; + return(Status); } @@ -440,12 +480,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, PKEY_VALUE_FULL_INFORMATION ValueFullInformation; DPRINT("KH %x I %d KVIC %x KVI %x L %d RL %x\n", - KeyHandle, - Index, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength); + KeyHandle, + Index, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength); /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, @@ -460,12 +500,15 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, return Status; } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - + /* Get Value block of interest */ Status = CmiGetValueFromKeyByIndex(RegistryHive, KeyCell, @@ -474,16 +517,26 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } - else if (ValueCell != NULL) + + if (ValueCell != NULL) { switch (KeyValueInformationClass) { case KeyValueBasicInformation: - *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + - (ValueCell->NameSize + 1) * sizeof(WCHAR); + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + + (ValueCell->NameSize + 1) * sizeof(WCHAR); + } + else + { + *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + + ValueCell->NameSize + sizeof(WCHAR); + } if (Length < *ResultLength) { Status = STATUS_BUFFER_OVERFLOW; @@ -494,12 +547,24 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, KeyValueInformation; ValueBasicInformation->TitleIndex = 0; ValueBasicInformation->Type = ValueCell->DataType; - ValueBasicInformation->NameLength = - (ValueCell->NameSize + 1) * sizeof(WCHAR); - mbstowcs(ValueBasicInformation->Name, - ValueCell->Name, - ValueCell->NameSize * 2); - ValueBasicInformation->Name[ValueCell->NameSize] = 0; + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + ValueBasicInformation->NameLength = + (ValueCell->NameSize + 1) * sizeof(WCHAR); + CmiCopyPackedName(ValueBasicInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueBasicInformation->Name[ValueCell->NameSize] = 0; + } + else + { + ValueBasicInformation->NameLength = + ValueCell->NameSize + sizeof(WCHAR); + RtlCopyMemory(ValueBasicInformation->Name, + ValueCell->Name, + ValueCell->NameSize * sizeof(WCHAR)); + ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0; + } } break; @@ -536,8 +601,18 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, break; case KeyValueFullInformation: - *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + - ValueCell->NameSize * sizeof(WCHAR) + (ValueCell->DataSize & LONG_MAX); + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + + (ValueCell->NameSize + 1) * sizeof(WCHAR) + + (ValueCell->DataSize & LONG_MAX); + } + else + { + *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + + ValueCell->NameSize + sizeof(WCHAR) + + (ValueCell->DataSize & LONG_MAX); + } if (Length < *ResultLength) { Status = STATUS_BUFFER_OVERFLOW; @@ -548,34 +623,47 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, KeyValueInformation; ValueFullInformation->TitleIndex = 0; ValueFullInformation->Type = ValueCell->DataType; + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + ValueFullInformation->NameLength = + (ValueCell->NameSize + 1) * sizeof(WCHAR); + + CmiCopyPackedName(ValueFullInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueFullInformation->Name[ValueCell->NameSize] = 0; + } + else + { + ValueFullInformation->NameLength = + ValueCell->NameSize + sizeof(WCHAR); + RtlCopyMemory(ValueFullInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0; + } ValueFullInformation->DataOffset = - (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation - + (ValueCell->NameSize + 1) * sizeof(WCHAR); + (ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation + + ValueFullInformation->NameLength; ValueFullInformation->DataOffset = - (ValueFullInformation->DataOffset + 3) & 0xfffffffc; + (ValueFullInformation->DataOffset + 3) & 0xfffffffc; ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX; - ValueFullInformation->NameLength = - (ValueCell->NameSize + 1) * sizeof(WCHAR); - mbstowcs(ValueFullInformation->Name, - ValueCell->Name, - ValueCell->NameSize * 2); - ValueFullInformation->Name[ValueCell->NameSize] = 0; if (ValueCell->DataSize > 0) - { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - DataCell->Data, - ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); - } + { + DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + DataCell->Data, + ValueCell->DataSize & LONG_MAX); + CmiReleaseBlock(RegistryHive, DataCell); + } else - { - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - &ValueCell->DataOffset, - ValueCell->DataSize & LONG_MAX); - } + { + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + &ValueCell->DataOffset, + ValueCell->DataSize & LONG_MAX); + } } break; } @@ -584,6 +672,8 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, { Status = STATUS_UNSUCCESSFUL; } + + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; @@ -593,47 +683,63 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, NTSTATUS STDCALL NtFlushKey(IN HANDLE KeyHandle) { - NTSTATUS Status; - PKEY_OBJECT KeyObject; - PREGISTRY_HIVE RegistryHive; - WCHAR LogName[MAX_PATH]; - UNICODE_STRING TmpFileName; - HANDLE FileHandle; - // HANDLE FileHandleLog; - OBJECT_ATTRIBUTES ObjectAttributes; - // KIRQL OldIrql; - LARGE_INTEGER fileOffset; - DWORD * pEntDword; - ULONG i; + NTSTATUS Status; + PKEY_OBJECT KeyObject; + PREGISTRY_HIVE RegistryHive; +#if 0 + WCHAR LogName[MAX_PATH]; + UNICODE_STRING TmpFileName; + HANDLE FileHandle; +// HANDLE FileHandleLog; + OBJECT_ATTRIBUTES ObjectAttributes; + LARGE_INTEGER fileOffset; + DWORD * pEntDword; + ULONG i; +#endif DPRINT("KeyHandle %x\n", KeyHandle); - /* Verify that the handle is valid and is a registry key */ - Status = ObReferenceObjectByHandle(KeyHandle, - KEY_QUERY_VALUE, - CmiKeyType, - UserMode, - (PVOID *) &KeyObject, - NULL); - + /* Verify that the handle is valid and is a registry key */ + Status = ObReferenceObjectByHandle(KeyHandle, + KEY_QUERY_VALUE, + CmiKeyType, + UserMode, + (PVOID *)&KeyObject, + NULL); if (!NT_SUCCESS(Status)) { - return Status; + return(Status); } VERIFY_KEY_OBJECT(KeyObject); RegistryHive = KeyObject->RegistryHive; -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); + + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource, + TRUE); + + if (IsPermanentHive(RegistryHive)) + { + /* Flush non-volatile hive */ + Status = CmiFlushRegistryHive(RegistryHive); + } + else + { + Status = STATUS_SUCCESS; + } + + +#if 0 /* Then write changed blocks in .log */ wcscpy(LogName,RegistryHive->Filename.Buffer); wcscat(LogName,L".log"); RtlInitUnicodeString (&TmpFileName, LogName); InitializeObjectAttributes(&ObjectAttributes, - &TmpFileName, - 0, - NULL, - NULL); + &TmpFileName, + 0, + NULL, + NULL); /* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files so we can't create log file @@ -717,28 +823,28 @@ END FIXME*/ NULL, 0, FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } RegistryHive->HiveHeader->Version++; - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - 0, - 0); - + Status = ZwWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + 0, + 0); if (!NT_SUCCESS(Status)) { ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } @@ -746,35 +852,33 @@ END FIXME*/ /* Update changed blocks in file */ fileOffset.u.HighPart = 0; for (i = 0; i < RegistryHive->BlockListSize ; i++) - { - if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime + { + if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime > RegistryHive->HiveHeader->DateModified.dwHighDateTime - || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime + || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime == RegistryHive->HiveHeader->DateModified.dwHighDateTime - && RegistryHive->BlockList[i]->DateModified.dwLowDateTime - > RegistryHive->HiveHeader->DateModified.dwLowDateTime - ) - ) + && RegistryHive->BlockList[i]->DateModified.dwLowDateTime + > RegistryHive->HiveHeader->DateModified.dwLowDateTime)) + { + fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096; + Status = NtWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->BlockList[i], + RegistryHive->BlockList[i]->BlockSize, + &fileOffset, + 0); + if (!NT_SUCCESS(Status)) { - fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096; - Status = NtWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->BlockList[i], - RegistryHive->BlockList[i]->BlockSize , - &fileOffset, - 0); - - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - ObDereferenceObject(KeyObject); - return Status; - } + ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + return(Status); } - } + } + } /* Change version in header */ RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version; @@ -790,26 +894,31 @@ END FIXME*/ /* Write new header */ fileOffset.u.LowPart = 0; - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - &fileOffset, - 0); + Status = ZwWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + &fileOffset, + 0); if (!NT_SUCCESS(Status)) { ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } ZwClose(FileHandle); -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); +#endif + + ExReleaseResourceLite(&RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + return STATUS_SUCCESS; } @@ -823,7 +932,7 @@ NtOpenKey(OUT PHANDLE KeyHandle, NTSTATUS Status; PVOID Object; - DPRINT("KH %x DA %x OA %x OA->ON %x\n", + DPRINT("NtOpenFile(KH %x DA %x OA %x OA->ON '%wZ'\n", KeyHandle, DesiredAccess, ObjectAttributes, @@ -841,7 +950,7 @@ NtOpenKey(OUT PHANDLE KeyHandle, VERIFY_KEY_OBJECT((PKEY_OBJECT) Object); - DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer); + DPRINT("RemainingPath '%wZ'\n", &RemainingPath); if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) { @@ -873,11 +982,11 @@ NtOpenKey(OUT PHANDLE KeyHandle, NTSTATUS STDCALL -NtQueryKey(IN HANDLE KeyHandle, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength) +NtQueryKey(IN HANDLE KeyHandle, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength) { PKEY_BASIC_INFORMATION BasicInformation; PKEY_NODE_INFORMATION NodeInformation; @@ -889,12 +998,12 @@ NtQueryKey(IN HANDLE KeyHandle, NTSTATUS Status; DPRINT("KH %x KIC %x KI %x L %d RL %x\n", - KeyHandle, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); - + KeyHandle, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_READ, @@ -902,22 +1011,28 @@ NtQueryKey(IN HANDLE KeyHandle, UserMode, (PVOID *) &KeyObject, NULL); - if (!NT_SUCCESS(Status)) { +CHECKPOINT1; return Status; } +CHECKPOINT1; + + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); +CHECKPOINT1; VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - + Status = STATUS_SUCCESS; switch (KeyInformationClass) { case KeyBasicInformation: +CHECKPOINT1; /* Check size of buffer */ if (Length < sizeof(KEY_BASIC_INFORMATION) + KeyObject->NameSize * sizeof(WCHAR)) @@ -938,8 +1053,9 @@ NtQueryKey(IN HANDLE KeyHandle, *ResultLength = sizeof(KEY_BASIC_INFORMATION) + KeyObject->NameSize * sizeof(WCHAR); } +CHECKPOINT1; break; - + case KeyNodeInformation: /* Check size of buffer */ if (Length < sizeof(KEY_NODE_INFORMATION) @@ -1019,11 +1135,16 @@ NtQueryKey(IN HANDLE KeyHandle, break; } +CHECKPOINT1; + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); +CHECKPOINT1; ObDereferenceObject(KeyObject); +CHECKPOINT1; - return Status; + return(Status); } + NTSTATUS STDCALL NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, @@ -1041,14 +1162,10 @@ NtQueryValueKey(IN HANDLE KeyHandle, PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation; PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation; PKEY_VALUE_FULL_INFORMATION ValueFullInformation; - char ValueName2[MAX_PATH]; DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x)\n", KeyHandle, ValueName->Buffer, Length); - wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1); - ValueName2[ValueName->Length >> 1] = 0; - /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_QUERY_VALUE, @@ -1063,30 +1180,43 @@ NtQueryValueKey(IN HANDLE KeyHandle, return Status; } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - /* Get Value block of interest */ - Status = CmiScanKeyForValue(RegistryHive, - KeyCell, - ValueName2, - &ValueCell,NULL); + /* Get Value block of interest */ + Status = CmiScanKeyForValue(RegistryHive, + KeyCell, + ValueName, + &ValueCell, + NULL); if (!NT_SUCCESS(Status)) { DPRINT("CmiScanKeyForValue() failed with status %x\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); - return Status; + return(Status); } else if (ValueCell != NULL) { switch (KeyValueInformationClass) { case KeyValueBasicInformation: - *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) - + ValueCell->NameSize * sizeof(WCHAR); + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + + (ValueCell->NameSize + 1) * sizeof(WCHAR); + } + else + { + *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + + ValueCell->NameSize + sizeof(WCHAR); + } if (Length < *ResultLength) { Status = STATUS_BUFFER_TOO_SMALL; @@ -1097,11 +1227,24 @@ NtQueryValueKey(IN HANDLE KeyHandle, KeyValueInformation; ValueBasicInformation->TitleIndex = 0; ValueBasicInformation->Type = ValueCell->DataType; - ValueBasicInformation->NameLength = - (ValueCell->NameSize + 1) * sizeof(WCHAR); - mbstowcs(ValueBasicInformation->Name, - ValueCell->Name,ValueCell->NameSize * 2); - ValueBasicInformation->Name[ValueCell->NameSize] = 0; + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + ValueBasicInformation->NameLength = + (ValueCell->NameSize + 1) * sizeof(WCHAR); + CmiCopyPackedName(ValueBasicInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueBasicInformation->Name[ValueCell->NameSize] = 0; + } + else + { + ValueBasicInformation->NameLength = + ValueCell->NameSize + sizeof(WCHAR); + RtlCopyMemory(ValueBasicInformation->Name, + ValueCell->Name, + ValueCell->NameSize * sizeof(WCHAR)); + ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0; + } } break; @@ -1114,68 +1257,91 @@ NtQueryValueKey(IN HANDLE KeyHandle, } else { - ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION) + ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation; ValuePartialInformation->TitleIndex = 0; ValuePartialInformation->Type = ValueCell->DataType; ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX; if (ValueCell->DataSize > 0) - { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); - RtlCopyMemory(ValuePartialInformation->Data, + { + DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); + RtlCopyMemory(ValuePartialInformation->Data, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); - } + CmiReleaseBlock(RegistryHive, DataCell); + } else - { - RtlCopyMemory(ValuePartialInformation->Data, - &ValueCell->DataOffset, + { + RtlCopyMemory(ValuePartialInformation->Data, + &ValueCell->DataOffset, ValueCell->DataSize & LONG_MAX); - } + } } break; case KeyValueFullInformation: - *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) - + (ValueCell->NameSize -1) * sizeof(WCHAR) - + (ValueCell->DataSize & LONG_MAX); + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + + (ValueCell->NameSize + 1) * sizeof(WCHAR) + + (ValueCell->DataSize & LONG_MAX); + } + else + { + *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + + ValueCell->NameSize + sizeof(WCHAR) + + (ValueCell->DataSize & LONG_MAX); + } if (Length < *ResultLength) { Status = STATUS_BUFFER_TOO_SMALL; } else { - ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION) + ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION) KeyValueInformation; ValueFullInformation->TitleIndex = 0; ValueFullInformation->Type = ValueCell->DataType; + if (ValueCell->Flags & REG_VALUE_NAME_PACKED) + { + ValueFullInformation->NameLength = + (ValueCell->NameSize + 1) * sizeof(WCHAR); + CmiCopyPackedName(ValueFullInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueFullInformation->Name[ValueCell->NameSize] = 0; + } + else + { + ValueFullInformation->NameLength = + ValueCell->NameSize + sizeof(WCHAR); + RtlCopyMemory(ValueFullInformation->Name, + ValueCell->Name, + ValueCell->NameSize); + ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0; + } ValueFullInformation->DataOffset = - (DWORD)ValueFullInformation->Name - (DWORD)ValueFullInformation - + (ValueCell->NameSize + 1) * sizeof(WCHAR); + (ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation + + ValueFullInformation->NameLength; ValueFullInformation->DataOffset = - (ValueFullInformation->DataOffset + 3) &0xfffffffc; + (ValueFullInformation->DataOffset + 3) & 0xfffffffc; ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX; - ValueFullInformation->NameLength = - (ValueCell->NameSize + 1) * sizeof(WCHAR); - mbstowcs(ValueFullInformation->Name, ValueCell->Name,ValueCell->NameSize*2); - ValueFullInformation->Name[ValueCell->NameSize] = 0; if (ValueCell->DataSize > 0) - { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - DataCell->Data, - ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); - } + { + DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + DataCell->Data, + ValueCell->DataSize & LONG_MAX); + CmiReleaseBlock(RegistryHive, DataCell); + } else - { - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - &ValueCell->DataOffset, - ValueCell->DataSize & LONG_MAX); - } + { + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + &ValueCell->DataOffset, + ValueCell->DataSize & LONG_MAX); + } } break; } @@ -1185,8 +1351,9 @@ NtQueryValueKey(IN HANDLE KeyHandle, Status = STATUS_OBJECT_NAME_NOT_FOUND; } + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); - + return Status; } @@ -1205,18 +1372,13 @@ NtSetValueKey(IN HANDLE KeyHandle, PKEY_CELL KeyCell; PVALUE_CELL ValueCell; BLOCK_OFFSET VBOffset; - char ValueName2[MAX_PATH]; PDATA_CELL DataCell; PDATA_CELL NewDataCell; PHBIN pBin; ULONG DesiredAccess; -// KIRQL OldIrql; - DPRINT("KeyHandle %x ValueName %S Type %d\n", - KeyHandle, ValueName? ValueName->Buffer : NULL, Type); - - wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1); - ValueName2[ValueName->Length>>1] = 0; + DPRINT("NtSetValueKey(KeyHandle %x ValueName %S Type %d)\n", + KeyHandle, ValueName? ValueName->Buffer : NULL, Type); DesiredAccess = KEY_SET_VALUE; if (Type == REG_LINK) @@ -1232,6 +1394,9 @@ NtSetValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) return(Status); + /* Acquire hive lock exclucively */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to key cell */ @@ -1239,105 +1404,138 @@ NtSetValueKey(IN HANDLE KeyHandle, RegistryHive = KeyObject->RegistryHive; Status = CmiScanKeyForValue(RegistryHive, KeyCell, - ValueName2, + ValueName, &ValueCell, &VBOffset); if (!NT_SUCCESS(Status)) { DPRINT1("Value not found. Status 0x%X\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return(Status); } -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); - if (ValueCell == NULL) { + DPRINT("Allocate new value cell\n"); Status = CmiAddValueToKey(RegistryHive, KeyCell, - ValueName2, + ValueName, &ValueCell, &VBOffset); + if (NT_SUCCESS(Status)) + { + CmiMarkBlockDirty(RegistryHive, VBOffset); + } } if (!NT_SUCCESS(Status)) { DPRINT1("Cannot add value. Status 0x%X\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return(Status); } - else - { - DPRINT("DataSize (%d)\n", DataSize); + DPRINT("DataSize %lu\n", DataSize); + DPRINT("ValueCell %p\n", ValueCell); + DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); + + if (DataSize <= 4) + { /* If datasize <= 4 then write in valueblock directly */ - if (DataSize <= 4) + DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); + if ((ValueCell->DataSize >= 0) && + (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL))) { - DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); - if ((ValueCell->DataSize >= 0) && - (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL))) - { - CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset); - } - - RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize); - ValueCell->DataSize = DataSize | 0x80000000; - ValueCell->DataType = Type; - RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize); + CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset); } + + RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize); + ValueCell->DataSize = DataSize | 0x80000000; + ValueCell->DataType = Type; + RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize); + CmiMarkBlockDirty(RegistryHive, VBOffset); + } + else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff)) + { /* If new data size is <= current then overwrite current data */ - else if (DataSize <= (ValueCell->DataSize & 0x7fffffff)) + DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin); + RtlZeroMemory(DataCell->Data, ValueCell->DataSize); + RtlCopyMemory(DataCell->Data, Data, DataSize); + ValueCell->DataSize = DataSize; + ValueCell->DataType = Type; + CmiReleaseBlock(RegistryHive, DataCell); + + /* Update time of heap */ + if (IsPermanentHive(RegistryHive)) { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin); - RtlCopyMemory(DataCell->Data, Data, DataSize); - ValueCell->DataSize = DataSize; - ValueCell->DataType = Type; - CmiReleaseBlock(RegistryHive, DataCell); - /* Update time of heap */ - if (IsPermanentHive(RegistryHive)) - { - ZwQuerySystemTime((PTIME) &pBin->DateModified); - } + ZwQuerySystemTime((PTIME) &pBin->DateModified); } - else - { - BLOCK_OFFSET NewOffset; + CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); + } + else + { + /* + * New data size is larger than the current, destroy current + * data block and allocate a new one. + */ + BLOCK_OFFSET NewOffset; - /* Destroy current data block and allocate a new one */ - if ((ValueCell->DataSize >= 0) && - (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL))) - { - CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset); - } - Status = CmiAllocateBlock(RegistryHive, - (PVOID *)&NewDataCell, - DataSize, - &NewOffset); - RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize); - ValueCell->DataSize = DataSize; - ValueCell->DataType = Type; - CmiReleaseBlock(RegistryHive, NewDataCell); - ValueCell->DataOffset = NewOffset; - } + DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); - if (strcmp(ValueName2, "SymbolicLinkValue") == 0) + if ((ValueCell->DataSize >= 0) && + (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL))) { - KeyCell->Type = REG_LINK_KEY_CELL_TYPE; + CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset); + ValueCell->DataSize = 0; + ValueCell->DataType = 0; + ValueCell->DataOffset = 0xffffffff; } - /* Update time of heap */ - if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) + Status = CmiAllocateBlock(RegistryHive, + (PVOID *)&NewDataCell, + DataSize, + &NewOffset); + if (!NT_SUCCESS(Status)) { - ZwQuerySystemTime((PTIME) &pBin->DateModified); + DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status); + + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + + return(Status); } + + RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize); + ValueCell->DataSize = DataSize; + ValueCell->DataType = Type; + CmiReleaseBlock(RegistryHive, NewDataCell); + ValueCell->DataOffset = NewOffset; + CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); + } + + /* Mark link key */ + if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) && + (Type == REG_LINK)) + { + KeyCell->Type = REG_LINK_KEY_CELL_TYPE; + CmiMarkBlockDirty(RegistryHive, KeyObject->BlockOffset); } -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); + /* Update time of heap */ + if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) + { + ZwQuerySystemTime((PTIME) &pBin->DateModified); + } + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); + CmiSyncHives(); + DPRINT("Return Status 0x%X\n", Status); return(Status); @@ -1346,17 +1544,10 @@ NtSetValueKey(IN HANDLE KeyHandle, NTSTATUS STDCALL NtDeleteValueKey(IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName) + IN PUNICODE_STRING ValueName) { - PREGISTRY_HIVE RegistryHive; - CHAR ValueName2[MAX_PATH]; PKEY_OBJECT KeyObject; - PKEY_CELL KeyCell; NTSTATUS Status; -// KIRQL OldIrql; - - wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1); - ValueName2[ValueName->Length>>1] = 0; /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, @@ -1365,22 +1556,28 @@ NtDeleteValueKey(IN HANDLE KeyHandle, UserMode, (PVOID *)&KeyObject, NULL); - if (!NT_SUCCESS(Status)) { return Status; } + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); - /* Get pointer to KeyCell */ - KeyCell = KeyObject->KeyCell; - RegistryHive = KeyObject->RegistryHive; -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); - Status = CmiDeleteValueFromKey(RegistryHive, KeyCell, ValueName2); -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); + Status = CmiDeleteValueFromKey(KeyObject->RegistryHive, + KeyObject->KeyCell, + KeyObject->BlockOffset, + ValueName); + + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + CmiSyncHives(); + return Status; } @@ -1405,12 +1602,12 @@ NtLoadKey2(IN PHANDLE KeyHandle, NTSTATUS STDCALL NtNotifyChangeKey( IN HANDLE KeyHandle, - IN HANDLE Event, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, + IN HANDLE Event, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG CompletionFilter, - IN BOOLEAN Asynchroneous, + IN BOOLEAN Asynchroneous, OUT PVOID ChangeBuffer, IN ULONG Length, IN BOOLEAN WatchSubtree) @@ -1421,14 +1618,13 @@ NtNotifyChangeKey( NTSTATUS STDCALL NtQueryMultipleValueKey(IN HANDLE KeyHandle, - IN OUT PKEY_VALUE_ENTRY ValueList, - IN ULONG NumberOfValues, - OUT PVOID Buffer, - IN OUT PULONG Length, - OUT PULONG ReturnLength) + IN OUT PKEY_VALUE_ENTRY ValueList, + IN ULONG NumberOfValues, + OUT PVOID Buffer, + IN OUT PULONG Length, + OUT PULONG ReturnLength) { PREGISTRY_HIVE RegistryHive; - UCHAR ValueName[MAX_PATH]; PVALUE_CELL ValueCell; PKEY_OBJECT KeyObject; PDATA_CELL DataCell; @@ -1451,6 +1647,9 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, return(Status); } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ @@ -1461,17 +1660,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, for (i = 0; i < NumberOfValues; i++) { - wcstombs(ValueName, - ValueList[i].ValueName->Buffer, - ValueList[i].ValueName->Length >> 1); - ValueName[ValueList[i].ValueName->Length >> 1] = 0; - - DPRINT("ValueName: '%s'\n", ValueName); + DPRINT("ValueName: '%wZ'\n", ValueList[i].ValueName); /* Get Value block of interest */ Status = CmiScanKeyForValue(RegistryHive, KeyCell, - ValueName, + ValueList[i].ValueName, &ValueCell, NULL); @@ -1524,11 +1718,14 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, *ReturnLength = BufferLength; + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); DPRINT("Return Status 0x%X\n", Status); - return Status; + return(Status); } diff --git a/ntoskrnl/cm/regfile.c b/ntoskrnl/cm/regfile.c index db89135..ea67394 100644 --- a/ntoskrnl/cm/regfile.c +++ b/ntoskrnl/cm/regfile.c @@ -6,6 +6,9 @@ * UPDATE HISTORY: */ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include #include @@ -19,11 +22,14 @@ #include #include "cm.h" +#endif - +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) BOOLEAN CmiDoVerify = FALSE; +/* FUNCTIONS ****************************************************************/ + VOID CmiCreateDefaultHiveHeader(PHIVE_HEADER Header) { @@ -62,7 +68,11 @@ CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell) { assert(RootKeyCell); RtlZeroMemory(RootKeyCell, sizeof(KEY_CELL)); +#ifdef WIN32_REGDBG + RootKeyCell->CellSize = -(LONG)sizeof(KEY_CELL); +#else RootKeyCell->CellSize = -sizeof(KEY_CELL); +#endif RootKeyCell->Id = REG_KEY_CELL_ID; RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE; ZwQuerySystemTime((PTIME) &RootKeyCell->LastWriteTime); @@ -358,7 +368,7 @@ CmiPopulateHive(HANDLE FileHandle) PHBIN BinCell; PCHAR tBuf; ULONG i; - + tBuf = (PCHAR) ExAllocatePool(NonPagedPool, REG_BLOCK_SIZE); if (tBuf == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -382,14 +392,14 @@ CmiPopulateHive(HANDLE FileHandle) FileOffset.u.LowPart = (2 + i) * REG_BLOCK_SIZE; Status = ZwWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - tBuf, - REG_BLOCK_SIZE, - &FileOffset, - NULL); + NULL, + NULL, + NULL, + &IoStatusBlock, + tBuf, + REG_BLOCK_SIZE, + &FileOffset, + NULL); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); if (!NT_SUCCESS(Status)) { @@ -413,48 +423,48 @@ CmiCreateNewRegFile(HANDLE FileHandle) PKEY_CELL RootKeyCell; NTSTATUS Status; PHBIN BinCell; - PCHAR tBuf; - - tBuf = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE); - if (tBuf == NULL) + PCHAR Buffer; + + Buffer = (PCHAR) ExAllocatePool(NonPagedPool, 2 * REG_BLOCK_SIZE); + if (Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES; - - HiveHeader = (PHIVE_HEADER) tBuf; - BinCell = (PHBIN) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE); - RootKeyCell = (PKEY_CELL) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET); - FreeCell = (PCELL_HEADER) ((ULONG_PTR) tBuf + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL)); + + HiveHeader = (PHIVE_HEADER)Buffer; + BinCell = (PHBIN)((ULONG_PTR)Buffer + REG_BLOCK_SIZE); + RootKeyCell = (PKEY_CELL)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET); + FreeCell = (PCELL_HEADER)((ULONG_PTR)Buffer + REG_BLOCK_SIZE + REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL)); CmiCreateDefaultHiveHeader(HiveHeader); CmiCreateDefaultBinCell(BinCell); CmiCreateDefaultRootKeyCell(RootKeyCell); - // First block + /* First block */ BinCell->BlockOffset = 0; - // Offset to root key block + /* Offset to root key block */ HiveHeader->RootKeyCell = REG_HBIN_DATA_OFFSET; - // The rest of the block is free + /* The rest of the block is free */ FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL)); Status = ZwWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - tBuf, - 2 * REG_BLOCK_SIZE, - 0, - NULL); + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + 2 * REG_BLOCK_SIZE, + 0, + NULL); - ExFreePool(tBuf); + ExFreePool(Buffer); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); #if 1 if (NT_SUCCESS(Status)) { - CmiPopulateHive(FileHandle); + CmiPopulateHive(FileHandle); } #endif @@ -464,8 +474,8 @@ CmiCreateNewRegFile(HANDLE FileHandle) NTSTATUS CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, - PWSTR Filename, - BOOLEAN CreateNew) + PWSTR Filename, + BOOLEAN CreateNew) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION fsi; @@ -475,16 +485,22 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, ULONG CreateDisposition; IO_STATUS_BLOCK IoSB; HANDLE FileHandle; - DWORD FreeOffset; + ULONG FreeOffset; NTSTATUS Status; - //BOOLEAN Success; PHBIN tmpBin; ULONG i, j; + ULONG BitmapSize; + PULONG BitmapBuffer; + + DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew); /* Duplicate Filename */ Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename); if (!NT_SUCCESS(Status)) - return Status; + { + DPRINT1("CmiInitPermanentRegistryHive() - Failed 1.\n"); + return Status; + } InitializeObjectAttributes(&ObjectAttributes, &RegistryHive->Filename, @@ -492,76 +508,98 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, NULL, NULL); - if (CreateNew) + /* + * Note: + * This is a workaround to prevent a BSOD because of missing registry hives. + * The workaround is only useful for developers. An implementation for the + * ordinary user must bail out on missing registry hives because they are + * essential to booting and configuring the OS. + */ +#if 0 + if (CreateNew == TRUE) CreateDisposition = FILE_OPEN_IF; else CreateDisposition = FILE_OPEN; +#endif + CreateDisposition = FILE_OPEN_IF; Status = NtCreateFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoSB, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - CreateDisposition, - FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - - if ((CreateNew) && (IoSB.Information == FILE_CREATED)) + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoSB, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + CreateDisposition, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) { - Status = CmiCreateNewRegFile(FileHandle); + RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); } - if (!NT_SUCCESS(Status)) + /* Note: Another workaround! See the note above! */ +#if 0 + if ((CreateNew) && (IoSB.Information == FILE_CREATED)) +#endif + if (IoSB.Information != FILE_OPENED) { - RtlFreeUnicodeString(&RegistryHive->Filename); - return Status; + Status = CmiCreateNewRegFile(FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiCreateNewRegFile() failed (Status %lx)\n", Status); + RtlFreeUnicodeString(&RegistryHive->Filename); + return(Status); + } } Status = ObReferenceObjectByHandle(FileHandle, - FILE_ALL_ACCESS, - IoFileObjectType, - UserMode, - (PVOID*) &RegistryHive->FileObject, - NULL); + FILE_ALL_ACCESS, + IoFileObjectType, + UserMode, + (PVOID*)&RegistryHive->FileObject, + NULL); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); if (!NT_SUCCESS(Status)) { - ZwClose(FileHandle); + NtClose(FileHandle); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT1("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status); return Status; } + /* Read hive header */ FileOffset.u.HighPart = 0; FileOffset.u.LowPart = 0; - Status = ZwReadFile(FileHandle, - 0, + DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader); + Status = NtReadFile(FileHandle, 0, 0, 0, + &IoSB, RegistryHive->HiveHeader, sizeof(HIVE_HEADER), &FileOffset, 0); - assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); - if (!NT_SUCCESS(Status)) { ObDereferenceObject(RegistryHive->FileObject); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed 4.\n"); return Status; } - Status = ZwQueryInformationFile(FileHandle, - &IoSB, - &fsi, - sizeof(fsi), - FileStandardInformation); + Status = NtQueryInformationFile(FileHandle, + &IoSB, + &fsi, + sizeof(fsi), + FileStandardInformation); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); @@ -569,15 +607,32 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, { ObDereferenceObject(RegistryHive->FileObject); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed 5.\n"); return Status; } + #if 0 /* We have a reference to the file object so we don't need the handle anymore */ ZwClose(FileHandle); #endif RegistryHive->FileSize = fsi.EndOfFile.u.LowPart; +#ifdef WIN32_REGDBG +// assert(RegistryHive->FileSize); + if (RegistryHive->FileSize) + { + RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; + } + else + { + ObDereferenceObject(RegistryHive->FileObject); + RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } +#else RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; +#endif DPRINT("Space needed for block list describing hive: 0x%x\n", sizeof(PHBIN *) * RegistryHive->BlockListSize); @@ -590,6 +645,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, ExFreePool(RegistryHive->BlockList); ObDereferenceObject(RegistryHive->FileObject); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed 6.\n"); return STATUS_INSUFFICIENT_RESOURCES; } @@ -611,6 +667,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, ExFreePool(RegistryHive->BlockList); ObDereferenceObject(RegistryHive->FileObject); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed 7.\n"); return Status; } @@ -618,30 +675,36 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, RegistryHive->BlockList[0] = ExAllocatePool(PagedPool, RegistryHive->FileSize - 4096); +#ifdef WIN32_REGDBG + RtlZeroMemory(RegistryHive->BlockList[0], RegistryHive->FileSize - 4096); +#endif if (RegistryHive->BlockList[0] == NULL) { ExFreePool(RegistryHive->BlockList); ObDereferenceObject(RegistryHive->FileObject); RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed 8.\n"); return STATUS_INSUFFICIENT_RESOURCES; } FileOffset.u.HighPart = 0; FileOffset.u.LowPart = 4096; - Status = ZwReadFile(FileHandle, - 0, - 0, - 0, - 0, - (PVOID) RegistryHive->BlockList[0], - RegistryHive->FileSize - 4096, - &FileOffset, - 0); + DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]); + Status = NtReadFile(FileHandle, + 0, + 0, + 0, + &IoSB, + (PVOID) RegistryHive->BlockList[0], + RegistryHive->FileSize - 4096, + &FileOffset, + 0); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); + NtClose(FileHandle); #endif RegistryHive->FreeListSize = 0; @@ -656,7 +719,8 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, if (tmpBin->BlockId != REG_BIN_ID) { DPRINT("Bad BlockId %x, offset %x\n", tmpBin->BlockId, BlockOffset); - KeBugCheck(0); + //KeBugCheck(0); + return STATUS_INSUFFICIENT_RESOURCES; } assertmsg((tmpBin->BlockSize % 4096) == 0, ("BlockSize (0x%.08x) must be multiplum of 4K\n", tmpBin->BlockSize)); @@ -697,7 +761,23 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, BlockOffset += tmpBin->BlockSize; } - return STATUS_SUCCESS; + /* Create block bitmap and clear all bits */ + + /* Calculate bitmap size in bytes (always a multiple of 32 bits) */ + BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; + DPRINT1("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize); + DPRINT1("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); + BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, + BitmapSize); + RtlInitializeBitMap(&RegistryHive->DirtyBitMap, + BitmapBuffer, + BitmapSize * 8); + RtlClearAllBits(&RegistryHive->DirtyBitMap); + RegistryHive->HiveDirty = FALSE; + + DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew); + + return(STATUS_SUCCESS); } @@ -737,7 +817,7 @@ CmiCreateRegistryHive(PWSTR Filename, Hive = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_HIVE)); if (Hive == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + return(STATUS_INSUFFICIENT_RESOURCES); DPRINT("Hive %x\n", Hive); @@ -749,7 +829,7 @@ CmiCreateRegistryHive(PWSTR Filename, if (Hive->HiveHeader == NULL) { ExFreePool(Hive); - return STATUS_INSUFFICIENT_RESOURCES; + return(STATUS_INSUFFICIENT_RESOURCES); } if (Filename != NULL) @@ -768,11 +848,156 @@ CmiCreateRegistryHive(PWSTR Filename, return(Status); } - KeInitializeSemaphore(&Hive->RegSem, 1, 1); + ExInitializeResourceLite(&Hive->HiveResource); + + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + /* Add the new hive to the hive list */ + InsertHeadList(&CmiHiveListHead, &Hive->HiveList); + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + VERIFY_REGISTRY_HIVE(Hive); *RegistryHive = Hive; + DPRINT("CmiCreateRegistryHive(Filename %S) - Finished.\n", Filename); + + return(STATUS_SUCCESS); +} + + +NTSTATUS +CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive) +{ + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + /* Remove hive from hive list */ + RemoveEntryList(&RegistryHive->HiveList); + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + + + /* FIXME: Remove attached keys and values */ + + + /* Release hive header */ + ExFreePool(RegistryHive->HiveHeader); + + /* Release hive */ + ExFreePool(RegistryHive); + + return(STATUS_SUCCESS); +} + + +NTSTATUS +CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) +{ + ULONG BlockIndex; + ULONG BlockOffset; + PVOID BlockPtr; + LARGE_INTEGER FileOffset; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + NTSTATUS Status; + + + + + DPRINT("CmiFlushRegistryHive() called\n"); + + if (RegistryHive->HiveDirty == FALSE) + { + return(STATUS_SUCCESS); + } + + DPRINT1("Hive '%wZ' is dirty\n", &RegistryHive->Filename); + + + /* Open hive for writing */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->Filename, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); + } + + + + BlockIndex = 0; + while (TRUE) + { + BlockIndex = RtlFindSetBitsAndClear(&RegistryHive->DirtyBitMap, + 1, + BlockIndex); + if (BlockIndex == (ULONG)-1) + { + DPRINT("No more set bits\n"); + break; + } + + DPRINT1("Block %lu is dirty\n", BlockIndex); + + BlockOffset = RegistryHive->BlockList[BlockIndex]->BlockOffset; + DPRINT1("Block offset %lx\n", BlockOffset); + + BlockPtr = RegistryHive->BlockList[BlockIndex] + ((BlockIndex * 4096) - BlockOffset); + DPRINT1("BlockPtr %p\n", BlockPtr); + + FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL; + DPRINT1("File offset %I64x\n", FileOffset.QuadPart); + + + /* Write hive block */ + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + BlockPtr, + REG_BLOCK_SIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + + } + + NtClose(FileHandle); + + + /* Clear dirty flag */ + RegistryHive->HiveDirty = FALSE; + + DPRINT("CmiFlushRegistryHive() done\n"); + return(STATUS_SUCCESS); } @@ -898,7 +1123,7 @@ CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive, { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; - ULONG MaxValueData; + LONG MaxValueData; ULONG i; VERIFY_KEY_CELL(KeyCell); @@ -944,7 +1169,7 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, VERIFY_KEY_CELL(KeyCell); - DPRINT("Scanning for sub key %s\n", KeyName); + //DPRINT("Scanning for sub key %s\n", KeyName); assert(RegistryHive); @@ -963,7 +1188,7 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, if (Attributes & OBJ_CASE_INSENSITIVE) { if ((HashBlock->Table[i].KeyOffset != 0) && - (HashBlock->Table[i].KeyOffset != -1) && + (HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1) && (_strnicmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4) == 0)) { CurSubKeyCell = CmiGetBlock(RegistryHive, @@ -985,7 +1210,7 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, else { if (HashBlock->Table[i].KeyOffset != 0 && - HashBlock->Table[i].KeyOffset != -1 && + HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 && !strncmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4)) { CurSubKeyCell = CmiGetBlock(RegistryHive, @@ -1013,13 +1238,13 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddSubKey(PREGISTRY_HIVE RegistryHive, - PKEY_OBJECT Parent, - PKEY_OBJECT SubKey, - PWSTR NewSubKeyName, - USHORT NewSubKeyNameSize, - ULONG TitleIndex, - PUNICODE_STRING Class, - ULONG CreateOptions) + PKEY_OBJECT Parent, + PKEY_OBJECT SubKey, + PWSTR NewSubKeyName, + USHORT NewSubKeyNameSize, + ULONG TitleIndex, + PUNICODE_STRING Class, + ULONG CreateOptions) { PHASH_TABLE_CELL NewHashBlock; PHASH_TABLE_CELL HashBlock; @@ -1057,33 +1282,33 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, } else { - NewKeyCell->Id = REG_KEY_CELL_ID; - NewKeyCell->Type = REG_KEY_CELL_TYPE; - ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime); - NewKeyCell->ParentKeyOffset = -1; - NewKeyCell->NumberOfSubKeys = 0; - NewKeyCell->HashTableOffset = -1; - NewKeyCell->NumberOfValues = 0; - NewKeyCell->ValuesOffset = -1; - NewKeyCell->SecurityKeyOffset = -1; - NewKeyCell->NameSize = NameSize; - wcstombs(NewKeyCell->Name, NewSubKeyName, NameSize); - NewKeyCell->ClassNameOffset = -1; + NewKeyCell->Id = REG_KEY_CELL_ID; + NewKeyCell->Type = REG_KEY_CELL_TYPE; + ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime); + NewKeyCell->ParentKeyOffset = -1; + NewKeyCell->NumberOfSubKeys = 0; + NewKeyCell->HashTableOffset = -1; + NewKeyCell->NumberOfValues = 0; + NewKeyCell->ValuesOffset = -1; + NewKeyCell->SecurityKeyOffset = -1; + NewKeyCell->NameSize = NameSize; + wcstombs(NewKeyCell->Name, NewSubKeyName, NameSize); + NewKeyCell->ClassNameOffset = -1; VERIFY_KEY_CELL(NewKeyCell); - if (Class) - { - PDATA_CELL pClass; - - NewKeyCell->ClassSize = Class->Length + sizeof(WCHAR); - Status = CmiAllocateBlock(RegistryHive, - (PVOID) &pClass, - NewKeyCell->ClassSize, - &NewKeyCell->ClassNameOffset); - wcsncpy((PWSTR) pClass->Data, Class->Buffer, Class->Length); - ((PWSTR) (pClass->Data))[Class->Length] = 0; - } + if (Class) + { + PDATA_CELL pClass; + + NewKeyCell->ClassSize = Class->Length + sizeof(WCHAR); + Status = CmiAllocateBlock(RegistryHive, + (PVOID) &pClass, + NewKeyCell->ClassSize, + &NewKeyCell->ClassNameOffset); + wcsncpy((PWSTR) pClass->Data, Class->Buffer, Class->Length); + ((PWSTR) (pClass->Data))[Class->Length] = 0; + } } if (!NT_SUCCESS(Status)) @@ -1096,72 +1321,148 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, /* Don't modify hash table if key is volatile and parent is not */ if (IsVolatileHive(RegistryHive) && (!IsVolatileHive(Parent->RegistryHive))) - { - return Status; - } + { + return(Status); + } - if (KeyCell->HashTableOffset == -1) + if (KeyCell->HashTableOffset == (ULONG_PTR) -1) { Status = CmiAllocateHashTableBlock(RegistryHive, - &HashBlock, - &KeyCell->HashTableOffset, - REG_INIT_HASH_TABLE_SIZE); - + &HashBlock, + &KeyCell->HashTableOffset, + REG_INIT_HASH_TABLE_SIZE); if (!NT_SUCCESS(Status)) - { - return Status; - } + { + return(Status); + } } else { HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize)) - { - BLOCK_OFFSET HTOffset; - - /* Reallocate the hash table block */ - Status = CmiAllocateHashTableBlock(RegistryHive, - &NewHashBlock, - &HTOffset, - HashBlock->HashTableSize + - REG_EXTEND_HASH_TABLE_SIZE); - - if (!NT_SUCCESS(Status)) - { - return Status; - } + { + BLOCK_OFFSET HTOffset; + + /* Reallocate the hash table block */ + Status = CmiAllocateHashTableBlock(RegistryHive, + &NewHashBlock, + &HTOffset, + HashBlock->HashTableSize + + REG_EXTEND_HASH_TABLE_SIZE); + if (!NT_SUCCESS(Status)) + { + return Status; + } - RtlZeroMemory(&NewHashBlock->Table[0], - sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize); - RtlCopyMemory(&NewHashBlock->Table[0], - &HashBlock->Table[0], - sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); - CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset); - KeyCell->HashTableOffset = HTOffset; - HashBlock = NewHashBlock; - } + RtlZeroMemory(&NewHashBlock->Table[0], + sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize); + RtlCopyMemory(&NewHashBlock->Table[0], + &HashBlock->Table[0], + sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); + CmiDestroyBlock(RegistryHive, + HashBlock, + KeyCell->HashTableOffset); + KeyCell->HashTableOffset = HTOffset; + HashBlock = NewHashBlock; + } } - Status = CmiAddKeyToHashTable(RegistryHive, HashBlock, NewKeyCell, NKBOffset); + Status = CmiAddKeyToHashTable(RegistryHive, + HashBlock, + NewKeyCell, + NKBOffset); if (NT_SUCCESS(Status)) { KeyCell->NumberOfSubKeys++; } - - return Status; + + return(Status); +} + + +NTSTATUS +CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, + PKEY_OBJECT ParentKey, + PKEY_OBJECT SubKey) +{ + PHASH_TABLE_CELL HashBlock; + + DPRINT1("CmiRemoveSubKey() called\n"); + + /* Remove the key from the parent key's hash block */ + if (ParentKey->KeyCell->HashTableOffset != -1) + { + DPRINT1("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset) + HashBlock = CmiGetBlock(RegistryHive, + ParentKey->KeyCell->HashTableOffset, + NULL); + DPRINT1("ParentKey HashBlock %p\n", HashBlock) + if (HashBlock != NULL) + { + CmiRemoveKeyFromHashTable(RegistryHive, + HashBlock, + SubKey->BlockOffset); + CmiMarkBlockDirty(RegistryHive, + ParentKey->KeyCell->HashTableOffset); + } + } + + /* Remove the key's hash block */ + if (SubKey->KeyCell->HashTableOffset != -1) + { + DPRINT1("SubKey HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset) + HashBlock = CmiGetBlock(RegistryHive, + SubKey->KeyCell->HashTableOffset, + NULL); + DPRINT1("SubKey HashBlock %p\n", HashBlock) + if (HashBlock != NULL) + { + CmiDestroyBlock(RegistryHive, + HashBlock, + SubKey->KeyCell->HashTableOffset); + SubKey->KeyCell->HashTableOffset = -1; + } + } + + /* Decrement the number of the parent key's sub keys */ + if (ParentKey != NULL) + { + DPRINT1("ParentKey %p\n", ParentKey) + ParentKey->KeyCell->NumberOfSubKeys--; + NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime); + CmiMarkBlockDirty(RegistryHive, + ParentKey->BlockOffset); + + /* Remove the parent key's hash table */ + if (ParentKey->KeyCell->NumberOfSubKeys == 0) + { + DPRINT1("FIXME: Remove parent key hash table\n") + + } + } + + /* Destroy key cell */ + CmiDestroyBlock(RegistryHive, + SubKey->KeyCell, + SubKey->BlockOffset); + SubKey->BlockOffset = -1; + SubKey->KeyCell = NULL; + + /* FIXME: Merge free blocks within the Bin */ + + return(STATUS_SUCCESS); } NTSTATUS CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, - IN PCHAR ValueName, + IN PUNICODE_STRING ValueName, OUT PVALUE_CELL *ValueCell, OUT BLOCK_OFFSET *VBOffset) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; - ULONG Length; ULONG i; ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); @@ -1179,26 +1480,26 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, for (i = 0; i < KeyCell->NumberOfValues; i++) { CurValueCell = CmiGetBlock(RegistryHive, - ValueListCell->Values[i], - NULL); - /* FIXME: perhaps we must not ignore case if NtCreateKey has not been */ - /* called with OBJ_CASE_INSENSITIVE flag ? */ - Length = strlen(ValueName); + ValueListCell->Values[i], + NULL); + if ((CurValueCell != NULL) && - (CurValueCell->NameSize == Length) && - (_strnicmp(CurValueCell->Name, ValueName, Length) == 0)) + CmiComparePackedNames(ValueName, + CurValueCell->Name, + CurValueCell->NameSize, + CurValueCell->Flags & REG_VALUE_NAME_PACKED)) { *ValueCell = CurValueCell; - if (VBOffset) + if (VBOffset) *VBOffset = ValueListCell->Values[i]; - DPRINT("Found value %s\n", ValueName); + //DPRINT("Found value %s\n", ValueName); break; } CmiReleaseBlock(RegistryHive, CurValueCell); } CmiReleaseBlock(RegistryHive, ValueListCell); - + return STATUS_SUCCESS; } @@ -1211,7 +1512,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; - + ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); *ValueCell = NULL; @@ -1239,7 +1540,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, CmiReleaseBlock(RegistryHive, CurValueCell); CmiReleaseBlock(RegistryHive, ValueListCell); - + return STATUS_SUCCESS; } @@ -1247,7 +1548,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, - IN PCHAR ValueNameBuf, + IN PUNICODE_STRING ValueName, OUT PVALUE_CELL *pValueCell, OUT BLOCK_OFFSET *pVBOffset) { @@ -1261,7 +1562,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, Status = CmiAllocateValueCell(RegistryHive, &NewValueCell, &VBOffset, - ValueNameBuf); + ValueName); *pVBOffset = VBOffset; if (!NT_SUCCESS(Status)) @@ -1286,7 +1587,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, KeyCell->ValuesOffset = VLBOffset; } else if ((KeyCell->NumberOfValues - >= ((LONG) (ValueListCell->CellSize - 4)) / (LONG) sizeof(BLOCK_OFFSET))) + >= (ULONG) ((LONG) (ValueListCell->CellSize - 4)) / (LONG) sizeof(BLOCK_OFFSET))) { Status = CmiAllocateBlock(RegistryHive, (PVOID) &NewValueListCell, @@ -1325,7 +1626,8 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, - IN PCHAR ValueName) + IN BLOCK_OFFSET KeyCellOffset, + IN PUNICODE_STRING ValueName) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -1343,9 +1645,12 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, for (i = 0; i < KeyCell->NumberOfValues; i++) { CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL); + if ((CurValueCell != NULL) && - (CurValueCell->NameSize == strlen(ValueName)) && - (memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0)) + CmiComparePackedNames(ValueName, + CurValueCell->Name, + CurValueCell->NameSize, + CurValueCell->Flags & REG_VALUE_NAME_PACKED)) { if ((KeyCell->NumberOfValues - 1) < i) { @@ -1367,6 +1672,21 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CmiReleaseBlock(RegistryHive, ValueListCell); + if (KeyCell->NumberOfValues == 0) + { + CmiDestroyBlock(RegistryHive, + ValueListCell, + KeyCell->ValuesOffset); + } + else + { + CmiMarkBlockDirty(RegistryHive, + KeyCell->ValuesOffset); + } + + CmiMarkBlockDirty(RegistryHive, + KeyCellOffset); + return STATUS_SUCCESS; } @@ -1386,9 +1706,9 @@ CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, NewHashSize = sizeof(HASH_TABLE_CELL) + (HashTableSize - 1) * sizeof(HASH_RECORD); Status = CmiAllocateBlock(RegistryHive, - (PVOID*) &NewHashBlock, - NewHashSize, - HBOffset); + (PVOID*) &NewHashBlock, + NewHashSize, + HBOffset); if ((NewHashBlock == NULL) || (!NT_SUCCESS(Status))) { @@ -1454,23 +1774,49 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, NTSTATUS +CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive, + PHASH_TABLE_CELL HashBlock, + BLOCK_OFFSET NKBOffset) +{ + ULONG i; + + for (i = 0; i < HashBlock->HashTableSize; i++) + { + if (HashBlock->Table[i].KeyOffset == NKBOffset) + { + HashBlock->Table[i].KeyOffset = 0; + RtlZeroMemory(&HashBlock->Table[i].HashValue, 4); + return STATUS_SUCCESS; + } + } + + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, PVALUE_CELL *ValueCell, BLOCK_OFFSET *VBOffset, - IN PCHAR ValueNameBuf) + IN PUNICODE_STRING ValueName) { PVALUE_CELL NewValueCell; - ULONG NewValueSize; NTSTATUS Status; + BOOLEAN Packable; + ULONG NameSize; + ULONG i; Status = STATUS_SUCCESS; - NewValueSize = sizeof(VALUE_CELL) + strlen(ValueNameBuf); - Status = CmiAllocateBlock(RegistryHive, - (PVOID*) &NewValueCell, - NewValueSize, - VBOffset); + NameSize = CmiGetPackedNameLength(ValueName, + &Packable); + + DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize); + Status = CmiAllocateBlock(RegistryHive, + (PVOID*) &NewValueCell, + sizeof(VALUE_CELL) + NameSize, + VBOffset); if ((NewValueCell == NULL) || (!NT_SUCCESS(Status))) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1478,8 +1824,22 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, else { NewValueCell->Id = REG_VALUE_CELL_ID; - NewValueCell->NameSize = strlen(ValueNameBuf); - memcpy(NewValueCell->Name, ValueNameBuf, strlen(ValueNameBuf)); + NewValueCell->NameSize = NameSize; + if (Packable) + { + /* Pack the value name */ + for (i = 0; i < NameSize; i++) + NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i]; + NewValueCell->Flags |= REG_VALUE_NAME_PACKED; + } + else + { + /* Copy the value name */ + RtlCopyMemory(NewValueCell->Name, + ValueName->Buffer, + NameSize); + NewValueCell->Flags = 0; + } NewValueCell->DataType = 0; NewValueCell->DataSize = 0; NewValueCell->DataOffset = 0xffffffff; @@ -1501,8 +1861,8 @@ CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, VERIFY_VALUE_CELL(ValueCell); - /* First, release datas: */ - if (ValueCell->DataSize > 0) + /* First, release data: */ + if (ValueCell->DataSize > 4) { pBlock = CmiGetBlock(RegistryHive, ValueCell->DataOffset, &pBin); Status = CmiDestroyBlock(RegistryHive, pBlock, ValueCell->DataOffset); @@ -1574,6 +1934,17 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, /* Initialize a free block in this heap : */ tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET); tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET); + + /* Grow bitmap if necessary */ + if (IsVolatileHive(RegistryHive) && + (RegistryHive->BlockListSize % (sizeof(ULONG) * 8) == 0)) + { + DPRINT1("Grow hive bitmap - BlockListSize %lu\n", RegistryHive->BlockListSize); + + /* FIXME */ + + } + *NewBlock = (PVOID) tmpBlock; if (NewBlockOffset) @@ -1587,9 +1958,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, - PVOID *Block, - LONG BlockSize, - BLOCK_OFFSET * pBlockOffset) + PVOID *Block, + LONG BlockSize, + BLOCK_OFFSET * pBlockOffset) { PCELL_HEADER NewBlock; NTSTATUS Status; @@ -1605,86 +1976,92 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, { NewBlock = ExAllocatePool(NonPagedPool, BlockSize); - if (NewBlock == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - else - { - RtlZeroMemory(NewBlock, BlockSize); - NewBlock->CellSize = BlockSize; - CmiLockBlock(RegistryHive, NewBlock); - *Block = NewBlock; - if (pBlockOffset) - *pBlockOffset = (BLOCK_OFFSET) NewBlock; - } + if (NewBlock == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + RtlZeroMemory(NewBlock, BlockSize); + NewBlock->CellSize = BlockSize; + CmiLockBlock(RegistryHive, NewBlock); + *Block = NewBlock; + if (pBlockOffset) + *pBlockOffset = (BLOCK_OFFSET) NewBlock; + } } else { - ULONG i; - - /* first search in free blocks */ - NewBlock = NULL; - for (i = 0; i < RegistryHive->FreeListSize; i++) - { - if (RegistryHive->FreeList[i]->CellSize >= BlockSize) - { - PVOID Temp; - NewBlock = RegistryHive->FreeList[i]; - - if (pBlockOffset) - *pBlockOffset = RegistryHive->FreeListOffset[i]; - - /* Update time of heap */ - Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin); - - if (Temp) - ZwQuerySystemTime((PTIME) &pBin->DateModified); - - if ((i + 1) < RegistryHive->FreeListSize) - { - RtlMoveMemory(&RegistryHive->FreeList[i], - &RegistryHive->FreeList[i + 1], - sizeof(RegistryHive->FreeList[0]) - * (RegistryHive->FreeListSize - i - 1)); - RtlMoveMemory(&RegistryHive->FreeListOffset[i], - &RegistryHive->FreeListOffset[i + 1], - sizeof(RegistryHive->FreeListOffset[0]) - * (RegistryHive->FreeListSize - i - 1)); - } - RegistryHive->FreeListSize--; - break; - } - } - - /* Need to extend hive file : */ - if (NewBlock == NULL) - { - /* Add a new block */ - Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset); - } - - if (NT_SUCCESS(Status)) - { - *Block = NewBlock; - - /* Split the block in two parts */ - if (NewBlock->CellSize > BlockSize) - { - NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); - NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; - CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize); - } - else if (NewBlock->CellSize < BlockSize) - { - return STATUS_UNSUCCESSFUL; - } - RtlZeroMemory(*Block, BlockSize); - ((PCELL_HEADER) (*Block))->CellSize = -BlockSize; - CmiLockBlock(RegistryHive, *Block); - } - } - return Status; + ULONG i; + + /* first search in free blocks */ + NewBlock = NULL; + for (i = 0; i < RegistryHive->FreeListSize; i++) + { + if (RegistryHive->FreeList[i]->CellSize >= BlockSize) + { + PVOID Temp; + + NewBlock = RegistryHive->FreeList[i]; + if (pBlockOffset) + *pBlockOffset = RegistryHive->FreeListOffset[i]; + + /* Update time of heap */ + Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin); + + if (Temp) + { + ZwQuerySystemTime((PTIME) &pBin->DateModified); + CmiMarkBlockDirty(RegistryHive, RegistryHive->FreeListOffset[i]); + } + + if ((i + 1) < RegistryHive->FreeListSize) + { + RtlMoveMemory(&RegistryHive->FreeList[i], + &RegistryHive->FreeList[i + 1], + sizeof(RegistryHive->FreeList[0]) + * (RegistryHive->FreeListSize - i - 1)); + RtlMoveMemory(&RegistryHive->FreeListOffset[i], + &RegistryHive->FreeListOffset[i + 1], + sizeof(RegistryHive->FreeListOffset[0]) + * (RegistryHive->FreeListSize - i - 1)); + } + RegistryHive->FreeListSize--; + break; + } + } + + /* Need to extend hive file : */ + if (NewBlock == NULL) + { + /* Add a new block */ + Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset); + } + + if (NT_SUCCESS(Status)) + { + *Block = NewBlock; + + /* Split the block in two parts */ + if (NewBlock->CellSize > BlockSize) + { + NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); + NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; + CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize); + CmiMarkBlockDirty(RegistryHive, *pBlockOffset + BlockSize); + } + else if (NewBlock->CellSize < BlockSize) + { + return(STATUS_UNSUCCESSFUL); + } + + RtlZeroMemory(*Block, BlockSize); + ((PCELL_HEADER) (*Block))->CellSize = -BlockSize; + CmiLockBlock(RegistryHive, *Block); + } + } + + return(Status); } @@ -1699,27 +2076,33 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive, Status = STATUS_SUCCESS; if (IsVolatileHive(RegistryHive)) - { - CmiReleaseBlock(RegistryHive, Block); - ExFreePool(Block); - } + { + CmiReleaseBlock(RegistryHive, Block); + ExFreePool(Block); + } else - { - PCELL_HEADER pFree = Block; + { + PCELL_HEADER pFree = Block; - if (pFree->CellSize < 0) - pFree->CellSize = -pFree->CellSize; + if (pFree->CellSize < 0) + pFree->CellSize = -pFree->CellSize; - CmiAddFree(RegistryHive, Block, Offset); - CmiReleaseBlock(RegistryHive, Block); + /* Clear block (except the block size) */ + RtlZeroMemory(((PVOID)pFree) + sizeof(ULONG), + pFree->CellSize - sizeof(ULONG)); - /* Update time of heap */ - if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin)) - ZwQuerySystemTime((PTIME) &pBin->DateModified); + CmiAddFree(RegistryHive, Block, Offset); + CmiReleaseBlock(RegistryHive, Block); - /* FIXME: Set first dword to block_offset of another free block ? */ - /* FIXME: Concatenate with previous and next block if free */ - } + /* Update time of heap */ + if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin)) + ZwQuerySystemTime((PTIME) &pBin->DateModified); + + CmiMarkBlockDirty(RegistryHive, Offset); + + /* FIXME: Set first dword to block_offset of another free block ? */ + /* FIXME: Concatenate with previous and next block if free */ + } return Status; } @@ -1743,98 +2126,100 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive, FreeBlock, FreeOffset); DPRINT("\n"); if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax) - { + { DPRINT("\n"); - tmpList = ExAllocatePool(PagedPool, + tmpList = ExAllocatePool(PagedPool, sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32)); DPRINT("\n"); - if (tmpList == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + if (tmpList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; DPRINT("\n"); - tmpListOffset = ExAllocatePool(PagedPool, + tmpListOffset = ExAllocatePool(PagedPool, sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32)); DPRINT("\n"); - if (tmpListOffset == NULL) - { - ExFreePool(tmpList); - return STATUS_INSUFFICIENT_RESOURCES; - } + if (tmpListOffset == NULL) + { + ExFreePool(tmpList); + return STATUS_INSUFFICIENT_RESOURCES; + } DPRINT("\n"); - if (RegistryHive->FreeListMax) - { + if (RegistryHive->FreeListMax) + { DPRINT("\n"); - RtlMoveMemory(tmpList, RegistryHive->FreeList, - sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); + RtlMoveMemory(tmpList, + RegistryHive->FreeList, + sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); DPRINT("\n"); - RtlMoveMemory(tmpListOffset, RegistryHive->FreeListOffset, - sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax)); + RtlMoveMemory(tmpListOffset, + RegistryHive->FreeListOffset, + sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax)); DPRINT("\n"); - ExFreePool(RegistryHive->FreeList); + ExFreePool(RegistryHive->FreeList); DPRINT("\n"); - ExFreePool(RegistryHive->FreeListOffset); + ExFreePool(RegistryHive->FreeListOffset); DPRINT("\n"); - } + } DPRINT("\n"); - RegistryHive->FreeList = tmpList; - RegistryHive->FreeListOffset = tmpListOffset; - RegistryHive->FreeListMax += 32; + RegistryHive->FreeList = tmpList; + RegistryHive->FreeListOffset = tmpListOffset; + RegistryHive->FreeListMax += 32; DPRINT("\n"); - } + } DPRINT("\n"); - /* Add new offset to free list, maintaining list in ascending order */ - if ((RegistryHive->FreeListSize == 0) - || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset)) - { + /* Add new offset to free list, maintaining list in ascending order */ + if ((RegistryHive->FreeListSize == 0) + || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset)) + { +DPRINT("\n"); + /* Add to end of list */ + RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock; + RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset; + } + else if (RegistryHive->FreeListOffset[0] > FreeOffset) + { DPRINT("\n"); - /* Add to end of list */ - RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock; - RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset; - } - else if (RegistryHive->FreeListOffset[0] > FreeOffset) - { + /* Add to begin of list */ + RtlMoveMemory(&RegistryHive->FreeList[1], + &RegistryHive->FreeList[0], + sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize); + RtlMoveMemory(&RegistryHive->FreeListOffset[1], + &RegistryHive->FreeListOffset[0], + sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize); + RegistryHive->FreeList[0] = FreeBlock; + RegistryHive->FreeListOffset[0] = FreeOffset; + RegistryHive->FreeListSize++; + } + else + { DPRINT("\n"); - /* Add to begin of list */ - RtlMoveMemory(&RegistryHive->FreeList[1], - &RegistryHive->FreeList[0], - sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize); - RtlMoveMemory(&RegistryHive->FreeListOffset[1], - &RegistryHive->FreeListOffset[0], - sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize); - RegistryHive->FreeList[0] = FreeBlock; - RegistryHive->FreeListOffset[0] = FreeOffset; - RegistryHive->FreeListSize++; - } + /* Search where to insert */ + minInd = 0; + maxInd = RegistryHive->FreeListSize - 1; + while ((maxInd - minInd) > 1) + { + medInd = (minInd + maxInd) / 2; + if (RegistryHive->FreeListOffset[medInd] > FreeOffset) + maxInd = medInd; else - { -DPRINT("\n"); - /* Search where to insert */ - minInd = 0; - maxInd = RegistryHive->FreeListSize - 1; - while ((maxInd - minInd) > 1) - { - medInd = (minInd + maxInd) / 2; - if (RegistryHive->FreeListOffset[medInd] > FreeOffset) - maxInd = medInd; - else - minInd = medInd; - } - - /* Insert before maxInd */ - RtlMoveMemory(&RegistryHive->FreeList[maxInd+1], - &RegistryHive->FreeList[maxInd], + minInd = medInd; + } + + /* Insert before maxInd */ + RtlMoveMemory(&RegistryHive->FreeList[maxInd+1], + &RegistryHive->FreeList[maxInd], sizeof(RegistryHive->FreeList[0]) * (RegistryHive->FreeListSize - minInd)); - RtlMoveMemory(&RegistryHive->FreeListOffset[maxInd + 1], + RtlMoveMemory(&RegistryHive->FreeListOffset[maxInd + 1], &RegistryHive->FreeListOffset[maxInd], sizeof(RegistryHive->FreeListOffset[0]) * (RegistryHive->FreeListSize-minInd)); - RegistryHive->FreeList[maxInd] = FreeBlock; - RegistryHive->FreeListOffset[maxInd] = FreeOffset; - RegistryHive->FreeListSize++; - } + RegistryHive->FreeList[maxInd] = FreeBlock; + RegistryHive->FreeListOffset[maxInd] = FreeOffset; + RegistryHive->FreeListSize++; + } DPRINT("\n"); return STATUS_SUCCESS; @@ -1843,13 +2228,13 @@ DPRINT("\n"); PVOID CmiGetBlock(PREGISTRY_HIVE RegistryHive, - BLOCK_OFFSET BlockOffset, - PHBIN * ppBin) + BLOCK_OFFSET BlockOffset, + PHBIN * ppBin) { if (ppBin) *ppBin = NULL; - if ((BlockOffset == 0) || (BlockOffset == -1)) + if ((BlockOffset == 0) || (BlockOffset == (ULONG_PTR) -1)) return NULL; if (IsVolatileHive(RegistryHive)) @@ -1869,24 +2254,19 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive, VOID -CmiPrepareForWrite(PREGISTRY_HIVE RegistryHive, - PHBIN pBin) +CmiLockBlock(PREGISTRY_HIVE RegistryHive, + PVOID Block) { - if (IsVolatileHive(RegistryHive)) - { - /* No need to do anything special for volatile hives */ - return; - } - else + if (IsPermanentHive(RegistryHive)) { - + /* FIXME: Implement */ } } VOID -CmiLockBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block) +CmiReleaseBlock(PREGISTRY_HIVE RegistryHive, + PVOID Block) { if (IsPermanentHive(RegistryHive)) { @@ -1896,11 +2276,96 @@ CmiLockBlock(PREGISTRY_HIVE RegistryHive, VOID -CmiReleaseBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block) +CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, + BLOCK_OFFSET BlockOffset) { - if (IsPermanentHive(RegistryHive)) + ULONG Index; + + if (IsVolatileHive(RegistryHive)) + return; + + Index = (ULONG)BlockOffset / 4096; + + DPRINT1("CmiMarkBlockDirty(Offset 0x%lx) Index %lu\n", + (ULONG)BlockOffset, Index); + + RegistryHive->HiveDirty = TRUE; + RtlSetBits(&RegistryHive->DirtyBitMap, + Index, + 1); +} + + +ULONG +CmiGetPackedNameLength(IN PUNICODE_STRING Name, + OUT PBOOLEAN Packable) +{ + ULONG i; + + if (Packable != NULL) + *Packable = TRUE; + + for (i = 0; i < Name->Length; i++) { - /* FIXME: Implement */ + if (Name->Buffer[i] > 0xFF) + { + if (Packable != NULL) + *Packable = FALSE; + return(Name->Length); + } + } + + return(Name->Length / sizeof(WCHAR)); +} + + +BOOLEAN +CmiComparePackedNames(IN PUNICODE_STRING Name, + IN PCHAR NameBuffer, + IN USHORT NameBufferSize, + IN BOOLEAN NamePacked) +{ + PWCHAR UNameBuffer; + ULONG i; + + if (NamePacked == TRUE) + { + if (Name->Length != NameBufferSize * sizeof(WCHAR)) + return(FALSE); + + for (i = 0; i < Name->Length / sizeof(WCHAR); i++) + { + if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i])) + return(FALSE); + } + } + else + { + if (Name->Length != NameBufferSize) + return(FALSE); + + UNameBuffer = (PWCHAR)NameBuffer; + + for (i = 0; i < Name->Length / sizeof(WCHAR); i++) + { + if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i])) + return(FALSE); + } } + + return(TRUE); } + + +VOID +CmiCopyPackedName(PWCHAR NameBuffer, + PCHAR PackedNameBuffer, + ULONG PackedNameSize) +{ + ULONG i; + + for (i = 0; i < PackedNameSize; i++) + NameBuffer[i] = (WCHAR)PackedNameBuffer[i]; +} + +/* EOF */ diff --git a/ntoskrnl/cm/registry.c b/ntoskrnl/cm/registry.c index d0d9c1d..8b7769e 100644 --- a/ntoskrnl/cm/registry.c +++ b/ntoskrnl/cm/registry.c @@ -11,17 +11,22 @@ * Created 22/05/98 */ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include #include #include #include #include +#include #define NDEBUG #include #include "cm.h" +#endif /* ------------------------------------------------- File Statics */ @@ -29,6 +34,14 @@ POBJECT_TYPE CmiKeyType = NULL; PREGISTRY_HIVE CmiVolatileHive = NULL; KSPIN_LOCK CmiKeyListLock; +LIST_ENTRY CmiHiveListHead; +ERESOURCE CmiHiveListLock; + +volatile BOOLEAN CmiHiveSyncEnabled = FALSE; +volatile BOOLEAN CmiHiveSyncPending = FALSE; +KDPC CmiHiveSyncDpc; +KTIMER CmiHiveSyncTimer; + static PKEY_OBJECT CmiRootKey = NULL; static PKEY_OBJECT CmiMachineKey = NULL; static PKEY_OBJECT CmiUserKey = NULL; @@ -38,6 +51,7 @@ static GENERIC_MAPPING CmiKeyMapping = {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS}; + VOID CmiCheckKey(BOOLEAN Verbose, HANDLE Key); @@ -45,6 +59,12 @@ CmiCheckKey(BOOLEAN Verbose, static NTSTATUS CmiCreateCurrentControlSetLink(VOID); +static VOID STDCALL +CmiHiveSyncDpcRoutine(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2); + /* FUNCTIONS ****************************************************************/ VOID @@ -65,58 +85,58 @@ CmiCheckSubKeys(BOOLEAN Verbose, Index = 0; while (TRUE) { - BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096; - KeyInfo = ExAllocatePool(PagedPool, BufferSize); - - Status = NtEnumerateKey(Key, - Index, - KeyNodeInformation, - KeyInfo, - BufferSize, - &ResultSize); + BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096; + KeyInfo = ExAllocatePool(PagedPool, BufferSize); + + Status = NtEnumerateKey(Key, + Index, + KeyNodeInformation, + KeyInfo, + BufferSize, + &ResultSize); if (!NT_SUCCESS(Status)) - { - ExFreePool(KeyInfo); - if (Status == STATUS_NO_MORE_ENTRIES) - Status = STATUS_SUCCESS; - break; - } + { + ExFreePool(KeyInfo); + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } wcsncpy(Name, - KeyInfo->Name, - KeyInfo->NameLength / sizeof(WCHAR)); + KeyInfo->Name, + KeyInfo->NameLength / sizeof(WCHAR)); if (Verbose) - { - DbgPrint("Key: %S\n", Name); - } + { + DbgPrint("Key: %S\n", Name); + } /* FIXME: Check info. */ ExFreePool(KeyInfo); - wcscpy(KeyBuffer, L"\\Registry\\"); - wcscat(KeyBuffer, Name); + wcscpy(KeyBuffer, L"\\Registry\\"); + wcscat(KeyBuffer, Name); - RtlInitUnicodeString(&KeyPath, KeyBuffer); + RtlInitUnicodeString(&KeyPath, KeyBuffer); - InitializeObjectAttributes(&ObjectAttributes, - &KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + InitializeObjectAttributes(&ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); - Status = NtOpenKey(&SubKey, - KEY_ALL_ACCESS, - &ObjectAttributes); + Status = NtOpenKey(&SubKey, + KEY_ALL_ACCESS, + &ObjectAttributes); - assert(NT_SUCCESS(Status)); - - CmiCheckKey(Verbose, SubKey); - - NtClose(SubKey); + assert(NT_SUCCESS(Status)); - Index++; + CmiCheckKey(Verbose, SubKey); + + NtClose(SubKey); + + Index++; } assert(NT_SUCCESS(Status)); @@ -137,37 +157,37 @@ CmiCheckValues(BOOLEAN Verbose, Index = 0; while (TRUE) { - BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096; - ValueInfo = ExAllocatePool(PagedPool, BufferSize); - - Status = NtEnumerateValueKey(Key, - Index, - KeyNodeInformation, - ValueInfo, - BufferSize, - &ResultSize); + BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096; + ValueInfo = ExAllocatePool(PagedPool, BufferSize); + + Status = NtEnumerateValueKey(Key, + Index, + KeyNodeInformation, + ValueInfo, + BufferSize, + &ResultSize); if (!NT_SUCCESS(Status)) - { - ExFreePool(ValueInfo); - if (Status == STATUS_NO_MORE_ENTRIES) - Status = STATUS_SUCCESS; - break; - } + { + ExFreePool(ValueInfo); + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } wcsncpy(Name, - ValueInfo->Name, - ValueInfo->NameLength / sizeof(WCHAR)); + ValueInfo->Name, + ValueInfo->NameLength / sizeof(WCHAR)); if (Verbose) - { - DbgPrint("Value: %S\n", Name); - } + { + DbgPrint("Value: %S\n", Name); + } /* FIXME: Check info. */ ExFreePool(ValueInfo); - Index++; + Index++; } assert(NT_SUCCESS(Status)); @@ -196,7 +216,7 @@ CmiCheckByName(BOOLEAN Verbose, wcscpy(KeyPathBuffer, L"\\Registry\\"); wcscat(KeyPathBuffer, KeyName); - RtlInitUnicodeString(&KeyPath, KeyPathBuffer); + RtlInitUnicodeString(&KeyPath, KeyPathBuffer); InitializeObjectAttributes(&ObjectAttributes, &KeyPath, @@ -211,11 +231,11 @@ CmiCheckByName(BOOLEAN Verbose, if (CHECKED) { if (!NT_SUCCESS(Status)) - { + { DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status); DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status); assert(NT_SUCCESS(Status)); - } + } } CmiCheckKey(Verbose, Key); @@ -244,7 +264,7 @@ CmInitializeRegistry(VOID) PKEY_OBJECT NewKey; HANDLE KeyHandle; NTSTATUS Status; - + /* Initialize the Key object type */ CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); assert(CmiKeyType); @@ -267,11 +287,15 @@ CmInitializeRegistry(VOID) CmiKeyType->DuplicationNotify = NULL; RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key"); + /* Initialize the hive list */ + InitializeListHead(&CmiHiveListHead); + ExInitializeResourceLite(&CmiHiveListLock); + /* Build volatile registry store */ Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE); assert(NT_SUCCESS(Status)); - /* Build the Root Key Object */ + /* Create '\Registry' key. */ RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME); InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL); Status = ObCreateObject(&RootKeyHandle, @@ -303,7 +327,7 @@ CmInitializeRegistry(VOID) /* Create initial predefined symbolic links */ - /* HKEY_LOCAL_MACHINE */ + /* Create '\Registry\Machine' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -330,7 +354,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiRootKey, NewKey); CmiMachineKey = NewKey; - /* HKEY_USERS */ + /* Create '\Registry\User' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -357,7 +381,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiRootKey, NewKey); CmiUserKey = NewKey; - /* Create '\\Registry\\Machine\\HARDWARE' key. */ + /* Create '\Registry\Machine\HARDWARE' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -384,7 +408,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiMachineKey, NewKey); CmiHardwareKey = NewKey; - /* Create '\\Registry\\Machine\\HARDWARE\\DESCRIPTION' key. */ + /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -410,7 +434,7 @@ CmInitializeRegistry(VOID) memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION")); CmiAddKeyToList(CmiHardwareKey, NewKey); - /* Create '\\Registry\\Machine\\HARDWARE\\DEVICEMAP' key. */ + /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -436,7 +460,7 @@ CmInitializeRegistry(VOID) memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP")); CmiAddKeyToList(CmiHardwareKey,NewKey); - /* Create '\\Registry\\Machine\\HARDWARE\\RESOURCEMAP' key. */ + /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -472,13 +496,21 @@ CmInit2(PCHAR CommandLine) { PCHAR p1, p2; ULONG PiceStart; + NTSTATUS Status; - /* FIXME: Store current command line */ + /* FIXME: Store system start options */ - /* Create the 'CurrentControlSet' link. */ - CmiCreateCurrentControlSetLink(); + /* Create the 'CurrentControlSet' link. */ + Status = CmiCreateCurrentControlSetLink(); +#ifndef WIN32_REGDBG + if (!NT_SUCCESS(Status)) + { + KeBugCheck(CONFIG_INITIALIZATION_FAILED); + } +#endif + /* Set PICE 'Start' value to 1, if PICE debugging is enabled */ PiceStart = 4; p1 = (PCHAR)CommandLine; @@ -500,14 +532,18 @@ CmInit2(PCHAR CommandLine) } p1 = p2; } - - RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, - L"\\Pice", - L"Start", - REG_DWORD, - &PiceStart, - sizeof(ULONG)); - +#ifndef WIN32_REGDBG + Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, + L"\\Pice", + L"Start", + REG_DWORD, + &PiceStart, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(CONFIG_INITIALIZATION_FAILED); + } +#endif } @@ -588,12 +624,12 @@ CmiCreateCurrentControlSetLink(VOID) RtlInitUnicodeStringFromLiteral(&LinkValue, L"SymbolicLinkValue"); - Status=NtSetValueKey(KeyHandle, - &LinkValue, - 0, - REG_LINK, - (PVOID)TargetNameBuffer, - TargetNameLength); + Status = NtSetValueKey(KeyHandle, + &LinkValue, + 0, + REG_LINK, + (PVOID)TargetNameBuffer, + TargetNameLength); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); @@ -619,11 +655,15 @@ CmiConnectHive(PWSTR FileName, HANDLE KeyHandle; NTSTATUS Status; - DPRINT("Called. FileName %S\n", FullName); + DPRINT("CmiConnectHive(%S, %S, %s, %p, %d) - Called.\n", FileName, FullName, KeyName, Parent, CreateNew); Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status); + KeBugCheck(0); + return(Status); + } RtlInitUnicodeString(&uKeyName, FullName); @@ -639,7 +679,12 @@ CmiConnectHive(PWSTR FileName, CmiKeyType, (PVOID*)&NewKey); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); + KeBugCheck(0); + CmiRemoveRegistryHive(RegistryHive); + return(Status); + } NewKey->RegistryHive = RegistryHive; NewKey->BlockOffset = RegistryHive->HiveHeader->RootKeyCell; @@ -651,9 +696,9 @@ CmiConnectHive(PWSTR FileName, if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0)) { - /* FIXME: Cleanup from CmiCreateRegistryHive() */ DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys); ZwClose(NewKey); + CmiRemoveRegistryHive(RegistryHive); return(STATUS_INSUFFICIENT_RESOURCES); } @@ -662,11 +707,11 @@ CmiConnectHive(PWSTR FileName, if ((NewKey->Name == NULL) && (strlen(KeyName) != 0)) { - /* FIXME: Cleanup from CmiCreateRegistryHive() */ DPRINT("strlen(KeyName) %d\n", strlen(KeyName)); if (NewKey->SubKeys != NULL) ExFreePool(NewKey->SubKeys); ZwClose(NewKey); + CmiRemoveRegistryHive(RegistryHive); return(STATUS_INSUFFICIENT_RESOURCES); } @@ -697,23 +742,25 @@ CmiInitializeHive(PWSTR FileName, if (!NT_SUCCESS(Status)) { - DPRINT("Status %.08x\n", Status); #if 0 +#ifdef WIN32_REGDBG WCHAR AltFileName[MAX_PATH]; CPRINT("WARNING! Registry file %S not found\n", FileName); + //DPRINT("Status %.08x\n", Status); wcscpy(AltFileName, FileName); wcscat(AltFileName, L".alt"); + DPRINT("Attempting to connect the alternative hive %S\n", AltFileName); /* Try to connect the alternative hive */ Status = CmiConnectHive(AltFileName, FullName, KeyName, Parent, TRUE); - if (!NT_SUCCESS(Status)) - { - CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName); - DPRINT("Status %.08x\n", Status); - } + if (!NT_SUCCESS(Status)) { + CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName); + //DPRINT("Status %.08x\n", Status); + } +#endif #endif } @@ -726,39 +773,166 @@ CmiInitializeHive(PWSTR FileName, NTSTATUS CmiInitHives(BOOLEAN SetUpBoot) { + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE KeyHandle; + NTSTATUS Status; + WCHAR ConfigPath[MAX_PATH]; + + ULONG BufferSize; + ULONG ResultSize; + PWSTR EndPtr; + + DPRINT("CmiInitHives() called\n"); + if (SetUpBoot == TRUE) + { + RtlInitUnicodeStringFromLiteral(&KeyName, + L"\\Registry\\Machine\\HARDWARE"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + return(Status); + } + + RtlInitUnicodeStringFromLiteral(&ValueName, + L"InstallPath"); + + BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096; + ValueInfo = ExAllocatePool(PagedPool, + BufferSize); + if (ValueInfo == NULL) + { + NtClose(KeyHandle); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + ValueInfo, + BufferSize, + &ResultSize); + NtClose(KeyHandle); + if (ValueInfo == NULL) + { + ExFreePool(ValueInfo); + return(Status); + } + + RtlCopyMemory(ConfigPath, + ValueInfo->Data, + ValueInfo->DataLength); + ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0; + ExFreePool(ValueInfo); + } + else + { + wcscpy(ConfigPath, L"\\SystemRoot"); + } + wcscat(ConfigPath, L"\\system32\\config"); + + DPRINT("ConfigPath: %S\n", ConfigPath); + + EndPtr = ConfigPath + wcslen(ConfigPath); + CmiDoVerify = TRUE; - /* FIXME: Delete temporary \Registry\Machine\System */ + /* FIXME: Save boot log */ + + /* FIXME: Rename \Registry\Machine\System */ /* Connect the SYSTEM hive */ - /* FIXME: Don't overwrite the existing 'System' hive yet */ -// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey); +// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot); // assert(NT_SUCCESS(Status)); + /* FIXME: Synchronize old and new system hive (??) */ + + /* FIXME: Delete old system hive */ + /* Connect the SOFTWARE hive */ - Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey, SetUpBoot); - //assert(NT_SUCCESS(Status)); + wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME); + DPRINT1("ConfigPath: %S\n", ConfigPath); + + Status = CmiInitializeHive(ConfigPath, + REG_SOFTWARE_KEY_NAME, + "Software", + CmiMachineKey, + SetUpBoot); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the SAM hive */ - Status = CmiInitializeHive(SAM_REG_FILE,REG_SAM_KEY_NAME, "Sam", CmiMachineKey, SetUpBoot); - //assert(NT_SUCCESS(Status)); + wcscpy(EndPtr, REG_SAM_FILE_NAME); + DPRINT1("ConfigPath: %S\n", ConfigPath); + + Status = CmiInitializeHive(ConfigPath, + REG_SAM_KEY_NAME, + "Sam", + CmiMachineKey, + SetUpBoot); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the SECURITY hive */ - Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey, SetUpBoot); - //assert(NT_SUCCESS(Status)); + wcscpy(EndPtr, REG_SEC_FILE_NAME); + DPRINT1("ConfigPath: %S\n", ConfigPath); + Status = CmiInitializeHive(ConfigPath, + REG_SEC_KEY_NAME, + "Security", + CmiMachineKey, + SetUpBoot); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the DEFAULT hive */ - Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey, SetUpBoot); - //assert(NT_SUCCESS(Status)); + wcscpy(EndPtr, REG_USER_FILE_NAME); + DPRINT1("ConfigPath: %S\n", ConfigPath); + + Status = CmiInitializeHive(ConfigPath, + REG_USER_KEY_NAME, + ".Default", + CmiUserKey, + SetUpBoot); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* FIXME : initialize standards symbolic links */ // CmiCheckRegistry(TRUE); + /* Start automatic hive synchronization */ + KeInitializeDpc(&CmiHiveSyncDpc, + CmiHiveSyncDpcRoutine, + NULL); + KeInitializeTimer(&CmiHiveSyncTimer); + CmiHiveSyncEnabled = TRUE; + DPRINT("CmiInitHives() done\n"); return(STATUS_SUCCESS); @@ -768,12 +942,135 @@ CmiInitHives(BOOLEAN SetUpBoot) VOID CmShutdownRegistry(VOID) { - DPRINT("CmShutdownRegistry() called\n"); + PREGISTRY_HIVE Hive; + PLIST_ENTRY Entry; + + DPRINT1("CmShutdownRegistry() called\n"); + + /* Stop automatic hive synchronization */ + CmiHiveSyncEnabled = FALSE; + + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + Entry = CmiHiveListHead.Flink; + while (Entry != &CmiHiveListHead) + { + Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList); + + if (IsPermanentHive(Hive)) + { + /* Acquire hive resource exclusively */ + ExAcquireResourceExclusiveLite(&Hive->HiveResource, + TRUE); + + /* Flush non-volatile hive */ + CmiFlushRegistryHive(Hive); + + /* Dereference file */ + ObDereferenceObject(Hive->FileObject); + Hive->FileObject = NULL; + + /* Release hive resource */ + ExReleaseResourceLite(&Hive->HiveResource); + } + + Entry = Entry->Flink; + } + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + + DPRINT1("CmShutdownRegistry() done\n"); +} + + +VOID STDCALL +CmiHiveSyncRoutine(PVOID DeferredContext) +{ + PREGISTRY_HIVE Hive; + PLIST_ENTRY Entry; + + DPRINT1("CmiHiveSyncRoutine() called\n"); + + CmiHiveSyncPending = FALSE; + + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + Entry = CmiHiveListHead.Flink; + while (Entry != &CmiHiveListHead) + { + Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList); + + if (IsPermanentHive(Hive)) + { + /* Acquire hive resource exclusively */ + ExAcquireResourceExclusiveLite(&Hive->HiveResource, + TRUE); + + /* Flush non-volatile hive */ + CmiFlushRegistryHive(Hive); + + /* Release hive resource */ + ExReleaseResourceLite(&Hive->HiveResource); + } + + Entry = Entry->Flink; + } + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + + DPRINT("DeferredContext %x\n", DeferredContext); + ExFreePool(DeferredContext); +} + + +static VOID STDCALL +CmiHiveSyncDpcRoutine(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PWORK_QUEUE_ITEM WorkQueueItem; + + WorkQueueItem = ExAllocatePool(NonPagedPool, + sizeof(WORK_QUEUE_ITEM)); + if (WorkQueueItem == NULL) + { + DbgPrint("Failed to allocate work item\n"); + return; + } + + ExInitializeWorkItem(WorkQueueItem, + CmiHiveSyncRoutine, + WorkQueueItem); + + DPRINT("DeferredContext %x\n", WorkQueueItem); + ExQueueWorkItem(WorkQueueItem, + CriticalWorkQueue); +} + + +VOID +CmiSyncHives(VOID) +{ + LARGE_INTEGER Timeout; + + DPRINT("CmiSyncHives() called\n"); + + if (CmiHiveSyncEnabled == FALSE || + CmiHiveSyncPending == TRUE) + return; + + CmiHiveSyncPending = TRUE; + - /* Note: - * Don't call UNIMPLEMENTED() here since this function is - * called by NtShutdownSystem(). - */ + Timeout.QuadPart = -50000000LL; + KeSetTimer(&CmiHiveSyncTimer, + Timeout, + &CmiHiveSyncDpc); } /* EOF */ diff --git a/ntoskrnl/cm/regobj.c b/ntoskrnl/cm/regobj.c index 41cfcbd..e4570e4 100644 --- a/ntoskrnl/cm/regobj.c +++ b/ntoskrnl/cm/regobj.c @@ -6,6 +6,9 @@ * UPDATE HISTORY: */ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include #include @@ -19,6 +22,7 @@ #include #include "cm.h" +#endif static NTSTATUS @@ -41,7 +45,9 @@ CmiObjectParse(PVOID ParsedObject, PKEY_CELL SubKeyCell; CHAR cPath[MAX_PATH]; NTSTATUS Status; - PWSTR end; + PWSTR StartPtr; + PWSTR EndPtr; + ULONG Length; UNICODE_STRING LinkPath; UNICODE_STRING TargetPath; @@ -59,22 +65,20 @@ CmiObjectParse(PVOID ParsedObject, DPRINT("Path '%S'\n", *Path); - if ((*Path[0]) == '\\') - { - end = wcschr((*Path) + 1, '\\'); - if (end != NULL) - *end = 0; - wcstombs(cPath, (*Path) + 1, wcslen((*Path) + 1)); - cPath[wcslen((*Path) + 1)] = 0; - } + /* Extract relevant path name */ + StartPtr = *Path; + if (*StartPtr == L'\\') + StartPtr++; + + EndPtr = wcschr(StartPtr, L'\\'); + if (EndPtr != NULL) + Length = ((PCHAR)EndPtr - (PCHAR)StartPtr) / sizeof(WCHAR); else - { - end = wcschr((*Path), '\\'); - if (end != NULL) - *end = 0; - wcstombs(cPath, (*Path), wcslen((*Path))); - cPath[wcslen((*Path))] = 0; - } + Length = wcslen(StartPtr); + + wcstombs(cPath, StartPtr, Length); + cPath[Length] = 0; + FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes); if (FoundObject == NULL) @@ -88,15 +92,11 @@ CmiObjectParse(PVOID ParsedObject, Attributes); if (!NT_SUCCESS(Status) || (SubKeyCell == NULL)) { - if (end != NULL) - { - *end = '\\'; - } return(STATUS_UNSUCCESSFUL); } if ((SubKeyCell->Type == REG_LINK_KEY_CELL_TYPE) && - !((Attributes & OBJ_OPENLINK) && (end == NULL))) + !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL) /*(end == NULL)*/)) { RtlInitUnicodeString(&LinkPath, NULL); Status = CmiGetLinkTarget(ParsedKey->RegistryHive, @@ -108,18 +108,17 @@ CmiObjectParse(PVOID ParsedObject, /* build new FullPath for reparsing */ TargetPath.MaximumLength = LinkPath.MaximumLength; - if (end != NULL) + if (EndPtr != NULL) { - *end = '\\'; - TargetPath.MaximumLength += (wcslen(end) * sizeof(WCHAR)); - } + TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR)); + } TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); TargetPath.Buffer = ExAllocatePool(NonPagedPool, TargetPath.MaximumLength); wcscpy(TargetPath.Buffer, LinkPath.Buffer); - if (end != NULL) + if (EndPtr != NULL) { - wcscat(TargetPath.Buffer, end); + wcscat(TargetPath.Buffer, EndPtr); } RtlFreeUnicodeString(FullPath); @@ -139,7 +138,7 @@ CmiObjectParse(PVOID ParsedObject, } /* Create new key object and put into linked list */ - DPRINT("CmiObjectParse %s\n", cPath); + DPRINT("CmiObjectParse: %s\n", cPath); Status = ObCreateObject(NULL, STANDARD_RIGHTS_REQUIRED, NULL, @@ -162,8 +161,10 @@ CmiObjectParse(PVOID ParsedObject, else { if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) && - !((Attributes & OBJ_OPENLINK) && (end == NULL))) + !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)/*(end == NULL)*/)) { + DPRINT("Found link\n"); + RtlInitUnicodeString(&LinkPath, NULL); Status = CmiGetLinkTarget(FoundObject->RegistryHive, FoundObject->KeyCell, @@ -174,18 +175,17 @@ CmiObjectParse(PVOID ParsedObject, /* build new FullPath for reparsing */ TargetPath.MaximumLength = LinkPath.MaximumLength; - if (end != NULL) + if (EndPtr != NULL) { - *end = '\\'; - TargetPath.MaximumLength += (wcslen(end) * sizeof(WCHAR)); - } + TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR)); + } TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); TargetPath.Buffer = ExAllocatePool(NonPagedPool, TargetPath.MaximumLength); wcscpy(TargetPath.Buffer, LinkPath.Buffer); - if (end != NULL) + if (EndPtr != NULL) { - wcscat(TargetPath.Buffer, end); + wcscat(TargetPath.Buffer, EndPtr); } RtlFreeUnicodeString(FullPath); @@ -209,18 +209,18 @@ CmiObjectParse(PVOID ParsedObject, NULL, UserMode); } - - DPRINT("CmiObjectParse %s\n", FoundObject->Name); - - if (end != NULL) - { - *end = '\\'; - *Path = end; - } - else - { - *Path = NULL; - } +#ifndef WIN32_REGDBG + DPRINT("CmiObjectParse: %s\n", FoundObject->Name); +#else + { + char buffer[_BUFFER_LEN]; + memset(buffer, 0, _BUFFER_LEN); + strncpy(buffer, FoundObject->Name, min(FoundObject->NameSize, _BUFFER_LEN - 1)); + DPRINT("CmiObjectParse: %s\n", buffer); + } +#endif + + *Path = EndPtr; VERIFY_KEY_OBJECT(FoundObject); @@ -278,9 +278,13 @@ CmiObjectDelete(PVOID DeletedObject) if (KeyObject->Flags & KO_MARKED_FOR_DELETE) { DPRINT("delete really key\n"); - CmiDestroyBlock(KeyObject->RegistryHive, - KeyObject->KeyCell, - KeyObject->BlockOffset); + + CmiRemoveSubKey(KeyObject->RegistryHive, + KeyObject->ParentKey, + KeyObject); + + if (IsPermanentHive(KeyObject->RegistryHive)) + CmiSyncHives(); } else { @@ -376,8 +380,17 @@ CmiScanKeyList(PKEY_OBJECT Parent, WORD NameSize; DWORD Index; - DPRINT("Scanning key list for %s (Parent %s)\n", +#ifndef WIN32_REGDBG + DPRINT("Scanning key list for: %s (Parent: %s)\n", KeyName, Parent->Name); +#else + { + char buffer[_BUFFER_LEN]; + memset(buffer, 0, _BUFFER_LEN); + strncpy(buffer, Parent->Name, min(Parent->NameSize, _BUFFER_LEN - 1)); + DPRINT("Scanning key list for: %s (Parent: %s)\n", KeyName, buffer); + } +#endif NameSize = strlen(KeyName); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); @@ -415,18 +428,22 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive, PKEY_CELL KeyCell, PUNICODE_STRING TargetPath) { + UNICODE_STRING LinkName = UNICODE_STRING_INITIALIZER(L"SymbolicLinkValue"); PVALUE_CELL ValueCell; PDATA_CELL DataCell; NTSTATUS Status; + DPRINT("CmiGetLinkTarget() called\n"); + /* Get Value block of interest */ Status = CmiScanKeyForValue(RegistryHive, KeyCell, - "SymbolicLinkValue", + &LinkName, &ValueCell, NULL); if (!NT_SUCCESS(Status)) { + DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status); return(Status); } @@ -445,7 +462,7 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive, } TargetPath->Length = min(TargetPath->MaximumLength - sizeof(WCHAR), - ValueCell->DataSize); + (ULONG) ValueCell->DataSize); if (ValueCell->DataSize > 0) { @@ -464,6 +481,8 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive, TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0; } + DPRINT("TargetPath '%wZ'\n", TargetPath); + return(STATUS_SUCCESS); } diff --git a/ntoskrnl/cm/rtlfunc.c b/ntoskrnl/cm/rtlfunc.c index 4c68311..7e36694 100644 --- a/ntoskrnl/cm/rtlfunc.c +++ b/ntoskrnl/cm/rtlfunc.c @@ -6,6 +6,11 @@ * UPDATE HISTORY: */ +/* INCLUDES *****************************************************************/ + +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else #include #include #include @@ -18,6 +23,10 @@ #include #include "cm.h" +#endif + + +/* FUNCTIONS ****************************************************************/ NTSTATUS STDCALL RtlCheckRegistryKey(IN ULONG RelativeTo, @@ -145,6 +154,10 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, PWSTR StringPtr; DPRINT("RtlQueryRegistryValues() called\n"); +#ifdef WIN32_REGDBG + BaseKeyHandle = NULL; + CurrentKeyHandle = NULL; +#endif Status = RtlpGetRegistryHandle(RelativeTo, Path, @@ -182,7 +195,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, ParamTable[1].DefaultType = REG_MULTI_SZ; Status = RtlQueryRegistryValues( - IN ULONG RelativeTo = RTL_REGISTRY_ABSOLUTE, + IN ULONG RelativeTo = RTL_REGISTRY_ABSOLUTE, IN PWSTR Path = Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable = ParamTable, IN PVOID Context = NULL, @@ -241,7 +254,9 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, Status = STATUS_NO_MEMORY; break; } - +#ifdef WIN32_REGDBG + memset(ValueInfo, 0, BufferSize); +#endif Status = ZwQueryValueKey(CurrentKeyHandle, &KeyName, KeyValuePartialInformation, @@ -466,7 +481,11 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND)) { DPRINT("Expand REG_MULTI_SZ type\n"); +#ifdef WIN32_REGDBG + StringPtr = (PWSTR)(FullValueInfo + FullValueInfo->DataOffset); +#else StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset); +#endif while (*StringPtr != 0) { StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR); @@ -485,7 +504,11 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, { Status = QueryEntry->QueryRoutine(FullValueInfo->Name, FullValueInfo->Type, +#ifdef WIN32_REGDBG + FullValueInfo + FullValueInfo->DataOffset, +#else (PVOID)FullValueInfo + FullValueInfo->DataOffset, +#endif FullValueInfo->DataLength, Context, QueryEntry->EntryContext); diff --git a/ntoskrnl/dbg/errinfo.c b/ntoskrnl/dbg/errinfo.c index 1e1653f..b4ea485 100644 --- a/ntoskrnl/dbg/errinfo.c +++ b/ntoskrnl/dbg/errinfo.c @@ -212,7 +212,7 @@ DbgGetErrorText(NTSTATUS ErrorCode, PUNICODE_STRING ErrorText, ULONG Flags) { for (i = 0; FacList[i].Name != NULL; i++) { - if (FacList[i].Code == NT_FACILITY(ErrorCode)) + if (FacList[i].Code == (ULONG) NT_FACILITY(ErrorCode)) { break; } @@ -257,11 +257,11 @@ DbgGetErrorText(NTSTATUS ErrorCode, PUNICODE_STRING ErrorText, ULONG Flags) { if (Flags & DBG_GET_SHOW_FACILITY) { - sprintf(NumBuf, "%08lx", ErrorCode); + sprintf(NumBuf, "%08x", ErrorCode); strcat(TempBuf, NumBuf); strcat(TempBuf, " "); } - sprintf(NumBuf, "Unknown Message #%08lx", ErrorCode); + sprintf(NumBuf, "Unknown Message #%08x", ErrorCode); strcat(TempBuf, NumBuf); } RtlInitAnsiString(&AnsiString, TempBuf); diff --git a/ntoskrnl/dbg/kdb.h b/ntoskrnl/dbg/kdb.h index 570759e..fed6cbc 100644 --- a/ntoskrnl/dbg/kdb.h +++ b/ntoskrnl/dbg/kdb.h @@ -1,3 +1,13 @@ +#define NTOS_MODE_KERNEL +#include + +NTSTATUS +LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL); + ULONG KdbTryGetCharKeyboard(VOID); VOID @@ -10,3 +20,13 @@ VOID DbgEnableFile(PCH Filename); VOID DbgDisableFile(PCH Filename); +VOID +KdbInitProfiling(); +VOID +KdbInitProfiling2(); +VOID +KdbDisableProfiling(); +VOID +KdbEnableProfiling(); +VOID +KdbProfileInterrupt(ULONG_PTR Eip); diff --git a/ntoskrnl/dbg/kdb_stabs.c b/ntoskrnl/dbg/kdb_stabs.c index 88b5bab..9457bde 100644 --- a/ntoskrnl/dbg/kdb_stabs.c +++ b/ntoskrnl/dbg/kdb_stabs.c @@ -210,12 +210,20 @@ KdbPrintAddress(PVOID address) } VOID -KdbFreeSymbolsProcess(PPEB Peb) +KdbFreeSymbolsProcess(PEPROCESS Process) { PLIST_ENTRY CurrentEntry; PLDR_MODULE Current; PIMAGE_SYMBOL_INFO SymbolInfo; - + PEPROCESS CurrentProcess; + PPEB Peb; + + CurrentProcess = PsGetCurrentProcess(); + if (CurrentProcess != Process) + { + KeAttachProcess(Process); + } + Peb = Process->Peb; assert (Peb); assert (Peb->Ldr); @@ -231,6 +239,10 @@ KdbFreeSymbolsProcess(PPEB Peb) CurrentEntry = CurrentEntry->Flink; } + if (CurrentProcess != Process) + { + KeDetachProcess(); + } } VOID @@ -456,6 +468,7 @@ LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo, Length = strlen(Symbol->Name.Buffer); strncpy(FunctionName, Symbol->Name.Buffer, Length); + FunctionName[Length]=0; return STATUS_SUCCESS; } Symbol = NextSymbol; @@ -783,6 +796,11 @@ KdbLdrLoadUserModuleSymbols(PLDR_MODULE LdrModule) RtlCreateUnicodeString(&CacheEntry->FullName, LdrModule->FullDllName.Buffer); assert(CacheEntry->FullName.Buffer); LdrpLoadModuleSymbols(&LdrModule->FullDllName, &LdrModule->SymbolInfo); + CacheEntry->FileBuffer = LdrModule->SymbolInfo.FileBuffer; + CacheEntry->SymbolsBase = LdrModule->SymbolInfo.SymbolsBase; + CacheEntry->SymbolsLength = LdrModule->SymbolInfo.SymbolsLength; + CacheEntry->SymbolStringsBase = LdrModule->SymbolInfo.SymbolStringsBase; + CacheEntry->SymbolStringsLength = LdrModule->SymbolInfo.SymbolStringsLength; InsertTailList(&SymbolListHead, &CacheEntry->ListEntry); } } diff --git a/ntoskrnl/dbg/profile.c b/ntoskrnl/dbg/profile.c new file mode 100755 index 0000000..89b3c0c --- /dev/null +++ b/ntoskrnl/dbg/profile.c @@ -0,0 +1,500 @@ +/* + * ReactOS kernel + * Copyright (C) 1998-2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/dbg/profile.c + * PURPOSE: Kernel profiling + * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * UPDATE HISTORY: + * Created 12/01/2003 + */ + +/* INCLUDES *****************************************************************/ + +#define NTOS_MODE_KERNEL +#include +#include +#include "kdb.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +#define PROFILE_SESSION_LENGTH 30 /* Session length in seconds */ + +typedef struct _PROFILE_DATABASE_ENTRY +{ + ULONG_PTR Address; +} PROFILE_DATABASE_ENTRY, *PPROFILE_DATABASE_ENTRY; + +#define PDE_BLOCK_ENTRIES ((PAGE_SIZE - (sizeof(LIST_ENTRY) + sizeof(ULONG))) / sizeof(PROFILE_DATABASE_ENTRY)) + +typedef struct _PROFILE_DATABASE_BLOCK +{ + LIST_ENTRY ListEntry; + ULONG UsedEntries; + PROFILE_DATABASE_ENTRY Entries[PDE_BLOCK_ENTRIES]; +} PROFILE_DATABASE_BLOCK, *PPROFILE_DATABASE_BLOCK; + +typedef struct _PROFILE_DATABASE +{ + LIST_ENTRY ListHead; +} PROFILE_DATABASE, *PPROFILE_DATABASE; + +typedef struct _SAMPLE_GROUP_INFO +{ + ULONG_PTR Address; + ULONG Count; + CHAR Description[128]; + LIST_ENTRY ListEntry; +} SAMPLE_GROUP_INFO, *PSAMPLE_GROUP_INFO; + +static volatile BOOLEAN KdbProfilingInitialized = FALSE; +static volatile BOOLEAN KdbProfilingEnabled = FALSE; +static volatile BOOLEAN KdbProfilingSuspended = FALSE; +static PPROFILE_DATABASE KdbProfileDatabase = NULL; +static KDPC KdbProfilerCollectorDpc; +static HANDLE KdbProfilerThreadHandle; +static CLIENT_ID KdbProfilerThreadCid; +static HANDLE KdbProfilerLogFile; +static KTIMER KdbProfilerTimer; +static KMUTEX KdbProfilerLock; +static BOOLEAN KdbEnableProfiler = FALSE; + +VOID +KdbDeleteProfileDatabase(PPROFILE_DATABASE ProfileDatabase) +{ + PLIST_ENTRY current = NULL; + + current = RemoveHeadList(&ProfileDatabase->ListHead); + while (current != &ProfileDatabase->ListHead) + { + PPROFILE_DATABASE_BLOCK block = CONTAINING_RECORD( + current, PROFILE_DATABASE_BLOCK, ListEntry); + ExFreePool(block); + current = RemoveHeadList(&ProfileDatabase->ListHead); + } +} + +VOID +KdbAddEntryToProfileDatabase(PPROFILE_DATABASE ProfileDatabase, ULONG_PTR Address) +{ + PPROFILE_DATABASE_BLOCK block; + + if (IsListEmpty(&ProfileDatabase->ListHead)) + { + block = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE_BLOCK)); + assert(block); + block->UsedEntries = 0; + InsertTailList(&ProfileDatabase->ListHead, &block->ListEntry); + block->Entries[block->UsedEntries++].Address = Address; + return; + } + + block = CONTAINING_RECORD(ProfileDatabase->ListHead.Blink, PROFILE_DATABASE_BLOCK, ListEntry); + if (block->UsedEntries >= PDE_BLOCK_ENTRIES) + { + block = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE_BLOCK)); + assert(block); + block->UsedEntries = 0; + InsertTailList(&ProfileDatabase->ListHead, &block->ListEntry); + } + block->Entries[block->UsedEntries++].Address = Address; +} + +VOID +KdbInitProfiling() +{ + KdbEnableProfiler = TRUE; +} + +VOID +KdbInitProfiling2() +{ + if (KdbEnableProfiler) + { + KdbEnableProfiling(); + KdbProfilingInitialized = TRUE; + } +} + +VOID +KdbSuspendProfiling() +{ + KdbProfilingSuspended = TRUE; +} + +VOID +KdbResumeProfiling() +{ + KdbProfilingSuspended = FALSE; +} + +BOOLEAN +KdbProfilerGetSymbolInfo(PVOID address, OUT PCH NameBuffer) +{ + PLIST_ENTRY current_entry; + MODULE_TEXT_SECTION* current; + extern LIST_ENTRY ModuleTextListHead; + ULONG_PTR RelativeAddress; + NTSTATUS Status; + ULONG LineNumber; + CHAR FileName[256]; + CHAR FunctionName[256]; + + current_entry = ModuleTextListHead.Flink; + + while (current_entry != &ModuleTextListHead && + current_entry != NULL) + { + current = + CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry); + + if (address >= (PVOID)current->Base && + address < (PVOID)(current->Base + current->Length)) + { + RelativeAddress = (ULONG_PTR) address - current->Base; + Status = LdrGetAddressInformation(¤t->SymbolInfo, + RelativeAddress, + &LineNumber, + FileName, + FunctionName); + if (NT_SUCCESS(Status)) + { + sprintf(NameBuffer, "%s (%s)", FileName, FunctionName); + return(TRUE); + } + return(TRUE); + } + current_entry = current_entry->Flink; + } + return(FALSE); +} + +PLIST_ENTRY +KdbProfilerLargestSampleGroup(PLIST_ENTRY SamplesListHead) +{ + PLIST_ENTRY current; + PLIST_ENTRY largest; + ULONG count; + + count = 0; + largest = SamplesListHead->Flink; + current = SamplesListHead->Flink; + while (current != SamplesListHead) + { + PSAMPLE_GROUP_INFO sgi = CONTAINING_RECORD( + current, SAMPLE_GROUP_INFO, ListEntry); + + if (sgi->Count > count) + { + largest = current; + count = sgi->Count; + } + + current = current->Flink; + } + if (count == 0) + { + return NULL; + } + return largest; +} + +VOID +KdbProfilerWriteString(PCH String) +{ + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + ULONG Length; + + Length = strlen(String); + Status = NtWriteFile(KdbProfilerLogFile, + NULL, + NULL, + NULL, + &Iosb, + String, + Length, + NULL, + NULL); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed with status 0x%.08x\n", Status); + } +} + +NTSTATUS +KdbProfilerWriteSampleGroups(PLIST_ENTRY SamplesListHead) +{ + CHAR Buffer[256]; + PLIST_ENTRY current = NULL; + PLIST_ENTRY Largest; + + KdbProfilerWriteString("\r\n\r\n"); + KdbProfilerWriteString("Count Symbol\n"); + KdbProfilerWriteString("--------------------------------------------------\r\n"); + + current = SamplesListHead->Flink; + while (current != SamplesListHead) + { + Largest = KdbProfilerLargestSampleGroup(SamplesListHead); + if (Largest != NULL) + { + PSAMPLE_GROUP_INFO sgi = CONTAINING_RECORD( + Largest, SAMPLE_GROUP_INFO, ListEntry); + + //DbgPrint("%.08d %s\n", sgi->Count, sgi->Description); + + sprintf(Buffer, "%.08d %s\r\n", sgi->Count, sgi->Description); + KdbProfilerWriteString(Buffer); + + RemoveEntryList(Largest); + ExFreePool(sgi); + } + else + { + break; + } + + current = SamplesListHead->Flink; + } + + return STATUS_SUCCESS; +} + +LONG STDCALL +KdbProfilerKeyCompare(IN PVOID Key1, + IN PVOID Key2) +{ + int value = strcmp(Key1, Key2); + + if (value == 0) + return 0; + + return (value < 0) ? -1 : 1; +} + + +NTSTATUS +KdbProfilerAnalyzeSamples() +{ + CHAR NameBuffer[512]; + ULONG KeyLength; + PLIST_ENTRY current = NULL; + HASH_TABLE Hashtable; + LIST_ENTRY SamplesListHead; + ULONG Index; + ULONG_PTR Address; + + if (!ExInitializeHashTable(&Hashtable, 17, KdbProfilerKeyCompare, TRUE)) + { + DPRINT1("ExInitializeHashTable() failed."); + KeBugCheck(0); + } + + InitializeListHead(&SamplesListHead); + + current = RemoveHeadList(&KdbProfileDatabase->ListHead); + while (current != &KdbProfileDatabase->ListHead) + { + PPROFILE_DATABASE_BLOCK block; + + block = CONTAINING_RECORD(current, PROFILE_DATABASE_BLOCK, ListEntry); + + for (Index = 0; Index < block->UsedEntries; Index++) + { + PSAMPLE_GROUP_INFO sgi; + Address = block->Entries[Index].Address; + if (KdbProfilerGetSymbolInfo((PVOID) Address, (PCH) &NameBuffer)) + { + } + else + { + sprintf(NameBuffer, "(0x%.08x)", (ULONG) Address); + } + + KeyLength = strlen(NameBuffer); + if (!ExSearchHashTable(&Hashtable, (PVOID) NameBuffer, KeyLength, (PVOID *) &sgi)) + { + sgi = ExAllocatePool(NonPagedPool, sizeof(SAMPLE_GROUP_INFO)); + assert(sgi); + sgi->Address = Address; + sgi->Count = 1; + strcpy(sgi->Description, NameBuffer); + InsertTailList(&SamplesListHead, &sgi->ListEntry); + ExInsertHashTable(&Hashtable, sgi->Description, KeyLength, (PVOID) sgi); + } + else + { + sgi->Count++; + } + } + + ExFreePool(block); + + current = RemoveHeadList(&KdbProfileDatabase->ListHead); + } + + KdbProfilerWriteSampleGroups(&SamplesListHead); + + ExDeleteHashTable(&Hashtable); + + KdbDeleteProfileDatabase(KdbProfileDatabase); + + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +KdbProfilerThreadMain(PVOID Context) +{ + for (;;) + { + KeWaitForSingleObject(&KdbProfilerTimer, Executive, KernelMode, TRUE, NULL); + + KeWaitForSingleObject(&KdbProfilerLock, Executive, KernelMode, FALSE, NULL); + + KdbSuspendProfiling(); + + KdbProfilerAnalyzeSamples(); + + KdbResumeProfiling(); + + KeReleaseMutex(&KdbProfilerLock, FALSE); + } +} + +VOID +KdbDisableProfiling() +{ + if (KdbProfilingEnabled == TRUE) + { + /* FIXME: Implement */ +#if 0 + KdbProfilingEnabled = FALSE; + /* Stop timer */ + /* Close file */ + if (KdbProfileDatabase != NULL) + { + KdbDeleteProfileDatabase(KdbProfileDatabase); + ExFreePool(KdbProfileDatabase); + KdbProfileDatabase = NULL; + } +#endif + } +} + +/* + * SystemArgument1 = EIP + */ +static VOID STDCALL +KdbProfilerCollectorDpcRoutine(PKDPC Dpc, PVOID DeferredContext, + PVOID SystemArgument1, PVOID SystemArgument2) +{ + ULONG_PTR address = (ULONG_PTR) SystemArgument1; + + KdbAddEntryToProfileDatabase(KdbProfileDatabase, address); +} + +VOID +KdbEnableProfiling() +{ + if (KdbProfilingEnabled == FALSE) + { + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING FileName; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER DueTime; + + RtlInitUnicodeString(&FileName, L"\\SystemRoot\\profiler.log"); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&KdbProfilerLogFile, + FILE_ALL_ACCESS, + &ObjectAttributes, + &Iosb, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create profiler log file\n"); + return; + } + + Status = PsCreateSystemThread(&KdbProfilerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &KdbProfilerThreadCid, + KdbProfilerThreadMain, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create profiler thread\n"); + return; + } + + KeInitializeMutex(&KdbProfilerLock, 0); + + KdbProfileDatabase = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE)); + assert(KdbProfileDatabase); + InitializeListHead(&KdbProfileDatabase->ListHead); + KeInitializeDpc(&KdbProfilerCollectorDpc, KdbProfilerCollectorDpcRoutine, NULL); + + /* Initialize our periodic timer and its associated DPC object. When the timer + expires, the KdbProfilerSessionEndDpc deferred procedure call (DPC) is queued */ + KeInitializeTimerEx(&KdbProfilerTimer, SynchronizationTimer); + + /* Start the periodic timer with an initial and periodic + relative expiration time of PROFILE_SESSION_LENGTH seconds */ + DueTime.QuadPart = -(LONGLONG) PROFILE_SESSION_LENGTH * 1000 * 10000; + KeSetTimerEx(&KdbProfilerTimer, DueTime, PROFILE_SESSION_LENGTH * 1000, NULL); + + KdbProfilingEnabled = TRUE; + } +} + +VOID +KdbProfileInterrupt(ULONG_PTR Address) +{ + assert(KeGetCurrentIrql() == PROFILE_LEVEL); + + if (KdbProfilingInitialized != TRUE) + { + return; + } + + if ((KdbProfilingEnabled) && (!KdbProfilingSuspended)) + { + (BOOLEAN) KeInsertQueueDpc(&KdbProfilerCollectorDpc, (PVOID) Address, NULL); + } +} diff --git a/ntoskrnl/ex/hashtab.c b/ntoskrnl/ex/hashtab.c index 207fa44..0c42567 100644 --- a/ntoskrnl/ex/hashtab.c +++ b/ntoskrnl/ex/hashtab.c @@ -195,7 +195,7 @@ ExInitializeHashTable(IN PHASH_TABLE HashTable, IN BOOLEAN UseNonPagedPool) { BOOLEAN Status; - LONG Index; + ULONG Index; RtlZeroMemory(HashTable, sizeof(HASH_TABLE)); diff --git a/ntoskrnl/ex/i386/interlck.c b/ntoskrnl/ex/i386/interlck.c index e5f23a6..2d5e2bc 100644 --- a/ntoskrnl/ex/i386/interlck.c +++ b/ntoskrnl/ex/i386/interlck.c @@ -34,8 +34,8 @@ Exfi386InterlockedExchangeUlong(IN PULONG Target, __asm__("\n\t.global @Exfi386InterlockedExchangeUlong@8\n\t" "@Exfi386InterlockedExchangeUlong@8:\n\t" - "movl (%ecx),%eax\n" "xchgl %edx,(%ecx)\n\t" + "movl %edx,%eax\n\t" "ret\n\t"); @@ -124,8 +124,8 @@ InterlockedExchange(PLONG Target, __asm__("\n\t.global @InterlockedExchange@8\n\t" "@InterlockedExchange@8:\n\t" - "movl (%ecx),%eax\n" "xchgl %edx,(%ecx)\n\t" + "movl %edx,%eax\n\t" "ret\n\t"); diff --git a/ntoskrnl/ex/napi.c b/ntoskrnl/ex/napi.c index ae64d80..939584b 100644 --- a/ntoskrnl/ex/napi.c +++ b/ntoskrnl/ex/napi.c @@ -8,8 +8,7 @@ /* INCLUDES *****************************************************************/ -#include -#include +#include #include /* GLOBALS ******************************************************************/ diff --git a/ntoskrnl/ex/power.c b/ntoskrnl/ex/power.c index 34c63a6..f4f0289 100644 --- a/ntoskrnl/ex/power.c +++ b/ntoskrnl/ex/power.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -40,6 +41,7 @@ NtShutdownSystem(IN SHUTDOWN_ACTION Action) IoShutdownRegisteredDevices(); CmShutdownRegistry(); IoShutdownRegisteredFileSystems(); + PiShutdownProcessManager(); MiShutdownMemoryManager(); diff --git a/ntoskrnl/ex/time.c b/ntoskrnl/ex/time.c index 17c4e56..05f402e 100644 --- a/ntoskrnl/ex/time.c +++ b/ntoskrnl/ex/time.c @@ -57,6 +57,7 @@ NtSetSystemTime (IN PLARGE_INTEGER UnsafeNewSystemTime, NTSTATUS Status; LARGE_INTEGER OldSystemTime; LARGE_INTEGER NewSystemTime; + TIME_FIELDS TimeFields; /* FIXME: Check for SeSystemTimePrivilege */ @@ -71,7 +72,8 @@ NtSetSystemTime (IN PLARGE_INTEGER UnsafeNewSystemTime, { KeQuerySystemTime(&OldSystemTime); } - HalSetRealTimeClock ((PTIME_FIELDS)&NewSystemTime); + RtlTimeToTimeFields (&NewSystemTime, &TimeFields); + HalSetRealTimeClock (&TimeFields); if (UnsafeOldSystemTime != NULL) { diff --git a/ntoskrnl/fs/filelock.c b/ntoskrnl/fs/filelock.c index 5629977..f41c6b1 100644 --- a/ntoskrnl/fs/filelock.c +++ b/ntoskrnl/fs/filelock.c @@ -3,379 +3,1276 @@ * reactos/ntoskrnl/fs/filelock.c * */ -#include +#include +#include #include +#define NDEBUG +#include + +/* +NOTE: +I'm not using resource syncronization here, since FsRtlFastCheckLockForRead/Write +are allowed to be called at DISPATCH_LEVEL. Must therefore use nonpaged memory for +the lists. +*/ + +#define LOCK_START_OFF(Lock) ((Lock).StartingByte.QuadPart) +#define LOCK_END_OFF(Lock) (((Lock).StartingByte.QuadPart) + ((Lock).Length.QuadPart) - 1) +#define REQUEST_START_OFF (FileOffset->QuadPart) +#define REQUEST_END_OFF ((FileOffset->QuadPart) + (Length->QuadPart) - 1) + +FAST_MUTEX LockTocMutex; +NPAGED_LOOKASIDE_LIST GrantedLookaside; +NPAGED_LOOKASIDE_LIST LockTocLookaside; +PAGED_LOOKASIDE_LIST LockLookaside; /********************************************************************** - * NAME EXPORTED - * FsRtlCheckLockForReadAccess@8 + * NAME PRIVATE + * FsRtlpInitFileLockingImplementation * - * DESCRIPTION - * - * ARGUMENTS + */ +VOID +STDCALL +FsRtlpInitFileLockingImplementation(VOID) +{ + ExInitializeNPagedLookasideList( &LockTocLookaside, + NULL, + NULL, + 0, + sizeof(FILE_LOCK_TOC), + IFS_POOL_TAG, + 0 + ); + + ExInitializeNPagedLookasideList( &GrantedLookaside, + NULL, + NULL, + 0, + sizeof(FILE_LOCK_GRANTED), + IFS_POOL_TAG, + 0 + ); + + ExInitializePagedLookasideList( &LockLookaside, + NULL, + NULL, + 0, + sizeof(FILE_LOCK), + IFS_POOL_TAG, + 0 + ); + + ExInitializeFastMutex(&LockTocMutex); +} + +/********************************************************************** + * NAME PRIVATE + * FsRtlpFileLockCancelRoutine * - * RETURN VALUE + */ +VOID +STDCALL +FsRtlpFileLockCancelRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + KIRQL oldIrql; + PKSPIN_LOCK SpinLock; + PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine; + + //don't need this since we have our own sync. protecting irp cancellation + IoReleaseCancelSpinLock(Irp->CancelIrql); + + SpinLock = &((PFILE_LOCK_TOC)Irp->Tail.Overlay.DriverContext[1])->SpinLock; + + KeAcquireSpinLock(SpinLock, &oldIrql); + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + KeReleaseSpinLock(SpinLock, oldIrql); + + Irp->IoStatus.Status = STATUS_CANCELLED; + + CompleteLockIrpRoutine = ((PFILE_LOCK)Irp->Tail.Overlay.DriverContext[0])->CompleteLockIrpRoutine; + if (CompleteLockIrpRoutine) + { + CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp); + } + else + { + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + +} + +/********************************************************************** + * NAME PRIVATE + * FsRtlpCheckLockForReadOrWriteAccess * - * NOTE (Bo Branten) - * All this really does is pick out the lock parameters from - * the irp (io stack location?), get IoGetRequestorProcess, - * and pass values on to FsRtlFastCheckLockForRead. + */ +BOOLEAN +FASTCALL +FsRtlpCheckLockForReadOrWriteAccess( + IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN BOOLEAN Read + ) +{ + KIRQL oldirql; + PFILE_LOCK_TOC LockToc; + PFILE_LOCK_GRANTED Granted; + PLIST_ENTRY EnumEntry; + + assert(FileLock); + LockToc = FileLock->LockInformation; + + if (LockToc == NULL || Length->QuadPart == 0) + { + return TRUE; + } + + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + + EnumEntry = LockToc->GrantedListHead.Flink; + while ( EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry ); + //if overlapping + if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) || + REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock))) + { + //No read conflict if (shared lock) OR (exclusive + our lock) + //No write conflict if exclusive lock AND our lock + if ((Read && !Granted->Lock.ExclusiveLock) || + (Granted->Lock.ExclusiveLock && + Granted->Lock.Process == Process && + Granted->Lock.FileObject == FileObject && + Granted->Lock.Key == Key ) ) + { + //AND if lock surround request region, stop searching and grant + if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) && + REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock)) + { + EnumEntry = &LockToc->GrantedListHead;//indicate no conflict + break; + } + //else continue searching for conflicts + } + else //conflict + { + break; + } + } + EnumEntry = EnumEntry->Flink; + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + + if (EnumEntry == &LockToc->GrantedListHead) + { //no conflict + return TRUE; + } + + return FALSE; +} + + +/********************************************************************** + * NAME EXPORTED + * FsRtlCheckLockForReadAccess * */ BOOLEAN STDCALL FsRtlCheckLockForReadAccess ( - IN PFILE_LOCK FileLock, - IN PIRP Irp - ) + IN PFILE_LOCK FileLock, + IN PIRP Irp + ) { - return FALSE; + PIO_STACK_LOCATION Stack; + LARGE_INTEGER LocalLength; + + Stack = IoGetCurrentIrpStackLocation(Irp); + + LocalLength.u.LowPart = Stack->Parameters.Read.Length; + LocalLength.u.HighPart = 0; + + return FsRtlpCheckLockForReadOrWriteAccess( FileLock, + &Stack->Parameters.Read.ByteOffset, + &LocalLength, + Stack->Parameters.Read.Key, + Stack->FileObject, + IoGetRequestorProcess(Irp), + TRUE//Read? + ); } /********************************************************************** * NAME EXPORTED - * FsRtlCheckLockForWriteAccess@8 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + * FsRtlCheckLockForWriteAccess * - * NOTE (Bo Branten) - * All this really does is pick out the lock parameters from - * the irp (io stack location?), get IoGetRequestorProcess, - * and pass values on to FsRtlFastCheckLockForWrite. */ BOOLEAN STDCALL FsRtlCheckLockForWriteAccess ( - IN PFILE_LOCK FileLock, - IN PIRP Irp - ) + IN PFILE_LOCK FileLock, + IN PIRP Irp + ) { - return FALSE; + PIO_STACK_LOCATION Stack; + LARGE_INTEGER LocalLength; + + Stack = IoGetCurrentIrpStackLocation(Irp); + + LocalLength.u.LowPart = Stack->Parameters.Read.Length; + LocalLength.u.HighPart = 0; + + return FsRtlpCheckLockForReadOrWriteAccess( FileLock, + &Stack->Parameters.Write.ByteOffset, + &LocalLength, + Stack->Parameters.Write.Key, + Stack->FileObject, + IoGetRequestorProcess(Irp), + FALSE//Read? + ); + } + + /********************************************************************** * NAME EXPORTED - * FsRtlFastCheckLockForRead@24 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + * FsRtlFastCheckLockForRead * */ BOOLEAN STDCALL FsRtlFastCheckLockForRead ( - IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process - ) + IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process + ) { - return FALSE; + return FsRtlpCheckLockForReadOrWriteAccess( FileLock, + FileOffset, + Length, + Key, + FileObject, + Process, + TRUE//Read? + ); } /********************************************************************** * NAME EXPORTED - * FsRtlFastCheckLockForWrite@24 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + * FsRtlFastCheckLockForWrite * */ BOOLEAN STDCALL FsRtlFastCheckLockForWrite ( - IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process - ) + IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process + ) { - return FALSE; + return FsRtlpCheckLockForReadOrWriteAccess( FileLock, + FileOffset, + Length, + Key, + FileObject, + Process, + FALSE//Read? + ); } + /********************************************************************** - * NAME EXPORTED - * FsRtlFastUnlockAll@16 - * FsRtlFastUnlockAllByKey@20 + * NAME PRIVATE + * FsRtlpFastUnlockAllByKey * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + */ +NTSTATUS +FASTCALL +FsRtlpFastUnlockAllByKey( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN DWORD Key, /* FIXME: guess */ + IN BOOLEAN UseKey, /* FIXME: guess */ + IN PVOID Context OPTIONAL + ) +{ + KIRQL oldirql; + PFILE_LOCK_TOC LockToc; + PLIST_ENTRY EnumEntry; + PFILE_LOCK_GRANTED Granted; + BOOLEAN Unlock = FALSE; + //must make local copy since FILE_LOCK struct is allowed to be paged + PUNLOCK_ROUTINE GotUnlockRoutine; + + assert(FileLock); + LockToc = FileLock->LockInformation; + + if (LockToc == NULL) + { + return STATUS_RANGE_NOT_LOCKED; + } + + GotUnlockRoutine = FileLock->UnlockRoutine; + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + + EnumEntry = LockToc->GrantedListHead.Flink; + while (EnumEntry != &LockToc->GrantedListHead ) + { + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry); + EnumEntry = EnumEntry->Flink; + + if (Granted->Lock.Process == Process && + Granted->Lock.FileObject == FileObject && + (!UseKey || (UseKey && Granted->Lock.Key == Key)) ) + { + RemoveEntryList(&Granted->ListEntry); + Unlock = TRUE; + + if (GotUnlockRoutine) + { + /* + Put on unlocked list and call unlock routine for them afterwards. + This way we don't have to restart enum after each call + */ + InsertHeadList(&LockToc->UnlockedListHead,&Granted->ListEntry); + } + else + { + ExFreeToNPagedLookasideList(&GrantedLookaside,Granted); + } + } + } + + if (Unlock) + { + //call unlock routine for each unlocked lock (if any) + while (!IsListEmpty(&LockToc->UnlockedListHead)) + { + EnumEntry = RemoveTailList(&LockToc->UnlockedListHead); + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry); + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + FileLock->UnlockRoutine(Context,&Granted->Lock); + ExFreeToNPagedLookasideList(&GrantedLookaside,Granted); + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + } + + //NOTE: holding spinlock while calling this + FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql); + + if (IsListEmpty(&LockToc->GrantedListHead)) + { + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; + } + else + { + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + } + return STATUS_SUCCESS; + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + return STATUS_RANGE_NOT_LOCKED; +} + +/********************************************************************** + * NAME EXPORTED + * FsRtlFastUnlockAll * */ -static NTSTATUS STDCALL -FsRtlpFastUnlockAllByKey ( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN DWORD Key, /* FIXME: guess */ - IN BOOLEAN UseKey, /* FIXME: guess */ - IN PVOID Context OPTIONAL - ) +FsRtlFastUnlockAll /*ByProcess*/ ( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN PVOID Context OPTIONAL + ) { - /* FIXME: */ - return (STATUS_RANGE_NOT_LOCKED); + return FsRtlpFastUnlockAllByKey( FileLock, + FileObject, + Process, + 0, /* Key */ + FALSE, /* Do NOT use Key */ + Context + ); } - +/********************************************************************** + * NAME EXPORTED + * FsRtlFastUnlockAllByKey + * + */ NTSTATUS STDCALL -FsRtlFastUnlockAll ( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN PVOID Context OPTIONAL - ) +FsRtlFastUnlockAllByKey ( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL + ) { - return FsRtlpFastUnlockAllByKey ( - FileLock, - FileObject, - Process, - 0, /* Key */ - FALSE, /* Do NOT use Key */ - Context - ); + return FsRtlpFastUnlockAllByKey( FileLock, + FileObject, + Process, + Key, + TRUE, /* Use Key */ + Context + ); } +/********************************************************************** + * NAME PRIVATE + * FsRtlpAddLock + * + * NOTE + * Spinlock held at entry !! + */ NTSTATUS -STDCALL -FsRtlFastUnlockAllByKey ( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL - ) +FASTCALL +FsRtlpAddLock( + IN PFILE_LOCK_TOC LockToc, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN BOOLEAN ExclusiveLock + ) { - return FsRtlpFastUnlockAllByKey ( - FileLock, - FileObject, - Process, - Key, - TRUE, /* Use Key */ - Context - ); + PLIST_ENTRY EnumEntry; + PFILE_LOCK_GRANTED Granted; + + EnumEntry = LockToc->GrantedListHead.Flink; + while (EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry); + //if overlapping + if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) || + REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock))) + { + //never conflict if shared lock and we want to add a shared lock + if (!Granted->Lock.ExclusiveLock && !ExclusiveLock) + { + //AND if lock surround region, stop searching and insert lock + if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) && + REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock)) + { + EnumEntry = &LockToc->GrantedListHead; + break; + } + //else keep locking for conflicts + } + else + {//conflict if we want share access to excl. lock OR exlc. access to shared lock + break;//FAIL + } + } + EnumEntry = EnumEntry->Flink; + } + + if (EnumEntry == &LockToc->GrantedListHead) + {//no conflict + Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside); + + Granted->Lock.StartingByte = *FileOffset; + Granted->Lock.Length = *Length; + Granted->Lock.ExclusiveLock = ExclusiveLock; + Granted->Lock.Key = Key; + Granted->Lock.FileObject = FileObject; + Granted->Lock.Process = Process; + Granted->Lock.EndingByte.QuadPart = REQUEST_END_OFF; + + InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry); + return TRUE; + } + + return FALSE; + } + /********************************************************************** - * NAME EXPORTED - * FsRtlFastUnlockSingle@32 + * NAME PRIVATE + * FsRtlpCompletePendingLocks * - * DESCRIPTION - * - * ARGUMENTS + * NOTE + * Spinlock held at entry !! + */ +VOID +FASTCALL +FsRtlpCompletePendingLocks( + IN PFILE_LOCK FileLock, + IN PFILE_LOCK_TOC LockToc, + IN OUT PKIRQL oldirql + ) +{ + //walk pending list, FIFO order, try 2 complete locks + PLIST_ENTRY EnumEntry; + PIRP Irp; + PIO_STACK_LOCATION Stack; + + EnumEntry = LockToc->PendingListHead.Blink; + while (EnumEntry != &LockToc->PendingListHead) + { + Irp = CONTAINING_RECORD(EnumEntry,IRP, Tail.Overlay.ListEntry); + + Stack = IoGetCurrentIrpStackLocation(Irp); + if (FsRtlpAddLock(LockToc, + Stack->FileObject, + &Stack->Parameters.LockControl.ByteOffset, + Stack->Parameters.LockControl.Length, + IoGetRequestorProcess(Irp), + Stack->Parameters.LockControl.Key, + Stack->Flags & SL_EXCLUSIVE_LOCK + ) ) + { + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + if (!IoSetCancelRoutine(Irp, NULL)) + { + /* + Cancel routine WILL be called after we release the spinlock. It will try to remove + the irp from the list and cancel/complete this irp. Since we allready removed it, + make its ListEntry point to itself. + */ + InitializeListHead(&Irp->Tail.Overlay.ListEntry); + } + else + { + /* + Cancel routine will NOT be called, canceled or not. + + Put on completed list and complete them all afterwards. + This way we don't have to restart enum after each completion. + */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + InsertHeadList(&LockToc->CompletedListHead,&Irp->Tail.Overlay.ListEntry); + } + } + EnumEntry = EnumEntry->Blink; + } + + //complete irp's (if any) + while (!IsListEmpty(&LockToc->CompletedListHead)) + { + EnumEntry = RemoveTailList(&LockToc->CompletedListHead); + KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);//fires cancel routine + Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry); + + if (FileLock->CompleteLockIrpRoutine) + { + FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp); + } + else + { + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + + KeAcquireSpinLock(&LockToc->SpinLock, oldirql); + } + +} + + + +/********************************************************************** + * NAME PRIVATE + * FsRtlpUnlockSingle * - * RETURN VALUE + */ +NTSTATUS +FASTCALL +FsRtlpUnlockSingle( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL, + IN BOOLEAN AlreadySynchronized, + IN BOOLEAN CallUnlockRoutine + ) +{ + KIRQL oldirql; + PFILE_LOCK_TOC LockToc; + PFILE_LOCK_GRANTED Granted; + PLIST_ENTRY EnumEntry; + + assert(FileLock); + LockToc = FileLock->LockInformation; + + if (LockToc == NULL || Length->QuadPart == 0) + { + return STATUS_RANGE_NOT_LOCKED; + } + + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql ); + + EnumEntry = LockToc->GrantedListHead.Flink; + while (EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry); + + //must be exact match + if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart && + Length->QuadPart == Granted->Lock.Length.QuadPart && + Granted->Lock.Process == Process && + Granted->Lock.FileObject == FileObject && + Granted->Lock.Key == Key) + { + RemoveEntryList(&Granted->ListEntry); + FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql); + + if (IsListEmpty(&LockToc->GrantedListHead)) + { + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; + } + else + { + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + } + + if (FileLock->UnlockRoutine && CallUnlockRoutine) + { + FileLock->UnlockRoutine(Context,&Granted->Lock); + } + + ExFreeToNPagedLookasideList(&GrantedLookaside,Granted); + + return STATUS_SUCCESS; + } + EnumEntry = EnumEntry->Flink; + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + + return STATUS_RANGE_NOT_LOCKED; + +} + + + +/********************************************************************** + * NAME EXPORTED + * FsRtlFastUnlockSingle * */ NTSTATUS STDCALL FsRtlFastUnlockSingle ( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL, - IN BOOLEAN AlreadySynchronized - ) + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL, + IN BOOLEAN AlreadySynchronized + ) { - return (STATUS_RANGE_NOT_LOCKED); + return FsRtlpUnlockSingle( FileLock, + FileObject, + FileOffset, + Length, + Process, + Key, + Context, + AlreadySynchronized, + TRUE//CallUnlockRoutine + ); } - /********************************************************************** * NAME EXPORTED - * FsRtlGetNextFileLock@8 + * FsRtlpDumpFileLocks * - * DESCRIPTION - * - * ARGUMENTS + * NOTE: used for testing and debugging + */ +VOID +FASTCALL +FsRtlpDumpFileLocks( + IN PFILE_LOCK FileLock + ) +{ + KIRQL oldirql; + PFILE_LOCK_TOC LockToc; + PFILE_LOCK_GRANTED Granted; + PIRP Irp; + PLIST_ENTRY EnumEntry; + PIO_STACK_LOCATION Stack; + + assert(FileLock); + LockToc = FileLock->LockInformation; + + if (LockToc == NULL) + { + DPRINT1("No file locks\n"); + return; + } + + DPRINT1("Dumping granted file locks, FIFO order\n"); + + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + + EnumEntry = LockToc->GrantedListHead.Blink; + while ( EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry ); + + DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n", + Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD", + Granted->Lock.StartingByte.QuadPart, + Granted->Lock.Length.QuadPart, + Granted->Lock.EndingByte.QuadPart, + Granted->Lock.Key, + Granted->Lock.Process, + Granted->Lock.FileObject + ); + + EnumEntry = EnumEntry->Blink; + } + + DPRINT1("Dumping pending file locks, FIFO order\n"); + + EnumEntry = LockToc->PendingListHead.Blink; + while ( EnumEntry != &LockToc->PendingListHead) + { + Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry ); + + Stack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n", + (Stack->Flags & SL_EXCLUSIVE_LOCK) ? "EXCL" : "SHRD", + Stack->Parameters.LockControl.ByteOffset.QuadPart, + Stack->Parameters.LockControl.Length->QuadPart, + Stack->Parameters.LockControl.ByteOffset.QuadPart + Stack->Parameters.LockControl.Length->QuadPart - 1, + Stack->Parameters.LockControl.Key, + IoGetRequestorProcess(Irp), + Stack->FileObject + ); + + EnumEntry = EnumEntry->Blink; + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); +} + + + +/********************************************************************** + * NAME EXPORTED + * FsRtlGetNextFileLock * * RETURN VALUE * NULL if no more locks. * - * NOTE (Bo Branten) - * Internals: FsRtlGetNextFileLock uses - * FileLock->LastReturnedLockInfo and FileLock->LastReturnedLock - * as storage. LastReturnedLock is a pointer to the 'raw' lock - * inkl. double linked list, and FsRtlGetNextFileLock needs this - * to get next lock on subsequent calls with Restart = FALSE. */ PFILE_LOCK_INFO STDCALL FsRtlGetNextFileLock ( - IN PFILE_LOCK FileLock, - IN BOOLEAN Restart - ) + IN PFILE_LOCK FileLock, + IN BOOLEAN Restart + ) { - return (NULL); + /* + Messy enumeration of granted locks. + What our last ptr. in LastReturnedLock points at, might have been freed between + calls, so we have to scan thru the list every time, searching for our last lock. + If it's not there anymore, restart the enumeration... + */ + KIRQL oldirql; + PLIST_ENTRY EnumEntry; + PFILE_LOCK_GRANTED Granted; + PFILE_LOCK_TOC LockToc; + BOOLEAN FoundPrevious = FALSE; + //must make local copy since FILE_LOCK struct is allowed to be in paged mem + FILE_LOCK_INFO LocalLastReturnedLockInfo; + PVOID LocalLastReturnedLock; + + assert(FileLock); + LockToc = FileLock->LockInformation; + if (LockToc == NULL) + { + return NULL; + } + + LocalLastReturnedLock = FileLock->LastReturnedLock; + + KeAcquireSpinLock(&LockToc->SpinLock,&oldirql); + +restart:; + + EnumEntry = LockToc->GrantedListHead.Flink; + + if (Restart) + { + if (EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry); + LocalLastReturnedLockInfo = Granted->Lock; + KeReleaseSpinLock(&LockToc->SpinLock,oldirql); + + FileLock->LastReturnedLockInfo = LocalLastReturnedLockInfo; + FileLock->LastReturnedLock = EnumEntry; + return &FileLock->LastReturnedLockInfo; + } + else + { + KeReleaseSpinLock(&LockToc->SpinLock,oldirql); + return NULL; + } + } + + //else: continue enum + while (EnumEntry != &LockToc->GrantedListHead) + { + //found previous lock? + if (EnumEntry == LocalLastReturnedLock) + { + FoundPrevious = TRUE; + //get next + EnumEntry = EnumEntry->Flink; + if (EnumEntry != &LockToc->GrantedListHead) + { + Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry); + LocalLastReturnedLockInfo = Granted->Lock; + KeReleaseSpinLock(&LockToc->SpinLock,oldirql); + + FileLock->LastReturnedLockInfo = LocalLastReturnedLockInfo; + FileLock->LastReturnedLock = EnumEntry; + return &FileLock->LastReturnedLockInfo; + } + break; + } + EnumEntry = EnumEntry->Flink; + } + + if (!FoundPrevious) + { + //got here? uh no, didn't find our last lock..must have been freed...restart + Restart = TRUE; + goto restart; + } + + KeReleaseSpinLock(&LockToc->SpinLock,oldirql); + + return NULL;//no (more) locks } /********************************************************************** * NAME EXPORTED - * FsRtlInitializeFileLock@12 + * FsRtlInitializeFileLock * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + * NOTE + * Called when creating/allocating/initializing FCB * */ VOID STDCALL FsRtlInitializeFileLock ( - IN PFILE_LOCK FileLock, - IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, - IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL - ) + IN PFILE_LOCK FileLock, + IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, + IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL + ) { + + FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; + FileLock->CompleteLockIrpRoutine = CompleteLockIrpRoutine; + FileLock->UnlockRoutine = UnlockRoutine; + FileLock->LockInformation = NULL; + } /********************************************************************** * NAME EXPORTED - * FsRtlPrivateLock@48 + * FsRtlPrivateLock * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * IoStatus->Status: STATUS_PENDING, STATUS_LOCK_NOT_GRANTED - * - * NOTE (Bo Branten) - * -Calls IoCompleteRequest if Irp - * -Uses exception handling / ExRaiseStatus with - * STATUS_INSUFFICIENT_RESOURCES */ BOOLEAN STDCALL FsRtlPrivateLock ( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN FailImmediately, - IN BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN PIRP Irp OPTIONAL, - IN PVOID Context, - IN BOOLEAN AlreadySynchronized - ) + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN BOOLEAN FailImmediately, //seems meaningless for fast io + IN BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN PIRP Irp OPTIONAL, + IN PVOID Context, + IN BOOLEAN AlreadySynchronized + ) { - return FALSE; + PFILE_LOCK_TOC LockToc; + KIRQL oldirql; + + assert(FileLock); + if (FileLock->LockInformation == NULL) + { + ExAcquireFastMutex(&LockTocMutex); + //still NULL? + if (FileLock->LockInformation == NULL) + { + FileLock->LockInformation = ExAllocateFromNPagedLookasideList(&LockTocLookaside); + LockToc = FileLock->LockInformation; + KeInitializeSpinLock(&LockToc->SpinLock); + InitializeListHead(&LockToc->GrantedListHead); + InitializeListHead(&LockToc->PendingListHead); + InitializeListHead(&LockToc->CompletedListHead); + InitializeListHead(&LockToc->UnlockedListHead); + } + ExReleaseFastMutex(&LockTocMutex); + } + + LockToc = FileLock->LockInformation; + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + + //try add new lock (while holding spin lock) + if (FsRtlpAddLock(LockToc, + FileObject, + FileOffset, + Length, + Process, + Key, + ExclusiveLock + ) ) + { + IoStatus->Status = STATUS_SUCCESS; + } + else if (Irp && !FailImmediately) + { //failed + irp + no fail = mk. pending + //for our cancel routine + Irp->Tail.Overlay.DriverContext[0] = (PVOID)FileLock; + Irp->Tail.Overlay.DriverContext[1] = (PVOID)LockToc; + Irp->Tail.Overlay.DriverContext[2] = Context; + + IoSetCancelRoutine(Irp, FsRtlpFileLockCancelRoutine); + + if (Irp->Cancel) + { + //irp canceled even before we got to queue it + if (IoSetCancelRoutine(Irp, NULL)) + { //Cancel routine will NOT be called: cancel it here + IoStatus->Status = STATUS_CANCELLED; + } + else + { //Cancel routine WILL be called. When we release the lock it will complete the irp + //Return pending since we are not completing the irp here + Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING; + Irp->IoStatus.Information = 0; + InitializeListHead(&Irp->Tail.Overlay.ListEntry); + } + + } + else + { //not cancelled: queue irp + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING; + Irp->IoStatus.Information = 0; + InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry); + } + + } + else + { + IoStatus->Status = STATUS_LOCK_NOT_GRANTED; + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); //fires cancel routine + + //never pending if no irp;-) + assert(!(IoStatus->Status == STATUS_PENDING && !Irp)); + + if (IoStatus->Status != STATUS_PENDING) + { + if (IoStatus->Status == STATUS_SUCCESS) + { + FsRtlAreThereCurrentFileLocks(FileLock) = TRUE; + } + + if (Irp) + { + Irp->IoStatus.Status = IoStatus->Status; + Irp->IoStatus.Information = 0; + + if (FileLock->CompleteLockIrpRoutine) + { //complete irp routine + + if (!NT_SUCCESS(FileLock->CompleteLockIrpRoutine(Context,Irp))) + { + //CompleteLockIrpRoutine complain: revert changes + FsRtlpUnlockSingle( FileLock, + FileObject, + FileOffset, + Length, + Process, + Key, + Context, + AlreadySynchronized, + FALSE//CallUnlockRoutine + ); + } + } + else + {//std irp completion + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + } + } + + //NOTE: only fast io seems to care about this return value + return (IoStatus->Status == STATUS_SUCCESS || FailImmediately); + } + /********************************************************************** * NAME EXPORTED - * FsRtlProcessFileLock@12 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * -STATUS_INVALID_DEVICE_REQUEST - * -STATUS_RANGE_NOT_LOCKED from unlock routines. - * -STATUS_PENDING, STATUS_LOCK_NOT_GRANTED from FsRtlPrivateLock - * (redirected IoStatus->Status). - * - * NOTE (Bo Branten) - * -switch ( Irp->CurrentStackLocation->MinorFunction ) - * lock: return FsRtlPrivateLock; - * unlocksingle: return FsRtlFastUnlockSingle; - * unlockall: return FsRtlFastUnlockAll; - * unlockallbykey: return FsRtlFastUnlockAllByKey; - * default: IofCompleteRequest with STATUS_INVALID_DEVICE_REQUEST; - * return STATUS_INVALID_DEVICE_REQUEST; + * FsRtlProcessFileLock * - * -'AllwaysZero' is passed thru as 'AllwaysZero' to lock / unlock routines. - * -'Irp' is passet thru as 'Irp' to FsRtlPrivateLock. */ NTSTATUS STDCALL FsRtlProcessFileLock ( - IN PFILE_LOCK FileLock, - IN PIRP Irp, - IN PVOID Context OPTIONAL - ) + IN PFILE_LOCK FileLock, + IN PIRP Irp, + IN PVOID Context OPTIONAL + ) { - return (STATUS_NOT_IMPLEMENTED); + PIO_STACK_LOCATION Stack; + NTSTATUS Status; + IO_STATUS_BLOCK LocalIoStatus; + + assert(FileLock); + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + + switch(Stack->MinorFunction) + { + case IRP_MN_LOCK: + //ret: BOOLEAN + FsRtlPrivateLock( FileLock, + Stack->FileObject, + &Stack->Parameters.LockControl.ByteOffset, //not pointer! + Stack->Parameters.LockControl.Length, + IoGetRequestorProcess(Irp), + Stack->Parameters.LockControl.Key, + Stack->Flags & SL_FAIL_IMMEDIATELY, + Stack->Flags & SL_EXCLUSIVE_LOCK, + &LocalIoStatus, + Irp, + Context, + FALSE); + + return LocalIoStatus.Status; + + case IRP_MN_UNLOCK_SINGLE: + Status = FsRtlFastUnlockSingle ( FileLock, + Stack->FileObject, + &Stack->Parameters.LockControl.ByteOffset, + Stack->Parameters.LockControl.Length, + IoGetRequestorProcess(Irp), + Stack->Parameters.LockControl.Key, + Context, + FALSE); + break; + + case IRP_MN_UNLOCK_ALL: + Status = FsRtlFastUnlockAll( FileLock, + Stack->FileObject, + IoGetRequestorProcess(Irp), + Context); + break; + + case IRP_MN_UNLOCK_ALL_BY_KEY: + Status = FsRtlFastUnlockAllByKey ( FileLock, + Stack->FileObject, + IoGetRequestorProcess(Irp), + Stack->Parameters.LockControl.Key, + Context); + + break; + + default: + Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + Irp->IoStatus.Status = Status; + + if (FileLock->CompleteLockIrpRoutine ) + { + FileLock->CompleteLockIrpRoutine(Context,Irp); + } + else + { + IofCompleteRequest(Irp,IO_NO_INCREMENT); + } + + return Status; } /********************************************************************** * NAME EXPORTED - * FsRtlUninitializeFileLock@4 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE + * FsRtlUninitializeFileLock * */ VOID STDCALL FsRtlUninitializeFileLock ( - IN PFILE_LOCK FileLock - ) + IN PFILE_LOCK FileLock + ) { + PFILE_LOCK_TOC LockToc; + PIRP Irp; + PFILE_LOCK_GRANTED Granted; + PLIST_ENTRY EnumEntry; + KIRQL oldirql; + + assert(FileLock); + if (FileLock->LockInformation == NULL) + { + return; + } + + LockToc = FileLock->LockInformation; + + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + + //remove and free granted locks + while (!IsListEmpty(&LockToc->GrantedListHead)) + { + EnumEntry = RemoveTailList(&LockToc->GrantedListHead); + Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry); + ExFreeToNPagedLookasideList(&GrantedLookaside, Granted); + } + + //remove, complete and free all pending locks + while (!IsListEmpty(&LockToc->PendingListHead)) + { + EnumEntry = RemoveTailList(&LockToc->PendingListHead); + Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry); + + if (!IoSetCancelRoutine(Irp, NULL)) + { + //The cancel routine will be called. When we release the lock it will complete the irp. + InitializeListHead(&Irp->Tail.Overlay.ListEntry); + } + else + { + /* + Cancel routine will NOT be called, even though the irp might have been canceled. + Don't care since we'l complete it faster than the cancel routine would have. + */ + KeReleaseSpinLock(&LockToc->SpinLock, oldirql);//fires cancel routine + + Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED; + + if (FileLock->CompleteLockIrpRoutine) + { + FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp); + } + else + { + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + + KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); + } + } + + KeReleaseSpinLock(&LockToc->SpinLock, oldirql); + + ExFreeToNPagedLookasideList(&LockTocLookaside, LockToc); + + FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; + FileLock->LockInformation = NULL; + } /********************************************************************** * NAME EXPORTED - * FsRtlAllocateFileLock@8 + * FsRtlAllocateFileLock * - * DESCRIPTION + * NOTE * Only present in NT 5.0 or later. - * - * ARGUMENTS - * - * RETURN VALUE + * FCB FILE_LOCK struct should/is acording to DDK allocated from paged pool! * */ PFILE_LOCK STDCALL -FsRtlAllocateFileLock ( - IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, - IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL - ) +FsRtlAllocateFileLock( + IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, + IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL + ) { - return NULL; + PFILE_LOCK FileLock; + + FileLock = ExAllocateFromPagedLookasideList(&LockLookaside); + + FsRtlInitializeFileLock(FileLock, + CompleteLockIrpRoutine, + UnlockRoutine + ); + + return FileLock; +} + +/********************************************************************** + * NAME EXPORTED + * FsRtlFreeFileLock + * + * NOTE + * Only present in NT 5.0 or later. + * FCB FILE_LOCK struct should/is acording to DDK allocated from paged pool! + * + */ +VOID +STDCALL +FsRtlFreeFileLock( + IN PFILE_LOCK FileLock + ) +{ + assert(FileLock); + + FsRtlUninitializeFileLock(FileLock); + ExFreeToPagedLookasideList(&LockLookaside, FileLock); } /* EOF */ diff --git a/ntoskrnl/include/internal/cc.h b/ntoskrnl/include/internal/cc.h index b698d24..fe10678 100644 --- a/ntoskrnl/include/internal/cc.h +++ b/ntoskrnl/include/internal/cc.h @@ -3,16 +3,20 @@ /* $Id$ */ #include + typedef struct _BCB { LIST_ENTRY BcbSegmentListHead; + LIST_ENTRY BcbRemoveListEntry; + BOOLEAN RemoveOnClose; + ULONG TimeStamp; PFILE_OBJECT FileObject; ULONG CacheSegmentSize; LARGE_INTEGER AllocationSize; LARGE_INTEGER FileSize; KSPIN_LOCK BcbLock; ULONG RefCount; -} BCB; +} BCB, *PBCB; typedef struct _CACHE_SEGMENT { @@ -45,45 +49,83 @@ typedef struct _CACHE_SEGMENT PBCB Bcb; /* Pointer to the next cache segment in a chain. */ struct _CACHE_SEGMENT* NextInChain; -} CACHE_SEGMENT; +} CACHE_SEGMENT, *PCACHE_SEGMENT; + +typedef struct _INTERNAL_BCB +{ + PUBLIC_BCB PFCB; + PCACHE_SEGMENT CacheSegment; + BOOLEAN Dirty; +} INTERNAL_BCB, *PINTERNAL_BCB; VOID STDCALL -CcMdlReadCompleteDev (IN PMDL MdlChain, - IN PDEVICE_OBJECT DeviceObject); +CcMdlReadCompleteDev (IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject); + NTSTATUS CcRosGetCacheSegment(PBCB Bcb, - ULONG FileOffset, - PULONG BaseOffset, - PVOID* BaseAddress, - PBOOLEAN UptoDate, - PCACHE_SEGMENT* CacheSeg); + ULONG FileOffset, + PULONG BaseOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate, + PCACHE_SEGMENT* CacheSeg); VOID CcInitView(VOID); +NTSTATUS +CcRosFreeCacheSegment(PBCB, PCACHE_SEGMENT); -NTSTATUS STDCALL CcRosFreeCacheSegment(PBCB, PCACHE_SEGMENT); +NTSTATUS +ReadCacheSegment(PCACHE_SEGMENT CacheSeg); -NTSTATUS ReadCacheSegment(PCACHE_SEGMENT CacheSeg); - -NTSTATUS WriteCacheSegment(PCACHE_SEGMENT CacheSeg); +NTSTATUS +WriteCacheSegment(PCACHE_SEGMENT CacheSeg); VOID CcInit(VOID); + NTSTATUS CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty); + NTSTATUS CcRosSuggestFreeCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty); + NTSTATUS CcRosGetCacheSegmentChain(PBCB Bcb, ULONG FileOffset, ULONG Length, PCACHE_SEGMENT* CacheSeg); -VOID CcInitCacheZeroPage(VOID); + +VOID +CcInitCacheZeroPage(VOID); + NTSTATUS CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset); + NTSTATUS CcRosFlushDirtyPages(ULONG Target, PULONG Count); -VOID CcRosDereferenceCache(PFILE_OBJECT FileObject); -VOID CcRosReferenceCache(PFILE_OBJECT FileObject); +VOID +CcRosDereferenceCache(PFILE_OBJECT FileObject); + +VOID +CcRosReferenceCache(PFILE_OBJECT FileObject); + +VOID +CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer); + +NTSTATUS +CcRosReleaseCacheSegment (BCB* Bcb, + CACHE_SEGMENT* CacheSeg, + BOOLEAN Valid, + BOOLEAN Dirty, + BOOLEAN Mapped); + +NTSTATUS STDCALL +CcRosRequestCacheSegment (BCB* Bcb, + ULONG FileOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate, + CACHE_SEGMENT** CacheSeg); + #endif diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 89d81e6..02f8f36 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -19,6 +19,10 @@ #ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H #define __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + #define KTRAP_FRAME_DEBUGEBP (0x0) #define KTRAP_FRAME_DEBUGEIP (0x4) #define KTRAP_FRAME_DEBUGARGMARK (0x8) diff --git a/ntoskrnl/include/internal/ifs.h b/ntoskrnl/include/internal/ifs.h index c389266..df815a4 100644 --- a/ntoskrnl/include/internal/ifs.h +++ b/ntoskrnl/include/internal/ifs.h @@ -2,7 +2,75 @@ #define __INCLUDE_INTERNAL_IFS_H /* $Id$ */ +#include + /* Look for "FSrt" in mem view */ #define IFS_POOL_TAG 0x74725346 +VOID STDCALL +FsRtlpInitFileLockingImplementation(VOID); + +VOID STDCALL +FsRtlpFileLockCancelRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +BOOLEAN FASTCALL +FsRtlpCheckLockForReadOrWriteAccess( + IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN BOOLEAN Read + ); + +NTSTATUS FASTCALL +FsRtlpFastUnlockAllByKey( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN DWORD Key, /* FIXME: guess */ + IN BOOLEAN UseKey, /* FIXME: guess */ + IN PVOID Context OPTIONAL + ); + +NTSTATUS FASTCALL +FsRtlpAddLock( + IN PFILE_LOCK_TOC LockToc, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN BOOLEAN ExclusiveLock + ); + +VOID FASTCALL +FsRtlpCompletePendingLocks( + IN PFILE_LOCK FileLock, + IN PFILE_LOCK_TOC LockToc, + IN OUT PKIRQL oldirql + ); + +NTSTATUS FASTCALL +FsRtlpUnlockSingle( + IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL, + IN BOOLEAN AlreadySynchronized, + IN BOOLEAN CallUnlockRoutine + ); + +VOID FASTCALL +FsRtlpDumpFileLocks( + IN PFILE_LOCK FileLock + ); + #endif diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h index 06d525d..45567d8 100644 --- a/ntoskrnl/include/internal/kd.h +++ b/ntoskrnl/include/internal/kd.h @@ -96,7 +96,7 @@ KdbUnloadDriver(PMODULE_OBJECT ModuleObject); VOID KdbLoadDriver(PUNICODE_STRING Filename, PMODULE_OBJECT Module); VOID -KdbFreeSymbolsProcess(PPEB Peb); +KdbFreeSymbolsProcess(PEPROCESS Process); BOOLEAN KdbPrintAddress(PVOID address); KD_CONTINUE_TYPE diff --git a/ntoskrnl/include/internal/ldr.h b/ntoskrnl/include/internal/ldr.h index 207e635..c1c326a 100644 --- a/ntoskrnl/include/internal/ldr.h +++ b/ntoskrnl/include/internal/ldr.h @@ -21,11 +21,10 @@ extern ULONG_PTR LdrHalBase; - NTSTATUS -LdrLoadInitialProcess ( - VOID - ); +LdrLoadInitialProcess(PHANDLE ProcessHandle, + PHANDLE ThreadHandle); + VOID LdrLoadAutoConfigDrivers ( VOID diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index bfe8408..89566a1 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -410,7 +410,11 @@ MmReleasePageOp(PMM_PAGEOP PageOp); PMM_PAGEOP MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType); - +PMM_PAGEOP +MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, + PMM_SECTION_SEGMENT Segment, ULONG Offset); +VOID +MmInitializePageOp(VOID); VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly); VOID @@ -437,7 +441,7 @@ MiZeroPage(PHYSICAL_ADDRESS PhysPage); BOOLEAN MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address); -#define STATUS_MM_RESTART_OPERATION (0xD0000001) +#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001) NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address, @@ -523,9 +527,6 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address); VOID MmInitializeMdlImplementation(VOID); extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress; -PMM_PAGEOP -MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, - PMM_SECTION_SEGMENT Segment, ULONG Offset); struct _KTRAP_FRAME; NTSTATUS STDCALL MmDumpToPagingFile(ULONG BugCode, diff --git a/ntoskrnl/io/arcname.c b/ntoskrnl/io/arcname.c index 2d9d14e..bf5b7ab 100644 --- a/ntoskrnl/io/arcname.c +++ b/ntoskrnl/io/arcname.c @@ -296,7 +296,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) return(Status); } - sprintf(p, "cdrom(%lu)", DeviceNumber); + sprintf(p, "cdrom(%u)", DeviceNumber); DPRINT("New ARC name: %s\n", ParamBuffer); @@ -313,7 +313,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) q++; strcpy(temp, q); - sprintf(p, "cdrom(%lu)", DeviceNumber); + sprintf(p, "cdrom(%u)", DeviceNumber); strcat(p, temp); } } diff --git a/ntoskrnl/io/cancel.c b/ntoskrnl/io/cancel.c index 0b711fd..bec5ede 100644 --- a/ntoskrnl/io/cancel.c +++ b/ntoskrnl/io/cancel.c @@ -44,6 +44,7 @@ NtCancelIoFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock) { UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } BOOLEAN STDCALL @@ -56,11 +57,12 @@ IoCancelIrp(PIRP Irp) IoAcquireCancelSpinLock(&oldlvl); Irp->Cancel = TRUE; if (Irp->CancelRoutine == NULL) - { - return(FALSE); - } - Irp->CancelRoutine(Irp->Stack[0].DeviceObject, Irp); - IoReleaseCancelSpinLock(oldlvl); + { + IoReleaseCancelSpinLock(oldlvl); + return(FALSE); + } + Irp->CancelIrql = oldlvl; + Irp->CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp); return(TRUE); } diff --git a/ntoskrnl/io/irp.c b/ntoskrnl/io/irp.c index ae8f6be..c436611 100644 --- a/ntoskrnl/io/irp.c +++ b/ntoskrnl/io/irp.c @@ -73,6 +73,7 @@ IoMakeAssociatedIrp(PIRP Irp, AssocIrp = IoAllocateIrp(StackSize,FALSE); UNIMPLEMENTED; + return NULL; } @@ -105,7 +106,6 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject, * FUNCTION: Sends an IRP to the next lower driver */ { - NTSTATUS Status; PDRIVER_OBJECT DriverObject; PIO_STACK_LOCATION Param; @@ -118,20 +118,18 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject, assert(DriverObject); - Param = IoGetNextIrpStackLocation(Irp); + IoSetNextIrpStackLocation(Irp); + Param = IoGetCurrentIrpStackLocation(Irp); DPRINT("IrpSp 0x%X\n", Param); - Irp->Tail.Overlay.CurrentStackLocation--; - Irp->CurrentLocation--; - + Param->DeviceObject = DeviceObject; + DPRINT("MajorFunction %d\n", Param->MajorFunction); DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n", - DriverObject->MajorFunction[Param->MajorFunction]); - Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, - Irp); - - return(Status); + DriverObject->MajorFunction[Param->MajorFunction]); + + return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp); } @@ -221,34 +219,62 @@ IofCompleteRequest(PIRP Irp, * thread making the request */ { - unsigned int i; - NTSTATUS Status; - + ULONG i; + NTSTATUS Status; + PDEVICE_OBJECT DeviceObject; + DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n", - Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread()); + Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread()); + + assert(Irp->CancelRoutine == NULL); + assert(Irp->IoStatus.Status != STATUS_PENDING); - for (i=Irp->CurrentLocation;iStackCount;i++) + if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED) { - if (Irp->Stack[i].CompletionRoutine != NULL) + Irp->PendingReturned = TRUE; + } + + for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++) + { + /* + Completion routines expect the current irp stack location to be the same as when + IoSetCompletionRoutine was called to set them. A side effect is that completion + routines set by highest level drivers without their own stack location will receive + an invalid current stack location (at least it should be considered as invalid). + Since the DeviceObject argument passed is taken from the current stack, this value + is also invalid (NULL). + */ + if (Irp->CurrentLocation < Irp->StackCount - 1) { - Status = Irp->Stack[i].CompletionRoutine( - Irp->Stack[i].DeviceObject, - Irp, - Irp->Stack[i].CompletionContext); - if (Status == STATUS_MORE_PROCESSING_REQUIRED) - { - return; - } + IoSetPreviousIrpStackLocation(Irp); + DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; } - if (Irp->Stack[i].Control & SL_PENDING_RETURNED) + else { - Irp->PendingReturned = TRUE; + DeviceObject = NULL; } - if (Irp->CurrentLocation < Irp->StackCount - 1) + + if (Irp->Stack[i].CompletionRoutine != NULL && + ((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) || + (!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) || + (Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL)))) { - IoSkipCurrentIrpStackLocation(Irp); + Status = Irp->Stack[i].CompletionRoutine(DeviceObject, + Irp, + Irp->Stack[i].CompletionContext); + + if (Status == STATUS_MORE_PROCESSING_REQUIRED) + { + return; + } + } + + if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED) + { + Irp->PendingReturned = TRUE; } } + if (Irp->PendingReturned) { DPRINT("Dispatching APC\n"); diff --git a/ntoskrnl/io/lock.c b/ntoskrnl/io/lock.c index f27ca8d..38cdd61 100644 --- a/ntoskrnl/io/lock.c +++ b/ntoskrnl/io/lock.c @@ -10,20 +10,38 @@ /* INCLUDES *****************************************************************/ + #include +#define NDEBUG #include + +#define TAG_LOCK TAG('F','l','c','k') + /* FUNCTIONS *****************************************************************/ NTSTATUS STDCALL + NtLockFileCompletionRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context + ) +{ + ExFreePool(Context); + return STATUS_SUCCESS; + //FIXME: should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED? +} + +NTSTATUS +STDCALL NtLockFile ( IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, + IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER Length, IN PULONG Key, @@ -31,19 +49,248 @@ NtLockFile ( IN BOOLEAN ExclusiveLock ) { - UNIMPLEMENTED; + NTSTATUS Status; + PFILE_OBJECT FileObject = NULL; + PLARGE_INTEGER LocalLength = NULL; + PKEVENT Event = NULL; + PIRP Irp = NULL; + PIO_STACK_LOCATION StackPtr; + IO_STATUS_BLOCK LocalIoStatusBlock; + PIO_STATUS_BLOCK IoStatusBlock; + PDEVICE_OBJECT DeviceObject; + + //FIXME: instead of this, use SEH when available? + if (!Length || !ByteOffset) { + Status = STATUS_INVALID_PARAMETER; + goto fail; + } + + /* + BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode! + It should ONLY fail if we desire an access that conflict with granted access! + */ + Status = ObReferenceObjectByHandle( + FileHandle, + FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to! + IoFileObjectType, + ExGetPreviousMode(), + (PVOID*)&FileObject, + NULL); + + if (!NT_SUCCESS(Status)){ + goto fail; + } + + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + Irp = IoAllocateIrp( + DeviceObject->StackSize, + TRUE + ); + + if (Irp == NULL) { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto fail; + } + + if (EventHandle != NULL && !FailImmediatedly) { + Status = ObReferenceObjectByHandle( + EventHandle, + SYNCHRONIZE, + ExEventObjectType, + ExGetPreviousMode(), + (PVOID*)&Event, + NULL); + + if (!NT_SUCCESS(Status)) { + goto fail; + } + + } + else { + Event = &FileObject->Event; + KeResetEvent(Event); + } + + if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly) + IoStatusBlock = &LocalIoStatusBlock; + else + IoStatusBlock = UserIoStatusBlock; + + Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; + + Irp->UserEvent = Event; + Irp->UserIosb = IoStatusBlock; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL; + StackPtr->MinorFunction = IRP_MN_LOCK; + StackPtr->DeviceObject = DeviceObject; + StackPtr->FileObject = FileObject; + + if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK; + if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY; + + LocalLength = ExAllocatePoolWithTag( + NonPagedPool, + sizeof(LARGE_INTEGER), + TAG_LOCK + ); + if (!LocalLength){ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto fail; + } + + *LocalLength = *Length; + + StackPtr->Parameters.LockControl.Length = LocalLength; + StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset; + StackPtr->Parameters.LockControl.Key = Key ? *Key : 0; + + IoSetCompletionRoutine( + Irp, + NtLockFileCompletionRoutine, + LocalLength, + TRUE, + TRUE, + TRUE ); + + Status = IofCallDriver(DeviceObject, Irp); + + if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { + + Status = KeWaitForSingleObject( + Event, + Executive, + ExGetPreviousMode() , + (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE, + NULL + ); + + if (Status != STATUS_WAIT_0) { + DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n"); + /* + FIXME: should do some special processing here if alertable wait + was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC) + */ + return Status; //set status to something else? + } + + Status = LocalIoStatusBlock.Status; + } + + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + *UserIoStatusBlock = LocalIoStatusBlock; + + return Status; + + fail:; + + if (LocalLength) ExFreePool(LocalLength); + if (Irp) IoFreeIrp(Irp); + if (Event) ObDereferenceObject(Event); + if (FileObject) ObDereferenceObject(FileObject); + + return Status; + } + + NTSTATUS STDCALL NtUnlockFile ( IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER Length, OUT PULONG Key OPTIONAL ) { - UNIMPLEMENTED; + NTSTATUS Status; + PFILE_OBJECT FileObject = NULL; + PLARGE_INTEGER LocalLength = NULL; + PIRP Irp = NULL; + PIO_STACK_LOCATION StackPtr; + IO_STATUS_BLOCK LocalIoStatusBlock; + PDEVICE_OBJECT DeviceObject; + + //FIXME: instead of this, use SEH when available + if (!Length || !ByteOffset) { + Status = STATUS_INVALID_PARAMETER; + goto fail; + } + + /* + BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode + It should ONLY fail if we desire an access that conflict with granted access! + */ + Status = ObReferenceObjectByHandle( + FileHandle, + FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to! + IoFileObjectType, + ExGetPreviousMode(), + (PVOID*)&FileObject, + NULL); + + if (!NT_SUCCESS(Status)){ + goto fail; + } + + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + Irp = IoAllocateIrp( + DeviceObject->StackSize, + TRUE + ); + + if (Irp == NULL) { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto fail; + } + + Irp->UserIosb = &LocalIoStatusBlock; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL; + StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE; + StackPtr->DeviceObject = DeviceObject; + StackPtr->FileObject = FileObject; + + LocalLength = ExAllocatePoolWithTag( + NonPagedPool, + sizeof(LARGE_INTEGER), + TAG_LOCK + ); + if (!LocalLength){ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto fail; + } + + *LocalLength = *Length; + + StackPtr->Parameters.LockControl.Length = LocalLength; + StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset; + StackPtr->Parameters.LockControl.Key = Key ? *Key : 0; + + //allways syncronious + Status = IofCallDriver(DeviceObject, Irp); + + *UserIoStatusBlock = LocalIoStatusBlock; + + ExFreePool(LocalLength); + + return Status; + + fail:; + + if (LocalLength) ExFreePool(LocalLength); + if (Irp) IoFreeIrp(Irp); + if (FileObject) ObDereferenceObject(FileObject); + + return Status; } diff --git a/ntoskrnl/io/pnpmgr.c b/ntoskrnl/io/pnpmgr.c index 90c52d1..845c574 100644 --- a/ntoskrnl/io/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr.c @@ -12,6 +12,7 @@ /* INCLUDES ******************************************************************/ #include +#include #include #include #include diff --git a/ntoskrnl/io/pnproot.c b/ntoskrnl/io/pnproot.c index 65a05a2..4f9f8dd 100644 --- a/ntoskrnl/io/pnproot.c +++ b/ntoskrnl/io/pnproot.c @@ -12,6 +12,7 @@ /* INCLUDES ******************************************************************/ #include +#include #include #include diff --git a/ntoskrnl/io/rw.c b/ntoskrnl/io/rw.c index 38f1b83..8ffe9ee 100644 --- a/ntoskrnl/io/rw.c +++ b/ntoskrnl/io/rw.c @@ -189,7 +189,7 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle, IO_STATUS_BLOCK Iosb; PIO_STATUS_BLOCK IoStatusBlock; - DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " + DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, IoStatusBlock); diff --git a/ntoskrnl/kd/gdbstub.c b/ntoskrnl/kd/gdbstub.c index 2d1ec76..89c2112 100644 --- a/ntoskrnl/kd/gdbstub.c +++ b/ntoskrnl/kd/gdbstub.c @@ -406,7 +406,7 @@ GspMem2Hex (PCHAR Address, if (MayFault) MemoryFaultRoutine = GspSetMemoryError; - for (i = 0; i < Count; i++) + for (i = 0; i < (ULONG) Count; i++) { ch = GspGetChar (Address++); if (MayFault && GspMemoryError) diff --git a/ntoskrnl/kd/kdebug.c b/ntoskrnl/kd/kdebug.c index 694616f..268fa49 100644 --- a/ntoskrnl/kd/kdebug.c +++ b/ntoskrnl/kd/kdebug.c @@ -216,6 +216,12 @@ KdInitSystem(ULONG Reserved, } } } +#ifdef KDBG + else if (!_strnicmp(p2, "PROFILE", 7)) + { + KdbInitProfiling(); + } +#endif /* KDBG */ p1 = p2; } diff --git a/ntoskrnl/ke/catch.c b/ntoskrnl/ke/catch.c index 96c671e..6bdda14 100644 --- a/ntoskrnl/ke/catch.c +++ b/ntoskrnl/ke/catch.c @@ -28,6 +28,7 @@ /* INCLUDES *****************************************************************/ #include +#include #include #include #include @@ -132,7 +133,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); } #ifdef KDBG - else if (KdDebuggerEnable && KdDebugState & KD_DEBUG_KDB) + else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB) { Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf); } diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c index c8da711..40ba941 100644 --- a/ntoskrnl/ke/i386/exp.c +++ b/ntoskrnl/ke/i386/exp.c @@ -46,6 +46,8 @@ /* GLOBALS *****************************************************************/ +#define FLAG_IF (1<<9) + #define _STR(x) #x #define STR(x) _STR(x) @@ -522,7 +524,10 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) */ if (ExceptionNr == 14) { - __asm__("sti\n\t"); + if (Tf->Eflags & FLAG_IF) + { + __asm__("sti\n\t"); + } Status = MmPageFault(Tf->Cs&0xffff, &Tf->Eip, &Tf->Eax, @@ -578,6 +583,14 @@ static void set_interrupt_gate(unsigned int sel, unsigned int func) DPRINT("set_interrupt_gate(sel %d, func %x)\n",sel,func); KiIdt[sel].a = (((int)func)&0xffff) + (KERNEL_CS << 16); + KiIdt[sel].b = 0x8e00 + (((int)func)&0xffff0000); +} + +static void set_trap_gate(unsigned int sel, unsigned int func) +{ + DPRINT("set_trap_gate(sel %d, func %x)\n",sel,func); + KiIdt[sel].a = (((int)func)&0xffff) + + (KERNEL_CS << 16); KiIdt[sel].b = 0x8f00 + (((int)func)&0xffff0000); } @@ -601,27 +614,28 @@ KeInitExceptions(VOID) /* * Set up the other gates */ - set_interrupt_gate(0, (ULONG)KiTrap0); - set_interrupt_gate(1, (ULONG)KiTrap1); - set_interrupt_gate(2, (ULONG)KiTrap2); - set_interrupt_gate(3, (ULONG)KiTrap3); - set_interrupt_gate(4, (ULONG)KiTrap4); - set_interrupt_gate(5, (ULONG)KiTrap5); - set_interrupt_gate(6, (ULONG)KiTrap6); - set_interrupt_gate(7, (ULONG)KiTrap7); + set_trap_gate(0, (ULONG)KiTrap0); + set_trap_gate(1, (ULONG)KiTrap1); + set_trap_gate(2, (ULONG)KiTrap2); + set_trap_gate(3, (ULONG)KiTrap3); + set_trap_gate(4, (ULONG)KiTrap4); + set_trap_gate(5, (ULONG)KiTrap5); + set_trap_gate(6, (ULONG)KiTrap6); + set_trap_gate(7, (ULONG)KiTrap7); set_task_gate(8, TRAP_TSS_SELECTOR); - set_interrupt_gate(9, (ULONG)KiTrap9); - set_interrupt_gate(10, (ULONG)KiTrap10); - set_interrupt_gate(11, (ULONG)KiTrap11); - set_interrupt_gate(12, (ULONG)KiTrap12); - set_interrupt_gate(13, (ULONG)KiTrap13); + set_trap_gate(9, (ULONG)KiTrap9); + set_trap_gate(10, (ULONG)KiTrap10); + set_trap_gate(11, (ULONG)KiTrap11); + set_trap_gate(12, (ULONG)KiTrap12); + set_trap_gate(13, (ULONG)KiTrap13); + set_trap_gate(14, (ULONG)KiTrap14); set_interrupt_gate(14, (ULONG)KiTrap14); - set_interrupt_gate(15, (ULONG)KiTrap15); - set_interrupt_gate(16, (ULONG)KiTrap16); + set_trap_gate(15, (ULONG)KiTrap15); + set_trap_gate(16, (ULONG)KiTrap16); for (i=17;i<256;i++) { - set_interrupt_gate(i,(int)KiTrapUnknown); + set_trap_gate(i,(int)KiTrapUnknown); } set_system_call_gate(0x2d,(int)interrupt_handler2d); diff --git a/ntoskrnl/ke/i386/irq.c b/ntoskrnl/ke/i386/irq.c index 286ef5e..fd4dbe6 100644 --- a/ntoskrnl/ke/i386/irq.c +++ b/ntoskrnl/ke/i386/irq.c @@ -41,6 +41,9 @@ #include #include #include +#ifdef KDBG +#include <../dbg/kdb.h> +#endif /* KDBG */ #ifdef MP #include @@ -290,6 +293,41 @@ KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, #ifdef MP +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level) +/* + * FUNCTION: Calls all the interrupt handlers for a given irq. + * ARGUMENTS: + * Irq - The number of the irq to call handlers for. + * old_level - The irql of the processor when the irq took place. + * NOTES: Must be called at DIRQL. + */ +{ + PKINTERRUPT isr; + PLIST_ENTRY current; + + DPRINT("\nWARNING - KiInterruptDispatch2 copied directly from UP version for build\npurposes only, please review\n\n"); + + if (Irq == 0) + { + KiUpdateSystemTime(old_level, 0); + } + else + { + /* + * Iterate the list until one of the isr tells us its device interrupted + */ + current = isr_table[Irq].Flink; + isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); + while (current != &isr_table[Irq] && + !isr->ServiceRoutine(isr, isr->ServiceContext)) + { + current = current->Flink; + isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); + } + } +} + VOID KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) /* @@ -335,6 +373,9 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) if (KeGetCurrentProcessorNumber() == 0) { KiUpdateSystemTime(old_level, Trapframe->Eip); +#ifdef KDBG + KdbProfileInterrupt(Trapframe->Eip); +#endif /* KDBG */ } } else @@ -378,7 +419,8 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) if (KeGetCurrentThread() != NULL) { - KeGetCurrentThread()->LastEip = Trapframe->Eip; + // FIXME TODO - What happend to LastEip definition? + //KeGetCurrentThread()->LastEip = Trapframe->Eip; } KiDispatchInterrupt(); if (KeGetCurrentThread() != NULL && @@ -418,13 +460,19 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level) * Iterate the list until one of the isr tells us its device interrupted */ current = isr_table[Irq].Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - while (current != &isr_table[Irq] && - !isr->ServiceRoutine(isr, isr->ServiceContext)) - { + while (current != &isr_table[Irq]) + { + isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); +#if 0 + if (isr->ServiceRoutine(isr, isr->ServiceContext)) + { + break; + } +#else + isr->ServiceRoutine(isr, isr->ServiceContext); +#endif current = current->Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - } + } } } @@ -465,18 +513,27 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) */ KiInterruptDispatch2(irq, old_level); - /* - * End the system interrupt. - */ - HalEndSystemInterrupt (old_level, 0); +#ifdef KDBG + if (irq == 0) + { + KdbProfileInterrupt(Trapframe->Eip); + } +#endif /* KDBG */ /* * Maybe do a reschedule as well. */ if (old_level < DISPATCH_LEVEL && irq == 0) { + KeLowerIrql(APC_LEVEL); PsDispatchThread(THREAD_STATE_READY); } + + /* + * End the system interrupt. + */ + __asm__("cli\n\t"); + HalEndSystemInterrupt (old_level, 0); } #endif /* MP */ @@ -543,6 +600,10 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject) KeRaiseIrql(InterruptObject->SynchLevel,&synch_oldlvl); KeAcquireSpinLockAtDpcLevel(InterruptObject->IrqLock); DPRINT("%x %x\n",isr_table[Vector].Flink,isr_table[Vector].Blink); + if (IsListEmpty(&isr_table[Vector])) + { + HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0); + } InsertTailList(&isr_table[Vector],&InterruptObject->Entry); DPRINT("%x %x\n",InterruptObject->Entry.Flink, InterruptObject->Entry.Blink); @@ -573,6 +634,10 @@ KeDisconnectInterrupt(PKINTERRUPT InterruptObject) KeRaiseIrql(InterruptObject->SynchLevel,&oldlvl); KeAcquireSpinLockAtDpcLevel(InterruptObject->IrqLock); RemoveEntryList(&InterruptObject->Entry); + if (IsListEmpty(&isr_table[InterruptObject->Vector])) + { + HalDisableSystemInterrupt(InterruptObject->Vector + IRQ_BASE, 0); + } KeReleaseSpinLockFromDpcLevel(InterruptObject->IrqLock); KeLowerIrql(oldlvl); } diff --git a/ntoskrnl/ke/main.c b/ntoskrnl/ke/main.c index 894f925..5de88d2 100644 --- a/ntoskrnl/ke/main.c +++ b/ntoskrnl/ke/main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -104,6 +105,26 @@ RtlpCheckFileNameExtension(PCHAR FileName, } +static BOOLEAN +RtlpIsSystemHive(PCHAR FileName) +{ + PCHAR Name; + + Name = strrchr(FileName, '\\'); + if (Name == NULL) + { + Name = FileName; + } + else + { + Name = Name + 1; + } + + return((_stricmp(Name, "system.hiv") == 0) || + (_stricmp(Name, "system") == 0)); +} + + static VOID InitSystemSharedUserPage (PCSZ ParameterLine) { @@ -282,9 +303,13 @@ InitSystemSharedUserPage (PCSZ ParameterLine) } } + VOID ExpInitializeExecutive(VOID) { + LARGE_INTEGER Timeout; + HANDLE ProcessHandle; + HANDLE ThreadHandle; ULONG BootDriverCount; ULONG i; ULONG start; @@ -292,6 +317,7 @@ ExpInitializeExecutive(VOID) PCHAR name; CHAR str[50]; NTSTATUS Status; + BOOLEAN SetupBoot; /* * Fail at runtime if someone has changed various structures without @@ -394,14 +420,14 @@ ExpInitializeExecutive(VOID) if (KeNumberProcessors > 1) { sprintf(str, - "Found %d system processors. [%lu MB Memory]\n", + "Found %d system processors. [%u MB Memory]\n", KeNumberProcessors, (KeLoaderBlock.MemHigher + 1088)/ 1024); } else { sprintf(str, - "Found 1 system processor. [%lu MB Memory]\n", + "Found 1 system processor. [%u MB Memory]\n", (KeLoaderBlock.MemHigher + 1088)/ 1024); } HalDisplayString(str); @@ -420,6 +446,7 @@ ExpInitializeExecutive(VOID) MmInit3(); CcInit(); KdInit2(); + FsRtlpInitFileLockingImplementation(); /* Report all resources used by hal */ HalReportResourceUsage(); @@ -473,6 +500,7 @@ ExpInitializeExecutive(VOID) } /* Pass 2: load registry chunks passed in */ + SetupBoot = TRUE; for (i = 1; i < KeLoaderBlock.ModsCount; i++) { start = KeLoaderModules[i].ModStart; @@ -484,10 +512,17 @@ ExpInitializeExecutive(VOID) CPRINT("Process registry chunk at %08lx\n", start); CmImportHive((PCHAR)start, length); } + if (RtlpIsSystemHive(name)) + { + SetupBoot = FALSE; + } } /* Initialize volatile registry settings */ - CmInit2((PCHAR)KeLoaderBlock.CommandLine); + if (SetupBoot == FALSE) + { + CmInit2((PCHAR)KeLoaderBlock.CommandLine); + } /* * Enter the kernel debugger before starting up the boot drivers @@ -537,6 +572,10 @@ ExpInitializeExecutive(VOID) DebugLogInit2(); #endif /* DBGPRINT_FILE_LOG */ +#ifdef KDBG + KdbInitProfiling2(); +#endif /* KDBG */ + PiInitDefaultLocale(); @@ -575,7 +614,27 @@ ExpInitializeExecutive(VOID) /* * Launch initial process */ - LdrLoadInitialProcess(); + Status = LdrLoadInitialProcess(&ProcessHandle, + &ThreadHandle); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + + /* + * Crash the system if the initial process terminates within 5 seconds. + */ + Timeout.QuadPart = -50000000LL; + Status = NtWaitForSingleObject(ProcessHandle, + FALSE, + &Timeout); + if (Status != STATUS_TIMEOUT) + { + KeBugCheckEx(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + + NtClose(ThreadHandle); + NtClose(ProcessHandle); PsTerminateSystemThread(STATUS_SUCCESS); } @@ -669,7 +728,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) } } sprintf(KeLoaderCommandLine, - "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s", + "multi(0)disk(0)rdisk(%d)partition(%d)%s %s", DiskNumber, PartNumber + 1, Temp, options); p = KeLoaderCommandLine; diff --git a/ntoskrnl/ke/queue.c b/ntoskrnl/ke/queue.c index 7b4bea5..bb6279e 100644 --- a/ntoskrnl/ke/queue.c +++ b/ntoskrnl/ke/queue.c @@ -48,7 +48,7 @@ KeInitializeQueue(IN PKQUEUE Queue, InitializeListHead(&Queue->EntryListHead); InitializeListHead(&Queue->ThreadListEntry); Queue->CurrentCount = 0; - Queue->MaximumCount = (Count == 0) ? KeNumberProcessors : Count; + Queue->MaximumCount = (Count == 0) ? (ULONG) KeNumberProcessors : Count; } diff --git a/ntoskrnl/ke/sem.c b/ntoskrnl/ke/sem.c index 5481811..922e137 100644 --- a/ntoskrnl/ke/sem.c +++ b/ntoskrnl/ke/sem.c @@ -89,7 +89,7 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore, KeAcquireDispatcherDatabaseLock(Wait); InitialState = Semaphore->Header.SignalState; - if (Semaphore->Limit < InitialState + Adjustment || + if (Semaphore->Limit < (LONG) InitialState + Adjustment || InitialState > InitialState + Adjustment) { ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); diff --git a/ntoskrnl/ke/timer.c b/ntoskrnl/ke/timer.c index d66ef4a..500e80b 100644 --- a/ntoskrnl/ke/timer.c +++ b/ntoskrnl/ke/timer.c @@ -35,8 +35,8 @@ /* * Current time */ -static unsigned long long boot_time = 0; -static unsigned long long system_time = 0; +static LARGE_INTEGER boot_time = (LARGE_INTEGER)0LL; +static LARGE_INTEGER system_time = (LARGE_INTEGER)0LL; /* * Number of timer interrupts since initialisation @@ -58,9 +58,10 @@ volatile ULONG KiRawTicks = 0; */ static LIST_ENTRY TimerListHead; static KSPIN_LOCK TimerListLock; +static KSPIN_LOCK TimerValueLock; static KDPC ExpireTimerDpc; -/* must raise IRQL to HIGH_LEVEL and grab spin lock there, to sync with ISR */ +/* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */ extern ULONG PiNrRunnableThreads; @@ -96,7 +97,18 @@ NTSTATUS STDCALL NtQueryPerformanceCounter(IN PLARGE_INTEGER Counter, IN PLARGE_INTEGER Frequency) { - UNIMPLEMENTED; + LARGE_INTEGER PerfCounter; + LARGE_INTEGER PerfFrequency; + + PerfCounter = KeQueryPerformanceCounter(&PerfFrequency); + + if (Counter != NULL) + Counter->QuadPart = PerfCounter.QuadPart; + + if (Frequency != NULL) + Frequency->QuadPart = PerfFrequency.QuadPart; + + return(STATUS_SUCCESS); } @@ -166,7 +178,12 @@ KeQuerySystemTime(PLARGE_INTEGER CurrentTime) * 1st of January, 1601. */ { - CurrentTime->QuadPart = system_time; + KIRQL oldIrql; + + KeRaiseIrql(PROFILE_LEVEL, &oldIrql); + KeAcquireSpinLockAtDpcLevel(&TimerValueLock); + *CurrentTime = system_time; + KeReleaseSpinLock(&TimerValueLock, oldIrql); } @@ -221,14 +238,23 @@ KeSetTimerEx (PKTIMER Timer, */ { KIRQL oldlvl; + LARGE_INTEGER SystemTime; DPRINT("KeSetTimerEx(Timer %x), DueTime: \n",Timer); - KeAcquireSpinLock( &TimerListLock, &oldlvl ); - + + KeRaiseIrql(PROFILE_LEVEL, &oldlvl); + KeAcquireSpinLockAtDpcLevel(&TimerValueLock); + + SystemTime = system_time; + + KeReleaseSpinLock(&TimerValueLock, DISPATCH_LEVEL); + KeAcquireSpinLockAtDpcLevel(&TimerListLock); + Timer->Dpc = Dpc; if (DueTime.QuadPart < 0) { - Timer->DueTime.QuadPart = system_time - DueTime.QuadPart; + + Timer->DueTime.QuadPart = SystemTime.QuadPart - DueTime.QuadPart; } else { @@ -261,8 +287,7 @@ KeCancelTimer (PKTIMER Timer) DPRINT("KeCancelTimer(Timer %x)\n",Timer); - KeRaiseIrql(HIGH_LEVEL, &oldlvl); - KeAcquireSpinLockAtDpcLevel( &TimerListLock ); + KeAcquireSpinLock(&TimerListLock, &oldlvl); if (Timer->TimerListEntry.Flink == NULL) { @@ -380,20 +405,34 @@ KeExpireTimers(PKDPC Dpc, PLIST_ENTRY current_entry = NULL; PKTIMER current = NULL; ULONG Eip = (ULONG)Arg1; + KIRQL oldIrql; + LARGE_INTEGER SystemTime; DPRINT("KeExpireTimers()\n"); - - current_entry = TimerListHead.Flink; - + + KeRaiseIrql(PROFILE_LEVEL, &oldIrql); + KeAcquireSpinLockAtDpcLevel(&TimerValueLock); + + SystemTime = system_time; + + KeReleaseSpinLock(&TimerValueLock, oldIrql); KeAcquireSpinLockAtDpcLevel(&TimerListLock); - + + if (KeGetCurrentIrql() > DISPATCH_LEVEL) + { + DPRINT1("-----------------------------\n"); + KeBugCheck(0); + } + + + current_entry = TimerListHead.Flink; + while (current_entry != &TimerListHead) { current = CONTAINING_RECORD(current_entry, KTIMER, TimerListEntry); current_entry = current_entry->Flink; - - if (system_time >= current->DueTime.QuadPart) + if ((ULONGLONG) SystemTime.QuadPart >= current->DueTime.QuadPart) { HandleExpiredTimer(current); } @@ -412,6 +451,9 @@ KiUpdateSystemTime(KIRQL oldIrql, * FUNCTION: Handles a timer interrupt */ { + + assert(KeGetCurrentIrql() == PROFILE_LEVEL); + KiRawTicks++; if (TimerInitDone == FALSE) @@ -423,7 +465,10 @@ KiUpdateSystemTime(KIRQL oldIrql, */ KeTickCount++; SharedUserData->TickCountLow++; - system_time = system_time + CLOCK_INCREMENT; + + KeAcquireSpinLockAtDpcLevel(&TimerValueLock); + system_time.QuadPart += CLOCK_INCREMENT; + KeReleaseSpinLockFromDpcLevel(&TimerValueLock); /* * Queue a DPC that will expire timers @@ -445,6 +490,7 @@ KeInitializeTimerImpl(VOID) DPRINT("KeInitializeTimerImpl()\n"); InitializeListHead(&TimerListHead); KeInitializeSpinLock(&TimerListLock); + KeInitializeSpinLock(&TimerValueLock); KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0); TimerInitDone = TRUE; /* @@ -452,7 +498,7 @@ KeInitializeTimerImpl(VOID) */ HalQueryRealTimeClock(&TimeFields); RtlTimeFieldsToTime(&TimeFields, &SystemBootTime); - boot_time=SystemBootTime.QuadPart; + boot_time=SystemBootTime; system_time=boot_time; DPRINT("Finished KeInitializeTimerImpl()\n"); diff --git a/ntoskrnl/ke/wait.c b/ntoskrnl/ke/wait.c index 12dcd29..df08f49 100644 --- a/ntoskrnl/ke/wait.c +++ b/ntoskrnl/ke/wait.c @@ -276,6 +276,14 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) { PrevBlock->NextWaitBlock = current->NextWaitBlock; } + current->NextWaitBlock = NULL; + /* if the last block is the timeout block then remove this block */ + PrevBlock = current->Thread->WaitBlockList; + if (PrevBlock == ¤t->Thread->WaitBlock[3] && PrevBlock->NextWaitBlock == NULL) + { + RemoveEntryList(¤t->Thread->WaitBlock[3].WaitListEntry); + current->Thread->WaitBlockList = NULL; + } } } KiSideEffectsBeforeWake(hdr, current->Thread, &Abandoned); @@ -341,6 +349,14 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) PrevBlock->NextWaitBlock = current->NextWaitBlock; } } + current->NextWaitBlock = NULL; + /* if the last block is the timeout block then remove this block */ + PrevBlock = current->Thread->WaitBlockList; + if (PrevBlock == ¤t->Thread->WaitBlock[3] && PrevBlock->NextWaitBlock == NULL) + { + RemoveEntryList(¤t->Thread->WaitBlock[3].WaitListEntry); + current->Thread->WaitBlockList = NULL; + } } DPRINT("Waking %x\n",current->Thread); @@ -348,8 +364,11 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) Status = current->WaitKey; if (Abandoned) Status += STATUS_ABANDONED_WAIT_0; - PsUnblockThread(CONTAINING_RECORD(current->Thread, ETHREAD, Tcb), - &Status); + if (current->Thread->WaitBlockList == NULL) + { + PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), + &Status); + } return(TRUE); } @@ -465,11 +484,11 @@ KeWaitForSingleObject(PVOID Object, */ if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned)) { - KeReleaseDispatcherDatabaseLock(FALSE); if (Timeout != NULL) { - KeCancelTimer(&KeGetCurrentThread()->Timer); + KeCancelTimer(&CurrentThread->Timer); } + KeReleaseDispatcherDatabaseLock(FALSE); if (Abandoned == TRUE) return(STATUS_ABANDONED_WAIT_0); return(STATUS_WAIT_0); @@ -481,11 +500,8 @@ KeWaitForSingleObject(PVOID Object, if (Timeout != NULL && KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread, NULL)) { + KeCancelTimer(&CurrentThread->Timer); KeReleaseDispatcherDatabaseLock(FALSE); - if (Timeout != NULL) - { - KeCancelTimer(&KeGetCurrentThread()->Timer); - } return(STATUS_TIMEOUT); } @@ -504,14 +520,14 @@ KeWaitForSingleObject(PVOID Object, if (Timeout != NULL) { CurrentThread->WaitBlock[0].NextWaitBlock = - &CurrentThread->WaitBlock[1]; - CurrentThread->WaitBlock[1].Object = (PVOID)&CurrentThread->Timer; - CurrentThread->WaitBlock[1].Thread = CurrentThread; - CurrentThread->WaitBlock[1].WaitKey = STATUS_TIMEOUT; - CurrentThread->WaitBlock[1].WaitType = WaitAny; - CurrentThread->WaitBlock[1].NextWaitBlock = NULL; + &CurrentThread->WaitBlock[3]; + CurrentThread->WaitBlock[3].Object = (PVOID)&CurrentThread->Timer; + CurrentThread->WaitBlock[3].Thread = CurrentThread; + CurrentThread->WaitBlock[3].WaitKey = STATUS_TIMEOUT; + CurrentThread->WaitBlock[3].WaitType = WaitAny; + CurrentThread->WaitBlock[3].NextWaitBlock = NULL; InsertTailList(&CurrentThread->Timer.Header.WaitListHead, - &CurrentThread->WaitBlock[1].WaitListEntry); + &CurrentThread->WaitBlock[3].WaitListEntry); } else { @@ -522,7 +538,7 @@ KeWaitForSingleObject(PVOID Object, if (Timeout != NULL) { - KeCancelTimer(&KeGetCurrentThread()->Timer); + KeCancelTimer(&CurrentThread->Timer); } DPRINT("Returning from KeWaitForSingleObject()\n"); @@ -567,7 +583,7 @@ KeWaitForMultipleObjects(ULONG Count, __FILE__,__LINE__); return(STATUS_UNSUCCESSFUL); } - blk = &CurrentThread->WaitBlock[0]; + WaitBlockArray = &CurrentThread->WaitBlock[0]; } else { @@ -577,7 +593,6 @@ KeWaitForMultipleObjects(ULONG Count, __FILE__,__LINE__); return(STATUS_UNSUCCESSFUL); } - blk = WaitBlockArray; } /* @@ -616,6 +631,10 @@ KeWaitForMultipleObjects(ULONG Count, if (WaitType == WaitAny) { + if (Timeout != NULL) + { + KeCancelTimer(&CurrentThread->Timer); + } KeReleaseDispatcherDatabaseLock(FALSE); DPRINT("One object is already signaled!\n"); if (Abandoned == TRUE) @@ -627,6 +646,10 @@ KeWaitForMultipleObjects(ULONG Count, if ((WaitType == WaitAll) && (CountSignaled == Count)) { + if (Timeout != NULL) + { + KeCancelTimer(&CurrentThread->Timer); + } KeReleaseDispatcherDatabaseLock(FALSE); DPRINT("All objects are already signaled!\n"); return(STATUS_WAIT_0); @@ -638,20 +661,18 @@ KeWaitForMultipleObjects(ULONG Count, if (Timeout != NULL && KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread, NULL)) { + KeCancelTimer(&CurrentThread->Timer); KeReleaseDispatcherDatabaseLock(FALSE); - if (Timeout != NULL) - { - KeCancelTimer(&KeGetCurrentThread()->Timer); - } return(STATUS_TIMEOUT); } /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = blk; + CurrentThread->WaitBlockList = blk = WaitBlockArray; /* * Set up the wait */ + CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; for (i = 0; i < Count; i++) { hdr = (DISPATCHER_HEADER *)Object[i]; @@ -696,7 +717,7 @@ KeWaitForMultipleObjects(ULONG Count, if (Timeout != NULL) { - KeCancelTimer(&KeGetCurrentThread()->Timer); + KeCancelTimer(&CurrentThread->Timer); } DPRINT("Returning from KeWaitForMultipleObjects()\n"); diff --git a/ntoskrnl/ldr/init.c b/ntoskrnl/ldr/init.c index ad0e8f3..80599c7 100644 --- a/ntoskrnl/ldr/init.c +++ b/ntoskrnl/ldr/init.c @@ -16,7 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* +/* $Id$ + * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ldr/init.c * PURPOSE: Loaders for PE executables @@ -31,7 +32,7 @@ * RJJ 06/03/99 Moved user PE loader into NTDLL * EA 19990717 LdrGetSystemDirectory() * EK 20000618 Using SystemRoot link instead of LdrGetSystemDirectory() - * HYP 20020911 Code to determine smss's path from the registry + * EK 20021119 Create a process parameter block for the initial process. */ /* INCLUDES *****************************************************************/ @@ -48,328 +49,421 @@ #define NDEBUG #include + +/* MACROS ******************************************************************/ + +#define DENORMALIZE(x,addr) {if(x) x=(VOID*)((ULONG)(x)-(ULONG)(addr));} +#define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL))) + + /* FUNCTIONS *****************************************************************/ -/* - * TODO: Read the location of the initial process from command line before - * trying the registry - embedded setups, like the installation CD-ROM, may not - * have a SYSTEM hive - */ -NTSTATUS LdrLoadInitialProcess (VOID) +static NTSTATUS +LdrpMapProcessImage(PHANDLE SectionHandle, + PUNICODE_STRING ImagePath) { - NTSTATUS Status; - HANDLE ProcessHandle; - UNICODE_STRING ProcessName = {0, 0, NULL}; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandle; - HANDLE SectionHandle; - PIMAGE_NT_HEADERS NTHeaders; - PEPROCESS Process; - CONTEXT Context; - HANDLE ThreadHandle; - INITIAL_TEB InitialTeb; - ULONG OldPageProtection; - SECTION_IMAGE_INFORMATION Sii; - ULONG ResultLength; - PVOID ImageBaseAddress; - ULONG InitialStack[5]; -#if 0 - /* FIXME: Test this please */ - HANDLE RootDir; - PWSTR Environment = L"SystemRoot=\\SystemRoot\0"; - RTL_QUERY_REGISTRY_TABLE RegistryValues[] = { - { - NULL, - RTL_QUERY_REGISTRY_DIRECT, - L"Path", - &ProcessName, - REG_SZ, - L"\\SystemRoot\\system32\\smss.exe" - sizeof(L"\\SystemRoot\\system32\\smss.exe") - sizeof(WCHAR) - }, - { NULL, 0, NULL, NULL, 0, NULL, 0 } - }; - - /* try to query the SMSS path from the registry */ - Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, - L"Session Manager", - RegistryValues, - NULL, - Environment); - - /* failure or invalid data: use default */ - if(!NT_SUCCESS(Status) || ProcessName.Length < sizeof(WCHAR)) - RtlInitUnicodeStringFromLiteral(&ProcessName, - L"\\SystemRoot\\system32\\smss.exe"); - /* relative path: open \SystemRoot\system32 */ - else if(ProcessName.Buffer[0] != L'\\') - { - UNICODE_STRING DirPath; - - RtlInitUnicodeStringFromLiteral(&DirPath, L"\\SystemRoot\\system32"); - - InitializeObjectAttributes(&ObjectAttributes, - &DirPath, - 0, - NULL, - NULL); - - if(!NT_SUCCESS(ZwOpenFile(&RootDir, 0, &ObjectAttributes, NULL, 0, 0))) - /* failure: use default */ - RtlInitUnicodeStringFromLiteral(&ProcessName, - L"\\SystemRoot\\system32\\smss.exe"); - } - - InitializeObjectAttributes(&ObjectAttributes, - &ProcessName, - 0, - RootDir, - NULL); -#else - /* - * Get the absolute path to smss.exe using the - * SystemRoot link. - */ - RtlInitUnicodeStringFromLiteral(&ProcessName, - L"\\SystemRoot\\system32\\smss.exe"); - /* - * Open process image to determine ImageBase - * and StackBase/Size. - */ - InitializeObjectAttributes(&ObjectAttributes, - &ProcessName, - 0, - NULL, - NULL); -#endif - DPRINT("Opening image file %S\n", ObjectAttributes.ObjectName->Buffer); - Status = ZwOpenFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - NULL, - 0, - 0); -#if 0 - /* FIXME? ExFreePool() should ignore non-pool data */ - RtlFreeUnicodeString(&ProcessName); - NtClose(RootDir); -#endif - if (!NT_SUCCESS(Status)) - { - DPRINT("Image open failed (Status was %x)\n", Status); - return Status; - } - - /* - * Create a section for the image - */ - DPRINT("Creating section\n"); - Status = ZwCreateSection(&SectionHandle, - SECTION_ALL_ACCESS, - NULL, - NULL, - PAGE_READWRITE, - SEC_COMMIT | SEC_IMAGE, - FileHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateSection failed (Status %x)\n", Status); - ZwClose(FileHandle); - return(Status); - } - ZwClose(FileHandle); - - /* - * Get information about the process image. - */ - Status = ZwQuerySection(SectionHandle, + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + NTSTATUS Status; + + /* Open image file */ + InitializeObjectAttributes(&ObjectAttributes, + ImagePath, + 0, + NULL, + NULL); + + DPRINT("Opening image file %S\n", ObjectAttributes.ObjectName->Buffer); + Status = NtOpenFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + NULL, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenFile() failed (Status %lx)\n", Status); + return(Status); + } + + /* Create a section for the image */ + DPRINT("Creating section\n"); + Status = NtCreateSection(SectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_READWRITE, + SEC_COMMIT | SEC_IMAGE, + FileHandle); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateSection() failed (Status %lx)\n", Status); + } + + return(Status); +} + + +static NTSTATUS +LdrpCreateProcessEnvironment(HANDLE ProcessHandle, + PUNICODE_STRING ImagePath, + PVOID* ImageBaseAddress) +{ + PRTL_USER_PROCESS_PARAMETERS LocalPpb; + PRTL_USER_PROCESS_PARAMETERS ProcessPpb; + ULONG BytesWritten; + ULONG Offset; + ULONG Size; + ULONG RegionSize; + NTSTATUS Status; + + /* Calculate the PPB size */ + Size = sizeof(RTL_USER_PROCESS_PARAMETERS); + Size += ALIGN(ImagePath->Length + sizeof(WCHAR), sizeof(ULONG)); + RegionSize = ROUND_UP(Size, PAGE_SIZE); + DPRINT("Size %lu RegionSize %lu\n", Size, RegionSize); + + /* Allocate the local PPB */ + LocalPpb = NULL; + Status = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID*)&LocalPpb, + 0, + &RegionSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); + return(Status); + } + + DPRINT("LocalPpb %p AllocationSize %lu\n", LocalPpb, RegionSize); + + /* Initialize the local PPB */ + RtlZeroMemory(LocalPpb, + RegionSize); + LocalPpb->AllocationSize = RegionSize; + LocalPpb->Size = Size; + LocalPpb->ImagePathName.Length = ImagePath->Length; + LocalPpb->ImagePathName.MaximumLength = ImagePath->Length + sizeof(WCHAR); + LocalPpb->ImagePathName.Buffer = (PWCHAR)(LocalPpb + 1); + + /* Copy image path */ + RtlCopyMemory(LocalPpb->ImagePathName.Buffer, + ImagePath->Buffer, + ImagePath->Length); + LocalPpb->ImagePathName.Buffer[ImagePath->Length / sizeof(WCHAR)] = (WCHAR)0; + + /* Denormalize the process parameter block */ + DENORMALIZE(LocalPpb->ImagePathName.Buffer, LocalPpb); + LocalPpb->Flags &= ~PPF_NORMALIZED; + + /* Create the process PPB */ + ProcessPpb = NULL; + Status = NtAllocateVirtualMemory(ProcessHandle, + (PVOID*)&ProcessPpb, + 0, + &RegionSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); + + /* Release the local PPB */ + RegionSize = 0; + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID*)&LocalPpb, + &RegionSize, + MEM_RELEASE); + return(Status); + } + + /* Copy local PPB into the process PPB */ + NtWriteVirtualMemory(ProcessHandle, + ProcessPpb, + LocalPpb, + LocalPpb->AllocationSize, + &BytesWritten); + + /* Update pointer to process PPB in the process PEB */ + Offset = FIELD_OFFSET(PEB, ProcessParameters); + NtWriteVirtualMemory(ProcessHandle, + (PVOID)(PEB_BASE + Offset), + &ProcessPpb, + sizeof(ProcessPpb), + &BytesWritten); + + /* Release local PPB */ + RegionSize = 0; + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID*)&LocalPpb, + &RegionSize, + MEM_RELEASE); + + /* Set image file name */ + Status = NtSetInformationProcess(ProcessHandle, + ProcessImageFileName, + "SMSS", + 5); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationProcess() failed (Status %lx)\n", Status); + return(Status); + } + + /* Read image base address. */ + Offset = FIELD_OFFSET(PEB, ImageBaseAddress); + NtReadVirtualMemory(ProcessHandle, + (PVOID)(PEB_BASE + Offset), + ImageBaseAddress, + sizeof(PVOID), + &BytesWritten); + + return(STATUS_SUCCESS); +} + + +static NTSTATUS +LdrpCreateStack(HANDLE ProcessHandle, + PINITIAL_TEB InitialTeb) +{ + ULONG OldPageProtection; + NTSTATUS Status; + + InitialTeb->StackAllocate = NULL; + + /* Allocate the reserved stack space */ + Status = NtAllocateVirtualMemory(ProcessHandle, + &InitialTeb->StackAllocate, + 0, + &InitialTeb->StackReserve, + MEM_RESERVE, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT("Stack allocation failed (Status %x)", Status); + return(Status); + } + + DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", + InitialTeb->StackAllocate, InitialTeb->StackReserve); + + InitialTeb->StackBase = (PVOID)((ULONG)InitialTeb->StackAllocate + InitialTeb->StackReserve); + InitialTeb->StackLimit = (PVOID)((ULONG)InitialTeb->StackBase - InitialTeb->StackCommit); + + DPRINT("StackBase: %p StackCommit: 0x%lX\n", + InitialTeb->StackBase, InitialTeb->StackCommit); + + /* Commit stack */ + Status = NtAllocateVirtualMemory(ProcessHandle, + &InitialTeb->StackLimit, + 0, + &InitialTeb->StackCommit, + MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT("Error comitting stack page!\n"); + /* release the stack space */ + NtFreeVirtualMemory(ProcessHandle, + InitialTeb->StackAllocate, + &InitialTeb->StackReserve, + MEM_RELEASE); + return(Status); + } + + DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", + InitialTeb->StackLimit, + InitialTeb->StackCommit); + + /* Protect guard page */ + Status = NtProtectVirtualMemory(ProcessHandle, + InitialTeb->StackLimit, + PAGE_SIZE, + PAGE_GUARD | PAGE_READWRITE, + &OldPageProtection); + if (!NT_SUCCESS(Status)) + { + DPRINT("Error protecting guard page!\n"); + + /* release the stack space */ + NtFreeVirtualMemory(ProcessHandle, + InitialTeb->StackAllocate, + &InitialTeb->StackReserve, + MEM_RELEASE); + return(Status); + } + + return(STATUS_SUCCESS); +} + + +NTSTATUS +LdrLoadInitialProcess(PHANDLE ProcessHandle, + PHANDLE ThreadHandle) +{ + SECTION_IMAGE_INFORMATION Sii; + UNICODE_STRING ImagePath; + HANDLE SectionHandle; + CONTEXT Context; + INITIAL_TEB InitialTeb; + ULONG ResultLength; + PVOID ImageBaseAddress; + ULONG InitialStack[5]; + NTSTATUS Status; + + /* Get the absolute path to smss.exe. */ + RtlInitUnicodeStringFromLiteral(&ImagePath, + L"\\SystemRoot\\system32\\smss.exe"); + + /* Map process image */ + Status = LdrpMapProcessImage(&SectionHandle, + &ImagePath); + if (!NT_SUCCESS(Status)) + { + DPRINT("LdrpMapImage() failed (Status %lx)\n", Status); + return(Status); + } + + /* Get information about the process image. */ + Status = NtQuerySection(SectionHandle, SectionImageInformation, &Sii, sizeof(Sii), &ResultLength); - if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii)) - { - DPRINT("ZwQuerySection failed (Status %X)\n", Status); - ZwClose(SectionHandle); - return(Status); - } - - DPRINT("Creating process\n"); - Status = ZwCreateProcess(&ProcessHandle, - PROCESS_ALL_ACCESS, - NULL, - SystemProcessHandle, - FALSE, - SectionHandle, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("Could not create process\n"); - return Status; - } - - /* - * Create initial stack and thread - */ - - /* - * Create page backed section for stack - */ - DPRINT("Allocating stack\n"); - - DPRINT("Referencing process\n"); - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_ALL_ACCESS, - PsProcessType, - KernelMode, - (PVOID*)&Process, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ObReferenceObjectByProcess() failed (Status %x)\n", Status); - return(Status); - } - - DPRINT("Attaching to process\n"); - KeAttachProcess(Process); - ImageBaseAddress = Process->Peb->ImageBaseAddress; - NTHeaders = RtlImageNtHeader(ImageBaseAddress); - DPRINT("NTHeaders %x\n", NTHeaders); - InitialTeb.StackReserve = NTHeaders->OptionalHeader.SizeOfStackReserve; - /* FIXME: use correct commit size */ - InitialTeb.StackCommit = NTHeaders->OptionalHeader.SizeOfStackReserve - PAGE_SIZE; - // InitialTeb.StackCommit = NTHeaders->OptionalHeader.SizeOfStackCommit; - /* add guard page size */ - InitialTeb.StackCommit += PAGE_SIZE; - DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n", - InitialTeb.StackReserve, InitialTeb.StackCommit); - KeDetachProcess(); - DPRINT("Dereferencing process\n"); - ObDereferenceObject(Process); - - DPRINT("Allocating stack\n"); - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Stack allocation failed (Status %x)", Status); - return(Status); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page!\n"); - return(Status); - } - - DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", - InitialTeb.StackLimit, - InitialTeb.StackCommit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error protecting guard page!\n"); - return(Status); - } - - /* - * Initialize context to point to LdrStartup - */ - memset(&Context,0,sizeof(CONTEXT)); - Context.Eip = (ULONG)(ImageBaseAddress + (ULONG)Sii.EntryPoint); - Context.SegCs = USER_CS; - Context.SegDs = USER_DS; - Context.SegEs = USER_DS; - Context.SegFs = TEB_SELECTOR; - Context.SegGs = USER_DS; - Context.SegSs = USER_DS; - Context.EFlags = 0x202; - Context.Esp = (ULONG)InitialTeb.StackBase - 20; - - /* - * Write in the initial stack. - */ - InitialStack[0] = 0; - InitialStack[1] = PEB_BASE; - Status = ZwWriteVirtualMemory(ProcessHandle, - (PVOID)Context.Esp, - InitialStack, - sizeof(InitialStack), - &ResultLength); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to write initial stack.\n"); - return(Status); - } - - /* - * FIXME: Create process and let 'er rip - */ - DPRINT("Creating thread for initial process\n"); - Status = ZwCreateThread(&ThreadHandle, - THREAD_ALL_ACCESS, + if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii)) + { + DPRINT("ZwQuerySection failed (Status %X)\n", Status); + NtClose(ProcessHandle); + NtClose(SectionHandle); + return(Status); + } + + DPRINT("Creating process\n"); + Status = NtCreateProcess(ProcessHandle, + PROCESS_ALL_ACCESS, NULL, - ProcessHandle, + SystemProcessHandle, + FALSE, + SectionHandle, NULL, - &Context, - &InitialTeb, - FALSE); + NULL); + NtClose(SectionHandle); if (!NT_SUCCESS(Status)) { - DPRINT("Thread creation failed (Status %x)\n", Status); - - NtFreeVirtualMemory(ProcessHandle, + DPRINT("NtCreateProcess() failed (Status %lx)\n", Status); + return(Status); + } + + /* Create process environment */ + DPRINT("Creating the process environment\n"); + Status = LdrpCreateProcessEnvironment(*ProcessHandle, + &ImagePath, + &ImageBaseAddress); + if (!NT_SUCCESS(Status)) + { + DPRINT("LdrpCreateProcessEnvironment() failed (Status %lx)\n", Status); + NtClose(*ProcessHandle); + return(Status); + } + DPRINT("ImageBaseAddress: %p\n", ImageBaseAddress); + + + /* Calculate initial stack sizes */ + if (Sii.StackReserve > 0x100000) + InitialTeb.StackReserve = Sii.StackReserve; + else + InitialTeb.StackReserve = 0x100000; /* 1MByte */ + + /* FIXME */ +#if 0 + if (Sii.StackCommit > PAGE_SIZE) + InitialTeb.StackCommit = Sii.StackCommit; + else + InitialTeb.StackCommit = PAGE_SIZE; +#endif + InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; + + /* add guard page size */ + InitialTeb.StackCommit += PAGE_SIZE; + DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n", + InitialTeb.StackReserve, InitialTeb.StackCommit); + + + /* Create the process stack */ + Status = LdrpCreateStack(*ProcessHandle, + &InitialTeb); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write initial stack.\n"); + NtClose(ProcessHandle); + return(Status); + } + + + /* + * Initialize context to point to LdrStartup + */ + memset(&Context,0,sizeof(CONTEXT)); + Context.Eip = (ULONG)(ImageBaseAddress + (ULONG)Sii.EntryPoint); + Context.SegCs = USER_CS; + Context.SegDs = USER_DS; + Context.SegEs = USER_DS; + Context.SegFs = TEB_SELECTOR; + Context.SegGs = USER_DS; + Context.SegSs = USER_DS; + Context.EFlags = 0x202; + Context.Esp = (ULONG)InitialTeb.StackBase - 20; + + /* + * Write in the initial stack. + */ + InitialStack[0] = 0; + InitialStack[1] = PEB_BASE; + Status = NtWriteVirtualMemory(*ProcessHandle, + (PVOID)Context.Esp, + InitialStack, + sizeof(InitialStack), + &ResultLength); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write initial stack.\n"); + + NtFreeVirtualMemory(*ProcessHandle, InitialTeb.StackAllocate, &InitialTeb.StackReserve, MEM_RELEASE); + NtClose(*ProcessHandle); + return(Status); + } - /* FIXME: unmap the section here */ - /* FIXME: destroy the section here */ - /* FIXME: Kill the process here */ + /* Create initial thread */ + DPRINT("Creating thread for initial process\n"); + Status = NtCreateThread(ThreadHandle, + THREAD_ALL_ACCESS, + NULL, + *ProcessHandle, + NULL, + &Context, + &InitialTeb, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateThread() failed (Status %lx)\n", Status); + + NtFreeVirtualMemory(*ProcessHandle, + InitialTeb.StackAllocate, + &InitialTeb.StackReserve, + MEM_RELEASE); + NtClose(*ProcessHandle); return(Status); } - + + DPRINT("Process created successfully\n"); + return(STATUS_SUCCESS); } diff --git a/ntoskrnl/ldr/loader.c b/ntoskrnl/ldr/loader.c index f428552..1bb0712 100644 --- a/ntoskrnl/ldr/loader.c +++ b/ntoskrnl/ldr/loader.c @@ -811,6 +811,40 @@ LdrGetModuleObject(PUNICODE_STRING ModuleName) /* ---------------------------------------------- PE Module support */ +static BOOL +PageNeedsWriteAccess(PVOID PageStart, + PVOID DriverBase, + PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders) +{ + BOOL NeedsWriteAccess; + unsigned Idx; + ULONG Characteristics; + ULONG Length; + PVOID BaseAddress; + + NeedsWriteAccess = FALSE; + /* Set the protections for the various parts of the driver */ + for (Idx = 0; Idx < PEFileHeader->NumberOfSections && ! NeedsWriteAccess; Idx++) + { + Characteristics = PESectionHeaders[Idx].Characteristics; + if (!(Characteristics & IMAGE_SECTION_CHAR_CODE) || + (Characteristics & IMAGE_SECTION_CHAR_WRITABLE || + Characteristics & IMAGE_SECTION_CHAR_DATA || + Characteristics & IMAGE_SECTION_CHAR_BSS)) + { + Length = + max(PESectionHeaders[Idx].Misc.VirtualSize, + PESectionHeaders[Idx].SizeOfRawData); + BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + NeedsWriteAccess = BaseAddress < PageStart + PAGE_SIZE && + PageStart < (PVOID)((PCHAR) BaseAddress + Length); + } + } + + return(NeedsWriteAccess); +} + static NTSTATUS LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName, @@ -1105,20 +1139,32 @@ LdrPEProcessModule(PVOID ModuleLoadBase, ULONG Characteristics = PESectionHeaders[Idx].Characteristics; ULONG Length; PVOID BaseAddress; - ULONG i; - Length = - max(PESectionHeaders[Idx].Misc.VirtualSize, - PESectionHeaders[Idx].SizeOfRawData); - BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + PVOID PageAddress; if (Characteristics & IMAGE_SECTION_CHAR_CODE && !(Characteristics & IMAGE_SECTION_CHAR_WRITABLE || Characteristics & IMAGE_SECTION_CHAR_DATA || Characteristics & IMAGE_SECTION_CHAR_BSS)) { - for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) + Length = + max(PESectionHeaders[Idx].Misc.VirtualSize, + PESectionHeaders[Idx].SizeOfRawData); + BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); + if (! PageNeedsWriteAccess(PageAddress, DriverBase, PEFileHeader, PESectionHeaders)) + { + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); + } + PageAddress = (PVOID)((PCHAR) PageAddress + PAGE_SIZE); + while ((PVOID)((PCHAR) PageAddress + PAGE_SIZE) < + (PVOID)((PCHAR) BaseAddress + Length)) + { + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); + PageAddress = (PVOID)((PCHAR) PageAddress + PAGE_SIZE); + } + if (PageAddress < (PVOID)((PCHAR) BaseAddress + Length) && + ! PageNeedsWriteAccess(PageAddress, DriverBase, PEFileHeader, PESectionHeaders)) { - MmSetPageProtect(NULL, BaseAddress + (i * PAGE_SIZE), - PAGE_READONLY); + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); } } } diff --git a/ntoskrnl/ldr/resource.c b/ntoskrnl/ldr/resource.c index 2107463..2e077f5 100644 --- a/ntoskrnl/ldr/resource.c +++ b/ntoskrnl/ldr/resource.c @@ -120,7 +120,7 @@ LdrFindResource_U(PVOID BaseAddress, { ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) && - wcslen((PWCHAR)Id) == (int)*ws ) + wcslen((PWCHAR)Id) == (ULONG)*ws ) { goto found; } diff --git a/ntoskrnl/lpc/connect.c b/ntoskrnl/lpc/connect.c index 78e0f35..09ffb02 100644 --- a/ntoskrnl/lpc/connect.c +++ b/ntoskrnl/lpc/connect.c @@ -479,7 +479,6 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, /* * All done. */ - ObDereferenceObject(ConnectedPort); return(STATUS_SUCCESS); } diff --git a/ntoskrnl/mm/anonmem.c b/ntoskrnl/mm/anonmem.c index 451c5c2..282b695 100644 --- a/ntoskrnl/mm/anonmem.c +++ b/ntoskrnl/mm/anonmem.c @@ -285,7 +285,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, /* * Get or create a page operation */ - PageOp = MmGetPageOp(MemoryArea, (ULONG)PsGetCurrentProcessId(), + PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId, (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0, MM_PAGEOP_PAGEIN); if (PageOp == NULL) @@ -325,6 +325,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, if (PageOp->OpType != MM_PAGEOP_PAGEIN) { MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_MM_RESTART_OPERATION); } @@ -334,6 +335,8 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, if (!NT_SUCCESS(PageOp->Status)) { MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + Status = PageOp->Status; MmReleasePageOp(PageOp); return(Status); } @@ -342,6 +345,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, { MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); } + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_SUCCESS); } @@ -356,6 +360,11 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); MmLockAddressSpace(AddressSpace); } + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status); + KeBugCheck(0); + } /* * Handle swapped out pages. @@ -380,15 +389,15 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, * Set the page. If we fail because we are out of memory then * try again */ - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), - Address, + Status = MmCreateVirtualMapping(MemoryArea->Process, + (PVOID)PAGE_ROUND_DOWN(Address), MemoryArea->Attributes, Page, FALSE); while (Status == STATUS_NO_MEMORY) { MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(MemoryArea->Process, Address, MemoryArea->Attributes, Page, @@ -405,7 +414,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, /* * Add the page to the process's working set */ - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, MemoryArea->Process, (PVOID)PAGE_ROUND_DOWN(Address)); /* * Finish the operation @@ -593,7 +602,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, MmAlterRegion(AddressSpace, MemoryArea->BaseAddress, &MemoryArea->Data.VirtualMemoryData.RegionListHead, - PBaseAddress, RegionSize, + BaseAddress, RegionSize, Type, Protect, MmModifyAttributes); MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); @@ -609,7 +618,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, } Status = MmCreateMemoryArea(Process, - &Process->AddressSpace, + AddressSpace, MEMORY_AREA_VIRTUAL_MEMORY, &BaseAddress, RegionSize, diff --git a/ntoskrnl/mm/balance.c b/ntoskrnl/mm/balance.c index 989baf0..309948e 100644 --- a/ntoskrnl/mm/balance.c +++ b/ntoskrnl/mm/balance.c @@ -171,7 +171,7 @@ MiRebalanceMemoryConsumers(VOID) NTSTATUS Status; Target = (MiMinimumAvailablePages - MiNrAvailablePages) + MiPagesRequired; - Target = min(Target, MiMinimumPagesPerRun); + Target = min(Target, (LONG) MiMinimumPagesPerRun); for (i = 0; i < MC_MAXIMUM && Target > 0; i++) { diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c index 7eff3ab..5a037f4 100644 --- a/ntoskrnl/mm/freelist.c +++ b/ntoskrnl/mm/freelist.c @@ -122,7 +122,7 @@ MmGetContinuousPages(ULONG NumberOfBytes, { ULONG NrPages; ULONG i; - ULONG start; + LONG start; ULONG length; KIRQL oldIrql; diff --git a/ntoskrnl/mm/marea.c b/ntoskrnl/mm/marea.c index dfb5dd5..d6dfe50 100644 --- a/ntoskrnl/mm/marea.c +++ b/ntoskrnl/mm/marea.c @@ -212,6 +212,7 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length) MEMORY_AREA* current; MEMORY_AREA* next; ULONG Gap; + PVOID Address; DPRINT("MmFindGap(Length %x)\n",Length); @@ -232,11 +233,29 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length) if (current_entry == ListHead) { - return((PVOID)AddressSpace->LowestAddress); + Address = (PVOID)AddressSpace->LowestAddress; } - - current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); - return(current->BaseAddress + PAGE_ROUND_UP(current->Length)); + else + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + Address = current->BaseAddress + PAGE_ROUND_UP(current->Length); + } + /* Check if enough space for the block */ + if (AddressSpace->LowestAddress < KERNEL_BASE) + { + if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) + { + return NULL; + } + } + else + { + if (Length >= 0xFFFFFFFF - (ULONG)Address) + { + return NULL; + } + } + return Address; } NTSTATUS MmInitMemoryAreas(VOID) diff --git a/ntoskrnl/mm/mdl.c b/ntoskrnl/mm/mdl.c index 4a2f83d..bf4b0bd 100644 --- a/ntoskrnl/mm/mdl.c +++ b/ntoskrnl/mm/mdl.c @@ -396,7 +396,7 @@ MmBuildMdlForNonPagedPool (PMDL Mdl) * byte offset and length */ { - int va; + ULONG va; Mdl->MdlFlags = Mdl->MdlFlags | (MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED); for (va=0; va < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); va++) diff --git a/ntoskrnl/mm/mminit.c b/ntoskrnl/mm/mminit.c index 6a5948f..1c7eb09 100644 --- a/ntoskrnl/mm/mminit.c +++ b/ntoskrnl/mm/mminit.c @@ -266,7 +266,9 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr, * Unmap low memory */ #ifndef MP - /* FIXME: This is broken in SMP mode */ + /* In SMP mode we unmap the low memory in MmInit3. + The APIC needs the mapping of the first pages + while the processors are starting up. */ MmDeletePageTable(NULL, 0); #endif /* @@ -351,9 +353,18 @@ VOID MmInit2(VOID) VOID MmInit3(VOID) { + /* + * Unmap low memory + */ +#ifdef MP + /* In SMP mode we can unmap the low memory + if all processors are started. */ + MmDeletePageTable(NULL, 0); +#endif MmInitPagerThread(); MmCreatePhysicalMemorySection(); MmInitializeRmapList(); + MmInitializePageOp(); /* * Initialise the modified page writer. diff --git a/ntoskrnl/mm/mpw.c b/ntoskrnl/mm/mpw.c index b9ae628..8078e54 100644 --- a/ntoskrnl/mm/mpw.c +++ b/ntoskrnl/mm/mpw.c @@ -56,6 +56,10 @@ MmWriteDirtyPages(ULONG Target, PULONG Actual) Page = MmGetLRUFirstUserPage(); while (Page.QuadPart != 0LL && Target > 0) { + /* + * FIXME: While the current page is write back it is possible + * that the next page is freed and not longer a user page. + */ NextPage = MmGetLRUNextUserPage(Page); if (MmIsDirtyPageRmap(Page)) { @@ -100,7 +104,12 @@ MmMpwThreadMain(PVOID Ignored) } PagesWritten = 0; +#if 0 + /* + * FIXME: MmWriteDirtyPages doesn't work correctly. + */ MmWriteDirtyPages(128, &PagesWritten); +#endif CcRosFlushDirtyPages(128, &PagesWritten); } } diff --git a/ntoskrnl/mm/npool.c b/ntoskrnl/mm/npool.c index daef537..29186d4 100644 --- a/ntoskrnl/mm/npool.c +++ b/ntoskrnl/mm/npool.c @@ -317,6 +317,8 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly) DbgPrint("TotalBlocks %d TotalSize %d\n", TotalBlocks, TotalSize); } + DbgPrint("Freeblocks %d TotalFreeSize %d AverageFreeSize %d\n", + EiNrFreeBlocks, EiFreeNonPagedPool, EiNrFreeBlocks ? EiFreeNonPagedPool / EiNrFreeBlocks : 0); DbgPrint("***************** Dump Complete ***************\n"); #endif /* TAG_STATISTICS_TRACKING */ } @@ -713,6 +715,10 @@ static BLOCK_HDR* lookup_block(unsigned int size) (best == NULL || current->Size < best->Size)) { best = current; + if (best->Size == size) + { + break; + } } current_entry = current_entry->Flink; } @@ -840,7 +846,7 @@ static void* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller) ULONG nr_pages = PAGE_ROUND_UP(size + sizeof(BLOCK_HDR)) / PAGE_SIZE; ULONG start; BLOCK_HDR* blk=NULL; - int i; + ULONG i; KIRQL oldIrql; NTSTATUS Status; PVOID block = NULL; diff --git a/ntoskrnl/mm/pagefile.c b/ntoskrnl/mm/pagefile.c index ade10f5..b47921e 100644 --- a/ntoskrnl/mm/pagefile.c +++ b/ntoskrnl/mm/pagefile.c @@ -136,7 +136,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); - if (i > MAX_PAGING_FILES) + if (i >= MAX_PAGING_FILES) { DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); KeBugCheck(0); @@ -180,7 +180,7 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); - if (i > MAX_PAGING_FILES) + if (i >= MAX_PAGING_FILES) { DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); KeBugCheck(0); diff --git a/ntoskrnl/mm/pageop.c b/ntoskrnl/mm/pageop.c index 6c7a46f..7c4b15e 100644 --- a/ntoskrnl/mm/pageop.c +++ b/ntoskrnl/mm/pageop.c @@ -22,8 +22,9 @@ #define PAGEOP_HASH_TABLE_SIZE (32) -KSPIN_LOCK MmPageOpHashTableLock; -PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE] = {NULL, } ; +static KSPIN_LOCK MmPageOpHashTableLock; +static PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE]; +static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList; #define TAG_MM_PAGEOP TAG('M', 'P', 'O', 'P') @@ -51,7 +52,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp) { MmPageOpHashTable[PageOp->Hash] = PageOp->Next; KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - ExFreePool(PageOp); + ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); return; } while (PrevPageOp->Next != NULL) @@ -60,7 +61,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp) { PrevPageOp->Next = PageOp->Next; KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - ExFreePool(PageOp); + ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); return; } PrevPageOp = PrevPageOp->Next; @@ -198,8 +199,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, /* * Otherwise add a new pageop. */ - PageOp = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_PAGEOP), - TAG_MM_PAGEOP); + PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList); if (PageOp == NULL) { KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); @@ -232,6 +232,20 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, return(PageOp); } +VOID +MmInitializePageOp(VOID) +{ + memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable)); + KeInitializeSpinLock(&MmPageOpHashTableLock); + + ExInitializeNPagedLookasideList (&MmPageOpLookasideList, + NULL, + NULL, + 0, + sizeof(MM_PAGEOP), + TAG_MM_PAGEOP, + 50); +} diff --git a/ntoskrnl/mm/pool.c b/ntoskrnl/mm/pool.c index 10c870f..30fffec 100644 --- a/ntoskrnl/mm/pool.c +++ b/ntoskrnl/mm/pool.c @@ -10,6 +10,7 @@ /* INCLUDES ****************************************************************/ #include +#include #include #include diff --git a/ntoskrnl/mm/region.c b/ntoskrnl/mm/region.c index 1070666..4f87a9c 100644 --- a/ntoskrnl/mm/region.c +++ b/ntoskrnl/mm/region.c @@ -183,12 +183,11 @@ MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, * and call the helper function to actually do the changes. */ CurrentEntry = NewRegion->RegionListEntry.Flink; + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); CurrentBaseAddress = StartAddress + NewRegion->Length; while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength) { - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - CurrentEntry = CurrentEntry->Flink; if (CurrentRegion->Type != NewType && CurrentRegion->Protect != NewProtect) { @@ -199,8 +198,11 @@ MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, CurrentBaseAddress += CurrentRegion->Length; NewRegion->Length += CurrentRegion->Length; RemainingLength -= CurrentRegion->Length; + CurrentEntry = CurrentEntry->Flink; RemoveEntryList(&CurrentRegion->RegionListEntry); ExFreePool(CurrentRegion); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); } /* diff --git a/ntoskrnl/mm/rmap.c b/ntoskrnl/mm/rmap.c index 056b906..2848be4 100644 --- a/ntoskrnl/mm/rmap.c +++ b/ntoskrnl/mm/rmap.c @@ -50,6 +50,7 @@ typedef struct _MM_RMAP_ENTRY /* GLOBALS ******************************************************************/ static FAST_MUTEX RmapListLock; +static NPAGED_LOOKASIDE_LIST RmapLookasideList; /* FUNCTIONS ****************************************************************/ @@ -57,6 +58,13 @@ VOID MmInitializeRmapList(VOID) { ExInitializeFastMutex(&RmapListLock); + ExInitializeNPagedLookasideList (&RmapLookasideList, + NULL, + NULL, + 0, + sizeof(MM_RMAP_ENTRY), + TAG_RMAP, + 50); } NTSTATUS @@ -104,6 +112,7 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace, Address); if (MemoryArea == NULL) { + MmUnlockAddressSpace(&Process->AddressSpace); ObDereferenceObject(Process); return(STATUS_UNSUCCESSFUL); } @@ -355,7 +364,7 @@ MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process, Address = (PVOID)PAGE_ROUND_DOWN(Address); - new_entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_RMAP_ENTRY), TAG_RMAP); + new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); if (new_entry == NULL) { KeBugCheck(0); @@ -404,7 +413,7 @@ MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context, DeleteMapping(Context, previous_entry->Process, previous_entry->Address); } - ExFreePool(previous_entry); + ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); } MmSetRmapListHeadPage(PhysicalAddress, NULL); ExReleaseFastMutex(&RmapListLock); @@ -427,15 +436,13 @@ MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process, if (previous_entry == NULL) { MmSetRmapListHeadPage(PhysicalAddress, current_entry->Next); - ExReleaseFastMutex(&RmapListLock); - ExFreePool(current_entry); } else { previous_entry->Next = current_entry->Next; - ExReleaseFastMutex(&RmapListLock); - ExFreePool(current_entry); } + ExReleaseFastMutex(&RmapListLock); + ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); return; } previous_entry = current_entry; diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 5c3af8c..3c7dddb 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -329,6 +329,8 @@ MiReadPage(PMEMORY_AREA MemoryArea, FileObject = MemoryArea->Data.SectionData.Section->FileObject; Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext; + assert(Fcb->Bcb); + /* * If the file system is letting us go directly to the cache and the * memory area was mapped at an offset in the file which is page aligned @@ -562,6 +564,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, if (PageOp->OpType != MM_PAGEOP_PAGEIN) { MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); DPRINT("Address 0x%.8X\n", Address); return(STATUS_MM_RESTART_OPERATION); @@ -572,8 +575,11 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, if (!NT_SUCCESS(PageOp->Status)) { MmLockAddressSpace(AddressSpace); + Status = PageOp->Status; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); DPRINT("Address 0x%.8X\n", Address); - return(PageOp->Status); + return(Status); } MmLockAddressSpace(AddressSpace); MmLockSection(Section); @@ -589,6 +595,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, { MmUnlockSectionSegment(Segment); MmUnlockSection(Section); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_MM_RESTART_OPERATION); } @@ -597,7 +604,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmReferencePage(Page); MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(MemoryArea->Process, Address, MemoryArea->Attributes, Page, @@ -607,7 +614,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, DbgPrint("Unable to create virtual mapping\n"); KeBugCheck(0); } - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, MemoryArea->Process, (PVOID)PAGE_ROUND_DOWN(Address)); } if (Locked) @@ -616,6 +623,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, } MmUnlockSectionSegment(Segment); MmUnlockSection(Section); + PageOp->Status = STATUS_SUCCESS; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); DPRINT("Address 0x%.8X\n", Address); return(STATUS_SUCCESS); @@ -648,7 +657,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, KeBugCheck(0); } - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Region->Protect, Page, @@ -656,7 +665,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, while (Status == STATUS_NO_MEMORY) { MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Region->Protect, Page, @@ -678,7 +687,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, /* * Add the page to the process's working set */ - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); /* @@ -703,7 +712,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, /* * Just map the desired physical page */ - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Region->Protect, Offset, @@ -746,12 +755,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmLockSectionSegment(Segment); } - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Region->Protect, Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); if (Locked) { @@ -840,7 +849,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Attributes, Page, @@ -850,7 +859,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmUnlockSectionSegment(Segment); MmUnlockSection(Section); MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Attributes, Page, @@ -863,7 +872,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmLockSection(Section); MmLockSectionSegment(Segment); } - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { @@ -941,12 +950,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, */ MmSetSavedSwapEntryPage(Page, SwapEntry); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Attributes, Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { @@ -976,12 +985,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmReferencePage(Page); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Attributes, Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { @@ -1107,6 +1116,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, * Restart the operation */ MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_MM_RESTART_OPERATION); } @@ -1135,18 +1145,18 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, /* * Delete the old entry. */ - MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE, NULL, NULL); + MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL); /* * Set the PTE to point to the new page */ MmLockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(PsGetCurrentProcess(), + Status = MmCreateVirtualMapping(AddressSpace->Process, Address, Region->Protect, NewPage, FALSE); - MmInsertRmap(NewPage, PsGetCurrentProcess(), + MmInsertRmap(NewPage, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { @@ -1162,7 +1172,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, * Unshare the old page. */ MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE); - MmDeleteRmap(OldPage, PsGetCurrentProcess(), + MmDeleteRmap(OldPage, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address)); MmReleasePageMemoryConsumer(MC_USER, OldPage); @@ -1773,7 +1783,7 @@ MmProtectSectionView(PMADDRESS_SPACE AddressSpace, NTSTATUS Status; Length = - min(Length, MemoryArea->BaseAddress + MemoryArea->Length - BaseAddress); + min(Length, (ULONG) (MemoryArea->BaseAddress + MemoryArea->Length - BaseAddress)); Region = MmFindRegion(MemoryArea->BaseAddress, &MemoryArea->Data.SectionData.RegionListHead, BaseAddress, NULL); @@ -1841,6 +1851,12 @@ MmpDeleteSection(PVOID ObjectBody) ObDereferenceObject(Section->FileObject); Section->FileObject = NULL; } + + if (Section->Segments->Flags & MM_PAGEFILE_SEGMENT) + { + MmFreePageTablesSectionSegment(Section->Segments); + ExFreePool(Section->Segments); + } } VOID STDCALL @@ -2022,6 +2038,7 @@ MmCreatePageFileSection(PHANDLE SectionHandle, Segment->Length = MaximumSize.u.LowPart; Segment->Flags = MM_PAGEFILE_SEGMENT; Segment->WriteCopy = FALSE; + ObDereferenceObject(Section); return(STATUS_SUCCESS); } @@ -2044,6 +2061,9 @@ MmCreateDataFileSection(PHANDLE SectionHandle, PFILE_OBJECT FileObject; PMM_SECTION_SEGMENT Segment; ULONG FileAccess; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER Offset; + CHAR Buffer; /* * Check the protection @@ -2053,7 +2073,27 @@ MmCreateDataFileSection(PHANDLE SectionHandle, { return(STATUS_INVALID_PAGE_PROTECTION); } - + + /* + * Read a bit so caching is initiated for the file object. + * This is only needed because MiReadPage currently cannot + * handle non-cached streams. + */ + Offset.QuadPart = 0; + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + &Buffer, + sizeof (Buffer), + &Offset, + 0); + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) + { + return(Status); + } + /* * Create the section */ @@ -2962,8 +3002,6 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, MmFreeSwapPage(SavedSwapEntry); MmSetSavedSwapEntryPage(PhysAddr, 0); } - MmDeleteRmap(PhysAddr, MArea->Process, Address); - MmReleasePageMemoryConsumer(MC_USER, PhysAddr); } else { @@ -2971,9 +3009,9 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, MArea->Data.SectionData.Segment, Offset, Dirty); - MmDeleteRmap(PhysAddr, MArea->Process, Address); - MmReleasePageMemoryConsumer(MC_USER, PhysAddr); } + MmDeleteRmap(PhysAddr, MArea->Process, Address); + MmReleasePageMemoryConsumer(MC_USER, PhysAddr); } } @@ -3483,8 +3521,20 @@ BOOLEAN STDCALL MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType) { - UNIMPLEMENTED; - return (FALSE); + switch(FlushType) + { + case MmFlushForDelete: + if (SectionObjectPointer->ImageSectionObject || + SectionObjectPointer->DataSectionObject) + { + return FALSE; + } + CcRosSetRemoveOnClose(SectionObjectPointer); + return TRUE; + case MmFlushForWrite: + break; + } + return FALSE; } BOOLEAN STDCALL diff --git a/ntoskrnl/ntoskrnl.def b/ntoskrnl/ntoskrnl.def index 685061b..06a6c1c 100644 --- a/ntoskrnl/ntoskrnl.def +++ b/ntoskrnl/ntoskrnl.def @@ -978,14 +978,14 @@ ZwWaitForSingleObject@12 ZwWriteFile@36 ZwYieldExecution@0 _abnormal_termination -;_alldiv -;_allmul -;_allrem -;_allshl -;_allshr -;_aulldiv -;_aullrem -;_aullshr +_alldiv +_allmul +_allrem +_allshl +_allshr +_aulldiv +_aullrem +_aullshr _except_handler2 _except_handler3 _global_unwind2 diff --git a/ntoskrnl/ntoskrnl.edf b/ntoskrnl/ntoskrnl.edf index 12bd828..70f2831 100644 --- a/ntoskrnl/ntoskrnl.edf +++ b/ntoskrnl/ntoskrnl.edf @@ -976,14 +976,14 @@ ZwWaitForSingleObject=ZwWaitForSingleObject@12 ZwWriteFile=ZwWriteFile@36 ZwYieldExecution=ZwYieldExecution@0 _abnormal_termination -;_alldiv -;_allmul -;_allrem -;_allshl -;_allshr -;_aulldiv -;_aullrem -;_aullshr +_alldiv +_allmul +_allrem +_allshl +_allshr +_aulldiv +_aullrem +_aullshr _except_handler2 _except_handler3 _global_unwind2 diff --git a/ntoskrnl/ob/handle.c b/ntoskrnl/ob/handle.c index 8d3b679..c005f74 100644 --- a/ntoskrnl/ob/handle.c +++ b/ntoskrnl/ob/handle.c @@ -278,6 +278,7 @@ VOID ObCloseAllHandles(PEPROCESS Process) PHANDLE_BLOCK current; ULONG i; PVOID ObjectBody; + BOOLEAN IsProcessHandle; DPRINT("ObCloseAllHandles(Process %x)\n", Process); @@ -313,8 +314,16 @@ VOID ObCloseAllHandles(PEPROCESS Process) current->handles[i].ObjectBody = NULL; KeReleaseSpinLock(&HandleTable->ListLock, oldIrql); - KeDetachProcess(); + if (Header->ObjectType == PsProcessType) + { + IsProcessHandle = TRUE; + KeDetachProcess(); + } + else + { + IsProcessHandle = FALSE; + } if ((Header->ObjectType != NULL) && (Header->ObjectType->Close != NULL)) { @@ -323,7 +332,10 @@ VOID ObCloseAllHandles(PEPROCESS Process) } ObDereferenceObject(ObjectBody); - KeAttachProcess(Process); + if (IsProcessHandle) + { + KeAttachProcess(Process); + } KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql); current_entry = &HandleTable->ListHead; break; diff --git a/ntoskrnl/ob/namespc.c b/ntoskrnl/ob/namespc.c index de66216..ecfc3e5 100644 --- a/ntoskrnl/ob/namespc.c +++ b/ntoskrnl/ob/namespc.c @@ -11,6 +11,10 @@ /* INCLUDES ***************************************************************/ +#ifdef WIN32_REGDBG +#include "cm_win32.h" +#else + #include #include #include @@ -20,6 +24,8 @@ #define NDEBUG #include +#endif + /* GLOBALS ****************************************************************/ POBJECT_TYPE ObDirectoryType = NULL; @@ -40,7 +46,7 @@ static GENERIC_MAPPING ObpTypeMapping = { 0x000F0001}; /* FUNCTIONS **************************************************************/ - +#ifndef WIN32_REGDBG NTSTATUS STDCALL ObReferenceObjectByName(PUNICODE_STRING ObjectPath, ULONG Attributes, @@ -84,7 +90,7 @@ DPRINT("Object %p\n", Object); RtlFreeUnicodeString (&RemainingPath); return(STATUS_SUCCESS); } - +#endif // WIN32_REGDBG /********************************************************************** * NAME EXPORTED @@ -125,7 +131,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, PVOID Object = NULL; NTSTATUS Status; - DPRINT("ObOpenObjectByName()\n"); + DPRINT("ObOpenObjectByName(...)\n"); Status = ObFindObject(ObjectAttributes, &Object, @@ -220,7 +226,7 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject, while (current!=(&(DirectoryObject->head))) { current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry); - DPRINT("Scanning %S %S\n",current_obj->Name.Buffer, Name); + DPRINT(" Scanning: %S for: %S\n",current_obj->Name.Buffer, Name); if (Attributes & OBJ_CASE_INSENSITIVE) { if (_wcsicmp(current_obj->Name.Buffer, Name)==0) @@ -239,7 +245,7 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject, } current = current->Flink; } - DPRINT("%s() = NULL\n",__FUNCTION__); + DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__); return(NULL); } @@ -417,7 +423,7 @@ ObpCreateTypeObject(POBJECT_TYPE ObjectType) UNICODE_STRING Name; NTSTATUS Status; - DPRINT("ObjectType: %wZ\n", &ObjectType->TypeName); + DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType->TypeName); wcscpy(NameString, L"\\ObjectTypes\\"); wcscat(NameString, ObjectType->TypeName.Buffer); RtlInitUnicodeString(&Name, diff --git a/ntoskrnl/ps/debug.c b/ntoskrnl/ps/debug.c index 7c843f3..963b195 100644 --- a/ntoskrnl/ps/debug.c +++ b/ntoskrnl/ps/debug.c @@ -74,7 +74,7 @@ KeContextToTrapFrame(PCONTEXT Context, */ /* TrapFrame->Edx = Context->Edx; */ TrapFrame->Esi = Context->Esi; - TrapFrame->Edx = Context->Edi; + TrapFrame->Edi = Context->Edi; } if (Context->ContextFlags & CONTEXT_SEGMENTS) { diff --git a/ntoskrnl/ps/kill.c b/ntoskrnl/ps/kill.c index 7d9fa12..03ec255 100644 --- a/ntoskrnl/ps/kill.c +++ b/ntoskrnl/ps/kill.c @@ -96,17 +96,48 @@ PsReapThreads(VOID) { PEPROCESS Process = current->ThreadsProcess; NTSTATUS Status = current->ExitStatus; + BOOLEAN Last; PiNrThreadsAwaitingReaping--; current->Tcb.State = THREAD_STATE_TERMINATED_2; RemoveEntryList(¤t->Tcb.ProcessThreadListEntry); - if (IsListEmpty(&Process->ThreadListHead)) - { - KeReleaseSpinLock( &PiThreadListLock, oldIrql ); - PiTerminateProcess(Process, Status); - KeAcquireSpinLock( &PiThreadListLock, &oldIrql ); - } + Last = IsListEmpty(&Process->ThreadListHead); KeReleaseSpinLock(&PiThreadListLock, oldIrql); + + if (Last) + { + PiTerminateProcess(Process, Status); + } + else + { + if (current->Tcb.Teb) + { + /* If this is not the last thread for the process than free the memory + from user stack and teb. */ + NTSTATUS Status; + ULONG Length; + ULONG Offset; + PVOID DeallocationStack; + HANDLE ProcessHandle; + Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObCreateHandle failed, status = %x\n", Status); + KeBugCheck(0); + } + Offset = FIELD_OFFSET(TEB, DeallocationStack); + Length = 0; + NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset, + (PVOID)&DeallocationStack, sizeof(PVOID), &Length); + if (DeallocationStack && Length == sizeof(PVOID)) + { + NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE); + } + Length = PAGE_SIZE; + NtFreeVirtualMemory(ProcessHandle, (PVOID*)¤t->Tcb.Teb, &Length, MEM_RELEASE); + NtClose(ProcessHandle); + } + } ObDereferenceObject(current); KeAcquireSpinLock(&PiThreadListLock, &oldIrql); current_entry = PiThreadListHead.Flink; diff --git a/ntoskrnl/ps/process.c b/ntoskrnl/ps/process.c index 0e9c285..7b64e18 100644 --- a/ntoskrnl/ps/process.c +++ b/ntoskrnl/ps/process.c @@ -299,12 +299,12 @@ PiDeleteProcess(PVOID ObjectBody) KeReleaseSpinLock(&PsProcessListLock, oldIrql); /* KDB hook */ - KDB_DELETEPROCESS_HOOK(Process->Peb); + KDB_DELETEPROCESS_HOOK(Process); ObDereferenceObject(Process->Token); + ObDeleteHandleTable(Process); (VOID)MmReleaseMmInfo(Process); - ObDeleteHandleTable(Process); } diff --git a/ntoskrnl/rtl/bitmap.c b/ntoskrnl/rtl/bitmap.c index 3760fa6..db9b430 100644 --- a/ntoskrnl/rtl/bitmap.c +++ b/ntoskrnl/rtl/bitmap.c @@ -13,6 +13,8 @@ #define ALIGN(x,align) (((x)+(align)-1) / (align)) +#define MASK(Count, Shift) ((Count) == 32 ? 0xFFFFFFFF : ~(0xFFFFFFFF << (Count)) << (Shift)) + VOID STDCALL @@ -38,24 +40,24 @@ RtlAreBitsClear ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Shift; ULONG Count; - PCHAR Ptr; + PULONG Ptr; if (StartingIndex >= Size || !Length || (StartingIndex + Length > Size)) return FALSE; - Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32); while (Length) { - /* get bit shift in current byte */ - Shift = StartingIndex & 7; + /* get bit shift in current dword */ + Shift = StartingIndex & 0x1F; - /* get number of bits to check in current byte */ - Count = (Length > 8 - Shift) ? 8 - Shift : Length; + /* get number of bits to check in current dword */ + Count = (Length > 32 - Shift) ? 32 - Shift : Length; - /* check byte */ - if (*Ptr++ & (~(0xFF << Count) << Shift)) + /* check dword */ + if (*Ptr++ & MASK(Count, Shift)) return FALSE; Length -= Count; @@ -77,24 +79,24 @@ RtlAreBitsSet ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Shift; ULONG Count; - PCHAR Ptr; + PULONG Ptr; if (StartingIndex >= Size || !Length || (StartingIndex + Length > Size)) return FALSE; - Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32); while (Length) { - /* get bit shift in current byte */ - Shift = StartingIndex & 7; + /* get bit shift in current dword */ + Shift = StartingIndex & 0x1F; - /* get number of bits to check in current byte */ - Count = (Length > 8 - Shift) ? 8 - Shift : Length; + /* get number of bits to check in current dword */ + Count = (Length > 32 - Shift) ? 32 - Shift : Length; - /* check byte */ - if (~*Ptr++ & (~(0xFF << Count) << Shift)) + /* check dword */ + if (~*Ptr++ & MASK(Count, Shift)) return FALSE; Length -= Count; @@ -128,7 +130,7 @@ RtlClearBits ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Count; ULONG Shift; - PCHAR Ptr; + PULONG Ptr; if (StartingIndex >= Size || NumberToClear == 0) return; @@ -136,17 +138,17 @@ RtlClearBits ( if (StartingIndex + NumberToClear > Size) NumberToClear = Size - StartingIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32); while (NumberToClear) { - /* bit shift in current byte */ - Shift = StartingIndex & 7; + /* bit shift in current dword */ + Shift = StartingIndex & 0x1F; - /* number of bits to change in current byte */ - Count = (NumberToClear > 8 - Shift ) ? 8 - Shift : NumberToClear; + /* number of bits to change in current dword */ + Count = (NumberToClear > 32 - Shift ) ? 32 - Shift : NumberToClear; - /* adjust byte */ - *Ptr++ &= ~(~(0xFF << Count) << Shift); + /* adjust dword */ + *Ptr++ &= ~MASK(Count, Shift); NumberToClear -= Count; StartingIndex += Count; } @@ -164,8 +166,8 @@ RtlFindClearBits ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - PCHAR Ptr; - CHAR Mask; + PULONG Ptr; + ULONG Mask; if (NumberToFind > Size || NumberToFind == 0) return -1; @@ -174,8 +176,8 @@ RtlFindClearBits ( HintIndex = 0; Index = HintIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); - Mask = 1 << (Index & 7); + Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); + Mask = 1 << (Index & 0x1F); while (HintIndex < Size) { @@ -241,8 +243,8 @@ RtlFindFirstRunClear ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - PCHAR Ptr; - CHAR Mask; + PULONG Ptr; + ULONG Mask; if (*StartingIndex > Size) { @@ -251,8 +253,8 @@ RtlFindFirstRunClear ( } Index = *StartingIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); - Mask = 1 << (Index & 7); + Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); + Mask = 1 << (Index & 0x1F); /* skip set bits */ for (; Index < Size && *Ptr & Mask; Index++) @@ -300,8 +302,8 @@ RtlFindFirstRunSet ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - PCHAR Ptr; - CHAR Mask; + PULONG Ptr; + ULONG Mask; if (*StartingIndex > Size) { @@ -310,8 +312,8 @@ RtlFindFirstRunSet ( } Index = *StartingIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); - Mask = 1 << (Index & 7); + Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); + Mask = 1 << (Index & 0x1F); /* skip clear bits */ for (; Index < Size && ~*Ptr & Mask; Index++) @@ -357,13 +359,13 @@ RtlFindLongestRunClear ( ) { ULONG Size = BitMapHeader->SizeOfBitMap; - PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + PULONG Ptr = (PULONG)BitMapHeader->Buffer; ULONG Index = 0; ULONG Count; ULONG Max = 0; ULONG Start; ULONG Maxstart = 0; - CHAR Mask = 1; + ULONG Mask = 1; while (Index < Size) { @@ -414,13 +416,13 @@ RtlFindLongestRunSet ( ) { ULONG Size = BitMapHeader->SizeOfBitMap; - PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + PULONG Ptr = (PULONG)BitMapHeader->Buffer; ULONG Index = 0; ULONG Count; ULONG Max = 0; ULONG Start; ULONG Maxstart = 0; - CHAR Mask = 1; + ULONG Mask = 1; while (Index < Size) { @@ -474,8 +476,8 @@ RtlFindSetBits ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - PCHAR Ptr; - CHAR Mask; + PULONG Ptr; + ULONG Mask; if (NumberToFind > Size || NumberToFind == 0) return (ULONG)-1; @@ -484,8 +486,8 @@ RtlFindSetBits ( HintIndex = 0; Index = HintIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); - Mask = 1 << (Index & 7); + Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); + Mask = 1 << (Index & 0x1F); while (HintIndex < Size) { @@ -547,11 +549,11 @@ RtlNumberOfClearBits ( PRTL_BITMAP BitMapHeader ) { - PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + PULONG Ptr = (PULONG)BitMapHeader->Buffer; ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - CHAR Mask; + ULONG Mask; for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++) { @@ -576,11 +578,11 @@ RtlNumberOfSetBits ( PRTL_BITMAP BitMapHeader ) { - PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + PULONG Ptr = (PULONG)BitMapHeader->Buffer; ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Index; ULONG Count; - CHAR Mask; + ULONG Mask; for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++) { @@ -622,7 +624,7 @@ RtlSetBits ( ULONG Size = BitMapHeader->SizeOfBitMap; ULONG Count; ULONG Shift; - PCHAR Ptr; + PULONG Ptr; if (StartingIndex >= Size || NumberToSet == 0) return; @@ -630,17 +632,17 @@ RtlSetBits ( if (StartingIndex + NumberToSet > Size) NumberToSet = Size - StartingIndex; - Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32); while (NumberToSet) { - /* bit shift in current byte */ - Shift = StartingIndex & 7; + /* bit shift in current dword */ + Shift = StartingIndex & 0x1F; - /* number of bits to change in current byte */ - Count = (NumberToSet > 8 - Shift) ? 8 - Shift : NumberToSet; + /* number of bits to change in current dword */ + Count = (NumberToSet > 32 - Shift) ? 32 - Shift : NumberToSet; - /* adjust byte */ - *Ptr++ |= ~(0xFF << Count) << Shift; + /* adjust dword */ + *Ptr++ |= MASK(Count, Shift); NumberToSet -= Count; StartingIndex += Count; } diff --git a/ntoskrnl/rtl/error.c b/ntoskrnl/rtl/error.c index 7e02546..753bac8 100644 --- a/ntoskrnl/rtl/error.c +++ b/ntoskrnl/rtl/error.c @@ -826,7 +826,8 @@ RPC_NT_SS_CONTEXT_MISMATCH ERROR_INVALID_HANDLE /* FUNCTIONS ***************************************************************/ -VOID STDCALL +VOID +STDCALL RtlAssert(PVOID FailedAssertion, PVOID FileName, ULONG LineNumber, @@ -871,16 +872,18 @@ RtlNtStatusToDosErrorNoTeb(IN NTSTATUS Status) while (Table->Start) { - if (Status < Table->Start) + if (Status < (NTSTATUS) Table->Start) break; - if (Status < Table->End) + if (Status < (NTSTATUS) Table->End) { DWORD ret = Table->Table[Status - Table->Start]; if (!ret) ret = Status; /* 0 means 1:1 mapping */ else if (ret == ERROR_MR_MID_NOT_FOUND) + { DbgPrint("RTL: RtlNtStatusToDosErrorNoTeb(0x%lx): no valid W32 error mapping\n", Status); + } return ret; } Table++; diff --git a/ntoskrnl/rtl/i386/exception.c b/ntoskrnl/rtl/i386/exception.c index db47357..6cec442 100755 --- a/ntoskrnl/rtl/i386/exception.c +++ b/ntoskrnl/rtl/i386/exception.c @@ -9,7 +9,7 @@ /* INCLUDES *****************************************************************/ -#include +#include #include #include @@ -58,8 +58,8 @@ __ret_label: /* Implemented in except.s */ -VOID -RtlpCaptureContext(PCONTEXT pContext); +VOID +RtlpCaptureContext(PCONTEXT pContext); /* Macros that will help streamline the SEH implementations for kernel mode and user mode */ @@ -152,7 +152,7 @@ RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame); - while ((ULONG_PTR)RegistrationFrame != -1) + while ((ULONG_PTR)RegistrationFrame != (ULONG_PTR)-1) { EXCEPTION_RECORD ExceptionRecord2; DWORD Temp = 0; @@ -363,7 +363,7 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, Context.Eax = EaxValue; // Begin traversing the list of EXCEPTION_REGISTRATION - while ((ULONG_PTR)ERHead != -1) + while ((ULONG_PTR)ERHead != (ULONG_PTR)-1) { EXCEPTION_RECORD er2; @@ -466,7 +466,7 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n", RegistrationFrame); - if ((ULONG_PTR)RegistrationFrame == -1) + if ((ULONG_PTR)RegistrationFrame == (ULONG_PTR)-1) NtContinue(&Context, FALSE); else NtRaiseException(pExceptRec, &Context, 0); diff --git a/ntoskrnl/rtl/largeint.c b/ntoskrnl/rtl/largeint.c index d45df86..de584b8 100644 --- a/ntoskrnl/rtl/largeint.c +++ b/ntoskrnl/rtl/largeint.c @@ -119,7 +119,8 @@ RtlExtendedLargeIntegerDivide ( return RC; } -LARGE_INTEGER STDCALL +LARGE_INTEGER +STDCALL RtlExtendedMagicDivide (LARGE_INTEGER Dividend, LARGE_INTEGER MagicDivisor, CCHAR ShiftCount) diff --git a/ntoskrnl/rtl/math.c b/ntoskrnl/rtl/math.c new file mode 100644 index 0000000..b9deb34 --- /dev/null +++ b/ntoskrnl/rtl/math.c @@ -0,0 +1,332 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: kernel/rtl/math.c + * PURPOSE: + * UPDATE HISTORY: + * Created 20/12/2002 + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +LARGE_INTEGER +STDCALL +_alldiv(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_allmul(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_allrem(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_allshl(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_allshr(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_aulldiv(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_aullrem(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + +LARGE_INTEGER +STDCALL +_aullshr(ULONG UnsignedInteger) +{ + LARGE_INTEGER RC; + + RC.QuadPart = 0; + return RC; +} + + +/* +LARGE_INTEGER +STDCALL +RtlConvertLongToLargeInteger ( + LONG SignedInteger + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = SignedInteger; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlConvertUlongToLargeInteger ( + ULONG UnsignedInteger + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = UnsignedInteger; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlEnlargedIntegerMultiply ( + LONG Multiplicand, + LONG Multiplier + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = (LONGLONG) Multiplicand * Multiplier; + + return RC; +} + +ULONG +STDCALL +RtlEnlargedUnsignedDivide ( + ULARGE_INTEGER Dividend, + ULONG Divisor, + PULONG Remainder + ) +{ + if (Remainder) + *Remainder = Dividend.QuadPart % Divisor; + + return (ULONG)(Dividend.QuadPart / Divisor); +} + +LARGE_INTEGER +STDCALL +RtlEnlargedUnsignedMultiply ( + ULONG Multiplicand, + ULONG Multiplier + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = (ULONGLONG) Multiplicand * Multiplier; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlExtendedIntegerMultiply ( + LARGE_INTEGER Multiplicand, + LONG Multiplier + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = Multiplicand.QuadPart * Multiplier; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlExtendedLargeIntegerDivide ( + LARGE_INTEGER Dividend, + ULONG Divisor, + PULONG Remainder + ) +{ + LARGE_INTEGER RC; + + if (Remainder) + *Remainder = Dividend.QuadPart % Divisor; + + RC.QuadPart = Dividend.QuadPart / Divisor; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlExtendedMagicDivide (LARGE_INTEGER Dividend, + LARGE_INTEGER MagicDivisor, + CCHAR ShiftCount) +{ + LARGE_INTEGER Result; + + Result.QuadPart = (Dividend.QuadPart * MagicDivisor.QuadPart) >> ShiftCount; + return(Result); +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerAdd ( + LARGE_INTEGER Addend1, + LARGE_INTEGER Addend2 + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = Addend1.QuadPart + Addend2.QuadPart; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerArithmeticShift ( + LARGE_INTEGER LargeInteger, + CCHAR ShiftCount + ) +{ + LARGE_INTEGER RC; + CHAR Shift; + + Shift = ShiftCount % 64; + + if (Shift < 32) + { + RC.QuadPart = LargeInteger.QuadPart >> Shift; + } + else + { + // copy the sign bit + RC.u.HighPart |= (LargeInteger.u.HighPart & 0x80000000); + RC.u.LowPart = LargeInteger.u.HighPart >> Shift; + } + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerDivide ( + LARGE_INTEGER Dividend, + LARGE_INTEGER Divisor, + PLARGE_INTEGER Remainder + ) +{ + LARGE_INTEGER RC; + + if (Remainder) + Remainder->QuadPart = Dividend.QuadPart % Divisor.QuadPart; + + RC.QuadPart = Dividend.QuadPart / Divisor.QuadPart; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerNegate ( + LARGE_INTEGER Subtrahend + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = - Subtrahend.QuadPart; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerShiftLeft ( + LARGE_INTEGER LargeInteger, + CCHAR ShiftCount + ) +{ + LARGE_INTEGER RC; + CHAR Shift; + + Shift = ShiftCount % 64; + RC.QuadPart = LargeInteger.QuadPart << Shift; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerShiftRight ( + LARGE_INTEGER LargeInteger, + CCHAR ShiftCount + ) +{ + LARGE_INTEGER RC; + CHAR Shift; + + Shift = ShiftCount % 64; + RC.QuadPart = LargeInteger.QuadPart >> ShiftCount; + + return RC; +} + +LARGE_INTEGER +STDCALL +RtlLargeIntegerSubtract ( + LARGE_INTEGER Minuend, + LARGE_INTEGER Subtrahend + ) +{ + LARGE_INTEGER RC; + + RC.QuadPart = Minuend.QuadPart - Subtrahend.QuadPart; + + return RC; +} + */ +/* EOF */ diff --git a/ntoskrnl/rtl/mem.c b/ntoskrnl/rtl/mem.c index dfdbdd7..ecf0384 100644 --- a/ntoskrnl/rtl/mem.c +++ b/ntoskrnl/rtl/mem.c @@ -64,11 +64,9 @@ MmCopyFromCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes) ULONG STDCALL -RtlCompareMemory ( - PVOID Source1, +RtlCompareMemory(PVOID Source1, PVOID Source2, - ULONG Length - ) + ULONG Length) /* * FUNCTION: Compares blocks of memory and returns the number of equal bytes * ARGUMENTS: @@ -78,7 +76,7 @@ RtlCompareMemory ( * RETURNS: Number of equal bytes */ { - int i,total; + ULONG i,total; for (i=0,total=0;i //#include #define NDEBUG #include +#endif + /* GLOBALS *******************************************************************/ BOOLEAN NlsMbCodePageTag = FALSE; diff --git a/ntoskrnl/rtl/string.c b/ntoskrnl/rtl/string.c index 99fd4ee..c7c76a0 100644 --- a/ntoskrnl/rtl/string.c +++ b/ntoskrnl/rtl/string.c @@ -60,7 +60,7 @@ char* _strnset(char* szToFill, int szFill, size_t sizeMaxFill) { char *t = szToFill; int i = 0; - while (*szToFill != 0 && i < sizeMaxFill) + while (*szToFill != 0 && i < (int) sizeMaxFill) { *szToFill = szFill; szToFill++; diff --git a/ntoskrnl/rtl/time.c b/ntoskrnl/rtl/time.c index 333c442..f4e3515 100644 --- a/ntoskrnl/rtl/time.c +++ b/ntoskrnl/rtl/time.c @@ -32,8 +32,8 @@ #define DAYSPERLEAPYEAR 366 #define MONSPERYEAR 12 -#define TICKSTO1970 0x019db1ded53e8000 -#define TICKSTO1980 0x01a8e79fe1d58000 +#define TICKSTO1970 0x019db1ded53e8000LL +#define TICKSTO1980 0x01a8e79fe1d58000LL static const int YearLengths[2] = {DAYSPERNORMALYEAR, DAYSPERLEAPYEAR}; @@ -60,10 +60,9 @@ static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize, VOID STDCALL -RtlTimeToTimeFields ( +RtlTimeToTimeFields( PLARGE_INTEGER liTime, - PTIME_FIELDS TimeFields - ) + PTIME_FIELDS TimeFields) { const int *Months; int LeapSecondCorrections, SecondsInDay, CurYear; @@ -111,13 +110,13 @@ RtlTimeToTimeFields ( /* compute year */ CurYear = EPOCHYEAR; - /* FIXME: handle calendar modifications */ CurYear += Days / DAYSPERLEAPYEAR; Days -= (CurYear - EPOCHYEAR) * DAYSPERLEAPYEAR; CurYear--; /* The next calculation needs CurYear - 1 */ Days += CurYear - CurYear / 4 + CurYear / 100 - CurYear / 400; CurYear++; Days -= EPOCHYEAR - 1 - (EPOCHYEAR -1) / 4 + (EPOCHYEAR -1) / 100 - (EPOCHYEAR - 1) / 400; + /* FIXME: handle calendar modifications */ while (1) { LeapYear = IsLeapYear(CurYear); @@ -141,10 +140,9 @@ RtlTimeToTimeFields ( BOOLEAN STDCALL -RtlTimeFieldsToTime ( +RtlTimeFieldsToTime( PTIME_FIELDS tfTimeFields, - PLARGE_INTEGER Time - ) + PLARGE_INTEGER Time) { int CurMonth; long long int rcTime; @@ -195,10 +193,9 @@ RtlTimeFieldsToTime ( VOID STDCALL -RtlSecondsSince1970ToTime ( +RtlSecondsSince1970ToTime( ULONG SecondsSince1970, - PLARGE_INTEGER Time - ) + PLARGE_INTEGER Time) { LONGLONG llTime; @@ -210,10 +207,9 @@ RtlSecondsSince1970ToTime ( VOID STDCALL -RtlSecondsSince1980ToTime ( +RtlSecondsSince1980ToTime( ULONG SecondsSince1980, - PLARGE_INTEGER Time - ) + PLARGE_INTEGER Time) { LONGLONG llTime; @@ -225,10 +221,9 @@ RtlSecondsSince1980ToTime ( BOOLEAN STDCALL -RtlTimeToSecondsSince1970 ( +RtlTimeToSecondsSince1970( PLARGE_INTEGER Time, - PULONG SecondsSince1970 - ) + PULONG SecondsSince1970) { LARGE_INTEGER liTime; @@ -246,10 +241,9 @@ RtlTimeToSecondsSince1970 ( BOOLEAN STDCALL -RtlTimeToSecondsSince1980 ( +RtlTimeToSecondsSince1980( PLARGE_INTEGER Time, - PULONG SecondsSince1980 - ) + PULONG SecondsSince1980) { LARGE_INTEGER liTime; diff --git a/ntoskrnl/rtl/unicode.c b/ntoskrnl/rtl/unicode.c index 705e7cc..a9ec745 100644 --- a/ntoskrnl/rtl/unicode.c +++ b/ntoskrnl/rtl/unicode.c @@ -26,7 +26,8 @@ /* FUNCTIONS *****************************************************************/ -WCHAR STDCALL +WCHAR +STDCALL RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar) { ULONG Size; @@ -47,7 +48,8 @@ RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar) } -ULONG STDCALL +ULONG +STDCALL RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString) { ULONG Size; @@ -60,7 +62,8 @@ RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString) } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -117,7 +120,8 @@ RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlAppendAsciizToString(IN OUT PSTRING Destination, IN PCSZ Source) { @@ -144,7 +148,8 @@ RtlAppendAsciizToString(IN OUT PSTRING Destination, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlAppendStringToString(IN OUT PSTRING Destination, IN PSTRING Source) { @@ -169,7 +174,8 @@ RtlAppendStringToString(IN OUT PSTRING Destination, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination, IN PUNICODE_STRING Source) { @@ -226,7 +232,8 @@ RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value) @@ -265,7 +272,8 @@ RtlCharToInteger(IN PCSZ String, } -LONG STDCALL +LONG +STDCALL RtlCompareString(IN PSTRING String1, IN PSTRING String2, IN BOOLEAN CaseInsensitive) @@ -310,7 +318,8 @@ RtlCompareString(IN PSTRING String1, } -LONG STDCALL +LONG +STDCALL RtlCompareUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInsensitive) @@ -355,7 +364,8 @@ RtlCompareUnicodeString(IN PUNICODE_STRING String1, } -VOID STDCALL +VOID +STDCALL RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString) { @@ -385,7 +395,8 @@ RtlCopyString(IN OUT PSTRING DestinationString, } -VOID STDCALL +VOID +STDCALL RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString) { @@ -415,7 +426,8 @@ RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination, IN PWSTR Source) { @@ -440,7 +452,8 @@ RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination, IN PCSZ Source) { @@ -458,7 +471,8 @@ RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -510,7 +524,8 @@ RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlEqualString(IN PSTRING String1, IN PSTRING String2, IN BOOLEAN CaseInsensitive) @@ -552,7 +567,8 @@ RtlEqualString(IN PSTRING String1, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlEqualUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInsensitive) @@ -593,7 +609,8 @@ RtlEqualUnicodeString(IN PUNICODE_STRING String1, } -VOID STDCALL +VOID +STDCALL RtlFreeAnsiString(IN PANSI_STRING AnsiString) { if (AnsiString->Buffer == NULL) @@ -607,7 +624,8 @@ RtlFreeAnsiString(IN PANSI_STRING AnsiString) } -VOID STDCALL +VOID +STDCALL RtlFreeOemString(IN POEM_STRING OemString) { if (OemString->Buffer == NULL) @@ -621,7 +639,8 @@ RtlFreeOemString(IN POEM_STRING OemString) } -VOID STDCALL +VOID +STDCALL RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString) { if (UnicodeString->Buffer == NULL) @@ -635,7 +654,8 @@ RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString) } -VOID STDCALL +VOID +STDCALL RtlInitAnsiString(IN OUT PANSI_STRING DestinationString, IN PCSZ SourceString) { @@ -656,7 +676,8 @@ RtlInitAnsiString(IN OUT PANSI_STRING DestinationString, } -VOID STDCALL +VOID +STDCALL RtlInitString(IN OUT PSTRING DestinationString, IN PCSZ SourceString) { @@ -677,7 +698,8 @@ RtlInitString(IN OUT PSTRING DestinationString, } -VOID STDCALL +VOID +STDCALL RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString) { @@ -702,7 +724,8 @@ RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlIntegerToChar(IN ULONG Value, IN ULONG Base, IN ULONG Length, @@ -735,7 +758,7 @@ RtlIntegerToChar(IN ULONG Value, tp++; } - if (tp - temp >= Length) + if ((ULONG) (tp - temp) >= Length) return STATUS_BUFFER_TOO_SMALL; sp = String; @@ -747,7 +770,8 @@ RtlIntegerToChar(IN ULONG Value, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */ IN OUT PUNICODE_STRING String) @@ -775,7 +799,8 @@ RtlIntegerToUnicodeString(IN ULONG Value, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN POEM_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -830,7 +855,8 @@ RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -ULONG STDCALL +ULONG +STDCALL RtlOemStringToUnicodeSize(IN POEM_STRING OemString) { ULONG Size; @@ -843,7 +869,8 @@ RtlOemStringToUnicodeSize(IN POEM_STRING OemString) } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN POEM_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -900,7 +927,8 @@ RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlPrefixString(IN PANSI_STRING String1, IN PANSI_STRING String2, IN BOOLEAN CaseInsensitive) @@ -940,7 +968,8 @@ RtlPrefixString(IN PANSI_STRING String1, } -BOOLEAN STDCALL +BOOLEAN +STDCALL RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInsensitive) @@ -981,7 +1010,8 @@ RtlPrefixUnicodeString(IN PUNICODE_STRING String1, } -ULONG STDCALL +ULONG +STDCALL RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString) { ULONG Size; @@ -994,7 +1024,8 @@ RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString) } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1046,7 +1077,8 @@ RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1108,7 +1140,8 @@ RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base, OUT PULONG Value) @@ -1195,7 +1228,8 @@ RtlUnicodeStringToInteger(IN PUNICODE_STRING String, } -ULONG STDCALL +ULONG +STDCALL RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) { ULONG Size; @@ -1207,7 +1241,8 @@ RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1259,7 +1294,8 @@ RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, } -WCHAR STDCALL +WCHAR +STDCALL RtlUpcaseUnicodeChar(IN WCHAR Source) { if (Source < L'a') @@ -1313,7 +1349,8 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1365,7 +1402,8 @@ RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1426,7 +1464,8 @@ RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, } -NTSTATUS STDCALL +NTSTATUS +STDCALL RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1478,7 +1517,8 @@ RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, } -CHAR STDCALL +CHAR +STDCALL RtlUpperChar(IN CHAR Source) { WCHAR Unicode; @@ -1513,7 +1553,8 @@ RtlUpperChar(IN CHAR Source) } -VOID STDCALL +VOID +STDCALL RtlUpperString(PSTRING DestinationString, PSTRING SourceString) { @@ -1539,31 +1580,35 @@ RtlUpperString(PSTRING DestinationString, } -ULONG STDCALL +ULONG +STDCALL RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString) { - return(RtlAnsiStringToUnicodeSize(AnsiString)); + return RtlAnsiStringToUnicodeSize(AnsiString); } -ULONG STDCALL +ULONG +STDCALL RtlxOemStringToUnicodeSize(IN POEM_STRING OemString) { - return(RtlOemStringToUnicodeSize((PANSI_STRING)OemString)); + return RtlOemStringToUnicodeSize((PANSI_STRING)OemString); } -ULONG STDCALL +ULONG +STDCALL RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString) { - return(RtlUnicodeStringToAnsiSize(UnicodeString)); + return RtlUnicodeStringToAnsiSize(UnicodeString); } -ULONG STDCALL +ULONG +STDCALL RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) { - return(RtlUnicodeStringToOemSize(UnicodeString)); + return RtlUnicodeStringToOemSize(UnicodeString); } /* EOF */ diff --git a/ntoskrnl/rtl/wstring.c b/ntoskrnl/rtl/wstring.c index ee59a51..f576000 100644 --- a/ntoskrnl/rtl/wstring.c +++ b/ntoskrnl/rtl/wstring.c @@ -1,4 +1,5 @@ -/* +/* $Id$ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/rtl/wstring.c @@ -60,7 +61,7 @@ wchar_t *_wcsnset (wchar_t* wsToFill, wchar_t wcFill, size_t sizeMaxFill) { wchar_t *t = wsToFill; int i = 0; - while( *wsToFill != 0 && i < sizeMaxFill) + while( *wsToFill != 0 && i < (int) sizeMaxFill) { *wsToFill = wcFill; wsToFill++; @@ -193,7 +194,7 @@ size_t wcslen(const wchar_t *s) wchar_t * wcsncat(wchar_t *dest, const wchar_t *src, size_t count) { - int i, j; + unsigned int i, j; for (j = 0; dest[j] != 0; j++) ; @@ -224,7 +225,7 @@ int wcsncmp(const wchar_t *cs, const wchar_t *ct, size_t count) wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t count) { - int i; + unsigned int i; for (i = 0; i < count; i++) { @@ -234,7 +235,6 @@ wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t count) return dest; } } - dest[i] = 0; return dest; } diff --git a/rules.mak b/rules.mak index 355c468..23ab1d6 100644 --- a/rules.mak +++ b/rules.mak @@ -8,6 +8,11 @@ ifeq ($(HOST),) HOST = mingw32-windows endif +# Default to no PCH support +ifeq ($(ROS_USE_PCH),) +ROS_USE_PCH = no +endif + # uncomment if you use bochs and it displays only 30 rows # BOCHS_30ROWS = yes @@ -77,6 +82,7 @@ RM = $(TOOLS_PATH)/rdel RMDIR = $(TOOLS_PATH)/rrmdir RMKDIR = $(TOOLS_PATH)/rmkdir RSYM = $(TOOLS_PATH)/rsym +RTOUCH = $(TOOLS_PATH)/rtouch MC = $(TOOLS_PATH)/wmc/wmc @@ -114,3 +120,24 @@ XDK_PATH_INC=$(XDK_PATH)/include WINE_PATH=$(PATH_TO_TOP)/../wine WINE_PATH_LIB=$(WINE_PATH)/lib WINE_PATH_INC=$(WINE_PATH)/include + +# Posix+ Integration +POSIX_PATH=$(PATH_TO_TOP)/../posix +POSIX_PATH_LIB=$(POSIX_PATH)/lib +POSIX_PATH_INC=$(POSIX_PATH)/include + +# OS/2 Integration +OS2_PATH=$(PATH_TO_TOP)/../os2 +OS2_PATH_LIB=$(OS2_PATH)/lib +OS2_PATH_INC=$(OS2_PATH)/include + +# Other systems integration +ROOT_PATH=$(PATH_TO_TOP)/.. + +COMCTL32_TARGET = comctl23 + +SHELL32_TARGET = shell23 + +COMDLG32_TARGET = comdlg23 + + diff --git a/services/eventlog/.cvsignore b/services/eventlog/.cvsignore index b349ee7..4ed488e 100644 --- a/services/eventlog/.cvsignore +++ b/services/eventlog/.cvsignore @@ -2,3 +2,4 @@ eventlog.coff *.d *.o *.sym +*.exe diff --git a/services/eventlog/eventlog.rc b/services/eventlog/eventlog.rc index fff9e1d..6e45fc9 100644 --- a/services/eventlog/eventlog.rc +++ b/services/eventlog/eventlog.rc @@ -1,5 +1,5 @@ -#include "../../include/defines.h" -#include "../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/services/rpcss/.cvsignore b/services/rpcss/.cvsignore index ff4292b..1d15953 100644 --- a/services/rpcss/.cvsignore +++ b/services/rpcss/.cvsignore @@ -2,3 +2,4 @@ rpcss.coff *.d *.o *.sym +*.exe diff --git a/services/rpcss/rpcss.rc b/services/rpcss/rpcss.rc index 5cd1dba..df3b65b 100644 --- a/services/rpcss/rpcss.rc +++ b/services/rpcss/rpcss.rc @@ -1,5 +1,5 @@ -#include "../../include/defines.h" -#include "../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/subsys/csrss/api.h b/subsys/csrss/api.h index e70bc96..c880c22 100644 --- a/subsys/csrss/api.h +++ b/subsys/csrss/api.h @@ -73,7 +73,7 @@ typedef struct CSRSS_CONSOLE_t BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ } CSRSS_CONSOLE, *PCSRSS_CONSOLE; -typedef struct +typedef struct _CSRSS_PROCESS_DATA { PCSRSS_CONSOLE Console; ULONG HandleTableSize; @@ -84,6 +84,7 @@ typedef struct HANDLE ConsoleEvent; PVOID CsrSectionViewBase; ULONG CsrSectionViewSize; + struct _CSRSS_PROCESS_DATA * next; } CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA; #define CSR_API(n) NTSTATUS n (\ @@ -129,6 +130,8 @@ CSR_API(CsrExitReactos); CSR_API(CsrGetShutdownParameters); CSR_API(CsrSetShutdownParameters); CSR_API(CsrPeekConsoleInput); +CSR_API(CsrReadConsoleOutput); +CSR_API(CsrWriteConsoleInput); /* print.c */ VOID STDCALL DisplayString(LPCWSTR lpwString); diff --git a/subsys/csrss/api/conio.c b/subsys/csrss/api/conio.c index 74f5647..4ae0b43 100644 --- a/subsys/csrss/api/conio.c +++ b/subsys/csrss/api/conio.c @@ -573,11 +573,16 @@ static VOID CsrpDrawRegion( return; } - /* wrap back around the end of the buffer */ - if( ++y == ScreenBuffer->MaxY ) - y = 0; - - SrcOffset += SrcDelta; + /* wrap back around the end of the buffer */ + if( ++y == ScreenBuffer->MaxY ) + { + y = 0; + SrcOffset = Region.Left * 2; + } + else + { + SrcOffset += SrcDelta; + } } Mode.dwMode = ENABLE_PROCESSED_OUTPUT; Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, @@ -634,7 +639,7 @@ NTSTATUS STDCALL CsrInitConsoleScreenBuffer( PCSRSS_SCREEN_BUFFER Console ) Console->Header.Type = CSRSS_SCREEN_BUFFER_MAGIC; Console->Header.ReferenceCount = 0; Console->MaxX = PhysicalConsoleSize.X; - Console->MaxY = PhysicalConsoleSize.Y * 2; + Console->MaxY = PhysicalConsoleSize.Y; Console->ShowX = 0; Console->ShowY = 0; Console->CurrentX = 0; @@ -1247,7 +1252,6 @@ CSR_API(CsrFillOutputChar) } X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX; Y = Request->Data.FillOutputRequest.Position.Y + Buff->ShowY; - for( i = 0; i < 20000; i++ ); for( i = 0; i < Request->Data.FillOutputRequest.Length; i++ ) { Buff->Buffer[ (Y * 2 * Buff->MaxX) + (X * 2) ] = Request->Data.FillOutputRequest.Char; @@ -1764,6 +1768,8 @@ CSR_API(CsrWriteConsoleOutput) UNLOCK; Reply->Data.WriteConsoleOutputReply.WriteRegion.Right = WriteRegion.Left + SizeX - 1; Reply->Data.WriteConsoleOutputReply.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + Reply->Data.WriteConsoleOutputReply.WriteRegion.Left = WriteRegion.Left; + Reply->Data.WriteConsoleOutputReply.WriteRegion.Top = WriteRegion.Top; return (Reply->Status = STATUS_SUCCESS); } @@ -2147,4 +2153,157 @@ CSR_API(CsrPeekConsoleInput) return Reply->Status; } + +CSR_API(CsrReadConsoleOutput) +{ + PCHAR_INFO CharInfo; + PCHAR_INFO CurCharInfo; + PCSRSS_SCREEN_BUFFER ScreenBuffer; + DWORD Size; + DWORD Length; + DWORD SizeX, SizeY; + NTSTATUS Status; + COORD BufferSize; + COORD BufferCoord; + SMALL_RECT ReadRegion; + SMALL_RECT ScreenRect; + DWORD i, Y, X, Offset; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + LOCK; + + Status = CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, (Object_t**)&ScreenBuffer); + if(!NT_SUCCESS(Status)) + { + Reply->Status = Status; + UNLOCK; + return Reply->Status; + } + + if(ScreenBuffer->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC) + { + Reply->Status = STATUS_INVALID_HANDLE; + UNLOCK; + return Reply->Status; + } + + CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; + ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; + BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; + BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; + Length = BufferSize.X * BufferSize.Y; + Size = Length * sizeof(INPUT_RECORD); + + if(((PVOID)CharInfo < ProcessData->CsrSectionViewBase) + || (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + UNLOCK; + Reply->Status = STATUS_ACCESS_VIOLATION; + return Reply->Status ; + } + + SizeY = RtlMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(ReadRegion)); + SizeX = RtlMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(ReadRegion)); + ReadRegion.Bottom = ReadRegion.Top + SizeY; + ReadRegion.Right = ReadRegion.Left + SizeX; + + CsrpInitRect(ScreenRect, 0, 0, ScreenBuffer->MaxY - 1, ScreenBuffer->MaxX - 1); + if (!CsrpGetIntersection(&ReadRegion, ScreenRect, ReadRegion)) + { + UNLOCK; + Reply->Status = STATUS_SUCCESS; + return Reply->Status; + } + + for(i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) + { + CurCharInfo = CharInfo + (i * BufferSize.Y); + + Offset = (Y * ScreenBuffer->MaxX + ReadRegion.Left) * 2; + for(X = ReadRegion.Left; X < ReadRegion.Right; ++X) + { + CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(ScreenBuffer, Offset); + CurCharInfo->Attributes = GET_CELL_BUFFER(ScreenBuffer, Offset); + ++CurCharInfo; + } + } + + UNLOCK; + + Reply->Status = STATUS_SUCCESS; + Reply->Data.ReadConsoleOutputReply.ReadRegion.Right = ReadRegion.Left + SizeX - 1; + Reply->Data.ReadConsoleOutputReply.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; + Reply->Data.ReadConsoleOutputReply.ReadRegion.Left = ReadRegion.Left; + Reply->Data.ReadConsoleOutputReply.ReadRegion.Top = ReadRegion.Top; + + return Reply->Status; +} + + +CSR_API(CsrWriteConsoleInput) +{ + PINPUT_RECORD InputRecord; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + DWORD Length; + DWORD Size; + DWORD i; + PLIST_ENTRY NextItem; + ConsoleInput* Record; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + LOCK; + + Status = CsrGetObject(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, (Object_t**)&Console); + if(!NT_SUCCESS(Status)) + { + Reply->Status = Status; + UNLOCK; + return Reply->Status; + } + + if(Console->Header.Type != CSRSS_CONSOLE_MAGIC) + { + Reply->Status = STATUS_INVALID_HANDLE; + UNLOCK; + return Reply->Status; + } + + InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; + Length = Request->Data.WriteConsoleInputRequest.Length; + Size = Length * sizeof(INPUT_RECORD); + + if(((PVOID)InputRecord < ProcessData->CsrSectionViewBase) + || (((PVOID)InputRecord + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) + { + UNLOCK; + Reply->Status = STATUS_ACCESS_VIOLATION; + return Reply->Status ; + } + + for(i = 0; i < Length; ++i) + { + Record = RtlAllocateHeap(CsrssApiHeap, 0, sizeof(ConsoleInput)); + if(Record == NULL) + { + UNLOCK; + Reply->Status = STATUS_INSUFFICIENT_RESOURCES; + return Reply->Status; + } + + Record->InputEvent = *InputRecord++; + InsertTailList(&Console->InputEvents, &Record->ListEntry); + } + + UNLOCK; + + Reply->Status = STATUS_SUCCESS; + Reply->Data.WriteConsoleInputReply.Length = i; + return Reply->Status; +} + /* EOF */ diff --git a/subsys/csrss/api/process.c b/subsys/csrss/api/process.c index 9cc6b34..4e42f94 100644 --- a/subsys/csrss/api/process.c +++ b/subsys/csrss/api/process.c @@ -31,13 +31,6 @@ CRITICAL_SECTION ProcessDataLock; VOID STDCALL CsrInitProcessData(VOID) { -/* ULONG i; - - for (i=0; i<256; i++) - { - ProcessData[i] = NULL; - } -*/ RtlZeroMemory (ProcessData, sizeof ProcessData); NrProcess = sizeof ProcessData / sizeof ProcessData[0]; RtlInitializeCriticalSection( &ProcessDataLock ); @@ -46,68 +39,96 @@ VOID STDCALL CsrInitProcessData(VOID) PCSRSS_PROCESS_DATA STDCALL CsrGetProcessData(ULONG ProcessId) { ULONG i; + ULONG hash; + PCSRSS_PROCESS_DATA pProcessData; + hash = ProcessId % (sizeof(ProcessData) / sizeof(*ProcessData)); + LOCK; - for (i=0; iProcessId == ProcessId) - { - UNLOCK; - return(ProcessData[i]); - } - } - for (i=0; iProcessId = ProcessId; - UNLOCK; - return(ProcessData[i]); - } - } -// DbgPrint("CSR: CsrGetProcessData() failed\n"); + + pProcessData = ProcessData[hash]; + + while (pProcessData && pProcessData->ProcessId != ProcessId) + { + pProcessData = pProcessData->next; + } + if (pProcessData == NULL) + { + pProcessData = RtlAllocateHeap(CsrssApiHeap, + HEAP_ZERO_MEMORY, + sizeof(CSRSS_PROCESS_DATA)); + if (pProcessData) + { + pProcessData->ProcessId = ProcessId; + pProcessData->next = ProcessData[hash]; + ProcessData[hash] = pProcessData; + } + } UNLOCK; - return(NULL); + if (pProcessData == NULL) + { + DbgPrint("CSR: CsrGetProcessData() failed\n"); + } + return pProcessData; } NTSTATUS STDCALL CsrFreeProcessData(ULONG Pid) { - int i; + ULONG hash; + int c; + PCSRSS_PROCESS_DATA pProcessData, pPrevProcessData = NULL; + + hash = Pid % (sizeof(ProcessData) / sizeof(*ProcessData)); + LOCK; - for( i = 0; i < NrProcess; i++ ) + + pProcessData = ProcessData[hash]; + + while (pProcessData && pProcessData->ProcessId != Pid) + { + pPrevProcessData = pProcessData; + pProcessData = pProcessData->next; + } + + if (pProcessData) + { + //DbgPrint("CsrFreeProcessData pid: %d\n", Pid); + W32kCleanupForProcess(Pid); //should check if win32k process + if (pProcessData->HandleTable) { - if( ProcessData[i] && ProcessData[i]->ProcessId == Pid ) + for( c = 0; c < pProcessData->HandleTableSize; c++ ) + { + if( pProcessData->HandleTable[c] ) { - //DbgPrint("CsrFreeProcessData pid: %d\n", Pid); - W32kCleanupForProcess( Pid ); //should check if win32k process - if( ProcessData[i]->HandleTable ) - { - int c; - for( c = 0; c < ProcessData[i]->HandleTableSize; c++ ) - if( ProcessData[i]->HandleTable[c] ) - CsrReleaseObject( ProcessData[i], (HANDLE)((c + 1) << 2) ); - RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i]->HandleTable ); - } - if( ProcessData[i]->Console ) - { - if( InterlockedDecrement( &(ProcessData[i]->Console->Header.ReferenceCount) ) == 0 ) - CsrDeleteConsole( ProcessData[i]->Console ); - } - RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i] ); - ProcessData[i] = 0; - UNLOCK; - return STATUS_SUCCESS; + CsrReleaseObject( pProcessData, (HANDLE)((c + 1) << 2) ); } + } + RtlFreeHeap( CsrssApiHeap, 0, pProcessData->HandleTable ); + } + if( pProcessData->Console ) + { + if( InterlockedDecrement( &(pProcessData->Console->Header.ReferenceCount) ) == 0 ) + { + CsrDeleteConsole( pProcessData->Console ); + } } + if (pProcessData->CsrSectionViewBase) + { + NtUnmapViewOfSection(NtCurrentProcess(), pProcessData->CsrSectionViewBase); + } + if (pPrevProcessData) + { + pPrevProcessData->next = pProcessData->next; + } + else + { + ProcessData[hash] = pProcessData->next; + } + + RtlFreeHeap( CsrssApiHeap, 0, pProcessData ); + UNLOCK; + return STATUS_SUCCESS; + } UNLOCK; return STATUS_INVALID_PARAMETER; } @@ -201,6 +222,7 @@ CSR_API(CsrCreateProcess) } else Reply->Data.CreateProcessReply.OutputHandle = Reply->Data.CreateProcessReply.InputHandle = INVALID_HANDLE_VALUE; + Reply->Status = STATUS_SUCCESS; return(STATUS_SUCCESS); } diff --git a/subsys/csrss/api/wapi.c b/subsys/csrss/api/wapi.c index 745b192..17459e6 100644 --- a/subsys/csrss/api/wapi.c +++ b/subsys/csrss/api/wapi.c @@ -61,6 +61,8 @@ static const CsrFunc CsrFuncs[] = { CsrGetShutdownParameters, CsrSetShutdownParameters, CsrPeekConsoleInput, + CsrReadConsoleOutput, + CsrWriteConsoleInput, 0 }; static void Thread_Api2(HANDLE ServerPort) diff --git a/subsys/csrss/csrss.def b/subsys/csrss/csrss.def new file mode 100644 index 0000000..292c1aa --- /dev/null +++ b/subsys/csrss/csrss.def @@ -0,0 +1,8 @@ +; $Id$ +; + +LIBRARY csrss.exe + +EXPORTS + +CsrServerInitialization diff --git a/subsys/csrss/csrss.edf b/subsys/csrss/csrss.edf new file mode 100644 index 0000000..ce21b2f --- /dev/null +++ b/subsys/csrss/csrss.edf @@ -0,0 +1,9 @@ +; $Id$ +; +; + +LIBRARY csrss.exe + +EXPORTS + +CsrServerInitialization=CsrServerInitialization@8 diff --git a/subsys/csrss/csrss.rc b/subsys/csrss/csrss.rc index c2ecd4d..4cd0488 100644 --- a/subsys/csrss/csrss.rc +++ b/subsys/csrss/csrss.rc @@ -1,5 +1,5 @@ -#include "../../include/defines.h" -#include "../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/subsys/csrss/makefile b/subsys/csrss/makefile index 4cb75b3..591ce02 100644 --- a/subsys/csrss/makefile +++ b/subsys/csrss/makefile @@ -2,7 +2,8 @@ PATH_TO_TOP = ../.. -TARGET_TYPE = program +#TARGET_TYPE = program +TARGET_TYPE = proglib TARGET_APPTYPE = native diff --git a/subsys/ntvdm/ntvdm.c b/subsys/ntvdm/ntvdm.c index 188d562..1f70f78 100644 --- a/subsys/ntvdm/ntvdm.c +++ b/subsys/ntvdm/ntvdm.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: subsys/ntvdm/ntvdm.c + * FILE: subsys/ntvdm/ntvdm->c * PURPOSE: Virtual DOS Machine * PROGRAMMER: Robert Dickenson (robd@mok.lvcm.com) * UPDATE HISTORY: @@ -62,19 +62,40 @@ NtUnmapViewOfSection NtVdmControl */ +typedef struct tag_VDM_CONFIG { + int dos_options; + int files; + int buffers; + WCHAR** device_list; +//dos=high, umb +//device=%SystemRoot%\system32\himem.sys +//files=40 +} VDM_CONFIG, *PVDM_CONFIG; -BOOLEAN -StartVirtualMachine(VOID) +typedef struct tag_VDM_AUTOEXEC { + WCHAR** load_list; +//lh %SystemRoot%\system32\mscdexnt.exe +//lh %SystemRoot%\system32\redir +//lh %SystemRoot%\system32\dosx +} VDM_AUTOEXEC, *PVDM_AUTOEXEC; + +typedef struct tag_VDM_CONTROL_BLOCK { + HANDLE hHeap; + PVOID ImageMem; + VDM_CONFIG vdmConfig; + VDM_AUTOEXEC vdmAutoexec; + PROCESS_INFORMATION ProcessInformation; + CHAR CommandLine[MAX_PATH]; + CHAR CurrentDirectory[MAX_PATH]; + +} VDM_CONTROL_BLOCK, *PVDM_CONTROL_BLOCK; + + +BOOL +StartVDM(PVDM_CONTROL_BLOCK vdm) { - BOOLEAN Result; + BOOL Result; STARTUPINFO StartupInfo; - PROCESS_INFORMATION ProcessInformation; - CHAR CommandLine[MAX_PATH]; - CHAR CurrentDirectory[MAX_PATH]; - - GetSystemDirectory(CommandLine, MAX_PATH); - strcat(CommandLine, "\\hello.exe"); - GetWindowsDirectory(CurrentDirectory, MAX_PATH); StartupInfo.cb = sizeof(StartupInfo); StartupInfo.lpReserved = NULL; @@ -84,7 +105,7 @@ StartVirtualMachine(VOID) StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = 0; - Result = CreateProcess(CommandLine, + Result = CreateProcess(vdm->CommandLine, NULL, NULL, NULL, @@ -93,35 +114,205 @@ StartVirtualMachine(VOID) NULL, NULL, &StartupInfo, - &ProcessInformation); + &vdm->ProcessInformation); if (!Result) { - PrintString("WL: Failed to execute target process\n"); + PrintString("VDM: Failed to execute target process\n"); + return FALSE; + } + WaitForSingleObject(vdm->ProcessInformation.hProcess, INFINITE); + CloseHandle(vdm->ProcessInformation.hProcess); + CloseHandle(vdm->ProcessInformation.hThread); + return TRUE; +} + +BOOL +ShutdownVDM(PVDM_CONTROL_BLOCK vdm) +{ + BOOL result = TRUE; + + return result; +} + +BOOL ReadConfigForVDM(PVDM_CONTROL_BLOCK vdm) +{ + BOOL result = TRUE; + DWORD dwError; + HANDLE hFile; + + hFile = CreateFileW(L"\\system32\\config.nt", + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS /*OPEN_EXISTING*/, + FILE_ATTRIBUTE_NORMAL, + 0); + dwError = GetLastError(); + if (hFile == INVALID_HANDLE_VALUE) { + // error with file path or system problem? + } else { + if (dwError == 0L) { + // we just created a new file, perhaps we should set/write some defaults? + } + if (dwError == ERROR_ALREADY_EXISTS) { + // read the line entries and cache in some struct... + } + CloseHandle(hFile); + } + + hFile = CreateFileW(L"\\system32\\autoexec.nt", + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + dwError = GetLastError(); + if (hFile == INVALID_HANDLE_VALUE) { + // error with file path or system problem? + } else { + if (dwError == 0L) { + // we just created a new file, perhaps we should set/write some defaults? + } + if (dwError == ERROR_ALREADY_EXISTS) { + // read the line entries and cache in some struct... + } + CloseHandle(hFile); + } + + return result; +} + +BOOL +LoadConfigDriversForVDM(PVDM_CONFIG vdmConfig) +{ + BOOL result = TRUE; + + return result; +} + +BOOL +SetConfigOptionsForVDM(PVDM_AUTOEXEC vdmAutoexec) +{ + BOOL result = TRUE; + + return result; +} + +BOOL +CreateVDM(PVDM_CONTROL_BLOCK vdm) +{ +// BOOL result = TRUE; + SYSTEM_INFO inf; + MEMORYSTATUS stat; + PVOID lpMem = NULL; + + GlobalMemoryStatus(&stat); + if (stat.dwLength != sizeof(MEMORYSTATUS)) { + printf("WARNING: GlobalMemoryStatus() returned unknown structure version, size %ld, expected %d.\n", stat.dwLength, sizeof(stat)); + } else { + printf("Memory Load: %ld percent in use.\n", stat.dwMemoryLoad); + printf("\t%ld total bytes physical memory.\n", stat.dwTotalPhys); + printf("\t%ld available physical memory.\n", stat.dwAvailPhys); + printf("\t%ld total bytes paging file.\n", stat.dwTotalPageFile); + printf("\t%ld available paging file.\n", stat.dwAvailPageFile); + printf("\t%lx total bytes virtual memory.\n", stat.dwTotalVirtual); + printf("\t%lx available bytes virtual memory.\n", stat.dwAvailVirtual); + +#define OUT_OF_HEADROOM 90 + if (stat.dwMemoryLoad > OUT_OF_HEADROOM) { + DPRINT("VDM: system resources deemed to low to start VDM.\n"); + //SetLastError(); + return FALSE; + } + } + + GetSystemInfo(&inf); + vdm->hHeap = HeapCreate(0, inf.dwAllocationGranularity, 0); + if (vdm->hHeap == NULL) { + DPRINT("VDM: failed to create heap.\n"); + return FALSE; + } + +#define DEFAULT_VDM_IMAGE_SIZE 2000000 + vdm->ImageMem = HeapAlloc(vdm->hHeap, 0, DEFAULT_VDM_IMAGE_SIZE); + if (vdm->ImageMem == NULL) { + DPRINT("VDM: failed to allocate image memory from heap %x.\n", vdm->hHeap); + HeapDestroy(vdm->hHeap); + vdm->hHeap = NULL; return FALSE; } - WaitForSingleObject(ProcessInformation.hProcess, INFINITE); - CloseHandle(ProcessInformation.hProcess); - CloseHandle(ProcessInformation.hThread); return TRUE; } +BOOL +DestroyVDM(PVDM_CONTROL_BLOCK vdm) +{ + BOOL result = TRUE; + + if (vdm->ImageMem != NULL) { + if (HeapFree(vdm->hHeap, 0, vdm->ImageMem) != FALSE) { + DPRINT("VDM: failed to free memory from heap %x.\n", vdm->hHeap); + result = FALSE; + } + vdm->ImageMem = NULL; + } + if (vdm->hHeap != NULL) { + if (!HeapDestroy(vdm->hHeap)) { + DPRINT("VDM: failed to destroy heap %x.\n", vdm->hHeap); + result = FALSE; + } + vdm->hHeap = NULL; + } + return result; +} + int STDCALL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { + VDM_CONTROL_BLOCK VdmCB; DWORD Result; BOOL Success; ULONG i; NTSTATUS Status; + BOOL vdmStarted = FALSE; - CHAR WelcomeMsg[] = "ReactOS Virtual DOS Machine support.\nType q to quit."; + CHAR WelcomeMsg[] = "ReactOS Virtual DOS Machine support.\n"; + CHAR PromptMsg[] = "Type r to run, s to shutdown or q to quit now."; CHAR InputBuffer[255]; AllocConsole(); SetConsoleTitle("ntvdm"); - StartVirtualMachine(); - + + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), + WelcomeMsg, strlen(WelcomeMsg), // wcslen(WelcomeMsg), + &Result, NULL); + + if (!CreateVDM(&VdmCB)) { + DPRINT("VDM: failed to create VDM.\n"); + //SetLastError(); + return 2; + } + + ReadConfigForVDM(&VdmCB); + + if (!LoadConfigDriversForVDM(&(VdmCB.vdmConfig))) { + DPRINT("VDM: failed to load configuration drivers.\n"); + //SetLastError(); + return 2; + } + if (!SetConfigOptionsForVDM(&(VdmCB.vdmAutoexec))) { + DPRINT("VDM: failed to set configuration options.\n"); + //SetLastError(); + return 3; + } + + GetSystemDirectory(VdmCB.CommandLine, MAX_PATH); + strcat(VdmCB.CommandLine, "\\hello.exe"); + GetWindowsDirectory(VdmCB.CurrentDirectory, MAX_PATH); + for (;;) { WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - WelcomeMsg, strlen(WelcomeMsg), // wcslen(WelcomeMsg), + PromptMsg, strlen(PromptMsg), // wcslen(PromptMsg), &Result, NULL); i = 0; do { @@ -134,11 +325,45 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho } while (InputBuffer[i - 1] != '\n'); InputBuffer[i - 1] = '\0'; + if (InputBuffer[0] == 'r' || InputBuffer[0] == 'R') { + if (!vdmStarted) { + if (StartVDM(&VdmCB)) { + vdmStarted = TRUE; + } else { + DPRINT("VDM: failed to start.\n"); + } + } else { + DPRINT("VDM: already started.\n"); + } + } + if (InputBuffer[0] == 's' || InputBuffer[0] == 'S') { + if (vdmStarted) { + if (ShutdownVDM(&VdmCB)) { + vdmStarted = FALSE; + } else { + DPRINT("VDM: failed to shutdown.\n"); + } + } else { + DPRINT("VDM: not started.\n"); + } + } if (InputBuffer[0] == 'q' || InputBuffer[0] == 'Q') { break; } } + if (!ShutdownVDM(&VdmCB)) { + DPRINT("VDM: failed to cleanly shutdown VDM.\n"); + //SetLastError(); + return 5; + } + + if (!DestroyVDM(&VdmCB)) { + DPRINT("VDM: failed to cleanly destroy VDM.\n"); + //SetLastError(); + return 6; + } + ExitProcess(0); return 0; } diff --git a/subsys/system/gstart/gstart.rc b/subsys/system/gstart/gstart.rc index 0982e26..9e541ab 100644 --- a/subsys/system/gstart/gstart.rc +++ b/subsys/system/gstart/gstart.rc @@ -1,5 +1,5 @@ -#include "../../../include/defines.h" -#include "../../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/subsys/system/services/services.c b/subsys/system/services/services.c index e15ce08..c2d17cc 100644 --- a/subsys/system/services/services.c +++ b/subsys/system/services/services.c @@ -53,14 +53,14 @@ void PrintString(char* fmt,...) { #ifdef DBG - char buffer[512]; - va_list ap; + char buffer[512]; + va_list ap; - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsprintf(buffer, fmt, ap); + va_end(ap); - OutputDebugStringA(buffer); + OutputDebugStringA(buffer); #endif } @@ -68,169 +68,192 @@ PrintString(char* fmt,...) BOOL ScmCreateStartEvent(PHANDLE StartEvent) { - HANDLE hEvent; - - hEvent = CreateEvent(NULL, - TRUE, - FALSE, - _T("SvcctrlStartEvent_A3725DX")); - if (hEvent == NULL) - { - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - hEvent = OpenEvent(EVENT_ALL_ACCESS, - FALSE, - _T("SvcctrlStartEvent_A3725DX")); - if (hEvent == NULL) - { - return(FALSE); - } - } - else - { - return(FALSE); - } + HANDLE hEvent; + + hEvent = CreateEvent(NULL, + TRUE, + FALSE, + _T("SvcctrlStartEvent_A3725DX")); + if (hEvent == NULL) { + if (GetLastError() == ERROR_ALREADY_EXISTS) { + hEvent = OpenEvent(EVENT_ALL_ACCESS, + FALSE, + _T("SvcctrlStartEvent_A3725DX")); + if (hEvent == NULL) { + return FALSE; + } + } else { + return FALSE; + } } - - *StartEvent = hEvent; - - return(TRUE); + *StartEvent = hEvent; + return TRUE; } BOOL ScmNamedPipeHandleRequest( - PVOID Request, - DWORD RequestSize, - PVOID Reply, - LPDWORD ReplySize) + PVOID Request, + DWORD RequestSize, + PVOID Reply, + LPDWORD ReplySize) { - DbgPrint("SCM READ: %s\n", Request); - - *ReplySize = 0; + DbgPrint("SCM READ: %s\n", Request); - return FALSE; + *ReplySize = 0; + return FALSE; } DWORD WINAPI -ScmNamedPipeThread( - LPVOID Context) +ScmNamedPipeThread(LPVOID Context) { - CHAR chRequest[PIPE_BUFSIZE]; - CHAR chReply[PIPE_BUFSIZE]; - DWORD cbReplyBytes; - DWORD cbBytesRead; - DWORD cbWritten; - BOOL fSuccess; - HANDLE hPipe; - - DPRINT("Accepting SCM commands through named pipe\n"); - - hPipe = (HANDLE)Context; - - for (;;) - { - fSuccess = ReadFile( - hPipe, - &chRequest, - PIPE_BUFSIZE, - &cbBytesRead, - NULL); - if (!fSuccess || cbBytesRead == 0) - { - break; + CHAR chRequest[PIPE_BUFSIZE]; + CHAR chReply[PIPE_BUFSIZE]; + DWORD cbReplyBytes; + DWORD cbBytesRead; + DWORD cbWritten; + BOOL fSuccess; + HANDLE hPipe; + + hPipe = (HANDLE)Context; + + DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe); + + for (;;) { + fSuccess = ReadFile(hPipe, + &chRequest, + PIPE_BUFSIZE, + &cbBytesRead, + NULL); + if (!fSuccess || cbBytesRead == 0) { + break; + } + if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) { + fSuccess = WriteFile(hPipe, + &chReply, + cbReplyBytes, + &cbWritten, + NULL); + if (!fSuccess || cbReplyBytes != cbWritten) { + break; + } + } } - - if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) - { - fSuccess = WriteFile( - hPipe, - &chReply, - cbReplyBytes, - &cbWritten, - NULL); - if (!fSuccess || cbReplyBytes != cbWritten) - { - break; - } - } - } - - FlushFileBuffers(hPipe); - DisconnectNamedPipe(hPipe); - CloseHandle(hPipe); - - return ERROR_SUCCESS; + DPRINT("ScmNamedPipeThread(%x) - Disconnecting named pipe connection\n", hPipe); + FlushFileBuffers(hPipe); + DisconnectNamedPipe(hPipe); + CloseHandle(hPipe); + DPRINT("ScmNamedPipeThread(%x) - Done.\n", hPipe); + return ERROR_SUCCESS; } - BOOL ScmCreateNamedPipe(VOID) { - DWORD dwThreadId; - BOOL fConnected; - HANDLE hThread; - HANDLE hPipe; - - hPipe = CreateNamedPipe("\\\\.\\pipe\\Ntsvcs", - PIPE_ACCESS_DUPLEX, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - PIPE_BUFSIZE, - PIPE_BUFSIZE, - PIPE_TIMEOUT, - NULL); - if (hPipe == INVALID_HANDLE_VALUE) - { - DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError()); - return(FALSE); + DWORD dwThreadId; + BOOL fConnected; + HANDLE hThread; + HANDLE hPipe; + + DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n"); + + hPipe = CreateNamedPipe("\\\\.\\pipe\\Ntsvcs", + PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + PIPE_BUFSIZE, + PIPE_BUFSIZE, + PIPE_TIMEOUT, + NULL); + if (hPipe == INVALID_HANDLE_VALUE) { + DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError()); + return FALSE; } - fConnected = ConnectNamedPipe(hPipe, - NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); - if (fConnected) - { - DPRINT("Pipe connected\n"); - - hThread = CreateThread(NULL, - 0, - ScmNamedPipeThread, - (LPVOID)hPipe, - 0, - &dwThreadId); - if (!hThread) - { - DPRINT("Could not create thread (%d)\n", GetLastError()); - - DisconnectNamedPipe(hPipe); - CloseHandle(hPipe); - return(FALSE); - } + DPRINT("CreateNamedPipe() - calling ConnectNamedPipe(%x)\n", hPipe); + fConnected = ConnectNamedPipe(hPipe, + NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); + DPRINT("CreateNamedPipe() - ConnectNamedPipe() returned %d\n", fConnected); + + if (fConnected) { + DPRINT("Pipe connected\n"); + hThread = CreateThread(NULL, + 0, + ScmNamedPipeThread, + (LPVOID)hPipe, + 0, + &dwThreadId); + if (!hThread) { + DPRINT("Could not create thread (%d)\n", GetLastError()); + DisconnectNamedPipe(hPipe); + CloseHandle(hPipe); + DPRINT("CreateNamedPipe() - returning FALSE\n"); + return FALSE; + } + } else { + DPRINT("Pipe not connected\n"); + CloseHandle(hPipe); + DPRINT("CreateNamedPipe() - returning FALSE\n"); + return FALSE; } - else - { - DPRINT("Pipe not connected\n"); + DPRINT("CreateNamedPipe() - returning TRUE\n"); + return TRUE; +} - CloseHandle(hPipe); - return FALSE; +DWORD +WINAPI +ScmNamedPipeListenerThread(LPVOID Context) +{ +// HANDLE hPipe; + DPRINT("ScmNamedPipeListenerThread(%x) - aka SCM.\n", Context); + +// hPipe = (HANDLE)Context; + for (;;) { + PrintString("SCM: Waiting for new connection on named pipe...\n"); + /* Create named pipe */ + if (!ScmCreateNamedPipe()) { + PrintString("\nSCM: Failed to create named pipe\n"); + break; + //ExitThread(0); + } + PrintString("\nSCM: named pipe session created.\n"); + Sleep(10); } - - return TRUE; + DPRINT("\n\nWARNING: ScmNamedPipeListenerThread(%x) - Aborted.\n\n", Context); + return ERROR_SUCCESS; } +BOOL StartScmNamedPipeThreadListener(void) +{ + DWORD dwThreadId; + HANDLE hThread; + + hThread = CreateThread(NULL, + 0, + ScmNamedPipeListenerThread, + NULL, /*(LPVOID)hPipe,*/ + 0, + &dwThreadId); + + if (!hThread) { + PrintString("SERVICES: Could not create thread (Status %lx)\n", GetLastError()); + return FALSE; + } + return TRUE; +} int STDCALL WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nShowCmd) + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) { HANDLE hScmStartEvent; HANDLE hEvent; NTSTATUS Status; - PrintString("Service Control Manager\n"); + PrintString("SERVICES: Service Control Manager\n"); /* Create start event */ if (!ScmCreateStartEvent(&hScmStartEvent)) @@ -239,6 +262,7 @@ WinMain(HINSTANCE hInstance, ExitThread(0); } + PrintString("SERVICES: created start event with handle %x.\n", hScmStartEvent); /* FIXME: more initialization */ @@ -247,7 +271,7 @@ WinMain(HINSTANCE hInstance, Status = ScmCreateServiceDataBase(); if (!NT_SUCCESS(Status)) { - PrintString("ScmCreateServiceDataBase() failed (Status %lx)\n", Status); + PrintString("SERVICES: failed to create SCM database (Status %lx)\n", Status); ExitThread(0); } @@ -255,12 +279,20 @@ WinMain(HINSTANCE hInstance, ScmGetBootAndSystemDriverState(); #if 0 - /* Create named pipe */ - if (!ScmCreateNamedPipe()) - { - PrintString("SERVICES: Failed to create named pipe\n"); - ExitThread(0); - } + PrintString("SERVICES: Attempting to create named pipe...\n"); + /* Create named pipe */ + if (!ScmCreateNamedPipe()) { + PrintString("SERVICES: Failed to create named pipe\n"); + ExitThread(0); + } + PrintString("SERVICES: named pipe created successfully.\n"); +#else + PrintString("SERVICES: Attempting to create named pipe listener...\n"); + if (!StartScmNamedPipeThreadListener()) { + PrintString("SERVICES: Failed to create named pipe listener thread.\n"); + ExitThread(0); + } + PrintString("SERVICES: named pipe listener thread created.\n"); #endif /* FIXME: create listener thread for pipe */ @@ -285,12 +317,13 @@ WinMain(HINSTANCE hInstance, PrintString("SERVICES: Running.\n"); +#if 1 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); WaitForSingleObject(hEvent, INFINITE); -#if 0 +#else for (;;) { - NtYieldExecution(); + NtYieldExecution(); } #endif diff --git a/subsys/system/services/services.rc b/subsys/system/services/services.rc index 6870571..1c4f2f4 100644 --- a/subsys/system/services/services.rc +++ b/subsys/system/services/services.rc @@ -1,5 +1,5 @@ -#include "../../../include/defines.h" -#include "../../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/subsys/system/shell/shell.rc b/subsys/system/shell/shell.rc index 0982e26..4272d05 100644 --- a/subsys/system/shell/shell.rc +++ b/subsys/system/shell/shell.rc @@ -1,5 +1,5 @@ -#include "../../../include/defines.h" -#include "../../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/subsys/system/usetup/bootsup.c b/subsys/system/usetup/bootsup.c new file mode 100644 index 0000000..77edba3 --- /dev/null +++ b/subsys/system/usetup/bootsup.c @@ -0,0 +1,1492 @@ +/* + * 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. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/bootsup.c + * PURPOSE: Bootloader support functions + * PROGRAMMER: Eric Kohl + */ + +#include +#include + +#include "usetup.h" +#include "inicache.h" +#include "bootsup.h" + + +#define SECTORSIZE 512 + +/* FUNCTIONS ****************************************************************/ + + +static VOID +CreateCommonFreeLoaderSections(PINICACHE IniCache) +{ + PINICACHESECTION IniSection; + + /* Create "FREELOADER" section */ + IniSection = IniCacheAppendSection(IniCache, + L"FREELOADER"); + + /* DefaultOS=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"DefaultOS", + L"ReactOS"); + +#if 0 + /* Timeout=10 */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"TimeOut", + L"10"); +#endif + + /* Create "Display" section */ + IniSection = IniCacheAppendSection(IniCache, + L"Display"); + + /* TitleText=ReactOS Boot Manager */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"TitleText", + L"ReactOS Boot Manager"); + + /* StatusBarColor=Cyan */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"StatusBarColor", + L"Cyan"); + + /* StatusBarTextColor=Black */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"StatusBarTextColor", + L"Black"); + + /* BackdropTextColor=White */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BackdropTextColor", + L"White"); + + /* BackdropColor=Blue */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BackdropColor", + L"Blue"); + + /* BackdropFillStyle=Medium */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BackdropFillStyle", + L"Medium"); + + /* TitleBoxTextColor=White */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"TitleBoxTextColor", + L"White"); + + /* TitleBoxColor=Red */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"TitleBoxColor", + L"Red"); + + /* MessageBoxTextColor=White */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"MessageBoxTextColor", + L"White"); + + /* MessageBoxColor=Blue */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"MessageBoxColor", + L"Blue"); + + /* MenuTextColor=White */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"MenuTextColor", + L"White"); + + /* MenuColor=Blue */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"MenuColor", + L"Blue"); + + /* TextColor=Yellow */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"TextColor", + L"Yellow"); + + /* SelectedTextColor=Black */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SelectedTextColor", + L"Black"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SelectedColor", + L"Gray"); +} + + +NTSTATUS +CreateFreeLoaderIniForDos(PWCHAR IniPath, + PWCHAR ArcPath) +{ + PINICACHE IniCache; + PINICACHESECTION IniSection; + + IniCache = IniCacheCreate(); + + CreateCommonFreeLoaderSections(IniCache); + + /* Create "Operating Systems" section */ + IniSection = IniCacheAppendSection(IniCache, + L"Operating Systems"); + + /* REACTOS=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"ReactOS", + L"\"ReactOS\""); + + /* ReactOS_Debug="ReactOS (Debug)" */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"ReactOS_Debug", + L"\"ReactOS (Debug)\""); + + /* DOS=Dos/Windows */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"DOS", + L"\"DOS/Windows\""); + + /* Create "ReactOS" section */ + IniSection = IniCacheAppendSection(IniCache, + L"ReactOS"); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + ArcPath); + + /* Create "ReactOS_Debug" section */ + IniSection = IniCacheAppendSection(IniCache, + L"ReactOS_Debug"); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + ArcPath); + + /* Options=/DEBUGPORT=SCREEN */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"Options", + L"/DEBUGPORT=SCREEN"); + + /* Create "DOS" section */ + IniSection = IniCacheAppendSection(IniCache, + L"DOS"); + + /* BootType=BootSector */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"BootSector"); + + /* BootDrive=hd0 */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootDrive", + L"hd0"); + + /* BootPartition=1 */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootPartition", + L"1"); + + /* BootSector=BOOTSECT.DOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootSectorFile", + L"BOOTSECT.DOS"); + + IniCacheSave(IniCache, IniPath); + IniCacheDestroy(IniCache); + + return(STATUS_SUCCESS); +} + + +NTSTATUS +CreateFreeLoaderIniForReactos(PWCHAR IniPath, + PWCHAR ArcPath) +{ + PINICACHE IniCache; + PINICACHESECTION IniSection; + + IniCache = IniCacheCreate(); + + CreateCommonFreeLoaderSections(IniCache); + + /* Create "Operating Systems" section */ + IniSection = IniCacheAppendSection(IniCache, + L"Operating Systems"); + + /* ReactOS="ReactOS" */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"ReactOS", + L"\"ReactOS\""); + + /* ReactOS_Debug="ReactOS (Debug)" */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"ReactOS_Debug", + L"\"ReactOS (Debug)\""); + + /* Create "ReactOS" section */ + IniSection = IniCacheAppendSection(IniCache, + L"ReactOS"); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + ArcPath); + + /* Create "ReactOS_Debug" section */ + IniSection = IniCacheAppendSection(IniCache, + L"ReactOS_Debug"); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + ArcPath); + + /* Options=/DEBUGPORT=SCREEN */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"Options", + L"/DEBUGPORT=SCREEN"); + + /* Save the ini file */ + IniCacheSave(IniCache, IniPath); + IniCacheDestroy(IniCache); + + return(STATUS_SUCCESS); +} + + +NTSTATUS +UpdateFreeLoaderIni(PWCHAR IniPath, + PWCHAR ArcPath) +{ + UNICODE_STRING Name; + PINICACHE IniCache; + PINICACHESECTION IniSection; + WCHAR SectionName[80]; + WCHAR OsName[80]; + PWCHAR KeyData; + ULONG i; + NTSTATUS Status; + + RtlInitUnicodeString(&Name, + IniPath); + + Status = IniCacheLoad(&IniCache, + &Name, + FALSE); + if (!NT_SUCCESS(Status)) + return(Status); + + /* Get "Operating Systems" section */ + IniSection = IniCacheGetSection(IniCache, + L"Operating Systems"); + if (IniSection == NULL) + return(STATUS_UNSUCCESSFUL); + + /* Find an unused section name */ + i = 1; + wcscpy(SectionName, L"ReactOS"); + wcscpy(OsName, L"\"ReactOS\""); + while(TRUE) + { + Status = IniCacheGetKey(IniSection, + SectionName, + &KeyData); + if (!NT_SUCCESS(Status)) + break; + + swprintf(SectionName, L"ReactOS_%lu", i); + swprintf(OsName, L"\"ReactOS %lu\"", i); + i++; + } + + /* = */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + SectionName, + OsName); + + /* Create section */ + IniSection = IniCacheAppendSection(IniCache, + SectionName); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + ArcPath); + + IniCacheSave(IniCache, IniPath); + IniCacheDestroy(IniCache); + + return(STATUS_SUCCESS); +} + + +NTSTATUS +SaveCurrentBootSector(PWSTR RootPath, + PWSTR DstPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR BootSector; + + /* Allocate buffer for bootsector */ + BootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (BootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, BootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + BootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, BootSector); + return(Status); + } + + /* Write bootsector to DstPath */ + RtlInitUnicodeString(&Name, + DstPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, BootSector); + return(Status); + } + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + BootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, BootSector); + + return(Status); +} + + +NTSTATUS +InstallFat16BootCodeToFile(PWSTR SrcPath, + PWSTR DstPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + + /* Allocate buffer for new bootsector */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Adjust bootsector (copy a part of the FAT BPB) */ + memcpy((NewBootSector + 11), (OrigBootSector + 11), 51 /*fat BPB length*/); + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write new bootsector to DstPath */ + RtlInitUnicodeString(&Name, + DstPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + +#if 0 + FilePosition.QuadPart = 0; +#endif + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + +NTSTATUS +InstallFat32BootCodeToFile(PWSTR SrcPath, + PWSTR DstPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + LARGE_INTEGER FileOffset; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + /* Allocate buffer for new bootsector (2 sectors) */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + 2 * SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + 2 * SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Adjust bootsector (copy a part of the FAT32 BPB) */ + memcpy((NewBootSector + 3), + (OrigBootSector + 3), + 87); /* FAT32 BPB length */ + + /* Disable the backup boot sector */ + NewBootSector[0x32] = 0xFF; + NewBootSector[0x33] = 0xFF; + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write the first sector of the new bootcode to DstPath */ + RtlInitUnicodeString(&Name, + DstPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Write the second sector of the new bootcode to boot disk sector 14 */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + (NewBootSector + SECTORSIZE), + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + } + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + +NTSTATUS +InstallFat16BootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + + /* Allocate buffer for new bootsector */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Adjust bootsector (copy a part of the FAT BPB) */ + memcpy((NewBootSector + 11), (OrigBootSector + 11), 51 /*fat BPB length*/); + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write new bootsector to RootPath */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + +#if 0 + FilePosition.QuadPart = 0; +#endif + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + +NTSTATUS +InstallFat32BootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + LARGE_INTEGER FileOffset; + USHORT BackupBootSector; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + + /* Allocate buffer for new bootsector (2 sectors) */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + 2 * SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + 2 * SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Adjust bootsector (copy a part of the FAT32 BPB) */ + memcpy((NewBootSector + 3), + (OrigBootSector + 3), + 87); /* FAT32 BPB length */ + + /* Get the location of the backup boot sector */ + BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x33]; + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write the first sector of the new bootcode to DstPath */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Write sector 0 */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Write backup boot sector */ + if (BackupBootSector != 0xFFFF) + { + FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + } + + /* Write sector 14 */ + FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + (NewBootSector + SECTORSIZE), + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + } + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + +static NTSTATUS +UnprotectBootIni(PWSTR FileName, + PULONG Attributes) +{ + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + NTSTATUS Status; + + RtlInitUnicodeString(&Name, + FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (Status == STATUS_NO_SUCH_FILE) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + *Attributes = 0; + return(STATUS_SUCCESS); + } + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return(Status); + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + *Attributes = FileInfo.FileAttributes; + + /* Delete attributes SYSTEM, HIDDEN and READONLY */ + FileInfo.FileAttributes = FileInfo.FileAttributes & + ~(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + return(Status); +} + + +static NTSTATUS +ProtectBootIni(PWSTR FileName, + ULONG Attributes) +{ + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + NTSTATUS Status; + + RtlInitUnicodeString(&Name, + FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return(Status); + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + return(Status); +} + + +NTSTATUS +UpdateBootIni(PWSTR BootIniPath, + PWSTR EntryName, + PWSTR EntryValue) +{ + UNICODE_STRING Name; + PINICACHE Cache = NULL; + PINICACHESECTION Section = NULL; + NTSTATUS Status; + ULONG FileAttribute; + + RtlInitUnicodeString(&Name, + BootIniPath); + + Status = IniCacheLoad(&Cache, + &Name, + FALSE); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + return(Status); + } + + Section = IniCacheGetSection(Cache, + L"operating systems"); + if (Section == NULL) + { +CHECKPOINT1; + IniCacheDestroy(Cache); + return(STATUS_UNSUCCESSFUL); + } + + IniCacheInsertKey(Section, + NULL, + INSERT_LAST, + EntryName, + EntryValue); + + Status = UnprotectBootIni(BootIniPath, + &FileAttribute); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + IniCacheDestroy(Cache); + return(Status); + } + + Status = IniCacheSave(Cache, + BootIniPath); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + IniCacheDestroy(Cache); + return(Status); + } + + FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); + Status = ProtectBootIni(BootIniPath, + FileAttribute); + + IniCacheDestroy(Cache); + + return(Status); +} + +/* EOF */ diff --git a/subsys/system/usetup/bootsup.h b/subsys/system/usetup/bootsup.h new file mode 100644 index 0000000..2bf1180 --- /dev/null +++ b/subsys/system/usetup/bootsup.h @@ -0,0 +1,72 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/bootsup.h + * PURPOSE: Bootloader support functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __BOOTSUP_H__ +#define __BOOTSUP_H__ + +NTSTATUS +CreateFreeLoaderIniForDos(PWCHAR IniPath, + PWCHAR ArcPath); + +NTSTATUS +CreateFreeLoaderIniForReactos(PWCHAR IniPath, + PWCHAR ArcPath); + +NTSTATUS +UpdateFreeLoaderIni(PWCHAR IniPath, + PWCHAR ArcPath); + +NTSTATUS +SaveCurrentBootSector(PWSTR RootPath, + PWSTR DstPath); + +NTSTATUS +InstallFat16BootCodeToFile(PWSTR SrcPath, + PWSTR DstPath, + PWSTR RootPath); + +NTSTATUS +InstallFat32BootCodeToFile(PWSTR SrcPath, + PWSTR DstPath, + PWSTR RootPath); + +NTSTATUS +InstallFat16BootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath); + +NTSTATUS +InstallFat32BootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath); + + +NTSTATUS +UpdateBootIni(PWSTR BootIniPath, + PWSTR EntryName, + PWSTR EntryValue); + +#endif /* __BOOTSUP_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/console.c b/subsys/system/usetup/console.c index 1655d4c..912f8be 100644 --- a/subsys/system/usetup/console.c +++ b/subsys/system/usetup/console.c @@ -367,6 +367,57 @@ WriteConsoleOutputCharacters(LPCSTR lpCharacter, NTSTATUS +WriteConsoleOutputCharactersW(LPCWSTR lpCharacter, + ULONG nLength, + COORD dwWriteCoord) +{ + IO_STATUS_BLOCK IoStatusBlock; + PCHAR Buffer; + COORD *pCoord; + PCHAR pText; + NTSTATUS Status; + ULONG i; + + Buffer = RtlAllocateHeap(ProcessHeap, + 0, + nLength + sizeof(COORD)); + pCoord = (COORD *)Buffer; + pText = (PCHAR)(pCoord + 1); + + *pCoord = dwWriteCoord; + + /* FIXME: use real unicode->oem conversion */ + for (i = 0; i < nLength; i++) + pText[i] = (CHAR)lpCharacter[i]; + pText[i] = 0; + + Status = NtDeviceIoControlFile(StdOutput, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, + NULL, + 0, + Buffer, + nLength + sizeof(COORD)); + if (Status == STATUS_PENDING) + { + NtWaitForSingleObject(StdOutput, + FALSE, + NULL); + Status = IoStatusBlock.Status; + } + + RtlFreeHeap(ProcessHeap, + 0, + Buffer); + + return(Status); +} + + +NTSTATUS WriteConsoleOutputAttributes(CONST USHORT *lpAttribute, ULONG nLength, COORD dwWriteCoord, @@ -892,7 +943,7 @@ SetTextXY(SHORT x, SHORT y, PCHAR Text) VOID -SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text) +SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text) { COORD coPos; ULONG Length; @@ -901,16 +952,20 @@ SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text) coPos.X = x; coPos.Y = y; - Length = strlen(Text); + Length = wcslen(Text); + if (Length > len - 1) + { + Length = len - 1; + } FillConsoleOutputAttribute(0x70, len, coPos, &Written); - WriteConsoleOutputCharacters(Text, - Length, - coPos); + WriteConsoleOutputCharactersW(Text, + Length, + coPos); coPos.X += Length; FillConsoleOutputCharacter('_', @@ -1000,7 +1055,7 @@ SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text) VOID -PrintTextXY(SHORT x, SHORT y, char* fmt,...) +PrintTextXY(SHORT x, SHORT y, char* fmt, ...) { char buffer[512]; va_list ap; @@ -1018,4 +1073,43 @@ PrintTextXY(SHORT x, SHORT y, char* fmt,...) coPos); } + +VOID +PrintTextXYN(SHORT x, SHORT y, SHORT len, char* fmt, ...) +{ + char buffer[512]; + va_list ap; + COORD coPos; + ULONG Length; + ULONG Written; + + va_start(ap, fmt); + vsprintf(buffer, fmt, ap); + va_end(ap); + + coPos.X = x; + coPos.Y = y; + + Length = strlen(buffer); + if (Length > len - 1) + { + Length = len - 1; + } + + WriteConsoleOutputCharacters(buffer, + Length, + coPos); + + coPos.X += Length; + + if (len > Length) + { + FillConsoleOutputCharacter(' ', + len - Length, + coPos, + &Written); + } +} + + /* EOF */ diff --git a/subsys/system/usetup/console.h b/subsys/system/usetup/console.h index cecff91..daf48e0 100644 --- a/subsys/system/usetup/console.h +++ b/subsys/system/usetup/console.h @@ -108,7 +108,7 @@ VOID SetTextXY(SHORT x, SHORT y, PCHAR Text); VOID -SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text); +SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text); VOID SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text); @@ -120,7 +120,10 @@ VOID SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text); VOID -PrintTextXY(SHORT x, SHORT y, char* fmt,...); +PrintTextXY(SHORT x, SHORT y, char* fmt, ...); + +VOID +PrintTextXYN(SHORT x, SHORT y, SHORT len, char* fmt, ...); #endif /* __CONSOLE_H__*/ diff --git a/subsys/system/usetup/drivesup.h b/subsys/system/usetup/drivesup.h index 86e5d0e..1ff5393 100644 --- a/subsys/system/usetup/drivesup.h +++ b/subsys/system/usetup/drivesup.h @@ -38,4 +38,4 @@ GetDriveLetter(ULONG DriveNumber, #endif /* __DRIVESUP_H__ */ -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/subsys/system/usetup/filequeue.c b/subsys/system/usetup/filequeue.c new file mode 100644 index 0000000..5b2ae96 --- /dev/null +++ b/subsys/system/usetup/filequeue.c @@ -0,0 +1,381 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/filequeue.c + * PURPOSE: File queue functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include "usetup.h" +#include "filesup.h" +#include "filequeue.h" + + +/* INCLUDES *****************************************************************/ + + +typedef struct _QUEUEENTRY +{ + struct _QUEUEENTRY *Prev; + struct _QUEUEENTRY *Next; + + PWSTR SourceRootPath; + PWSTR SourcePath; + PWSTR SourceFilename; + PWSTR TargetDirectory; + PWSTR TargetFilename; + +} QUEUEENTRY, *PQUEUEENTRY; + + +typedef struct _FILEQUEUEHEADER +{ + PQUEUEENTRY CopyHead; + PQUEUEENTRY CopyTail; + ULONG CopyCount; +} FILEQUEUEHEADER, *PFILEQUEUEHEADER; + + +/* FUNCTIONS ****************************************************************/ + +HSPFILEQ +SetupOpenFileQueue(VOID) +{ + PFILEQUEUEHEADER QueueHeader; + + /* Allocate queue header */ + QueueHeader = (PFILEQUEUEHEADER)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(FILEQUEUEHEADER)); + if (QueueHeader == NULL) + return(NULL); + + /* Initialize queue header */ + RtlZeroMemory(QueueHeader, + sizeof(FILEQUEUEHEADER)); + + + return((HSPFILEQ)QueueHeader); +} + + +BOOL +SetupCloseFileQueue(HSPFILEQ QueueHandle) +{ + PFILEQUEUEHEADER QueueHeader; + PQUEUEENTRY Entry; + + if (QueueHandle == NULL) + return(FALSE); + + QueueHeader = (PFILEQUEUEHEADER)QueueHandle; + + /* Delete copy queue */ + Entry = QueueHeader->CopyHead; + while (Entry != NULL) + { + /* Delete all strings */ + if (Entry->SourceRootPath != NULL) + RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); + if (Entry->SourcePath != NULL) + RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); + if (Entry->SourceFilename != NULL) + RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); + if (Entry->TargetDirectory != NULL) + RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory); + if (Entry->TargetFilename != NULL) + RtlFreeHeap(ProcessHeap, 0, Entry->TargetFilename); + + /* Unlink current queue entry */ + if (Entry->Next != NULL) + { + QueueHeader->CopyHead = Entry->Next; + QueueHeader->CopyHead->Prev = NULL; + } + else + { + QueueHeader->CopyHead = NULL; + QueueHeader->CopyTail = NULL; + } + + /* Delete queue entry */ + RtlFreeHeap(ProcessHeap, 0, Entry); + + /* Get next queue entry */ + Entry = QueueHeader->CopyHead; + } + + /* Delete queue header */ + RtlFreeHeap(ProcessHeap, + 0, + QueueHeader); + + return(TRUE); +} + + +BOOL +SetupQueueCopy(HSPFILEQ QueueHandle, + PCWSTR SourceRootPath, + PCWSTR SourcePath, + PCWSTR SourceFilename, + PCWSTR TargetDirectory, + PCWSTR TargetFilename) +{ + PFILEQUEUEHEADER QueueHeader; + PQUEUEENTRY Entry; + ULONG Length; + + if (QueueHandle == NULL || + SourceRootPath == NULL || + SourceFilename == NULL || + TargetDirectory == NULL) + return(FALSE); + + QueueHeader = (PFILEQUEUEHEADER)QueueHandle; + + /* Allocate new queue entry */ + Entry = (PQUEUEENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(QUEUEENTRY)); + if (Entry == NULL) + return(FALSE); + + RtlZeroMemory(Entry, + sizeof(QUEUEENTRY)); + + /* Copy source root path */ + Length = wcslen(SourceRootPath); + Entry->SourceRootPath = RtlAllocateHeap(ProcessHeap, + 0, + (Length + 1) * sizeof(WCHAR)); + if (Entry->SourceRootPath == NULL) + { + RtlFreeHeap(ProcessHeap, 0, Entry); + return(FALSE); + } + wcsncpy(Entry->SourceRootPath, SourceRootPath, Length); + Entry->SourceRootPath[Length] = (WCHAR)0; + + /* Copy source path */ + if (SourcePath != NULL) + { + Length = wcslen(SourcePath); + Entry->SourcePath = RtlAllocateHeap(ProcessHeap, + 0, + (Length + 1) * sizeof(WCHAR)); + if (Entry->SourcePath == NULL) + { + RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); + RtlFreeHeap(ProcessHeap, 0, Entry); + return(FALSE); + } + wcsncpy(Entry->SourcePath, SourcePath, Length); + Entry->SourcePath[Length] = (WCHAR)0; + } + + /* Copy source file name */ + Length = wcslen(SourceFilename); + Entry->SourceFilename = RtlAllocateHeap(ProcessHeap, + 0, + (Length + 1) * sizeof(WCHAR)); + if (Entry->SourceFilename == NULL) + { + RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); + RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); + RtlFreeHeap(ProcessHeap, 0, Entry); + return(FALSE); + } + wcsncpy(Entry->SourceFilename, SourceFilename, Length); + Entry->SourceFilename[Length] = (WCHAR)0; + + /* Copy target directory */ + Length = wcslen(TargetDirectory); + if (TargetDirectory[Length] == '\\') + Length--; + Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap, + 0, + (Length + 1) * sizeof(WCHAR)); + if (Entry->TargetDirectory == NULL) + { + RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); + RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); + RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); + RtlFreeHeap(ProcessHeap, 0, Entry); + return(FALSE); + } + wcsncpy(Entry->TargetDirectory, TargetDirectory, Length); + Entry->TargetDirectory[Length] = (WCHAR)0; + + /* Copy optional target filename */ + if (TargetFilename != NULL) + { + Length = wcslen(TargetFilename); + Entry->TargetFilename = RtlAllocateHeap(ProcessHeap, + 0, + (Length + 1) * sizeof(WCHAR)); + if (Entry->TargetFilename == NULL) + { + RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); + RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); + RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); + RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory); + RtlFreeHeap(ProcessHeap, 0, Entry); + return(FALSE); + } + wcsncpy(Entry->TargetFilename, TargetFilename, Length); + Entry->TargetFilename[Length] = (WCHAR)0; + } + + /* Append queue entry */ + if (QueueHeader->CopyHead == NULL) // && QueueHeader->CopyTail == NULL) + { + Entry->Prev = NULL; + Entry->Next = NULL; + QueueHeader->CopyHead = Entry; + QueueHeader->CopyTail = Entry; + } + else + { + Entry->Prev = QueueHeader->CopyTail; + Entry->Next = NULL; + QueueHeader->CopyTail->Next = Entry; + QueueHeader->CopyTail = Entry; + } + QueueHeader->CopyCount++; + + return(TRUE); +} + + +BOOL +SetupCommitFileQueue(HSPFILEQ QueueHandle, + PCWSTR TargetRootPath, + PCWSTR TargetPath, + PSP_FILE_CALLBACK MsgHandler, + PVOID Context) +{ + PFILEQUEUEHEADER QueueHeader; + PQUEUEENTRY Entry; + NTSTATUS Status; + + WCHAR FileSrcPath[MAX_PATH]; + WCHAR FileDstPath[MAX_PATH]; + + if (QueueHandle == NULL) + return(FALSE); + + QueueHeader = (PFILEQUEUEHEADER)QueueHandle; + + MsgHandler(Context, + SPFILENOTIFY_STARTQUEUE, + NULL, + NULL); + + MsgHandler(Context, + SPFILENOTIFY_STARTSUBQUEUE, + (PVOID)FILEOP_COPY, + (PVOID)QueueHeader->CopyCount); + + /* Commit copy queue */ + Entry = QueueHeader->CopyHead; + while (Entry != NULL) + { + /* Build the full source path */ + wcscpy(FileSrcPath, Entry->SourceRootPath); + if (Entry->SourcePath != NULL) + wcscat(FileSrcPath, Entry->SourcePath); + wcscat(FileSrcPath, L"\\"); + wcscat(FileSrcPath, Entry->SourceFilename); + + /* Build the full target path */ + wcscpy(FileDstPath, TargetRootPath); + if (Entry->TargetDirectory[0] == L'\\') + { + wcscat(FileDstPath, Entry->TargetDirectory); + } + else + { + if (TargetPath != NULL) + { + if (TargetPath[0] != L'\\') + wcscat(FileDstPath, L"\\"); + wcscat(FileDstPath, TargetPath); + } + wcscat(FileDstPath, L"\\"); + wcscat(FileDstPath, Entry->TargetDirectory); + } + wcscat(FileDstPath, L"\\"); + if (Entry->TargetFilename != NULL) + wcscat(FileDstPath, Entry->TargetFilename); + else + wcscat(FileDstPath, Entry->SourceFilename); + + /* FIXME: Do it! */ + DPRINT("'%S' ==> '%S'\n", + FileSrcPath, + FileDstPath); + + MsgHandler(Context, + SPFILENOTIFY_STARTCOPY, + (PVOID)Entry->SourceFilename, + (PVOID)FILEOP_COPY); + + /* Copy the file */ + Status = SetupCopyFile(FileSrcPath, FileDstPath); + if (!NT_SUCCESS(Status)) + { + MsgHandler(Context, + SPFILENOTIFY_COPYERROR, + (PVOID)Entry->SourceFilename, + (PVOID)FILEOP_COPY); + + } + else + { + MsgHandler(Context, + SPFILENOTIFY_ENDCOPY, + (PVOID)Entry->SourceFilename, + (PVOID)FILEOP_COPY); + } + + Entry = Entry->Next; + } + + MsgHandler(Context, + SPFILENOTIFY_ENDSUBQUEUE, + (PVOID)FILEOP_COPY, + NULL); + + MsgHandler(Context, + SPFILENOTIFY_ENDQUEUE, + NULL, + NULL); + + return(TRUE); +} + +/* EOF */ diff --git a/subsys/system/usetup/filequeue.h b/subsys/system/usetup/filequeue.h new file mode 100644 index 0000000..591adfa --- /dev/null +++ b/subsys/system/usetup/filequeue.h @@ -0,0 +1,87 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/filequeue.h + * PURPOSE: File queue functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __FILEQUEUE_H__ +#define __FILEQUEUE_H__ + + +#define SPFILENOTIFY_STARTQUEUE 0x1 +#define SPFILENOTIFY_ENDQUEUE 0x2 +#define SPFILENOTIFY_STARTSUBQUEUE 0x3 +#define SPFILENOTIFY_ENDSUBQUEUE 0x4 + +#define SPFILENOTIFY_STARTCOPY 0xb +#define SPFILENOTIFY_ENDCOPY 0xc +#define SPFILENOTIFY_COPYERROR 0xd + +#define FILEOP_COPY 0x0 +#define FILEOP_RENAME 0x1 +#define FILEOP_DELETE 0x2 +#define FILEOP_BACKUP 0x3 + +#define FILEOP_ABORT 0x0 +#define FILEOP_DOIT 0x1 +#define FILEOP_SKIP 0x2 +#define FILEOP_RETRY FILEOP_DOIT +#define FILEOP_NEWPATH 0x4 + + +/* TYPES ********************************************************************/ + +typedef PVOID HSPFILEQ; + +typedef ULONG (*PSP_FILE_CALLBACK)(PVOID Context, + ULONG Notification, + PVOID Param1, + PVOID Param2); + + +/* FUNCTIONS ****************************************************************/ + +HSPFILEQ +SetupOpenFileQueue(VOID); + +BOOL +SetupCloseFileQueue(HSPFILEQ QueueHandle); + +BOOL +SetupQueueCopy(HSPFILEQ QueueHandle, + PCWSTR SourceRootPath, + PCWSTR SourcePath, + PCWSTR SourceFilename, + PCWSTR TargetDirectory, + PCWSTR TargetFilename); + +BOOL +SetupCommitFileQueue(HSPFILEQ QueueHandle, + PCWSTR TargetRootPath, + PCWSTR TargetPath, + PSP_FILE_CALLBACK MsgHandler, + PVOID Context); + +#endif /* __FILEQUEUE_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/filesup.c b/subsys/system/usetup/filesup.c new file mode 100644 index 0000000..f735dc0 --- /dev/null +++ b/subsys/system/usetup/filesup.c @@ -0,0 +1,331 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/filesup.c + * PURPOSE: File support functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include "usetup.h" +#include "filesup.h" + + +/* FUNCTIONS ****************************************************************/ + + +NTSTATUS +CreateDirectory(PWCHAR DirectoryName) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING PathName; + HANDLE DirectoryHandle; + NTSTATUS Status; + + RtlCreateUnicodeString(&PathName, + DirectoryName); + + InitializeObjectAttributes(&ObjectAttributes, + &PathName, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + NULL, + NULL); + + Status = NtCreateFile(&DirectoryHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_DIRECTORY, + 0, + FILE_CREATE, + FILE_DIRECTORY_FILE, + NULL, + 0); + if (NT_SUCCESS(Status)) + { + NtClose(DirectoryHandle); + } + + RtlFreeUnicodeString(&PathName); + + return(Status); +} + + +NTSTATUS +SetupCopyFile(PWCHAR SourceFileName, + PWCHAR DestinationFileName) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandleSource; + HANDLE FileHandleDest; + IO_STATUS_BLOCK IoStatusBlock; + FILE_STANDARD_INFORMATION FileStandard; + FILE_BASIC_INFORMATION FileBasic; + FILE_POSITION_INFORMATION FilePosition; + PUCHAR Buffer; + ULONG RegionSize; + UNICODE_STRING FileName; + NTSTATUS Status; + + Buffer = NULL; + + RtlInitUnicodeString(&FileName, + SourceFileName); + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandleSource, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + return(Status); + } + + Status = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock, + &FileStandard, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + return(Status); + } + + Status = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock,&FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + return(Status); + } + + RtlInitUnicodeString(&FileName, + DestinationFileName); + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtCreateFile(&FileHandleDest, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + return(Status); + } + + FilePosition.CurrentByteOffset.QuadPart = 0; + + Status = NtSetInformationFile(FileHandleSource, + &IoStatusBlock, + &FilePosition, + sizeof(FILE_POSITION_INFORMATION), + FilePositionInformation); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + NtClose(FileHandleDest); + return(Status); + } + + Status = NtSetInformationFile(FileHandleDest, + &IoStatusBlock, + &FilePosition, + sizeof(FILE_POSITION_INFORMATION), + FilePositionInformation); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + NtClose(FileHandleDest); + return(Status); + } + + RegionSize = PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); + if (RegionSize > 0x100000) + { + RegionSize = 0x100000; + } + Status = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID *)&Buffer, + 2, + &RegionSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtClose(FileHandleSource); + NtClose(FileHandleDest); + return(Status); + } + + while (TRUE) + { + Status = NtReadFile(FileHandleSource, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + RegionSize, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID *)&Buffer, + &RegionSize, + MEM_RELEASE); + if (Status == STATUS_END_OF_FILE) + { + DPRINT("STATUS_END_OF_FILE\n"); + break; + } +CHECKPOINT1; + NtClose(FileHandleSource); + NtClose(FileHandleDest); + return(Status); + } + + DPRINT("Bytes read %lu\n", IoStatusBlock.Information); + + Status = NtWriteFile(FileHandleDest, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + IoStatusBlock.Information, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID *)&Buffer, + &RegionSize, + MEM_RELEASE); + NtClose(FileHandleSource); + NtClose(FileHandleDest); + return(Status); + } + } + + + /* Copy file date/time from source file */ + Status = NtSetInformationFile(FileHandleDest, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandleSource); + NtClose(FileHandleDest); + + return(Status); +} + + +BOOLEAN +DoesFileExist(PWSTR PathName, + PWSTR FileName) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + WCHAR FullName[MAX_PATH]; + HANDLE FileHandle; + NTSTATUS Status; + + wcscpy(FullName, PathName); + if (FileName != NULL) + { + if (FileName[0] != L'\\') + wcscat(FullName, L"\\"); + wcscat(FullName, FileName); + } + + RtlInitUnicodeString(&Name, + FullName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { +CHECKPOINT1; + return(FALSE); + } + + NtClose(FileHandle); + + return(TRUE); +} + +/* EOF */ diff --git a/subsys/system/usetup/filesup.h b/subsys/system/usetup/filesup.h new file mode 100644 index 0000000..949c75e --- /dev/null +++ b/subsys/system/usetup/filesup.h @@ -0,0 +1,44 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/filesup.h + * PURPOSE: File support functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __FILESUP_H__ +#define __FILESUP_H__ + +NTSTATUS +CreateDirectory(PWCHAR DirectoryName); + +NTSTATUS +SetupCopyFile(PWCHAR SourceFileName, + PWCHAR DestinationFileName); + +BOOLEAN +DoesFileExist(PWSTR PathName, + PWSTR FileName); + + +#endif /* __FILESUP_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/inicache.c b/subsys/system/usetup/inicache.c new file mode 100644 index 0000000..6c90eed --- /dev/null +++ b/subsys/system/usetup/inicache.c @@ -0,0 +1,1202 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/inicache.c + * PURPOSE: INI file parser that caches contents of INI file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include "usetup.h" +#include "inicache.h" + + +/* PRIVATE FUNCTIONS ********************************************************/ + +static PINICACHEKEY +IniCacheFreeKey(PINICACHEKEY Key) +{ + PINICACHEKEY Next; + + if (Key == NULL) + { + return(NULL); + } + + Next = Key->Next; + if (Key->Name != NULL) + { + RtlFreeHeap(ProcessHeap, + 0, + Key->Name); + Key->Name = NULL; + } + + if (Key->Data != NULL) + { + RtlFreeHeap(ProcessHeap, + 0, + Key->Data); + Key->Data = NULL; + } + + RtlFreeHeap(ProcessHeap, + 0, + Key); + + return(Next); +} + + +static PINICACHESECTION +IniCacheFreeSection(PINICACHESECTION Section) +{ + PINICACHESECTION Next; + + if (Section == NULL) + { + return(NULL); + } + + Next = Section->Next; + while (Section->FirstKey != NULL) + { + Section->FirstKey = IniCacheFreeKey(Section->FirstKey); + } + Section->LastKey = NULL; + + if (Section->Name != NULL) + { + RtlFreeHeap(ProcessHeap, + 0, + Section->Name); + Section->Name = NULL; + } + + RtlFreeHeap(ProcessHeap, + 0, + Section); + + return(Next); +} + + +static PINICACHEKEY +IniCacheFindKey(PINICACHESECTION Section, + PWCHAR Name, + ULONG NameLength) +{ + PINICACHEKEY Key; + + Key = Section->FirstKey; + while (Key != NULL) + { + if (NameLength == wcslen(Key->Name)) + { + if (_wcsnicmp(Key->Name, Name, NameLength) == 0) + break; + } + + Key = Key->Next; + } + + return(Key); +} + + +static PINICACHEKEY +IniCacheAddKey(PINICACHESECTION Section, + PCHAR Name, + ULONG NameLength, + PCHAR Data, + ULONG DataLength) +{ + PINICACHEKEY Key; + ULONG i; + + Key = NULL; + + if (Section == NULL || + Name == NULL || + NameLength == 0 || + Data == NULL || + DataLength == 0) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHEKEY)); + if (Key == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + + RtlZeroMemory(Key, + sizeof(INICACHEKEY)); + + + Key->Name = RtlAllocateHeap(ProcessHeap, + 0, + (NameLength + 1) * sizeof(WCHAR)); + if (Key->Name == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Key); + return(NULL); + } + + /* Copy value name */ + for (i = 0; i < NameLength; i++) + { + Key->Name[i] = (WCHAR)Name[i]; + } + Key->Name[NameLength] = 0; + + + Key->Data = RtlAllocateHeap(ProcessHeap, + 0, + (DataLength + 1) * sizeof(WCHAR)); + if (Key->Data == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Key->Name); + RtlFreeHeap(ProcessHeap, + 0, + Key); + return(NULL); + } + + /* Copy value data */ + for (i = 0; i < DataLength; i++) + { + Key->Data[i] = (WCHAR)Data[i]; + } + Key->Data[DataLength] = 0; + + + if (Section->FirstKey == NULL) + { + Section->FirstKey = Key; + Section->LastKey = Key; + } + else + { + Section->LastKey->Next = Key; + Key->Prev = Section->LastKey; + Section->LastKey = Key; + } + + return(Key); +} + + +static PINICACHESECTION +IniCacheFindSection(PINICACHE Cache, + PWCHAR Name, + ULONG NameLength) +{ + PINICACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL || NameLength == 0) + { + return(NULL); + } + + Section = Cache->FirstSection; + + /* iterate through list of sections */ + while (Section != NULL) + { + if (NameLength == wcslen(Section->Name)) + { + /* are the contents the same too? */ + if (_wcsnicmp(Section->Name, Name, NameLength) == 0) + break; + } + + /* get the next section*/ + Section = Section->Next; + } + + return(Section); +} + + +static PINICACHESECTION +IniCacheAddSection(PINICACHE Cache, + PCHAR Name, + ULONG NameLength) +{ + PINICACHESECTION Section = NULL; + ULONG i; + + if (Cache == NULL || Name == NULL || NameLength == 0) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + Section = (PINICACHESECTION)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHESECTION)); + if (Section == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + RtlZeroMemory(Section, + sizeof(INICACHESECTION)); + + /* Allocate and initialize section name */ + Section->Name = RtlAllocateHeap(ProcessHeap, + 0, + (NameLength + 1) * sizeof(WCHAR)); + if (Section->Name == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Section); + return(NULL); + } + + /* Copy section name */ + for (i = 0; i < NameLength; i++) + { + Section->Name[i] = (WCHAR)Name[i]; + } + Section->Name[NameLength] = 0; + + /* Append section */ + if (Cache->FirstSection == NULL) + { + Cache->FirstSection = Section; + Cache->LastSection = Section; + } + else + { + Cache->LastSection->Next = Section; + Section->Prev = Cache->LastSection; + Cache->LastSection = Section; + } + + return(Section); +} + + +static PCHAR +IniCacheSkipWhitespace(PCHAR Ptr) +{ + while (*Ptr != 0 && isspace(*Ptr)) + Ptr++; + + return((*Ptr == 0) ? NULL : Ptr); +} + + +static PCHAR +IniCacheSkipToNextSection(PCHAR Ptr) +{ + while (*Ptr != 0 && *Ptr != '[') + { + while (*Ptr != 0 && *Ptr != L'\n') + { + Ptr++; + } + Ptr++; + } + + return((*Ptr == 0) ? NULL : Ptr); +} + + +static PCHAR +IniCacheGetSectionName(PCHAR Ptr, + PCHAR *NamePtr, + PULONG NameSize) +{ + ULONG Size = 0; + CHAR Name[256]; + + *NamePtr = NULL; + *NameSize = 0; + + /* skip whitespace */ + while (*Ptr != 0 && isspace(*Ptr)) + { + Ptr++; + } + + *NamePtr = Ptr; + + while (*Ptr != 0 && *Ptr != ']') + { + Size++; + Ptr++; + } + + Ptr++; + + while (*Ptr != 0 && *Ptr != L'\n') + { + Ptr++; + } + Ptr++; + + *NameSize = Size; + + strncpy(Name, *NamePtr, Size); + Name[Size] = 0; + + DPRINT("SectionName: '%s'\n", Name); + + return(Ptr); +} + + +static PCHAR +IniCacheGetKeyName(PCHAR Ptr, + PCHAR *NamePtr, + PULONG NameSize) +{ + ULONG Size = 0; + + *NamePtr = NULL; + *NameSize = 0; + + while(Ptr && *Ptr) + { + *NamePtr = NULL; + *NameSize = 0; + Size = 0; + + /* skip whitespace and empty lines */ + while (isspace(*Ptr) || *Ptr == '\n' || *Ptr == '\r') + { + Ptr++; + } + if (*Ptr == 0) + { + continue; + } + + *NamePtr = Ptr; + + while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '=' && *Ptr != ';') + { + Size++; + Ptr++; + } + if (*Ptr == ';') + { + while (*Ptr != 0 && *Ptr != '\r' && *Ptr != '\n') + { + Ptr++; + } + } + else + { + *NameSize = Size; + break; + } + } + + return(Ptr); +} + + +static PCHAR +IniCacheGetKeyValue(PCHAR Ptr, + PCHAR *DataPtr, + PULONG DataSize, + BOOL String) +{ + ULONG Size = 0; + + *DataPtr = NULL; + *DataSize = 0; + + /* Skip whitespace */ + while (*Ptr != 0 && isspace(*Ptr)) + { + Ptr++; + } + + /* Check and skip '=' */ + if (*Ptr != '=') + { + return(NULL); + } + Ptr++; + + /* Skip whitespace */ + while (*Ptr != 0 && isspace(*Ptr)) + { + Ptr++; + } + + if (*Ptr == '"' && String) + { + Ptr++; + + /* Get data */ + *DataPtr = Ptr; + while (*Ptr != '"') + { + Ptr++; + Size++; + } + Ptr++; + while (*Ptr && *Ptr != '\r' && *Ptr != '\n') + { + Ptr++; + } + } + else + { + /* Get data */ + *DataPtr = Ptr; + while (*Ptr != 0 && *Ptr != '\r' && *Ptr != ';') + { + Ptr++; + Size++; + } + } + + /* Skip to next line */ + if (*Ptr == '\r') + Ptr++; + if (*Ptr == '\n') + Ptr++; + + *DataSize = Size; + + return(Ptr); +} + + + + +/* PUBLIC FUNCTIONS *********************************************************/ + +NTSTATUS +IniCacheLoad(PINICACHE *Cache, + PUNICODE_STRING FileName, + BOOL String) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + FILE_STANDARD_INFORMATION FileInfo; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + NTSTATUS Status; + PCHAR FileBuffer; + ULONG FileLength; + PCHAR Ptr; + LARGE_INTEGER FileOffset; + + ULONG i; + PINICACHESECTION Section; + PINICACHEKEY Key; + + PCHAR SectionName; + ULONG SectionNameSize; + + PCHAR KeyName; + ULONG KeyNameSize; + + PCHAR KeyValue; + ULONG KeyValueSize; + + *Cache = NULL; + + /* Open ini file */ + InitializeObjectAttributes(&ObjectAttributes, + FileName, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_NON_DIRECTORY_FILE); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenFile() failed (Status %lx)\n", Status); + return(Status); + } + + DPRINT("NtOpenFile() successful\n"); + + /* Query file size */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (Status == STATUS_PENDING) + { + DPRINT("NtQueryInformationFile() returns STATUS_PENDING\n"); + + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + FileLength = FileInfo.EndOfFile.u.LowPart; + + DPRINT("File size: %lu\n", FileLength); + + /* Allocate file buffer */ + FileBuffer = RtlAllocateHeap(ProcessHeap, + 0, + FileLength + 1); + if (FileBuffer == NULL) + { + DPRINT1("RtlAllocateHeap() failed\n"); + NtClose(FileHandle); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read file */ + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FileBuffer, + FileLength, + &FileOffset, + NULL); + + if (Status == STATUS_PENDING) + { + DPRINT("NtReadFile() returns STATUS_PENDING\n"); + + Status = IoStatusBlock.Status; + } + + /* Append string terminator */ + FileBuffer[FileLength] = 0; + + NtClose(FileHandle); + + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, + 0, + FileBuffer); + return(Status); + } + + + /* Allocate inicache header */ + *Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHE)); + if (*Cache == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Initialize inicache header */ + RtlZeroMemory(*Cache, + sizeof(INICACHE)); + + /* Parse ini file */ + Section = NULL; + Ptr = FileBuffer; + while (Ptr != NULL && *Ptr != 0) + { + Ptr = IniCacheSkipWhitespace(Ptr); + if (Ptr == NULL) + continue; + + if (*Ptr == '[') + { + Section = NULL; + Ptr++; + + Ptr = IniCacheGetSectionName(Ptr, + &SectionName, + &SectionNameSize); + + DPRINT1("[%.*s]\n", SectionNameSize, SectionName); + + Section = IniCacheAddSection(*Cache, + SectionName, + SectionNameSize); + if (Section == NULL) + { + DPRINT("IniCacheAddSection() failed\n"); + Ptr = IniCacheSkipToNextSection(Ptr); + continue; + } + } + else + { + if (Section == NULL) + { + Ptr = IniCacheSkipToNextSection(Ptr); + continue; + } + + Ptr = IniCacheGetKeyName(Ptr, + &KeyName, + &KeyNameSize); + + Ptr = IniCacheGetKeyValue(Ptr, + &KeyValue, + &KeyValueSize, + String); + + DPRINT1("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue); + + Key = IniCacheAddKey(Section, + KeyName, + KeyNameSize, + KeyValue, + KeyValueSize); + if (Key == NULL) + { + DPRINT("IniCacheAddKey() failed\n"); + } + } + } + + /* Free file buffer */ + RtlFreeHeap(ProcessHeap, + 0, + FileBuffer); + + return(Status); +} + + +VOID +IniCacheDestroy(PINICACHE Cache) +{ + if (Cache == NULL) + { + return; + } + + while (Cache->FirstSection != NULL) + { + Cache->FirstSection = IniCacheFreeSection(Cache->FirstSection); + } + Cache->LastSection = NULL; + + RtlFreeHeap(ProcessHeap, + 0, + Cache); +} + + +PINICACHESECTION +IniCacheGetSection(PINICACHE Cache, + PWCHAR Name) +{ + PINICACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + /* Iterate through list of sections */ + Section = Cache->FirstSection; + while (Section != NULL) + { + DPRINT("Comparing '%S' and '%S'\n", Section->Name, Name); + + /* Are the section names the same? */ + if (_wcsicmp(Section->Name, Name) == 0) + return(Section); + + /* Get the next section */ + Section = Section->Next; + } + + DPRINT("Section not found\n"); + + return(NULL); +} + + +NTSTATUS +IniCacheGetKey(PINICACHESECTION Section, + PWCHAR KeyName, + PWCHAR *KeyData) +{ + PINICACHEKEY Key; + + if (Section == NULL || KeyName == NULL || KeyData == NULL) + { + DPRINT("Invalid parameter\n"); + return(STATUS_INVALID_PARAMETER); + } + + *KeyData = NULL; + + Key = IniCacheFindKey(Section, KeyName, wcslen(KeyName)); + if (Key == NULL) + { + return(STATUS_INVALID_PARAMETER); + } + + *KeyData = Key->Data; + + return(STATUS_SUCCESS); +} + + +PINICACHEITERATOR +IniCacheFindFirstValue(PINICACHESECTION Section, + PWCHAR *KeyName, + PWCHAR *KeyData) +{ + PINICACHEITERATOR Iterator; + PINICACHEKEY Key; + + if (Section == NULL || KeyName == NULL || KeyData == NULL) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + Key = Section->FirstKey; + if (Key == NULL) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + *KeyName = Key->Name; + *KeyData = Key->Data; + + Iterator = (PINICACHEITERATOR)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHEITERATOR)); + if (Iterator == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + + Iterator->Section = Section; + Iterator->Key = Key; + + return(Iterator); +} + + +BOOLEAN +IniCacheFindNextValue(PINICACHEITERATOR Iterator, + PWCHAR *KeyName, + PWCHAR *KeyData) +{ + PINICACHEKEY Key; + + if (Iterator == NULL || KeyName == NULL || KeyData == NULL) + { + DPRINT("Invalid parameter\n"); + return(FALSE); + } + + Key = Iterator->Key->Next; + if (Key == NULL) + { + DPRINT("No more entries\n"); + return(FALSE); + } + + *KeyName = Key->Name; + *KeyData = Key->Data; + + Iterator->Key = Key; + + return(TRUE); +} + + +VOID +IniCacheFindClose(PINICACHEITERATOR Iterator) +{ + if (Iterator == NULL) + return; + + RtlFreeHeap(ProcessHeap, + 0, + Iterator); +} + + +PINICACHEKEY +IniCacheInsertKey(PINICACHESECTION Section, + PINICACHEKEY AnchorKey, + INSERTATION_TYPE InsertationType, + PWCHAR Name, + PWCHAR Data) +{ + PINICACHEKEY Key; + ULONG i; + + Key = NULL; + + if (Section == NULL || + Name == NULL || + *Name == 0 || + Data == NULL || + *Data == 0) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + /* Allocate key buffer */ + Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHEKEY)); + if (Key == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + RtlZeroMemory(Key, + sizeof(INICACHEKEY)); + + /* Allocate name buffer */ + Key->Name = RtlAllocateHeap(ProcessHeap, + 0, + (wcslen(Name) + 1) * sizeof(WCHAR)); + if (Key->Name == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Key); + return(NULL); + } + + /* Copy value name */ + wcscpy(Key->Name, Name); + + /* Allocate data buffer */ + Key->Data = RtlAllocateHeap(ProcessHeap, + 0, + (wcslen(Data) + 1) * sizeof(WCHAR)); + if (Key->Data == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Key->Name); + RtlFreeHeap(ProcessHeap, + 0, + Key); + return(NULL); + } + + /* Copy value data */ + wcscpy(Key->Data, Data); + + /* Insert key into section */ + if (Section->FirstKey == NULL) + { + Section->FirstKey = Key; + Section->LastKey = Key; + } + else if ((InsertationType == INSERT_FIRST) || + ((InsertationType == INSERT_BEFORE) && ((AnchorKey == NULL) || (AnchorKey == Section->FirstKey)))) + { + /* Insert at the head of the list */ + Section->FirstKey->Prev = Key; + Key->Next = Section->FirstKey; + Section->FirstKey = Key; + } + else if ((InsertationType == INSERT_BEFORE) && (AnchorKey != NULL)) + { + /* Insert before the anchor key */ + Key->Next = AnchorKey; + Key->Prev = AnchorKey->Prev; + AnchorKey->Prev->Next = Key; + AnchorKey->Prev = Key; + } + else if ((InsertationType == INSERT_LAST) || + ((InsertationType == INSERT_AFTER) && ((AnchorKey == NULL) || (AnchorKey == Section->LastKey)))) + { + Section->LastKey->Next = Key; + Key->Prev = Section->LastKey; + Section->LastKey = Key; + } + else if ((InsertationType == INSERT_AFTER) && (AnchorKey != NULL)) + { + /* Insert before the anchor key */ + Key->Next = AnchorKey->Next; + Key->Prev = AnchorKey; + AnchorKey->Next->Prev = Key; + AnchorKey->Next = Key; + } + + return(Key); +} + + +PINICACHE +IniCacheCreate(VOID) +{ + PINICACHE Cache; + + /* Allocate inicache header */ + Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHE)); + if (Cache == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + + /* Initialize inicache header */ + RtlZeroMemory(Cache, + sizeof(INICACHE)); + + return(Cache); +} + + +NTSTATUS +IniCacheSave(PINICACHE Cache, + PWCHAR FileName) +{ + UNICODE_STRING Name; + PINICACHESECTION Section; + PINICACHEKEY Key; + ULONG BufferSize; + PCHAR Buffer; + PCHAR Ptr; + ULONG Len; + NTSTATUS Status; + + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + LARGE_INTEGER Offset; + HANDLE FileHandle; + + + /* Calculate required buffer size */ + BufferSize = 0; + Section = Cache->FirstSection; + while (Section != NULL) + { + BufferSize += (Section->Name ? wcslen(Section->Name) : 0) + + 4; /* "[]\r\n" */ + + Key = Section->FirstKey; + while (Key != NULL) + { + BufferSize += wcslen(Key->Name) + + (Key->Data ? wcslen(Key->Data) : 0) + + 3; /* "=\r\n" */ + Key = Key->Next; + } + + Section = Section->Next; + if (Section != NULL) + BufferSize += 2; /* extra "\r\n" at end of each section */ + } + BufferSize++; /* Null-terminator */ + + DPRINT1("BufferSize: %lu\n", BufferSize); + + /* Allocate file buffer */ + Buffer = RtlAllocateHeap(ProcessHeap, + 0, + BufferSize); + if (Buffer == NULL) + { + DPRINT1("RtlAllocateHeap() failed\n"); + return(STATUS_INSUFFICIENT_RESOURCES); + } + RtlZeroMemory(Buffer, BufferSize); + + /* Fill file buffer */ + Ptr = Buffer; + Section = Cache->FirstSection; + while (Section != NULL) + { + Len = sprintf(Ptr, "[%S]\r\n", Section->Name); + Ptr += Len; + + Key = Section->FirstKey; + while (Key != NULL) + { + Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data); + Ptr += Len; + Key = Key->Next; + } + + Section = Section->Next; + if (Section != NULL) + { + Len = sprintf(Ptr, "\r\n"); + Ptr += Len; + } + } + + /* Create ini file */ + RtlInitUnicodeString(&Name, + FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, + 0, + Buffer); + return(Status); + } + + Offset.QuadPart = 0LL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BufferSize, + &Offset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, + 0, + Buffer); + return(Status); + } + + NtClose(FileHandle); + + RtlFreeHeap(ProcessHeap, + 0, + Buffer); + + return(STATUS_SUCCESS); +} + + +PINICACHESECTION +IniCacheAppendSection(PINICACHE Cache, + PWCHAR Name) +{ + PINICACHESECTION Section = NULL; + ULONG i; + + if (Cache == NULL || Name == NULL || *Name == 0) + { + DPRINT("Invalid parameter\n"); + return(NULL); + } + + Section = (PINICACHESECTION)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INICACHESECTION)); + if (Section == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return(NULL); + } + RtlZeroMemory(Section, + sizeof(INICACHESECTION)); + + /* Allocate and initialize section name */ + Section->Name = RtlAllocateHeap(ProcessHeap, + 0, + (wcslen(Name) + 1) * sizeof(WCHAR)); + if (Section->Name == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + Section); + return(NULL); + } + + /* Copy section name */ + wcscpy(Section->Name, Name); + + /* Append section */ + if (Cache->FirstSection == NULL) + { + Cache->FirstSection = Section; + Cache->LastSection = Section; + } + else + { + Cache->LastSection->Next = Section; + Section->Prev = Cache->LastSection; + Cache->LastSection = Section; + } + + return(Section); +} + +/* EOF */ diff --git a/subsys/system/usetup/inicache.h b/subsys/system/usetup/inicache.h new file mode 100644 index 0000000..e22a8ac --- /dev/null +++ b/subsys/system/usetup/inicache.h @@ -0,0 +1,132 @@ +/* + * 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. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/inicache.h + * PURPOSE: INI file parser that caches contents of INI file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +#ifndef __INICACHE_H__ +#define __INICACHE_H__ + + +typedef struct _INICACHEKEY +{ + PWCHAR Name; + PWCHAR Data; + + struct _INICACHEKEY *Next; + struct _INICACHEKEY *Prev; +} INICACHEKEY, *PINICACHEKEY; + + +typedef struct _INICACHESECTION +{ + PWCHAR Name; + + PINICACHEKEY FirstKey; + PINICACHEKEY LastKey; + + struct _INICACHESECTION *Next; + struct _INICACHESECTION *Prev; +} INICACHESECTION, *PINICACHESECTION; + + +typedef struct _INICACHE +{ + PINICACHESECTION FirstSection; + PINICACHESECTION LastSection; +} INICACHE, *PINICACHE; + + +typedef struct _PINICACHEITERATOR +{ + PINICACHESECTION Section; + PINICACHEKEY Key; +} INICACHEITERATOR, *PINICACHEITERATOR; + + +typedef enum +{ + INSERT_FIRST, + INSERT_BEFORE, + INSERT_AFTER, + INSERT_LAST +} INSERTATION_TYPE; + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS +IniCacheLoad(PINICACHE *Cache, + PUNICODE_STRING FileName, + BOOL String); + +VOID +IniCacheDestroy(PINICACHE Cache); + +PINICACHESECTION +IniCacheGetSection(PINICACHE Cache, + PWCHAR Name); + +NTSTATUS +IniCacheGetKey(PINICACHESECTION Section, + PWCHAR KeyName, + PWCHAR *KeyData); + + + +PINICACHEITERATOR +IniCacheFindFirstValue(PINICACHESECTION Section, + PWCHAR *KeyName, + PWCHAR *KeyData); + +BOOLEAN +IniCacheFindNextValue(PINICACHEITERATOR Iterator, + PWCHAR *KeyName, + PWCHAR *KeyData); + +VOID +IniCacheFindClose(PINICACHEITERATOR Iterator); + + +PINICACHEKEY +IniCacheInsertKey(PINICACHESECTION Section, + PINICACHEKEY AnchorKey, + INSERTATION_TYPE InsertationType, + PWCHAR Name, + PWCHAR Data); + +PINICACHE +IniCacheCreate(VOID); + +NTSTATUS +IniCacheSave(PINICACHE Cache, + PWCHAR FileName); + +PINICACHESECTION +IniCacheAppendSection(PINICACHE Cache, + PWCHAR Name); + + +#endif /* __INICACHE_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/makefile b/subsys/system/usetup/makefile index 06f4540..78491d0 100644 --- a/subsys/system/usetup/makefile +++ b/subsys/system/usetup/makefile @@ -12,7 +12,8 @@ TARGET_INSTALLDIR = system32 TARGET_CFLAGS = -D__NTAPP__ -TARGET_OBJECTS = $(TARGET_NAME).o console.o drivesup.o partlist.o +TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o console.o drivesup.o filequeue.o \ + filesup.o inicache.o partlist.o progress.o include $(PATH_TO_TOP)/rules.mak diff --git a/subsys/system/usetup/partlist.c b/subsys/system/usetup/partlist.c index 8969cd3..6181363 100644 --- a/subsys/system/usetup/partlist.c +++ b/subsys/system/usetup/partlist.c @@ -39,6 +39,122 @@ /* FUNCTIONS ****************************************************************/ +static VOID +AddPartitionList(ULONG DiskNumber, + PDISKENTRY DiskEntry, + DRIVE_LAYOUT_INFORMATION *LayoutBuffer) +{ + PPARTENTRY PartEntry; + ULONG i; + ULONG EntryCount; + + + /* + * FIXME: + * Determine required number of partiton entries. + * This must include entries for unused disk space. + */ + + /* Check for unpartitioned disk */ + if (LayoutBuffer->PartitionCount == 0) + { + EntryCount = 1; + } + else + { + +#if 0 + for (i = 0; i < LayoutBuffer->PartitionCount; i++) + { + + } +#endif + + EntryCount = LayoutBuffer->PartitionCount; + } + + + DiskEntry->PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + EntryCount * sizeof(PARTENTRY)); + DiskEntry->PartCount = EntryCount; + + RtlZeroMemory(DiskEntry->PartArray, + EntryCount * sizeof(PARTENTRY)); + + if (LayoutBuffer->PartitionCount == 0) + { + /* Initialize an 'Unpartitioned space' entry */ + PartEntry = &DiskEntry->PartArray[0]; + + PartEntry->Unpartitioned = TRUE; + PartEntry->PartSize = 0; /* ?? */ + + PartEntry->Used = TRUE; + } + else + { + for (i = 0; i < LayoutBuffer->PartitionCount; i++) + { + PartEntry = &DiskEntry->PartArray[i]; + + if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && + (!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType))) + { + PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; + PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber, + PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType; + PartEntry->Active = LayoutBuffer->PartitionEntry[i].BootIndicator; + + PartEntry->DriveLetter = GetDriveLetter(DiskNumber, + LayoutBuffer->PartitionEntry[i].PartitionNumber); + + PartEntry->Unpartitioned = FALSE; + + PartEntry->Used = TRUE; + } + else + { + PartEntry->Used = FALSE; + } + } + } +} + + +static VOID +GetDriverName(PDISKENTRY DiskEntry) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + WCHAR KeyName[32]; + NTSTATUS Status; + + RtlInitUnicodeString(&DiskEntry->DriverName, + NULL); + + swprintf(KeyName, + L"\\Scsi\\Scsi Port %lu", + DiskEntry->Port); + + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); + + QueryTable[0].Name = L"Driver"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &DiskEntry->DriverName; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, + KeyName, + QueryTable, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + } +} + + PPARTLIST CreatePartitionList(SHORT Left, SHORT Top, @@ -49,16 +165,15 @@ CreatePartitionList(SHORT Left, OBJECT_ATTRIBUTES ObjectAttributes; SYSTEM_DEVICE_INFORMATION Sdi; DISK_GEOMETRY DiskGeometry; + IO_STATUS_BLOCK Iosb; ULONG ReturnSize; NTSTATUS Status; - ULONG DiskCount; - IO_STATUS_BLOCK Iosb; + ULONG DiskNumber; WCHAR Buffer[MAX_PATH]; UNICODE_STRING Name; HANDLE FileHandle; DRIVE_LAYOUT_INFORMATION *LayoutBuffer; SCSI_ADDRESS ScsiAddress; - ULONG i; List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST)); if (List == NULL) @@ -96,11 +211,11 @@ CreatePartitionList(SHORT Left, Sdi.NumberOfDisks * sizeof(DISKENTRY)); List->DiskCount = Sdi.NumberOfDisks; - for (DiskCount = 0; DiskCount < Sdi.NumberOfDisks; DiskCount++) + for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++) { swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", - DiskCount); + DiskNumber); RtlInitUnicodeString(&Name, Buffer); @@ -144,18 +259,19 @@ CreatePartitionList(SHORT Left, sizeof(SCSI_ADDRESS)); - List->DiskArray[DiskCount].DiskSize = + List->DiskArray[DiskNumber].DiskSize = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack * (ULONGLONG)DiskGeometry.BytesPerSector; - List->DiskArray[DiskCount].DiskNumber = DiskCount; - List->DiskArray[DiskCount].Port = ScsiAddress.PortNumber; - List->DiskArray[DiskCount].Bus = ScsiAddress.PathId; - List->DiskArray[DiskCount].Id = ScsiAddress.TargetId; + List->DiskArray[DiskNumber].DiskNumber = DiskNumber; + List->DiskArray[DiskNumber].Port = ScsiAddress.PortNumber; + List->DiskArray[DiskNumber].Bus = ScsiAddress.PathId; + List->DiskArray[DiskNumber].Id = ScsiAddress.TargetId; - List->DiskArray[DiskCount].FixedDisk = TRUE; + List->DiskArray[DiskNumber].FixedDisk = TRUE; + GetDriverName(&List->DiskArray[DiskNumber]); LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); @@ -171,31 +287,9 @@ CreatePartitionList(SHORT Left, 8192); if (NT_SUCCESS(Status)) { - - List->DiskArray[DiskCount].PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - LayoutBuffer->PartitionCount * sizeof(PARTENTRY)); - List->DiskArray[DiskCount].PartCount = LayoutBuffer->PartitionCount; - - for (i = 0; i < LayoutBuffer->PartitionCount; i++) - { - if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && - !IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)) - { - List->DiskArray[DiskCount].PartArray[i].PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; - List->DiskArray[DiskCount].PartArray[i].PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber, - List->DiskArray[DiskCount].PartArray[i].PartType = LayoutBuffer->PartitionEntry[i].PartitionType; - - List->DiskArray[DiskCount].PartArray[i].DriveLetter = GetDriveLetter(DiskCount, - LayoutBuffer->PartitionEntry[i].PartitionNumber); - - List->DiskArray[DiskCount].PartArray[i].Used = TRUE; - } - else - { - List->DiskArray[DiskCount].PartArray[i].Used = FALSE; - } - } + AddPartitionList(DiskNumber, + &List->DiskArray[DiskNumber], + LayoutBuffer); } RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); @@ -203,9 +297,9 @@ CreatePartitionList(SHORT Left, else { /* mark removable disk entry */ - List->DiskArray[DiskCount].FixedDisk = FALSE; - List->DiskArray[DiskCount].PartCount = 0; - List->DiskArray[DiskCount].PartArray = NULL; + List->DiskArray[DiskNumber].FixedDisk = FALSE; + List->DiskArray[DiskNumber].PartCount = 0; + List->DiskArray[DiskNumber].PartArray = NULL; } } @@ -251,12 +345,15 @@ DestroyPartitionList(PPARTLIST List) } #endif - /* free disk and partition info */ + /* Release disk and partition info */ if (List->DiskArray != NULL) { - /* free partition arrays */ for (i = 0; i < List->DiskCount; i++) { + /* Release driver name */ + RtlFreeUnicodeString(&List->DiskArray[i].DriverName); + + /* Release partition array */ if (List->DiskArray[i].PartArray != NULL) { RtlFreeHeap(ProcessHeap, 0, List->DiskArray[i].PartArray); @@ -265,13 +362,13 @@ DestroyPartitionList(PPARTLIST List) } } - /* free disk array */ + /* Release disk array */ RtlFreeHeap(ProcessHeap, 0, List->DiskArray); List->DiskCount = 0; List->DiskArray = NULL; } - /* free list head */ + /* Release list head */ RtlFreeHeap(ProcessHeap, 0, List); } @@ -321,9 +418,8 @@ PrintPartitionData(PPARTLIST List, ULONGLONG PartSize; PCHAR Unit; - PCHAR PartType; UCHAR Attribute; - + PCHAR PartType; Width = List->Right - List->Left - 1; Height = List->Bottom - List->Top - 1; @@ -336,33 +432,38 @@ PrintPartitionData(PPARTLIST List, PartEntry = &List->DiskArray[DiskIndex].PartArray[PartIndex]; - if ((PartEntry->PartType == PARTITION_FAT_12) || - (PartEntry->PartType == PARTITION_FAT_16) || - (PartEntry->PartType == PARTITION_HUGE) || - (PartEntry->PartType == PARTITION_XINT13)) - { - PartType = "FAT"; - } - else if ((PartEntry->PartType == PARTITION_FAT32) || - (PartEntry->PartType == PARTITION_FAT32_XINT13)) - { - PartType = "FAT32"; - } - else if (PartEntry->PartType == PARTITION_IFS) + /* Determine partition type */ + PartType = NULL; + if (PartEntry->Unpartitioned == FALSE) { - PartType = "NTFS"; /* FIXME: Not quite correct! */ - } - else - { - PartType = "Unknown"; + if ((PartEntry->PartType == PARTITION_FAT_12) || + (PartEntry->PartType == PARTITION_FAT_16) || + (PartEntry->PartType == PARTITION_HUGE) || + (PartEntry->PartType == PARTITION_XINT13)) + { + PartType = "FAT"; + } + else if ((PartEntry->PartType == PARTITION_FAT32) || + (PartEntry->PartType == PARTITION_FAT32_XINT13)) + { + PartType = "FAT32"; + } + else if (PartEntry->PartType == PARTITION_IFS) + { + PartType = "NTFS"; /* FIXME: Not quite correct! */ + } } + +#if 0 if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */ { PartSize = (PartEntry->PartSize + (1 << 29)) >> 30; Unit = "GB"; } - else if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */ + else +#endif + if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */ { PartSize = (PartEntry->PartSize + (1 << 19)) >> 20; Unit = "MB"; @@ -370,29 +471,58 @@ PrintPartitionData(PPARTLIST List, else { PartSize = (PartEntry->PartSize + (1 << 9)) >> 10; - Unit = "kB"; + Unit = "KB"; } - if (PartEntry->DriveLetter != (CHAR)0) + + if (PartEntry->Unpartitioned == TRUE) { sprintf(LineBuffer, - "%c: %d: nr: %d type: %x (%s) %I64u %s", + " Unpartitioned space %I64u %s", + PartSize, + Unit); + } + else if (PartEntry->DriveLetter != (CHAR)0) + { + if (PartType == NULL) + { + sprintf(LineBuffer, + "%c: Type %-3lu %I64u %s", + PartEntry->DriveLetter, + PartEntry->PartType, + PartSize, + Unit); + } + else + { + sprintf(LineBuffer, + "%c: %s %I64u %s", + PartEntry->DriveLetter, + PartType, + PartSize, + Unit); + } + +#if 0 + sprintf(LineBuffer, + "%c: %s (%d: nr: %d type: %x) %I64u %s", PartEntry->DriveLetter, + PartType, PartIndex, PartEntry->PartNumber, PartEntry->PartType, - PartType, PartSize, Unit); +#endif } else { sprintf(LineBuffer, - " %d: nr: %d type: %x (%s) %I64u %s", + "-- %s (%d: nr: %d type: %x) %I64u %s", + PartEntry->FileSystemName, PartIndex, PartEntry->PartNumber, PartEntry->PartType, - PartType, PartSize, Unit); } @@ -435,7 +565,6 @@ PrintDiskData(PPARTLIST List, ULONGLONG DiskSize; PCHAR Unit; SHORT PartIndex; - BOOL PartPrinted; DiskEntry = &List->DiskArray[DiskIndex]; @@ -448,31 +577,45 @@ PrintDiskData(PPARTLIST List, coPos.X = List->Left + 1; coPos.Y = List->Top + 1 + List->Line; +#if 0 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ { DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30; Unit = "GB"; } - else if (DiskEntry->DiskSize >= 0xA00000ULL) /* 10 MB */ + else +#endif { DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20; + if (DiskSize == 0) + DiskSize = 1; Unit = "MB"; } + + if (DiskEntry->DriverName.Length > 0) + { + sprintf(LineBuffer, + "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ", + DiskSize, + Unit, + DiskEntry->DiskNumber, + DiskEntry->Port, + DiskEntry->Bus, + DiskEntry->Id, + &DiskEntry->DriverName); + } else { - DiskSize = (DiskEntry->DiskSize + (1 << 9)) >> 10; - Unit = "kB"; + sprintf(LineBuffer, + "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)", + DiskSize, + Unit, + DiskEntry->DiskNumber, + DiskEntry->Port, + DiskEntry->Bus, + DiskEntry->Id); } - sprintf(LineBuffer, - "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)", - DiskSize, - Unit, - DiskEntry->DiskNumber, - DiskEntry->Port, - DiskEntry->Bus, - DiskEntry->Id); - FillConsoleOutputAttribute(0x17, Width, coPos, @@ -494,25 +637,19 @@ PrintDiskData(PPARTLIST List, PrintEmptyLine(List); - PartPrinted = FALSE; - /* Print partition lines*/ - for (PartIndex = 0; PartIndex < List->DiskArray[DiskIndex].PartCount; PartIndex++) + for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++) { - if (List->DiskArray[DiskIndex].PartArray[PartIndex].Used == TRUE) + if (DiskEntry->PartArray[PartIndex].Used == TRUE) { PrintPartitionData(List, DiskIndex, PartIndex); - PartPrinted = TRUE; } } /* Print separator line */ - if (PartPrinted == TRUE) - { - PrintEmptyLine(List); - } + PrintEmptyLine(List); } @@ -582,7 +719,7 @@ DrawPartitionList(PPARTLIST List) coPos, &Written); - /* draw upper right corner */ + /* draw lower right corner */ coPos.X = List->Right; coPos.Y = List->Bottom; FillConsoleOutputCharacter(0xD9, // '+', @@ -681,34 +818,125 @@ ScrollUpPartitionList(PPARTLIST List) BOOL -GetPartitionData(PPARTLIST List, - PPARTDATA Data) +GetSelectedPartition(PPARTLIST List, + PPARTDATA Data) { + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + if (List->CurrentDisk >= List->DiskCount) return(FALSE); - if (List->DiskArray[List->CurrentDisk].FixedDisk == FALSE) - return(FALSE); + DiskEntry = &List->DiskArray[List->CurrentDisk]; - if (List->CurrentPartition >= List->DiskArray[List->CurrentDisk].PartCount) + if (DiskEntry->FixedDisk == FALSE) return(FALSE); - if (List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].Used == FALSE) + if (List->CurrentPartition >= DiskEntry->PartCount) return(FALSE); - Data->DiskSize = List->DiskArray[List->CurrentDisk].DiskSize; - Data->DiskNumber = List->DiskArray[List->CurrentDisk].DiskNumber; - Data->Port = List->DiskArray[List->CurrentDisk].Port; - Data->Bus = List->DiskArray[List->CurrentDisk].Bus; - Data->Id = List->DiskArray[List->CurrentDisk].Id; + PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; + + if (PartEntry->Used == FALSE) + return(FALSE); - Data->PartSize = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartSize; - Data->PartNumber = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartNumber; - Data->PartType = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].PartType; + /* Copy disk-specific data */ + Data->DiskSize = DiskEntry->DiskSize; + Data->DiskNumber = DiskEntry->DiskNumber; + Data->Port = DiskEntry->Port; + Data->Bus = DiskEntry->Bus; + Data->Id = DiskEntry->Id; + + /* Copy driver name */ + RtlInitUnicodeString(&Data->DriverName, + NULL); + if (DiskEntry->DriverName.Length != 0) + { + Data->DriverName.Buffer = RtlAllocateHeap(ProcessHeap, + 0, + DiskEntry->DriverName.MaximumLength); + if (Data->DriverName.Buffer != NULL) + { + Data->DriverName.MaximumLength = DiskEntry->DriverName.MaximumLength; + Data->DriverName.Length = DiskEntry->DriverName.Length; + RtlCopyMemory(Data->DriverName.Buffer, + DiskEntry->DriverName.Buffer, + DiskEntry->DriverName.MaximumLength); + } + } - Data->DriveLetter = List->DiskArray[List->CurrentDisk].PartArray[List->CurrentPartition].DriveLetter; + /* Copy partition-specific data */ + Data->PartSize = PartEntry->PartSize; + Data->PartNumber = PartEntry->PartNumber; + Data->PartType = PartEntry->PartType; + Data->DriveLetter = PartEntry->DriveLetter; return(TRUE); } + +BOOL +GetActiveBootPartition(PPARTLIST List, + PPARTDATA Data) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + ULONG i; + + if (List->CurrentDisk >= List->DiskCount) + return(FALSE); + + DiskEntry = &List->DiskArray[0]; + + if (DiskEntry->FixedDisk == FALSE) + return(FALSE); + + for (i = 0; i < DiskEntry->PartCount; i++) + { + if (DiskEntry->PartArray[i].Active) + { + PartEntry = &DiskEntry->PartArray[i]; + + if (PartEntry->Used == FALSE) + return(FALSE); + + /* Copy disk-specific data */ + Data->DiskSize = DiskEntry->DiskSize; + Data->DiskNumber = DiskEntry->DiskNumber; + Data->Port = DiskEntry->Port; + Data->Bus = DiskEntry->Bus; + Data->Id = DiskEntry->Id; + + /* Copy driver name */ + RtlInitUnicodeString(&Data->DriverName, + NULL); + if (DiskEntry->DriverName.Length != 0) + { + Data->DriverName.Buffer = RtlAllocateHeap(ProcessHeap, + 0, + DiskEntry->DriverName.MaximumLength); + if (Data->DriverName.Buffer != NULL) + { + Data->DriverName.MaximumLength = DiskEntry->DriverName.MaximumLength; + Data->DriverName.Length = DiskEntry->DriverName.Length; + RtlCopyMemory(Data->DriverName.Buffer, + DiskEntry->DriverName.Buffer, + DiskEntry->DriverName.MaximumLength); + } + } + + /* Copy partition-specific data */ + Data->PartSize = PartEntry->PartSize; + Data->PartNumber = PartEntry->PartNumber; + Data->PartType = PartEntry->PartType; + Data->DriveLetter = PartEntry->DriveLetter; + + return(TRUE); + } + } + + return(FALSE); +} + + /* EOF */ diff --git a/subsys/system/usetup/partlist.h b/subsys/system/usetup/partlist.h index 96decfa..ce79d5b 100644 --- a/subsys/system/usetup/partlist.h +++ b/subsys/system/usetup/partlist.h @@ -40,6 +40,8 @@ typedef struct _PARTDATA ULONG PartType; CHAR DriveLetter; + + UNICODE_STRING DriverName; } PARTDATA, *PPARTDATA; @@ -48,8 +50,14 @@ typedef struct _PARTENTRY ULONGLONG PartSize; ULONG PartNumber; ULONG PartType; + BOOLEAN Active; CHAR DriveLetter; + CHAR VolumeLabel[17]; + CHAR FileSystemName[9]; + + BOOL Unpartitioned; + BOOL Used; } PARTENTRY, *PPARTENTRY; @@ -62,6 +70,8 @@ typedef struct _DISKENTRY USHORT Id; BOOL FixedDisk; + UNICODE_STRING DriverName; + ULONG PartCount; PPARTENTRY PartArray; @@ -110,8 +120,12 @@ VOID ScrollUpPartitionList(PPARTLIST List); BOOL -GetPartitionData(PPARTLIST List, - PPARTDATA Data); +GetSelectedPartition(PPARTLIST List, + PPARTDATA Data); + +BOOL +GetActiveBootPartition(PPARTLIST List, + PPARTDATA Data); #endif /* __PARTLIST_H__ */ diff --git a/subsys/system/usetup/progress.c b/subsys/system/usetup/progress.c new file mode 100644 index 0000000..9049692 --- /dev/null +++ b/subsys/system/usetup/progress.c @@ -0,0 +1,246 @@ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include "usetup.h" +#include "progress.h" + +/* FUNCTIONS ****************************************************************/ + + +static VOID +DrawBorder(PPROGRESS Bar) +{ + COORD coPos; + ULONG Written; + SHORT i; + + /* draw upper left corner */ + coPos.X = Bar->Left; + coPos.Y = Bar->Top + 1; + FillConsoleOutputCharacter(0xDA, // '+', + 1, + coPos, + &Written); + + /* draw upper edge */ + coPos.X = Bar->Left + 1; + coPos.Y = Bar->Top + 1; + FillConsoleOutputCharacter(0xC4, // '-', + Bar->Right - Bar->Left - 1, + coPos, + &Written); + + /* draw upper right corner */ + coPos.X = Bar->Right; + coPos.Y = Bar->Top + 1; + FillConsoleOutputCharacter(0xBF, // '+', + 1, + coPos, + &Written); + + /* draw left and right edge */ + for (i = Bar->Top + 2; i < Bar->Bottom; i++) + { + coPos.X = Bar->Left; + coPos.Y = i; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + + coPos.X = Bar->Right; + FillConsoleOutputCharacter(0xB3, //'|', + 1, + coPos, + &Written); + } + + /* draw lower left corner */ + coPos.X = Bar->Left; + coPos.Y = Bar->Bottom; + FillConsoleOutputCharacter(0xC0, // '+', + 1, + coPos, + &Written); + + /* draw lower edge */ + coPos.X = Bar->Left + 1; + coPos.Y = Bar->Bottom; + FillConsoleOutputCharacter(0xC4, // '-', + Bar->Right - Bar->Left - 1, + coPos, + &Written); + + /* draw lower right corner */ + coPos.X = Bar->Right; + coPos.Y = Bar->Bottom; + FillConsoleOutputCharacter(0xD9, // '+', + 1, + coPos, + &Written); +} + + +static VOID +DrawProgressBar(PPROGRESS Bar) +{ + CHAR TextBuffer[8]; + COORD coPos; + ULONG Written; + SHORT i; + + /* Print percentage */ + sprintf(TextBuffer, "%-3lu%%", Bar->Percent); + + coPos.X = Bar->Left + (Bar->Width - 2) / 2; + coPos.Y = Bar->Top; + WriteConsoleOutputCharacters(TextBuffer, + 4, + coPos); + + DrawBorder(Bar); + + /* Draw the bar */ + coPos.X = Bar->Left + 1; + for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++) + { + FillConsoleOutputAttribute(0x1E, /* Yellow on blue */ + Bar->Width - 2, + coPos, + &Written); + + FillConsoleOutputCharacter(' ', + Bar->Width - 2, + coPos, + &Written); + } + +} + + + +PPROGRESS +CreateProgressBar(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom) +{ + PPROGRESS Bar; + + Bar = (PPROGRESS)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PROGRESS)); + if (Bar == NULL) + return(NULL); + + Bar->Left = Left; + Bar->Top = Top; + Bar->Right = Right; + Bar->Bottom = Bottom; + + Bar->Width = Bar->Right - Bar->Left + 1; + + Bar->Percent = 0; + Bar->Pos = 0; + + Bar->StepCount = 0; + Bar->CurrentStep = 0; + + DrawProgressBar(Bar); + + return(Bar); +} + + +VOID +DestroyProgressBar(PPROGRESS Bar) +{ + RtlFreeHeap(ProcessHeap, + 0, + Bar); +} + +VOID +ProgressSetStepCount(PPROGRESS Bar, + ULONG StepCount) +{ + Bar->CurrentStep = 0; + Bar->StepCount = StepCount; + + DrawProgressBar(Bar); +} + + +VOID +ProgressNextStep(PPROGRESS Bar) +{ + CHAR TextBuffer[8]; + COORD coPos; + ULONG Written; + ULONG NewPercent; + ULONG NewPos; + + if ((Bar->StepCount == 0) || + (Bar->CurrentStep == Bar->StepCount)) + return; + + Bar->CurrentStep++; + + /* Calculate new percentage */ + NewPercent = (ULONG)(((100.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5); + + /* Redraw precentage if changed */ + if (Bar->Percent != NewPercent) + { + Bar->Percent = NewPercent; + + sprintf(TextBuffer, "%-3lu%%", Bar->Percent); + + coPos.X = Bar->Left + (Bar->Width - 2) / 2; + coPos.Y = Bar->Top; + WriteConsoleOutputCharacters(TextBuffer, + 4, + coPos); + } + + /* Calculate bar position */ + NewPos = (ULONG)((((float)(Bar->Width - 2) * 2.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5); + + /* Redraw bar if changed */ + if (Bar->Pos != NewPos) + { + Bar->Pos = NewPos; + + for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++) + { + coPos.X = Bar->Left + 1; + FillConsoleOutputCharacter(0xDB, + Bar->Pos / 2, + coPos, + &Written); + coPos.X += Bar->Pos/2; + + if (Pos & 1) + { + FillConsoleOutputCharacter(0xDD, + 1, + coPos, + &Written); + coPos.X++; + } + + if (coPos.X <= Bar->Right - 1) + { + FillConsoleOutputCharacter(' ', + Bar->Right - coPos.X, + coPos, + &Written); + } + } + } +} + +/* EOF */ diff --git a/subsys/system/usetup/progress.h b/subsys/system/usetup/progress.h new file mode 100644 index 0000000..45d1ed2 --- /dev/null +++ b/subsys/system/usetup/progress.h @@ -0,0 +1,67 @@ +/* + * 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$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/partlist.h + * PURPOSE: Partition list functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __PROGRESS_H__ +#define __PROGRESS_H__ + + +typedef struct _PROGRESS +{ + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; + + SHORT Width; + + ULONG Percent; + ULONG Pos; + + ULONG StepCount; + ULONG CurrentStep; +} PROGRESS, *PPROGRESS; + +/* FUNCTIONS ****************************************************************/ + +PPROGRESS +CreateProgressBar(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom); + +VOID +DestroyProgressBar(PPROGRESS Bar); + +VOID +ProgressSetStepCount(PPROGRESS Bar, + ULONG StepCount); + +VOID +ProgressNextStep(PPROGRESS Bar); + +#endif /* __PROGRESS_H__ */ + +/* EOF */ \ No newline at end of file diff --git a/subsys/system/usetup/usetup.c b/subsys/system/usetup/usetup.c index 87d28fa..20d1883 100644 --- a/subsys/system/usetup/usetup.c +++ b/subsys/system/usetup/usetup.c @@ -27,10 +27,16 @@ #include #include +#include +#include + #include "usetup.h" #include "console.h" #include "partlist.h" - +#include "inicache.h" +#include "filequeue.h" +#include "progress.h" +#include "bootsup.h" #define START_PAGE 0 @@ -43,7 +49,8 @@ #define PREPARE_COPY_PAGE 7 #define INSTALL_DIRECTORY_PAGE 8 #define FILE_COPY_PAGE 9 -#define INIT_SYSTEM_PAGE 10 +#define REGISTRY_PAGE 10 +#define BOOT_LOADER_PAGE 11 #define REPAIR_INTRO_PAGE 20 @@ -52,18 +59,38 @@ #define REBOOT_PAGE 102 +typedef struct _COPYCONTEXT +{ + ULONG TotalOperations; + ULONG CompletedOperations; + PPROGRESS ProgressBar; +} COPYCONTEXT, *PCOPYCONTEXT; + + /* GLOBALS ******************************************************************/ HANDLE ProcessHeap; -BOOL PartDataValid = FALSE; +BOOLEAN PartDataValid; PARTDATA PartData; -CHAR InstallDir[51]; +BOOLEAN ActivePartitionValid; +PARTDATA ActivePartition; UNICODE_STRING SourcePath; UNICODE_STRING SourceRootPath; +UNICODE_STRING InstallPath; +UNICODE_STRING DestinationPath; +UNICODE_STRING DestinationArcPath; +UNICODE_STRING DestinationRootPath; + +UNICODE_STRING SystemRootPath; /* Path to the active partition */ + +PINICACHE IniCache; + +HSPFILEQ SetupFileQueue = NULL; + /* FUNCTIONS ****************************************************************/ @@ -88,6 +115,215 @@ PrintString(char* fmt,...) } +static VOID +PopupError(PCHAR Text, + PCHAR Status) +{ + SHORT xScreen; + SHORT yScreen; + SHORT yTop; + SHORT xLeft; + COORD coPos; + ULONG Written; + ULONG Length; + ULONG MaxLength; + ULONG Lines; + PCHAR p; + PCHAR pnext; + BOOLEAN LastLine; + SHORT Width; + SHORT Height; + + /* Count text lines and longest line */ + MaxLength = 0; + Lines = 0; + pnext = Text; + while (TRUE) + { + p = strchr(pnext, '\n'); + if (p == NULL) + { + Length = strlen(pnext); + LastLine = TRUE; + } + else + { + Length = (ULONG)(p - pnext); + LastLine = FALSE; + } + + Lines++; + if (Length > MaxLength) + MaxLength = Length; + + if (LastLine == TRUE) + break; + + pnext = p + 1; + } + + /* Check length of status line */ + if (Status != NULL) + { + Length = strlen(Status); + if (Length > MaxLength) + MaxLength = Length; + } + + GetScreenSize(&xScreen, &yScreen); + + Width = MaxLength + 4; + Height = Lines + 2; + if (Status != NULL) + Height += 2; + + yTop = (yScreen - Height) / 2; + xLeft = (xScreen - Width) / 2; + + + /* Set screen attributes */ + coPos.X = xLeft; + for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++) + { + FillConsoleOutputAttribute(0x74, + Width, + coPos, + &Written); + } + + /* draw upper left corner */ + coPos.X = xLeft; + coPos.Y = yTop; + FillConsoleOutputCharacter(0xDA, // '+', + 1, + coPos, + &Written); + + /* draw upper edge */ + coPos.X = xLeft + 1; + coPos.Y = yTop; + FillConsoleOutputCharacter(0xC4, // '-', + Width - 2, + coPos, + &Written); + + /* draw upper right corner */ + coPos.X = xLeft + Width - 1; + coPos.Y = yTop; + FillConsoleOutputCharacter(0xBF, // '+', + 1, + coPos, + &Written); + + /* Draw right edge, inner space and left edge */ + for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++) + { + coPos.X = xLeft; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + + coPos.X = xLeft + 1; + FillConsoleOutputCharacter(' ', + Width - 2, + coPos, + &Written); + + coPos.X = xLeft + Width - 1; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + } + + /* draw lower left corner */ + coPos.X = xLeft; + coPos.Y = yTop + Height - 1; + FillConsoleOutputCharacter(0xC0, // '+', + 1, + coPos, + &Written); + + /* draw lower edge */ + coPos.X = xLeft + 1; + coPos.Y = yTop + Height - 1; + FillConsoleOutputCharacter(0xC4, // '-', + Width - 2, + coPos, + &Written); + + /* draw lower right corner */ + coPos.X = xLeft + Width - 1; + coPos.Y = yTop + Height - 1; + FillConsoleOutputCharacter(0xD9, // '+', + 1, + coPos, + &Written); + + /* Print message text */ + coPos.Y = yTop + 1; + pnext = Text; + while (TRUE) + { + p = strchr(pnext, '\n'); + if (p == NULL) + { + Length = strlen(pnext); + LastLine = TRUE; + } + else + { + Length = (ULONG)(p - pnext); + LastLine = FALSE; + } + + if (Length != 0) + { + coPos.X = xLeft + 2; + WriteConsoleOutputCharacters(pnext, + Length, + coPos); + } + + if (LastLine == TRUE) + break; + + coPos.Y++; + pnext = p + 1; + } + + /* Print separator line and status text */ + if (Status != NULL) + { + coPos.Y = yTop + Height - 3; + coPos.X = xLeft; + FillConsoleOutputCharacter(0xC3, // '+', + 1, + coPos, + &Written); + + coPos.X = xLeft + 1; + FillConsoleOutputCharacter(0xC4, // '-', + Width - 2, + coPos, + &Written); + + coPos.X = xLeft + Width - 1; + FillConsoleOutputCharacter(0xB4, // '+', + 1, + coPos, + &Written); + + coPos.Y++; + coPos.X = xLeft + 2; + WriteConsoleOutputCharacters(Status, + min(strlen(Status), Width - 4), + coPos); + } +} + + /* * Confirm quit setup * RETURNS @@ -97,65 +333,15 @@ PrintString(char* fmt,...) static BOOL ConfirmQuit(PINPUT_RECORD Ir) { - SHORT xScreen; - SHORT yScreen; - SHORT yTop; - SHORT xLeft; BOOL Result = FALSE; - PUSHORT pAttributes = NULL; - PUCHAR pCharacters = NULL; - COORD Pos; - - GetScreenSize(&xScreen, &yScreen); - yTop = (yScreen - 10) / 2; - xLeft = (xScreen - 52) / 2; - - /* Save screen */ -#if 0 - Pos.X = 0; - Pos.Y = 0; - pAttributes = (PUSHORT)RtlAllocateHeap(ProcessHeap, - 0, - xScreen * yScreen * sizeof(USHORT)); -CHECKPOINT1; -DPRINT1("pAttributes %p\n", pAttributes); - ReadConsoleOutputAttributes(pAttributes, - xScreen * yScreen, - Pos, - NULL); -CHECKPOINT1; - pCharacters = (PUCHAR)RtlAllocateHeap(ProcessHeap, - 0, - xScreen * yScreen * sizeof(UCHAR)); -CHECKPOINT1; - ReadConsoleOutputCharacters(pCharacters, - xScreen * yScreen, - Pos, - NULL); -CHECKPOINT1; -#endif - /* Draw popup window */ - SetTextXY(xLeft, yTop, - "+----------------------------------------------------+"); - SetTextXY(xLeft, yTop + 1, - "| ReactOS 0.0.20 is not completely installed on your |"); - SetTextXY(xLeft, yTop + 2, - "| computer. If you quit Setup now, you will need to |"); - SetTextXY(xLeft, yTop + 3, - "| run Setup again to install ReactOS. |"); - SetTextXY(xLeft, yTop + 4, - "| |"); - SetTextXY(xLeft, yTop + 5, - "| * Press ENTER to continue Setup. |"); - SetTextXY(xLeft, yTop + 6, - "| * Press F3 to quit Setup. |"); - SetTextXY(xLeft, yTop + 7, - "+----------------------------------------------------+"); - SetTextXY(xLeft, yTop + 8, - "| F3= Quit ENTER = Continue |"); - SetTextXY(xLeft, yTop + 9, - "+----------------------------------------------------+"); + PopupError("ReactOS is not completely installed on your\n" + "computer. If you quit Setup now, you will need to\n" + "run Setup again to install ReactOS.\n" + "\n" + " * Press ENTER to continue Setup.\n" + " * Press F3 to quit Setup.", + "F3= Quit ENTER = Continue"); while(TRUE) { @@ -174,34 +360,11 @@ CHECKPOINT1; } } - /* Restore screen */ -#if 0 -CHECKPOINT1; - WriteConsoleOutputAttributes(pAttributes, - xScreen * yScreen, - Pos, - NULL); -CHECKPOINT1; - - WriteConsoleOutputCharacters(pCharacters, - xScreen * yScreen, - Pos); -CHECKPOINT1; - - RtlFreeHeap(ProcessHeap, - 0, - pAttributes); - RtlFreeHeap(ProcessHeap, - 0, - pCharacters); -#endif - return(Result); } - /* * Start page * RETURNS @@ -211,6 +374,12 @@ static ULONG StartPage(PINPUT_RECORD Ir) { NTSTATUS Status; + WCHAR FileNameBuffer[MAX_PATH]; + UNICODE_STRING FileName; + + PINICACHESECTION Section; + PWCHAR Value; + SetStatusText(" Please wait..."); @@ -226,26 +395,91 @@ StartPage(PINPUT_RECORD Ir) PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath); } - /* - * FIXME: Open and load txtsetup.sif here. A pointer (or handle) to the - * ini data should be stored in a global variable. - * The full path to txtsetup.sif is created by appending '\txtsetup.sif' - * to the unicode string SourceRootPath. - */ - SetStatusText(" ENTER = Continue"); + /* Load txtsetup.sif from install media. */ + wcscpy(FileNameBuffer, SourceRootPath.Buffer); + wcscat(FileNameBuffer, L"\\install\\txtsetup.sif"); + RtlInitUnicodeString(&FileName, + FileNameBuffer); - while(TRUE) + IniCache = NULL; + Status = IniCacheLoad(&IniCache, + &FileName, + TRUE); + if (!NT_SUCCESS(Status)) { - ConInKey(Ir); + PopupError("Setup failed to load the file TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + while(TRUE) { - return(INTRO_PAGE); + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Open 'Version' section */ + Section = IniCacheGetSection(IniCache, + L"Version"); + if (Section == NULL) + { + PopupError("Setup found a corrupt TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + + /* Get pointer 'Signature' key */ + Status = IniCacheGetKey(Section, + L"Signature", + &Value); + if (!NT_SUCCESS(Status)) + { + PopupError("Setup found a corrupt TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Check 'Signature' string */ + if (_wcsicmp(Value, L"$ReactOS$") != 0) + { + PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } } - return(START_PAGE); + return(INTRO_PAGE); } @@ -258,9 +492,9 @@ RepairIntroPage(PINPUT_RECORD Ir) SetTextXY(6, 12, "The repair functions are not implemented yet."); - SetTextXY(8, 15, "\xf9 Press ESC to return to the main page."); + SetTextXY(8, 15, "\xfa Press ESC to return to the main page."); - SetTextXY(8, 17, "\xf9 Press ENTER to reboot your computer."); + SetTextXY(8, 17, "\xfa Press ENTER to reboot your computer."); SetStatusText(" ESC = Main page ENTER = Reboot"); @@ -297,13 +531,13 @@ IntroPage(PINPUT_RECORD Ir) SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your"); SetTextXY(6, 12, "computer and prepares the second part of the setup."); - SetTextXY(8, 15, "\xf9 Press ENTER to install ReactOS."); + SetTextXY(8, 15, "\xfa Press ENTER to install ReactOS."); - SetTextXY(8, 17, "\xf9 Press E to start the emergency repair console."); + SetTextXY(8, 17, "\xfa Press E to start the emergency repair console."); - SetTextXY(8, 19, "\xf9 Press R to repair ReactOS."); + SetTextXY(8, 19, "\xfa Press R to repair ReactOS."); - SetTextXY(8, 21, "\xf9 Press F3 to quit without installing ReactOS."); + SetTextXY(8, 21, "\xfa Press F3 to quit without installing ReactOS."); SetStatusText(" ENTER = Continue F3 = Quit"); @@ -350,13 +584,12 @@ InstallIntroPage(PINPUT_RECORD Ir) SetTextXY(8, 14, "- Formatting partitions."); SetTextXY(8, 15, "- Support for non-FAT file systems."); SetTextXY(8, 16, "- Checking file systems."); - SetTextXY(8, 17, "- Installing the bootloader."); - SetTextXY(8, 21, "\xf9 Press ENTER to install ReactOS."); + SetTextXY(8, 21, "\xfa Press ENTER to install ReactOS."); - SetTextXY(8, 23, "\xf9 Press F3 to quit without installing ReactOS."); + SetTextXY(8, 23, "\xfa Press F3 to quit without installing ReactOS."); SetStatusText(" ENTER = Continue F3 = Quit"); @@ -385,6 +618,7 @@ InstallIntroPage(PINPUT_RECORD Ir) static ULONG SelectPartitionPage(PINPUT_RECORD Ir) { + WCHAR PathBuffer[MAX_PATH]; PPARTLIST PartList; SHORT xScreen; SHORT yScreen; @@ -392,13 +626,16 @@ SelectPartitionPage(PINPUT_RECORD Ir) SetTextXY(6, 8, "The list below shows existing partitions and unused disk"); SetTextXY(6, 9, "space for new partitions."); - SetTextXY(8, 11, "\xf9 Press UP or DOWN to select a list entry."); - SetTextXY(8, 13, "\xf9 Press ENTER to install ReactOS onto the selected partition."); - SetTextXY(8, 15, "\xf9 Press C to create a new partition."); - SetTextXY(8, 17, "\xf9 Press D to delete an existing partition."); + SetTextXY(8, 11, "\xfa Press UP or DOWN to select a list entry."); + SetTextXY(8, 13, "\xfa Press ENTER to install ReactOS onto the selected partition."); + SetTextXY(8, 15, "\xfa Press C to create a new partition."); + SetTextXY(8, 17, "\xfa Press D to delete an existing partition."); SetStatusText(" Please wait..."); + RtlFreeUnicodeString(&DestinationPath); + RtlFreeUnicodeString(&DestinationRootPath); + GetScreenSize(&xScreen, &yScreen); PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3); @@ -436,8 +673,28 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - PartDataValid = GetPartitionData(PartList, &PartData); + PartDataValid = GetSelectedPartition(PartList, + &PartData); + ActivePartitionValid = GetActiveBootPartition(PartList, + &ActivePartition); DestroyPartitionList(PartList); + + RtlFreeUnicodeString(&DestinationRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + RtlCreateUnicodeString(&DestinationRootPath, + PathBuffer); + + RtlFreeUnicodeString(&SystemRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + ActivePartition.DiskNumber, + ActivePartition.PartNumber); + RtlCreateUnicodeString(&SystemRootPath, + PathBuffer); + return(SELECT_FILE_SYSTEM_PAGE); } @@ -512,30 +769,32 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartType = "Unknown"; } - SetTextXY(6, 8, "ReactOS will be installed"); + SetTextXY(6, 8, "Setup will install ReactOS on"); + + PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s on", + PartData.PartNumber, + PartSize, + PartUnit, + PartType); - PrintTextXY(8, 9, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu.", + PrintTextXY(8, 12, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).", PartData.DiskNumber, DiskSize, DiskUnit, PartData.Port, PartData.Bus, - PartData.Id); + PartData.Id, + &PartData.DriverName); - PrintTextXY(8, 10, "on Partition %lu (%I64u %s) %s", - PartData.PartNumber, - PartSize, - PartUnit, - PartType); - SetTextXY(6, 13, "Select a file system for the partition from the list below."); + SetTextXY(6, 17, "Select a file system for the partition from the list below."); - SetTextXY(8, 15, "\xf9 Press UP or DOWN to select a file system."); - SetTextXY(8, 17, "\xf9 Press ENTER to format the partition."); - SetTextXY(8, 19, "\xf9 Press ESC to select another partition."); + SetTextXY(8, 19, "\xfa Press UP or DOWN to select a file system."); + SetTextXY(8, 21, "\xfa Press ENTER to format the partition."); + SetTextXY(8, 23, "\xfa Press ESC to select another partition."); /* FIXME: use a real list later */ - SetInvertedTextXY(6, 22, " Keep current file system (no changes) "); + SetInvertedTextXY(6, 26, " Keep current file system (no changes) "); SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit"); @@ -602,21 +861,56 @@ CheckFileSystemPage(PINPUT_RECORD Ir) static ULONG InstallDirectoryPage(PINPUT_RECORD Ir) { + PINICACHESECTION Section; + WCHAR PathBuffer[MAX_PATH]; + WCHAR InstallDir[51]; + PWCHAR DefaultPath; ULONG Length; + NTSTATUS Status; + + /* Open 'SetupData' section */ + Section = IniCacheGetSection(IniCache, + L"SetupData"); + if (Section == NULL) + { + PopupError("Setup failed to find the 'SetupData' section\n" + "in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Read the 'DefaultPath' key */ + Status = IniCacheGetKey(Section, + L"DefaultPath", + &DefaultPath); + if (!NT_SUCCESS(Status)) + { + wcscpy(InstallDir, L"\\reactos"); + } + else + { + wcscpy(InstallDir, DefaultPath); + } + Length = wcslen(InstallDir); SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a"); SetTextXY(6, 9, "directory where you want ReactOS to be installed:"); - strcpy(InstallDir, "\\reactos"); - Length = strlen(InstallDir); - SetInputTextXY(8, 11, 51, InstallDir); SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete"); SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to"); SetTextXY(6, 16, "be installed."); - SetStatusText(" ENTER = Continue F3 = Quit"); while(TRUE) @@ -632,6 +926,35 @@ InstallDirectoryPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { + /* Create 'InstallPath' string */ + RtlFreeUnicodeString(&InstallPath); + RtlCreateUnicodeString(&InstallPath, + InstallDir); + + /* Create 'DestinationPath' string */ + RtlFreeUnicodeString(&DestinationPath); + wcscpy(PathBuffer, + DestinationRootPath.Buffer); + if (InstallDir[0] != L'\\') + wcscat(PathBuffer, + L"\\"); + wcscat(PathBuffer, InstallDir); + RtlCreateUnicodeString(&DestinationPath, + PathBuffer); + + /* Create 'DestinationArcPath' */ + RtlFreeUnicodeString(&DestinationArcPath); + swprintf(PathBuffer, + L"multi(0)disk(0)rdisk(%lu)partition(%lu)", + PartData.DiskNumber, + PartData.PartNumber); + if (InstallDir[0] != L'\\') + wcscat(PathBuffer, + L"\\"); + wcscat(PathBuffer, InstallDir); + RtlCreateUnicodeString(&DestinationArcPath, + PathBuffer); + return(PREPARE_COPY_PAGE); } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */ @@ -647,7 +970,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { if (Length < 50) { - InstallDir[Length] = Ir->Event.KeyEvent.uChar.AsciiChar; + InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar; Length++; InstallDir[Length] = 0; SetInputTextXY(8, 11, 51, InstallDir); @@ -662,152 +985,234 @@ InstallDirectoryPage(PINPUT_RECORD Ir) static ULONG PrepareCopyPage(PINPUT_RECORD Ir) { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - CHAR PathBuffer[MAX_PATH]; - UNICODE_STRING PathName; - HANDLE DirectoryHandle; - NTSTATUS Status; - PCHAR End; + WCHAR PathBuffer[MAX_PATH]; + PINICACHESECTION DirSection; + PINICACHESECTION FilesSection; + PINICACHEITERATOR Iterator; + PWCHAR KeyName; + PWCHAR KeyValue; ULONG Length; - ULONG i; + NTSTATUS Status; - PCHAR Dirs[]= { - "System32", - "System32\\Config", - "System32\\Drivers", - "Inf", - "Help", - "Fonts", - NULL}; + PWCHAR FileKeyName; + PWCHAR FileKeyValue; + PWCHAR DirKeyName; + PWCHAR DirKeyValue; SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. "); - SetTextXY(8, 12, "Build file copy list"); +// SetTextXY(8, 12, "Build file copy list"); - SetTextXY(8, 14, "Create directories"); +// SetTextXY(8, 14, "Create directories"); - SetStatusText(" Please wait..."); +// SetStatusText(" Please wait..."); - /* build the file copy list */ + /* + * Build the file copy list + */ + SetStatusText(" Building the file copy list..."); +// SetInvertedTextXY(8, 12, "Build file copy list"); - SetInvertedTextXY(8, 12, "Build file copy list"); - /* FIXME: build that list */ + /* Open 'Directories' section */ + DirSection = IniCacheGetSection(IniCache, + L"Directories"); + if (DirSection == NULL) + { + PopupError("Setup failed to find the 'Directories' section\n" + "in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); - SetTextXY(8, 12, "Build file copy list"); - SetHighlightedTextXY(50, 12, "Done"); + while(TRUE) + { + ConInKey(Ir); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Open 'SourceFiles' section */ + FilesSection = IniCacheGetSection(IniCache, + L"SourceFiles"); + if (FilesSection == NULL) + { + PopupError("Setup failed to find the 'SourceFiles' section\n" + "in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - /* create directories */ - SetInvertedTextXY(8, 14, "Create directories"); + /* Create the file queue */ + SetupFileQueue = SetupOpenFileQueue(); + if (SetupFileQueue == NULL) + { + PopupError("Setup failed to open the copy file queue.\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } /* - * FIXME: Enumerate the ini section 'Directories' and create all "relative" directories + * Enumerate the files in the 'SourceFiles' section + * and add them to the file queue. */ + Iterator = IniCacheFindFirstValue(FilesSection, + &FileKeyName, + &FileKeyValue); + if (Iterator != NULL) + { + do + { + DPRINT1("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue); + /* Lookup target directory */ + Status = IniCacheGetKey(DirSection, + FileKeyValue, + &DirKeyValue); + if (!NT_SUCCESS(Status)) + { + /* FIXME: Handle error! */ + DPRINT1("IniCacheGetKey() failed (Status 0x%lX)\n", Status); + } + + if (SetupQueueCopy(SetupFileQueue, + SourceRootPath.Buffer, + L"\\install", + FileKeyName, + DirKeyValue, + NULL) == FALSE) + { + /* FIXME: Handle error! */ + DPRINT1("SetupQueueCopy() failed\n"); + } + } + while (IniCacheFindNextValue(Iterator, &FileKeyName, &FileKeyValue)); - /* create the systemroot directory */ - sprintf(PathBuffer, - "\\Device\\Harddisk%lu\\Partition%lu", - PartData.DiskNumber, - PartData.PartNumber); - if (InstallDir[0] != '\\') - strcat(PathBuffer, "\\"); - strcat(PathBuffer, InstallDir); + IniCacheFindClose(Iterator); + } + + /* Report that the file queue has been built */ +// SetTextXY(8, 12, "Build file copy list"); +// SetHighlightedTextXY(50, 12, "Done"); + + /* create directories */ + SetStatusText(" Creating directories..."); +// SetInvertedTextXY(8, 14, "Create directories"); - /* remove trailing backslash */ - Length = strlen(PathBuffer); + + /* + * FIXME: + * Install directories like '\reactos\test' are not handled yet. + */ + + /* Get destination path */ + wcscpy(PathBuffer, DestinationPath.Buffer); + + /* Remove trailing backslash */ + Length = wcslen(PathBuffer); if ((Length > 0) && (PathBuffer[Length - 1] == '\\')) PathBuffer[Length - 1] = 0; - RtlCreateUnicodeStringFromAsciiz(&PathName, - PathBuffer); - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = &PathName; - ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = NULL; - ObjectAttributes.SecurityQualityOfService = NULL; - - Status = NtCreateFile(&DirectoryHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_DIRECTORY, - 0, - FILE_CREATE, - FILE_DIRECTORY_FILE, - NULL, - 0); - if (!NT_SUCCESS(Status)) + /* Create the install directory */ + Status = CreateDirectory(PathBuffer); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) + { + DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + + PopupError("Setup could not create the install directory.", + "ENTER = Reboot computer"); + + while(TRUE) { - PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status); + ConInKey(Ir); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } - else + } + + + /* Enumerate the directory values and create the subdirectories */ + Iterator = IniCacheFindFirstValue(DirSection, + &KeyName, + &KeyValue); + if (Iterator != NULL) + { + do { - PrintTextXY(6, 25, "Created directory."); - NtClose (DirectoryHandle); - } + if (KeyValue[0] == L'\\' && KeyValue[1] != 0) + { + DPRINT("Absolute Path: '%S'\n", KeyValue); + wcscpy(PathBuffer, DestinationRootPath.Buffer); + wcscat(PathBuffer, KeyValue); - RtlFreeUnicodeString(&PathName); + DPRINT("FullPath: '%S'\n", PathBuffer); + } + else if (KeyValue[0] != L'\\') + { + DPRINT("RelativePath: '%S'\n", KeyValue); + wcscpy(PathBuffer, DestinationPath.Buffer); + wcscat(PathBuffer, L"\\"); + wcscat(PathBuffer, KeyValue); + DPRINT("FullPath: '%S'\n", PathBuffer); - /* create the subdirectories */ + Status = CreateDirectory(PathBuffer); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) + { + DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); - /* append backslash and init end pointer */ - strcat(PathBuffer, "\\"); - Length = strlen(PathBuffer); - End = &PathBuffer[Length]; + PopupError("Setup could not create install directories.", + "ENTER = Reboot computer"); - for (i = 0; Dirs[i] != NULL; i++) - { - strcpy(End, Dirs[i]); - - - RtlCreateUnicodeStringFromAsciiz(&PathName, - PathBuffer); - - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = &PathName; - ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = NULL; - ObjectAttributes.SecurityQualityOfService = NULL; - - Status = NtCreateFile(&DirectoryHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_DIRECTORY, - 0, - FILE_CREATE, - FILE_DIRECTORY_FILE, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status); - } - else - { - PrintTextXY(6, 25, "Created directory."); - NtClose (DirectoryHandle); - } + while(TRUE) + { + ConInKey(Ir); - RtlFreeUnicodeString(&PathName); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + IniCacheFindClose(Iterator); + return(QUIT_PAGE); + } + } + } + } } + while (IniCacheFindNextValue(Iterator, &KeyName, &KeyValue)); + IniCacheFindClose(Iterator); + } + + + return(FILE_COPY_PAGE); +#if 0 SetTextXY(8, 14, "Create directories"); SetHighlightedTextXY(50, 14, "Done"); @@ -832,16 +1237,81 @@ PrepareCopyPage(PINPUT_RECORD Ir) } return(PREPARE_COPY_PAGE); +#endif +} + + +static ULONG +FileCopyCallback(PVOID Context, + ULONG Notification, + PVOID Param1, + PVOID Param2) +{ + PCOPYCONTEXT CopyContext; + + CopyContext = (PCOPYCONTEXT)Context; + + switch (Notification) + { + case SPFILENOTIFY_STARTSUBQUEUE: + CopyContext->TotalOperations = (ULONG)Param2; + ProgressSetStepCount(CopyContext->ProgressBar, + CopyContext->TotalOperations); + break; + + case SPFILENOTIFY_STARTCOPY: + /* Display copy message */ + PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1); + + PrintTextXYN(6, 18, 60, "File %lu of %lu", + CopyContext->CompletedOperations + 1, + CopyContext->TotalOperations); + break; + + + case SPFILENOTIFY_ENDCOPY: + CopyContext->CompletedOperations++; + ProgressNextStep(CopyContext->ProgressBar); + break; + } + + return(0); } static ULONG FileCopyPage(PINPUT_RECORD Ir) { + COPYCONTEXT CopyContext; + SHORT xScreen; + SHORT yScreen; + + SetStatusText(" Please wait..."); SetTextXY(6, 8, "Copying files"); + GetScreenSize(&xScreen, &yScreen); + + CopyContext.TotalOperations = 0; + CopyContext.CompletedOperations = 0; + CopyContext.ProgressBar = CreateProgressBar(6, + yScreen - 14, + xScreen - 7, + yScreen - 10); + + SetupCommitFileQueue(SetupFileQueue, + DestinationRootPath.Buffer, + InstallPath.Buffer, + (PSP_FILE_CALLBACK)FileCopyCallback, + &CopyContext); + + SetupCloseFileQueue(SetupFileQueue); + + DestroyProgressBar(CopyContext.ProgressBar); + return(REGISTRY_PAGE); + +#if 0 SetStatusText(" ENTER = Continue F3 = Quit"); while(TRUE) @@ -857,123 +1327,775 @@ FileCopyPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - return(INIT_SYSTEM_PAGE); + return(REGISTRY_PAGE); } } return(FILE_COPY_PAGE); +#endif } -#if 0 -static NTSTATUS -UpdateSystemRootLink(VOID) + +static ULONG +RegistryPage(PINPUT_RECORD Ir) { OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING LinkName; - UNICODE_STRING TargetName; - CHAR TargetBuffer[MAX_PATH]; - HANDLE Handle; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE KeyHandle; NTSTATUS Status; - RtlInitUnicodeString(&LinkName, - L"\\SystemRoot"); + SetTextXY(6, 8, "Setup initializes system settings"); + + +// SetTextXY(6, 12, "Create registry hives"); + +// SetTextXY(6, 14, "Update registry hives"); + +// SetStatusText(" Please wait..."); + + SetStatusText(" Creating registry hives..."); + + /* Create the 'secret' InstallPath key */ + RtlInitUnicodeStringFromLiteral(&KeyName, + L"\\Registry\\Machine\\HARDWARE"); InitializeObjectAttributes(&ObjectAttributes, - &LinkName, - OBJ_OPENLINK, + &KeyName, + OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = NtOpenKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + PopupError("Setup failed to open the HARDWARE registry key.", + "ENTER = Reboot computer"); - Status = NtOpenSymbolicLinkObject(&Handle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes); + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + RtlInitUnicodeStringFromLiteral(&ValueName, + L"InstallPath"); + + Status = NtSetValueKey(KeyHandle, + &ValueName, + 0, + REG_SZ, + (PVOID)DestinationPath.Buffer, + DestinationPath.Length); + NtClose(KeyHandle); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); + PopupError("Setup failed to set the \'InstallPath\' registry value.", + "ENTER = Reboot computer"); - Status = NtMakeTemporaryObject(Handle); - NtClose(Handle); + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Create the standard hives */ + Status = NtInitializeRegistry(TRUE); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status); + PopupError("Setup failed to initialize the registry.", + "ENTER = Reboot computer"); - sprintf(TargetBuffer, - "\\Device\\Harddisk%lu\\Partition%lu", - PartData.DiskNumber, - PartData.PartNumber); - if (InstallDir[0] != '\\') - strcat(TargetBuffer, "\\"); - strcat(TargetBuffer, InstallDir); + while(TRUE) + { + ConInKey(Ir); - RtlCreateUnicodeStringFromAsciiz(&TargetName, - TargetBuffer); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - Status = NtCreateSymbolicLinkObject(&Handle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &TargetName); - RtlFreeUnicodeString(&TargetName); + /* Update registry */ + SetStatusText(" Updating registry hives..."); - if (!NT_SUCCESS(Status)) - return(Status); + /* FIXME: Create key '\Registry\Machine\System\Setup' */ - NtClose(Handle); + /* FIXME: Create value 'SystemSetupInProgress' */ - return(STATUS_SUCCESS); -} + + return(BOOT_LOADER_PAGE); + +#if 0 + SetStatusText(" ENTER = Continue F3 = Quit"); + + while(TRUE) + { + ConInKey(Ir); + + if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + { + if (ConfirmQuit(Ir) == TRUE) + return(QUIT_PAGE); + break; + } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(BOOT_LOADER_PAGE); + } + } + + return(REGISTRY_PAGE); #endif +} static ULONG -InitSystemPage(PINPUT_RECORD Ir) +BootLoaderPage(PINPUT_RECORD Ir) { -#if 0 + WCHAR SrcPath[MAX_PATH]; + WCHAR DstPath[MAX_PATH]; + PINICACHE IniCache; + PINICACHESECTION IniSection; NTSTATUS Status; -#endif - SetTextXY(6, 8, "Initializing system settings"); + SetTextXY(6, 8, "Installing the boot loader"); + SetStatusText(" Please wait..."); - SetTextXY(6, 12, "Create registry hives"); + if (ActivePartitionValid == FALSE) + { + DPRINT1("Error: no active partition found\n"); + PopupError("Setup could not find an active partiton\n", + "ENTER = Reboot computer"); - SetTextXY(6, 14, "Update registry hives"); + while(TRUE) + { + ConInKey(Ir); - SetTextXY(6, 16, "Install/update boot manager"); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - SetStatusText(" Please wait..."); + if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED) + { + DPRINT1("Error: active partition invalid (unused)\n"); + PopupError("The active partition is unused (invalid).\n", + "ENTER = Reboot computer"); -#if 0 - /* - * Initialize registry - */ + while(TRUE) + { + ConInKey(Ir); - /* Update 'SystemRoot' link */ - Status = UpdateSystemRootLink(); - if (!NT_SUCCESS(Status)) + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + if (ActivePartition.PartType == 0x0A) + { + /* OS/2 boot manager partition */ + DPRINT1("Found OS/2 boot manager partition\n"); + PopupError("Setup found an OS/2 boot manager partiton.\n" + "The OS/2 boot manager is not supported yet!", + "ENTER = Reboot computer"); + + while(TRUE) { + ConInKey(Ir); - PrintTextXY(6, 25, "UpdateSystemRootLink() failed (Status = 0x%08lx)", Status); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } + } + else if (ActivePartition.PartType == 0x83) + { + /* Linux ext2 partition */ + DPRINT1("Found Linux ext2 partition\n"); + PopupError("Setup found a Linux ext2 partiton.\n" + "Linux ext2 partitions are not supported yet!", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + else if (ActivePartition.PartType == PARTITION_IFS) + { + /* NTFS partition */ + DPRINT1("Found NTFS partition\n"); + PopupError("Setup found an NTFS partiton.\n" + "NTFS partitions are not supported yet!", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); - Status = NtInitializeRegistry(TRUE); - if (!NT_SUCCESS(Status)) + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + else if ((ActivePartition.PartType == PARTITION_FAT_12) || + (ActivePartition.PartType == PARTITION_FAT_16) || + (ActivePartition.PartType == PARTITION_HUGE) || + (ActivePartition.PartType == PARTITION_XINT13) || + (ActivePartition.PartType == PARTITION_FAT32) || + (ActivePartition.PartType == PARTITION_FAT32_XINT13)) + { + /* FAT or FAT32 partition */ + DPRINT1("System path: '%wZ'\n", &SystemRootPath); + + if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE || + DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE) { + /* Search root directory for 'ntldr' and 'boot.ini'. */ + DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n"); + + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + PopupError("Setup failed to copy 'freeldr.sys'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Create or update freeldr.ini */ + if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE) + { + /* Create new 'freeldr.ini' */ + DPRINT1("Create new 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = CreateFreeLoaderIniForReactos(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); + PopupError("Setup failed to create 'freeldr.ini'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Install new bootcode */ + if ((ActivePartition.PartType == PARTITION_FAT32) || + (ActivePartition.PartType == PARTITION_FAT32_XINT13)) + { + /* Install FAT32 bootcode */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\bootsect.ros"); + + DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); + Status = InstallFat32BootCodeToFile(SrcPath, + DstPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT32 bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); - PrintTextXY(6, 26, "NtInitializeRegistry() failed (Status = 0x%08lx)", Status); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + else + { + /* Install FAT16 bootcode */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\bootsect.ros"); + + DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); + Status = InstallFat16BootCodeToFile(SrcPath, + DstPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + + /* Update 'boot.ini' */ + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\boot.ini"); + + DPRINT1("Update 'boot.ini': %S\n", DstPath); + Status = UpdateBootIni(DstPath, + L"C:\\bootsect.ros", + L"\"ReactOS\""); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status); + PopupError("Setup failed to update \'boot.ini\'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + DPRINT1("Update existing 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + PopupError("Setup failed to update 'freeldr.ini'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } } -#endif + else if (DoesFileExist(SystemRootPath.Buffer, L"io.sys") == TRUE || + DoesFileExist(SystemRootPath.Buffer, L"msdos.sys") == TRUE) + { + /* Search for root directory for 'io.sys' and 'msdos.sys'. */ + DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); - /* - * Update registry - */ + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.sys"); - /* FIXME: Create key '\Registry\Machine\System\Setup' */ + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + PopupError("Setup failed to copy 'freeldr.sys'.", + "ENTER = Reboot computer"); - /* FIXME: Create value 'SystemSetupInProgress' */ + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Create or update 'freeldr.ini' */ + if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE) + { + /* Create new 'freeldr.ini' */ + DPRINT1("Create new 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = CreateFreeLoaderIniForDos(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status); + PopupError("Setup failed to create 'freeldr.ini'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Save current bootsector as 'BOOTSECT.DOS' */ + wcscpy(SrcPath, SystemRootPath.Buffer); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\bootsect.dos"); + + DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); + Status = SaveCurrentBootSector(SrcPath, + DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); + PopupError("Setup failed to save the current bootsector.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Install new bootsector */ + if ((ActivePartition.PartType == PARTITION_FAT32) || + (ActivePartition.PartType == PARTITION_FAT32_XINT13)) + { + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + + DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer); + Status = InstallFat32BootCodeToDisk(SrcPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT32 bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + else + { + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + + DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer); + Status = InstallFat16BootCodeToDisk(SrcPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + PopupError("Setup failed to update 'freeldr.ini'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + } + else + { + /* No or unknown boot loader */ + DPRINT1("No or unknown boot loader found\n"); + + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + PopupError("Setup failed to copy 'freeldr.sys'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Create or update 'freeldr.ini' */ + if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE) + { + /* Create new freeldr.ini */ + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = CreateFreeLoaderIniForReactos(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); + PopupError("Setup failed to create \'freeldr.ini\'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Save current bootsector as 'BOOTSECT.OLD' */ + wcscpy(SrcPath, SystemRootPath.Buffer); + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\bootsect.old"); + + DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); + Status = SaveCurrentBootSector(SrcPath, + DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); + PopupError("Setup failed save the current bootsector.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + + /* Install new bootsector */ + if ((ActivePartition.PartType == PARTITION_FAT32) || + (ActivePartition.PartType == PARTITION_FAT32_XINT13)) + { + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + + DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer); + Status = InstallFat32BootCodeToDisk(SrcPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT32 bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + else + { + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + + DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer); + Status = InstallFat16BootCodeToDisk(SrcPath, + SystemRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the FAT bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath.Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + PopupError("Setup failed to update 'freeldr.ini'.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + } + } + } + else + { + /* Unknown partition */ + DPRINT1("Unknown partition found\n"); + PopupError("Setup found an unknown partiton type.\n" + "This partition type is not supported!", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + return(SUCCESS_PAGE); +#if 0 SetStatusText(" ENTER = Continue F3 = Quit"); while(TRUE) @@ -993,17 +2115,19 @@ InitSystemPage(PINPUT_RECORD Ir) } } - return(INIT_SYSTEM_PAGE); + return(BOOT_LOADER_PAGE); +#endif } + static ULONG QuitPage(PINPUT_RECORD Ir) { SetTextXY(10, 6, "ReactOS is not completely installed"); SetTextXY(10, 8, "Remove floppy disk from Drive A: and"); - SetTextXY(10, 9, "all CD-ROMs from CD-Drive."); + SetTextXY(10, 9, "all CD-ROMs from CD-Drives."); SetTextXY(10, 11, "Press ENTER to reboot your computer."); @@ -1066,12 +2190,24 @@ NtProcessStartup(PPEB Peb) 0,0,0,0,0); } + PartDataValid = FALSE; + + /* Initialize global unicode strings */ + RtlInitUnicodeString(&SourcePath, NULL); + RtlInitUnicodeString(&SourceRootPath, NULL); + RtlInitUnicodeString(&InstallPath, NULL); + RtlInitUnicodeString(&DestinationPath, NULL); + RtlInitUnicodeString(&DestinationArcPath, NULL); + RtlInitUnicodeString(&DestinationRootPath, NULL); + RtlInitUnicodeString(&SystemRootPath, NULL); + + Page = START_PAGE; while (Page != REBOOT_PAGE) { ClearScreen(); - SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup "); + SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup "); switch (Page) { @@ -1124,8 +2260,12 @@ NtProcessStartup(PPEB Peb) Page = FileCopyPage(&Ir); break; - case INIT_SYSTEM_PAGE: - Page = InitSystemPage(&Ir); + case REGISTRY_PAGE: + Page = RegistryPage(&Ir); + break; + + case BOOT_LOADER_PAGE: + Page = BootLoaderPage(&Ir); break; diff --git a/subsys/system/winlogon/winlogon.c b/subsys/system/winlogon/winlogon.c index ebeb403..2b3da97 100644 --- a/subsys/system/winlogon/winlogon.c +++ b/subsys/system/winlogon/winlogon.c @@ -18,7 +18,7 @@ #include -#define NDEBUG +#define DBG #include /* GLOBALS ******************************************************************/ @@ -30,7 +30,7 @@ HDESK ScreenSaverDesktop; /* WinSta0\Screen-Saver */ /* FUNCTIONS *****************************************************************/ -void PrintString (char* fmt,...) +static void PrintString (char* fmt,...) { char buffer[512]; va_list ap; @@ -43,7 +43,7 @@ void PrintString (char* fmt,...) } -BOOLEAN StartServices(VOID) +static BOOLEAN StartServices(VOID) { HANDLE ServicesInitEvent; BOOLEAN Result; @@ -64,44 +64,56 @@ BOOLEAN StartServices(VOID) StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = 0; + PrintString("WL: Creating new process - \"services.exe\".\n"); + Result = CreateProcess(CommandLine, - NULL, - NULL, - NULL, - FALSE, - DETACHED_PROCESS, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); + NULL, + NULL, + NULL, + FALSE, + DETACHED_PROCESS, + NULL, + NULL, + &StartupInfo, + &ProcessInformation); if (!Result) { - PrintString("WL: Failed to execute services\n"); - return FALSE; + PrintString("WL: Failed to execute services\n"); + return FALSE; } /* wait for event creation (by SCM) for max. 20 seconds */ for (Count = 0; Count < 20; Count++) { - Sleep(1000); + Sleep(1000); - ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE, - FALSE, - "SvcctrlStartEvent_A3725DX"); - if (ServicesInitEvent != NULL) - { - break; - } + //DbgPrint("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n"); + ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE, + FALSE, + "SvcctrlStartEvent_A3725DX"); + if (ServicesInitEvent != NULL) + { + break; + } } + if (ServicesInitEvent == NULL) + { + DbgPrint("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n"); + return FALSE; + } + /* wait for event signalization */ + //DbgPrint("WL: Waiting forever on event handle: %x\n", ServicesInitEvent); WaitForSingleObject(ServicesInitEvent, INFINITE); + //DbgPrint("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n"); CloseHandle(ServicesInitEvent); + DbgPrint("WL: StartServices() Done.\n"); return TRUE; } -BOOLEAN StartLsass(VOID) +static BOOLEAN StartLsass(VOID) { HANDLE LsassInitEvent; BOOLEAN Result; @@ -110,14 +122,14 @@ BOOLEAN StartLsass(VOID) CHAR CommandLine[MAX_PATH]; LsassInitEvent = CreateEvent(NULL, - TRUE, - FALSE, - "\\LsassInitDone"); + TRUE, + FALSE, + "\\LsassInitDone"); if (LsassInitEvent == NULL) { - DbgPrint("Failed to create lsass notification event\n"); - return(FALSE); + DbgPrint("WL: Failed to create lsass notification event\n"); + return(FALSE); } /* Start the local security authority subsystem (lsass.exe) */ @@ -134,19 +146,19 @@ BOOLEAN StartLsass(VOID) StartupInfo.lpReserved2 = 0; Result = CreateProcess(CommandLine, - NULL, - NULL, - NULL, - FALSE, - DETACHED_PROCESS, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); + NULL, + NULL, + NULL, + FALSE, + DETACHED_PROCESS, + NULL, + NULL, + &StartupInfo, + &ProcessInformation); if (!Result) { - DbgPrint("WL: Failed to execute lsass\n"); - return(FALSE); + DbgPrint("WL: Failed to execute lsass\n"); + return(FALSE); } DPRINT("WL: Waiting for lsass\n"); @@ -156,16 +168,94 @@ BOOLEAN StartLsass(VOID) return(TRUE); } -VOID DoLoginUser(PCHAR Name, PCHAR Password) +static BOOLEAN OpenRegistryKey(HANDLE *WinLogonKey) +{ + return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, + _T("SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon"), + 0, + KEY_QUERY_VALUE, + WinLogonKey); +} + +static BOOLEAN StartProcess(PCHAR ValueName) +{ + BOOL StartIt; + HANDLE WinLogonKey; + DWORD Type; + DWORD Size; + DWORD StartValue; + + StartIt = TRUE; + if (OpenRegistryKey(&WinLogonKey)) + { + Size = sizeof(DWORD); + if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey, + ValueName, + NULL, + &Type, + (LPBYTE) &StartValue, + &Size)) + { + if (REG_DWORD == Type) + { + StartIt = (0 != StartValue); + } + } + RegCloseKey(WinLogonKey); + } + + return StartIt; +} + +static PCHAR GetShell(PCHAR CommandLine) +{ + HANDLE WinLogonKey; + BOOL GotCommandLine; + DWORD Type; + DWORD Size; + CHAR Shell[_MAX_PATH]; + + GotCommandLine = FALSE; + if (OpenRegistryKey(&WinLogonKey)) + { + Size = MAX_PATH; + if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey, + _T("Shell"), + NULL, + &Type, + (LPBYTE) Shell, + &Size)) + { + if (REG_EXPAND_SZ == Type) + { + ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH); + GotCommandLine = TRUE; + } + else if (REG_SZ == Type) + { + strcpy(CommandLine, Shell); + GotCommandLine = TRUE; + } + } + RegCloseKey(WinLogonKey); + } + + if (! GotCommandLine) + { + GetSystemDirectory(CommandLine, MAX_PATH - 10); + strcat(CommandLine, "\\shell.exe"); + } + + return CommandLine; +} + +static BOOL DoLoginUser(PCHAR Name, PCHAR Password) { PROCESS_INFORMATION ProcessInformation; STARTUPINFO StartupInfo; BOOLEAN Result; CHAR CommandLine[MAX_PATH]; CHAR CurrentDirectory[MAX_PATH]; - - GetSystemDirectory(CommandLine, MAX_PATH); - strcat(CommandLine, "\\shell.exe"); GetWindowsDirectory(CurrentDirectory, MAX_PATH); @@ -177,31 +267,33 @@ VOID DoLoginUser(PCHAR Name, PCHAR Password) StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = 0; - Result = CreateProcess(CommandLine, - NULL, - NULL, - NULL, - FALSE, - DETACHED_PROCESS, - NULL, - CurrentDirectory, - &StartupInfo, - &ProcessInformation); + Result = CreateProcess(NULL, + GetShell(CommandLine), + NULL, + NULL, + FALSE, + DETACHED_PROCESS, + NULL, + CurrentDirectory, + &StartupInfo, + &ProcessInformation); if (!Result) { - DbgPrint("WL: Failed to execute user shell\n"); - return; + DbgPrint("WL: Failed to execute user shell %s\n", CommandLine); + return FALSE; } WaitForSingleObject(ProcessInformation.hProcess, INFINITE); CloseHandle( ProcessInformation.hProcess ); CloseHandle( ProcessInformation.hThread ); + + return TRUE; } int STDCALL WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nShowCmd) + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) { #if 0 LSA_STRING ProcessName; @@ -230,7 +322,7 @@ WinMain(HINSTANCE hInstance, CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL); if (InteractiveWindowStation == NULL) { - DbgPrint("Failed to create window station (0x%X)\n", GetLastError()); + DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError()); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); } @@ -245,40 +337,40 @@ WinMain(HINSTANCE hInstance, */ ApplicationDesktop = CreateDesktopW(L"Default", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); /* * Create the winlogon desktop */ WinlogonDesktop = CreateDesktopW(L"Winlogon", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); /* * Create the screen saver desktop */ ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); /* * Switch to winlogon desktop */ /* FIXME: Do start up in the application desktop for now. */ Status = NtSetInformationProcess(NtCurrentProcess(), - ProcessDesktop, - &ApplicationDesktop, - sizeof(ApplicationDesktop)); + ProcessDesktop, + &ApplicationDesktop, + sizeof(ApplicationDesktop)); if (!NT_SUCCESS(Status)) { DbgPrint("WL: Cannot set default desktop for winlogon.\n"); @@ -287,15 +379,27 @@ WinMain(HINSTANCE hInstance, Success = SwitchDesktop(ApplicationDesktop); if (!Success) { - DbgPrint("Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); + DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); } AllocConsole(); SetConsoleTitle( "Winlogon" ); /* start system processes (services.exe & lsass.exe) */ - StartServices(); + if (StartProcess("StartServices")) + { + if (!StartServices()) + { + DbgPrint("WL: Failed to Start Services (0x%X)\n", GetLastError()); + } + } #if 0 - StartLsass(); + if (StartProcess("StartLsass")) + { + if (!StartLsass()) + { + DbgPrint("WL: Failed to Start Security System (0x%X)\n", GetLastError()); + } + } #endif /* FIXME: What name does the real WinLogon use? */ @@ -304,8 +408,8 @@ WinMain(HINSTANCE hInstance, Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); if (!NT_SUCCESS(Status)) { - DbgPrint("WL: Failed to connect to lsass\n"); - return(1); + DbgPrint("WL: Failed to connect to lsass\n"); + return(1); } #endif @@ -321,41 +425,44 @@ WinMain(HINSTANCE hInstance, #if 0 /* Display login prompt */ WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - LoginPrompt, - strlen(LoginPrompt), // wcslen(LoginPrompt), - &Result, - NULL); + LoginPrompt, + strlen(LoginPrompt), // wcslen(LoginPrompt), + &Result, + NULL); i = 0; do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &LoginName[i], - 1, - &Result, - NULL); - i++; - } while (LoginName[i - 1] != '\n'); + { + ReadConsole(GetStdHandle(STD_INPUT_HANDLE), + &LoginName[i], + 1, + &Result, + NULL); + i++; + } while (LoginName[i - 1] != '\n'); LoginName[i - 1] = 0; - /* Display password prompt */ + /* Display password prompt */ WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - PasswordPrompt, - strlen(PasswordPrompt), // wcslen(PasswordPrompt), - &Result, - NULL); + PasswordPrompt, + strlen(PasswordPrompt), // wcslen(PasswordPrompt), + &Result, + NULL); i = 0; do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &Password[i], - 1, - &Result, - NULL); - i++; - } while (Password[i - 1] != '\n'); + { + ReadConsole(GetStdHandle(STD_INPUT_HANDLE), + &Password[i], + 1, + &Result, + NULL); + i++; + } while (Password[i - 1] != '\n'); Password[i - 1] =0; #endif - DoLoginUser(LoginName, Password); + if (! DoLoginUser(LoginName, Password)) + { + break; + } } ExitProcess(0); diff --git a/subsys/win32k/.cvsignore b/subsys/win32k/.cvsignore index 1057c1a..5100004 100644 --- a/subsys/win32k/.cvsignore +++ b/subsys/win32k/.cvsignore @@ -1,8 +1,9 @@ base.tmp junk.tmp temp.exp -win32k.coff win32k.sys +win32k.nostrip.sys +win32k.coff +win32k.sym *.d *.o -*.sym diff --git a/subsys/win32k/eng/mouse.c b/subsys/win32k/eng/mouse.c index a865521..44136f6 100644 --- a/subsys/win32k/eng/mouse.c +++ b/subsys/win32k/eng/mouse.c @@ -43,76 +43,76 @@ static LONG mouse_x, mouse_y; static UINT mouse_width = 0, mouse_height = 0; static UCHAR DefaultCursor[256] = { - 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, 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, 0x00, 0x00, - 0x00, 0xC0, 0x00, 0x00, - 0x00, 0xC0, 0x00, 0x00, - 0x01, 0x80, 0x00, 0x00, - 0x01, 0x80, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - 0x43, 0x00, 0x00, 0x00, - 0x66, 0x00, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x00, - 0x7E, 0x00, 0x00, 0x00, - 0x7F, 0xC0, 0x00, 0x00, - 0x7F, 0x80, 0x00, 0x00, - 0x7F, 0x00, 0x00, 0x00, - 0x7E, 0x00, 0x00, 0x00, - 0x7C, 0x00, 0x00, 0x00, - 0x78, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - - 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, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x3F, 0xFF, 0xFF, - 0xFE, 0x1F, 0xFF, 0xFF, - 0xFE, 0x1F, 0xFF, 0xFF, - 0xFC, 0x3F, 0xFF, 0xFF, - 0x7C, 0x3F, 0xFF, 0xFF, - 0x38, 0x7F, 0xFF, 0xFF, - 0x18, 0x7F, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x00, 0x0F, 0xFF, 0xFF, - 0x00, 0x1F, 0xFF, 0xFF, - 0x00, 0x3F, 0xFF, 0xFF, - 0x00, 0x7F, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x01, 0xFF, 0xFF, 0xFF, - 0x03, 0xFF, 0xFF, 0xFF, - 0x07, 0xFF, 0xFF, 0xFF, - 0x0F, 0xFF, 0xFF, 0xFF, - 0x1F, 0xFF, 0xFF, 0xFF, + 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, + 0x76, 0x00, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0x00, + 0x7F, 0x00, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 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, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x3F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFC, 0x3F, 0xFF, 0xFF, + 0x7C, 0x3F, 0xFF, 0xFF, + 0x38, 0x7F, 0xFF, 0xFF, + 0x18, 0x7F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x01, 0xFF, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xFF, + 0x07, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF}; /* FUNCTIONS *****************************************************************/ -INT -MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, +INT +MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2) /* * FUNCTION: Notify the mouse driver that drawing is about to begin in @@ -122,23 +122,23 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, RECTL MouseRect; LONG tmp; - if (SurfObj == NULL) + if (SurfObj == NULL) { return(FALSE); } - if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE) + if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE) { return(FALSE); } - if (HazardX1 > HazardX2) - { - tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; + if (HazardX1 > HazardX2) + { + tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; } - if (HazardY1 > HazardY2) - { - tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; + if (HazardY1 > HazardY2) + { + tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; } if (((mouse_x + mouse_width) >= HazardX1) && (mouse_x <= HazardX2) && @@ -154,7 +154,7 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, return(TRUE); } -INT +INT MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI) /* * FUNCTION: Notify the mouse driver that drawing has finished on a surface. @@ -162,12 +162,12 @@ MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI) { RECTL MouseRect; - if (SurfObj == NULL) + if (SurfObj == NULL) { return(FALSE); } - if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE) + if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE) { return(FALSE); } @@ -177,7 +177,7 @@ MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI) SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); SafetySwitch = FALSE; } - + SafetySwitch2 = FALSE; return(TRUE); @@ -195,13 +195,13 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) PDC dc; PSURFOBJ SurfObj; PSURFGDI SurfGDI; - RECTL MouseRect; + RECTL MouseRect; MSG Msg; ULONG j; LARGE_INTEGER LargeTickCount; ULONG TickCount; static ULONG ButtonsDown = 0; - const UINT MouseButtonDownMessage[3] = + const UINT MouseButtonDownMessage[3] = {WM_RBUTTONDOWN, WM_MBUTTONDOWN, WM_LBUTTONDOWN}; const UINT MouseButtonUpMessage[3] = {WM_RBUTTONUP, WM_MBUTTONUP, WM_LBUTTONUP}; @@ -218,7 +218,8 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) dc = DC_HandleToPtr(hDC); SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); - + DC_ReleasePtr( hDC ); + /* Compile the total mouse movement change and dispatch button events. */ for (i = 0; i < InputCount; i++) { @@ -232,7 +233,7 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) Msg.pt.x = mouse_x + mouse_cx; Msg.pt.y = mouse_y + mouse_cy; MsqInsertSystemMessage(&Msg); - + for (j = 0; j < 3; j++) { ULONG Flag = MouseButtonFlag[j]; @@ -245,8 +246,8 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) MsqInsertSystemMessage(&Msg); } if (!(Data[i].ButtonData & (1 << j)) && (ButtonsDown & Flag)) - { - ButtonsDown &= ~Flag; + { + ButtonsDown &= ~Flag; Msg.wParam = ButtonsDown; Msg.message = MouseButtonUpMessage[j]; @@ -257,9 +258,9 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) /* If the mouse moved then move the pointer. */ if (mouse_cx != 0 || mouse_cy != 0) - { + { mouse_x += mouse_cx; - mouse_y += mouse_cy; + mouse_y += mouse_cy; mouse_x = max(mouse_x, 0); mouse_y = max(mouse_y, 0); @@ -268,36 +269,46 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) if (SafetySwitch == FALSE && SafetySwitch2 == FALSE) { - SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); + SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); } } } -VOID +VOID EnableMouse(HDC hDisplayDC) { - PDC dc = DC_HandleToPtr(hDisplayDC); - PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); - PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); + PDC dc; + PSURFOBJ SurfObj; + PSURFGDI SurfGDI; HBITMAP hMouseSurf; PSURFOBJ MouseSurf; SIZEL MouseSize; RECTL MouseRect; - /* Create the default mouse cursor. */ - mouse_width = 32; - mouse_height = 32; - MouseSize.cx = 32; - MouseSize.cy = 64; - hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, 0, DefaultCursor); - MouseSurf = (PSURFOBJ)AccessUserObject(hMouseSurf); - - /* Tell the display driver to set the pointer shape. */ - SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 320, 240, - &MouseRect, 0); - - mouse_x = 320; - mouse_y = 240; - MouseEnabled = TRUE; + dc = DC_HandleToPtr(hDisplayDC); + if( dc ){ + SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); + SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); + DC_ReleasePtr( hDisplayDC ); + + /* Create the default mouse cursor. */ + mouse_width = 32; + mouse_height = 32; + MouseSize.cx = 32; + MouseSize.cy = 64; + hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, 0, DefaultCursor); + MouseSurf = (PSURFOBJ)AccessUserObject(hMouseSurf); + + /* Tell the display driver to set the pointer shape. */ + SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 320, 240, + &MouseRect, 0); + + mouse_x = 320; + mouse_y = 240; + MouseEnabled = TRUE; + } + else{ + MouseEnabled = FALSE; + } } diff --git a/subsys/win32k/eng/xlate.c b/subsys/win32k/eng/xlate.c index 3022c56..da83776 100644 --- a/subsys/win32k/eng/xlate.c +++ b/subsys/win32k/eng/xlate.c @@ -32,16 +32,6 @@ ULONG BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red) return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff); } -INT abs(INT nm) -{ - if(nm<0) - { - return nm * -1; - } else - { - return nm; - } -} // FIXME: If the caller knows that the destinations are indexed and not RGB // then we should cache more than one value. Same with the source. @@ -68,9 +58,12 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, { cDestColors = (PVIDEO_CLUTDATA)&DestColors[i]; - cxRed = abs(cSourceColor->Red - cDestColors->Red) ^ 2; - cxGreen = abs(cSourceColor->Green - cDestColors->Green) ^ 2; - cxBlue = abs(cSourceColor->Blue - cDestColors->Blue) ^ 2; + cxRed = (cSourceColor->Red - cDestColors->Red); + cxRed *= cxRed; //compute cxRed squared + cxGreen = (cSourceColor->Green - cDestColors->Green); + cxGreen *= cxGreen; + cxBlue = (cSourceColor->Blue - cDestColors->Blue); + cxBlue *= cxBlue; rt = /* sqrt */ (cxRed + cxGreen + cxBlue); diff --git a/subsys/win32k/freetype/src/base/ftinit.c b/subsys/win32k/freetype/src/base/ftinit.c index cc754eb..1d6590a 100644 --- a/subsys/win32k/freetype/src/base/ftinit.c +++ b/subsys/win32k/freetype/src/base/ftinit.c @@ -39,6 +39,7 @@ #include #include + #include #include diff --git a/subsys/win32k/freetype/src/cff/.cvsignore b/subsys/win32k/freetype/src/cff/.cvsignore index a438335..31dc307 100644 --- a/subsys/win32k/freetype/src/cff/.cvsignore +++ b/subsys/win32k/freetype/src/cff/.cvsignore @@ -1 +1,2 @@ *.d +*.o diff --git a/subsys/win32k/include/window.h b/subsys/win32k/include/window.h index 66f123c..03f4f1b 100644 --- a/subsys/win32k/include/window.h +++ b/subsys/win32k/include/window.h @@ -77,6 +77,10 @@ typedef struct _WINDOW_OBJECT PDCE Dce; /* Property list head.*/ LIST_ENTRY PropListHead; + /* Scrollbar info */ + PSCROLLBARINFO pHScroll; + PSCROLLBARINFO pVScroll; + PSCROLLBARINFO wExtra; } WINDOW_OBJECT, *PWINDOW_OBJECT; /* Window flags. */ diff --git a/subsys/win32k/makefile b/subsys/win32k/makefile index 1544ef2..7584dee 100644 --- a/subsys/win32k/makefile +++ b/subsys/win32k/makefile @@ -31,7 +31,7 @@ NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \ ntuser/userobj.o ntuser/window.o ntuser/winsta.o \ ntuser/input.o ntuser/keyboard.o ntuser/callback.o \ ntuser/winpos.o ntuser/painting.o ntuser/metric.o \ - ntuser/windc.o ntuser/prop.o + ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ objects/color.o objects/coord.o objects/dc.o \ objects/fillshap.o objects/gdiobj.o objects/icm.o \ diff --git a/subsys/win32k/ntuser/painting.c b/subsys/win32k/ntuser/painting.c index 938ccb5..9f4e321 100644 --- a/subsys/win32k/ntuser/painting.c +++ b/subsys/win32k/ntuser/painting.c @@ -229,7 +229,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, { W32kCombineRgn(Window->UpdateRegion, Window->UpdateRegion, hRgn, RGN_OR); - Window->UpdateRegion = + Window->UpdateRegion = REGION_CropRgn(Window->UpdateRegion, Window->UpdateRegion, &Rect, NULL); if (!HadOne) @@ -246,7 +246,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, } else if (Window->UpdateRegion == 0) { - Window->UpdateRegion = + Window->UpdateRegion = REGION_CropRgn(Window->UpdateRegion, hRgn, &Rect, NULL); if (!HadOne) { @@ -673,7 +673,7 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) { if (Flags & UNC_UPDATE) { - Window->UpdateRegion = + Window->UpdateRegion = UnsafeW32kCreateRectRgnIndirect(&ClientRect); } if (Flags & UNC_REGION) @@ -692,7 +692,7 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) else if (Window->UpdateRegion == (HANDLE)1 && Flags & UNC_UPDATE) { W32kGetClientRect(Window, &ClientRect); - Window->UpdateRegion = + Window->UpdateRegion = UnsafeW32kCreateRectRgnIndirect(&ClientRect); if (Flags & UNC_REGION) { @@ -721,7 +721,9 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) hClip = W32kCreateRectRgn(0, 0, 0, 0); W32kCombineRgn(hClip, hRgnRet, 0, RGN_COPY); } + NtUserSendMessage(Window->Self, WM_NCPAINT, (WPARAM)hClip, 0); + if (hClip > (HANDLE)1 && hClip != hRgn && hClip != hRgnRet) { W32kDeleteObject(hClip); @@ -758,7 +760,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) { return(NULL); } - + if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) { DbgPrint("[ayes:0]"); } else { DbgPrint("[ano:0]"); } /*testing*/ IsIcon = Window->Style & WS_MINIMIZE && NtUserGetClassLong(Window->Self, GCL_HICON); @@ -771,7 +773,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) UpdateRegion = Window->UpdateRegion; Window->UpdateRegion = 0; - if (UpdateRegion != NULL || + if (UpdateRegion != NULL || (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) { MsqDecPaintCountQueue(Window->MessageQueue); @@ -780,6 +782,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) /* FIXME: Hide claret. */ + if (NtUserGetClassLong(Window->Self, GCL_STYLE) & CS_PARENTDC) { if (UpdateRegion != NULL) @@ -815,6 +818,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) { BOOLEAN Result; +DbgPrint("[dne:0]"); Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; Result = NtUserSendMessage(hWnd, IsIcon ? WM_ICONERASEBKGND : WM_ERASEBKGND, @@ -824,6 +828,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) } else { +DbgPrint("[dne:1]"); lPs->fErase = FALSE; } diff --git a/subsys/win32k/ntuser/scrollbar.c b/subsys/win32k/ntuser/scrollbar.c new file mode 100644 index 0000000..42d0874 --- /dev/null +++ b/subsys/win32k/ntuser/scrollbar.c @@ -0,0 +1,309 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Scrollbars + * FILE: subsys/win32k/ntuser/scrollbar.c + * PROGRAMER: Jason Filby (jasonfilby@yahoo.com) + * REVISION HISTORY: + * 16-11-2002 Jason Filby Created + */ +/* INCLUDES ******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define NDEBUG +#include + +#define SCROLL_MIN_RECT 4 /* Minimum size of the rectangle between the arrows */ +#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */ + +/* FUNCTIONS *****************************************************************/ + +/* Ported from WINE20020904 */ +/* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and + * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar), + * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to + * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal. + */ +static BOOL +SCROLL_GetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect) +{ + SCROLLBARINFO info; + INT pixels, thumbSize, arrowSize; + BOOL vertical; + RECT ClientRect = Window->ClientRect; + RECT WindowRect = Window->WindowRect; + ULONG Style; + + switch (nBar) + { + case SB_HORZ: + lprect->left = ClientRect.left - WindowRect.left; + lprect->top = ClientRect.bottom - WindowRect.top; + lprect->right = ClientRect.right - WindowRect.left; + lprect->bottom = lprect->top + NtUserGetSystemMetrics (SM_CYHSCROLL); + if (Window->Style & WS_BORDER) + { + lprect->left--; + lprect->right++; + } + else if (Window->Style & WS_VSCROLL) + lprect->right++; + vertical = FALSE; + break; + + case SB_VERT: + lprect->left = ClientRect.right - WindowRect.left; + lprect->top = ClientRect.top - WindowRect.top; + lprect->right = lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL); + lprect->bottom = ClientRect.bottom - WindowRect.top; + if (Window->Style & WS_BORDER) + { + lprect->top--; + lprect->bottom++; + } + else if (Window->Style & WS_HSCROLL) + lprect->bottom++; + vertical = TRUE; + break; + + case SB_CTL: + W32kGetClientRect (Window, lprect); + vertical = ((Window->Style & SBS_VERT) != 0); + break; + + default: + W32kReleaseWindowObject(Window); + return FALSE; + } + + if (vertical) + pixels = lprect->bottom - lprect->top; + else + pixels = lprect->right - lprect->left; + + info.cbSize = sizeof(SCROLLBARINFO); + SCROLL_GetScrollBarInfo (Window, nBar, &info); + + if (pixels <= 2 * NtUserGetSystemMetrics (SM_CXVSCROLL) + SCROLL_MIN_RECT) + { + info.dxyLineButton = info.xyThumbTop = info.xyThumbBottom = 0; + } + else + { + arrowSize = NtUserGetSystemMetrics (SM_CXVSCROLL); + pixels -= (2 * (NtUserGetSystemMetrics (SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)); + + /* Temporary initialization - to be removed once proper code is in */ + info.dxyLineButton = info.xyThumbTop = info.xyThumbBottom = 0; + +/* if (info->Page) + { + thumbSize = MulDiv(pixels,info->Page,(info->MaxVal-info->MinVal+1)); + if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB; + } + else *thumbSize = NtUserGetSystemMetrics(SM_CXVSCROLL); */ +/* + if (((pixels -= *thumbSize ) < 0) || + ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)) + { */ + /* Rectangle too small or scrollbar disabled -> no thumb */ +/* *thumbPos = *thumbSize = 0; + } + else + { */ +/* INT max = info->MaxVal - max( info->Page-1, 0 ); + if (info->MinVal >= max) + *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP; + else + *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP + + MulDiv(pixels, (info->CurVal-info->MinVal),(max - info->MinVal)); + } */ + } + + return vertical; +} + +DWORD SCROLL_CreateScrollBar(PWINDOW_OBJECT Window, LONG idObject) +{ + PSCROLLBARINFO psbi; + LRESULT Result; + INT i; + + Result = WinPosGetNonClientSize(Window->Self, + &Window->WindowRect, + &Window->ClientRect); + + psbi = ExAllocatePool(NonPagedPool, sizeof(SCROLLBARINFO)); + + for (i=0; irgstate[i] = 0; + + switch(idObject) + { + case SB_HORZ: + Window->pHScroll = psbi; + break; + case SB_VERT: + Window->pVScroll = psbi; + break; + case SB_CTL: + Window->wExtra = psbi; + break; + default: + return FALSE; + } + + SCROLL_GetScrollBarRect (Window, idObject, &(psbi->rcScrollBar)); + + return 0; +} + +DWORD SCROLL_GetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi) +{ + switch(idObject) + { + case SB_HORZ: + memcpy(psbi, Window->pHScroll, psbi->cbSize); + break; + case SB_VERT: + memcpy(psbi, Window->pVScroll, psbi->cbSize); + break; + case SB_CTL: + memcpy(psbi, Window->wExtra, psbi->cbSize); + break; + default: + W32kReleaseWindowObject(Window); + return FALSE; + } + + return TRUE; +} + +DWORD +STDCALL +NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) +{ + PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd); + + if (!Window) return FALSE; + + SCROLL_GetScrollBarInfo(Window, idObject, psbi); + + W32kReleaseWindowObject(Window); + + return TRUE; +} + +DWORD +STDCALL +NtUserEnableScrollBar( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2) +{ + return 0; +} + +DWORD +STDCALL +NtUserScrollDC( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5, + DWORD Unknown6) + +{ + UNIMPLEMENTED + + return 0; +} + +DWORD +STDCALL +NtUserSetScrollInfo( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3) +{ + UNIMPLEMENTED + + return 0; +} + +/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ +DWORD +STDCALL +NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow) +{ + BOOL fShowV = (wBar == SB_VERT) ? 0 : bShow; + BOOL fShowH = (wBar == SB_HORZ) ? 0 : bShow; + PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd); + + switch (wBar) + { + case SB_CTL: + NtUserShowWindow (hWnd, fShowH ? SW_SHOW : SW_HIDE); + return TRUE; + + case SB_BOTH: + case SB_HORZ: + if (fShowH) + { + fShowH = !(Window->Style & WS_HSCROLL); + Window->Style |= WS_HSCROLL; + } + else /* hide it */ + { + fShowH = (Window->Style & WS_HSCROLL); + Window->Style &= ~WS_HSCROLL; + } + if (wBar == SB_HORZ) + { + fShowV = FALSE; + break; + } + /* fall through */ + + case SB_VERT: + if (fShowV) + { + fShowV = !(Window->Style & WS_VSCROLL); + Window->Style |= WS_VSCROLL; + } + else /* hide it */ + { + fShowV = (Window->Style & WS_VSCROLL); + Window->Style &= ~WS_VSCROLL; + } + if (wBar == SB_VERT) + fShowH = FALSE; + break; + + default: + return FALSE; /* Nothing to do! */ + } + + if (fShowH || fShowV) /* frame has been changed, let the window redraw itself */ + { + NtUserSetWindowPos (hWnd, 0, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); + return TRUE; + } + return FALSE; /* no frame changes */ +} + +/* EOF */ diff --git a/subsys/win32k/ntuser/stubs.c b/subsys/win32k/ntuser/stubs.c index e85cf53..f848bd5 100644 --- a/subsys/win32k/ntuser/stubs.c +++ b/subsys/win32k/ntuser/stubs.c @@ -536,18 +536,6 @@ NtUserEnableMenuItem( DWORD STDCALL -NtUserEnableScrollBar( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserEndMenu(VOID) { UNIMPLEMENTED @@ -1001,18 +989,6 @@ NtUserGetPriorityClipboardFormat( DWORD STDCALL -NtUserGetScrollBarInfo( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserGetSystemMenu( DWORD Unknown0, DWORD Unknown1) @@ -1373,23 +1349,6 @@ NtUserSBGetParms( DWORD STDCALL -NtUserScrollDC( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6) - -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserSendInput( DWORD Unknown0, DWORD Unknown1, @@ -1591,19 +1550,6 @@ NtUserSetRipFlags( DWORD STDCALL -NtUserSetScrollInfo( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserSetSysColors( DWORD Unknown0, DWORD Unknown1, @@ -1686,18 +1632,6 @@ NtUserShowCaret( DWORD STDCALL -NtUserShowScrollBar( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserSystemParametersInfo( DWORD Unknown0, DWORD Unknown1, diff --git a/subsys/win32k/ntuser/window.c b/subsys/win32k/ntuser/window.c index 5b8d0fb..e7d7757 100644 --- a/subsys/win32k/ntuser/window.c +++ b/subsys/win32k/ntuser/window.c @@ -278,7 +278,7 @@ W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation, /* Create the window object. */ WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable, &Handle, - otWindow, + otWindow, sizeof(WINDOW_OBJECT)); if (!WindowObject) { @@ -343,7 +343,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, POINT MaxSize, MaxPos, MinTrack, MaxTrack; CREATESTRUCTW Cs; LRESULT Result; - + DPRINT("NtUserCreateWindowEx\n"); /* Initialize gui state if necessary. */ @@ -391,11 +391,11 @@ NtUserCreateWindowEx(DWORD dwExStyle, } /* Create the window object. */ - WindowObject = (PWINDOW_OBJECT) - ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle, + WindowObject = (PWINDOW_OBJECT) + ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle, otWindow, sizeof(WINDOW_OBJECT)); DPRINT("Created object with handle %X\n", Handle); - if (!WindowObject) + if (!WindowObject) { ObDereferenceObject(WinStaObject); ObmDereferenceObject(ClassObject); @@ -422,18 +422,18 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->Self = Handle; WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue; WindowObject->Parent = ParentWindow; - InsertHeadList(&ParentWindow->ChildrenListHead, + InsertHeadList(&ParentWindow->ChildrenListHead, &WindowObject->SiblingListEntry); InitializeListHead(&WindowObject->ChildrenListHead); InitializeListHead(&WindowObject->PropListHead); RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer); RtlFreeUnicodeString(&WindowName); - + if (ClassObject->Class.cbWndExtra != 0) { - WindowObject->ExtraData = - ExAllocatePool(PagedPool, + WindowObject->ExtraData = + ExAllocatePool(PagedPool, ClassObject->Class.cbWndExtra * sizeof(DWORD)); WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra; } @@ -460,7 +460,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, &WindowObject->ThreadListEntry); ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock); - /* + /* * Insert the window into the list of windows associated with the thread's * desktop. */ @@ -497,6 +497,12 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* FIXME: Initialize the window menu. */ + /* Initialize the window's scrollbars */ + if (dwStyle & WS_VSCROLL) + SCROLL_CreateScrollBar(WindowObject, SB_VERT); + if (dwStyle & WS_HSCROLL) + SCROLL_CreateScrollBar(WindowObject, SB_HORZ); + /* Send a NCCREATE message. */ Cs.lpCreateParams = lpParam; Cs.hInstance = hInstance; diff --git a/subsys/win32k/objects/brush.c b/subsys/win32k/objects/brush.c index 4ed6bf6..1b71ec0 100644 --- a/subsys/win32k/objects/brush.c +++ b/subsys/win32k/objects/brush.c @@ -200,7 +200,7 @@ BOOL STDCALL W32kPatBlt(HDC hDC, BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); assert(BrushObj); if (BrushObj->logbrush.lbStyle != BS_NULL) - { + { if (Width > 0) { DestRect.left = XLeft + dc->w.DCOrgX; @@ -213,15 +213,15 @@ BOOL STDCALL W32kPatBlt(HDC hDC, } if (Height > 0) { - DestRect.top = YLeft + dc->w.DCOrgY; + DestRect.top = YLeft + dc->w.DCOrgY; DestRect.bottom = YLeft + Height + dc->w.DCOrgY; } else { - DestRect.top = YLeft + Height + dc->w.DCOrgY; + DestRect.top = YLeft + Height + dc->w.DCOrgY; DestRect.bottom = YLeft + dc->w.DCOrgY; } - ret = EngBitBlt(SurfObj, + ret = EngBitBlt(SurfObj, NULL, NULL, NULL, @@ -233,7 +233,8 @@ BOOL STDCALL W32kPatBlt(HDC hDC, NULL, PATCOPY); } - GDIOBJ_UnlockObj( dc->w.hBrush, GO_PEN_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); + DC_ReleasePtr( hDC ); return(ret); } diff --git a/subsys/win32k/objects/cliprgn.c b/subsys/win32k/objects/cliprgn.c index 2439268..8ec98ac 100644 --- a/subsys/win32k/objects/cliprgn.c +++ b/subsys/win32k/objects/cliprgn.c @@ -54,19 +54,22 @@ HRGN WINAPI SaveVisRgn(HDC hdc) return copy; } -INT WINAPI +INT WINAPI W32kSelectVisRgn(HDC hdc, HRGN hrgn) { int retval; DC *dc; - if (!hrgn) return ERROR; - if (!(dc = DC_HandleToPtr(hdc))) return ERROR; + if (!hrgn) + return ERROR; + if (!(dc = DC_HandleToPtr(hdc))) + return ERROR; dc->w.flags &= ~DC_DIRTY; retval = W32kCombineRgn(dc->w.hVisRgn, hrgn, 0, RGN_COPY); CLIPPING_UpdateGCRegion(dc); + DC_ReleasePtr( hdc ); return retval; } @@ -93,12 +96,15 @@ int STDCALL W32kGetClipBox(HDC hDC, int retval; DC *dc; - if (!(dc = DC_HandleToPtr(hDC))) return ERROR; + if (!(dc = DC_HandleToPtr(hDC))) + return ERROR; retval = UnsafeW32kGetRgnBox(dc->w.hGCClipRgn, rc); rc->left -= dc->w.DCOrgX; rc->right -= dc->w.DCOrgX; rc->top -= dc->w.DCOrgY; rc->bottom -= dc->w.DCOrgY; + + DC_ReleasePtr( hDC ); W32kDPtoLP(hDC, (LPPOINT)rc, 2); return(retval); } diff --git a/subsys/win32k/objects/color.c b/subsys/win32k/objects/color.c index a9a2f91..c56e447 100644 --- a/subsys/win32k/objects/color.c +++ b/subsys/win32k/objects/color.c @@ -50,6 +50,22 @@ const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] = { 0xff, 0xff, 0xff, PC_SYS_USED } // last 10 }; +ULONG W32kGetSysColor(int nIndex) +{ + PALETTEENTRY *p = COLOR_sysPalTemplate + (nIndex * sizeof(PALETTEENTRY)); + return RGB(p->peRed, p->peGreen, p->peBlue); +} + +HPEN STDCALL W32kGetSysColorPen(int nIndex) +{ + return(W32kCreatePen(PS_SOLID, 1, COLOR_sysPalTemplate[nIndex])); +} + +HBRUSH STDCALL W32kGetSysColorBrush(int nIndex) +{ + return(W32kCreateSolidBrush(COLOR_sysPalTemplate[nIndex])); +} + //forward declarations COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color ); @@ -255,8 +271,7 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC hDC) UNIMPLEMENTED; } -UINT STDCALL W32kRealizePalette(HDC hDC) -/* +/*! The RealizePalette function modifies the palette for the device associated with the specified device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified. A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows. @@ -271,16 +286,19 @@ A logical palette is a buffer between color-intensive applications and the syste the dc palette. -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette. */ +UINT STDCALL W32kRealizePalette(HDC hDC) { PPALOBJ palPtr, sysPtr; PPALGDI palGDI, sysGDI; int realized = 0; - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc; HPALETTE systemPalette; PSURFGDI SurfGDI; BOOLEAN success; - if (!dc) return 0; + dc = DC_HandleToPtr(hDC); + if (!dc) + return 0; palPtr = (PPALOBJ)AccessUserObject(dc->w.hPalette); SurfGDI = (PSURFGDI)AccessInternalObjectFromUserObject(dc->Surface); @@ -365,17 +383,31 @@ BOOL STDCALL W32kResizePalette(HPALETTE hpal, UNIMPLEMENTED; } +/*! + * Select logical palette into device context. + * \param hDC handle to the device context + * \param hpal handle to the palette + * \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon + * is in the foreground. If this value is TRUE then map the colors in the logical palette to the device + * palette colors in the best way. + * \return old palette + * + * \todo implement ForceBackground == TRUE +*/ HPALETTE STDCALL W32kSelectPalette(HDC hDC, HPALETTE hpal, BOOL ForceBackground) { - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc; HPALETTE oldPal; - oldPal = dc->w.hPalette; - dc->w.hPalette = hpal; - // FIXME: mark the palette as a [fore\back]ground pal + dc = DC_HandleToPtr(hDC); + if( dc ){ + oldPal = dc->w.hPalette; + dc->w.hPalette = hpal; + DC_ReleasePtr( hDC ); + } return oldPal; } diff --git a/subsys/win32k/objects/dc.c b/subsys/win32k/objects/dc.c index 9c28ef1..7727c29 100644 --- a/subsys/win32k/objects/dc.c +++ b/subsys/win32k/objects/dc.c @@ -7,6 +7,7 @@ #undef WIN32_LEAN_AND_MEAN #include #include +#include #include #include @@ -22,6 +23,8 @@ //#define NDEBUG #include +static GDIDEVICE PrimarySurface; +static BOOL PrimarySurfaceCreated = FALSE; /* FIXME: DCs should probably be thread safe */ @@ -156,8 +159,6 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) NewDC->vportExtY = OrigDC->vportExtY; } - DC_InitDC(hNewDC); - /* Create default bitmap */ if (!(hBitmap = W32kCreateBitmap( 1, 1, 1, 1, NULL ))) { @@ -178,15 +179,11 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) } DC_ReleasePtr( hDC ); DC_ReleasePtr( hNewDC ); + DC_InitDC(hNewDC); return hNewDC; } -#include - -static GDIDEVICE PrimarySurface; -static BOOL PrimarySurfaceCreated = FALSE; - BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, LPCWSTR Device) { @@ -338,13 +335,13 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver, DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel); + NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, 640, 480); + DC_ReleasePtr( hNewDC ); + /* Initialize the DC state */ DC_InitDC(hNewDC); - - NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, 640, 480); W32kSetTextColor(hNewDC, RGB(0, 0, 0)); W32kSetTextAlign(hNewDC, TA_TOP); - DC_ReleasePtr( hNewDC ); return hNewDC; } @@ -960,7 +957,9 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if( PalGDI ){ XlateObj = (PXLATEOBJ)EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); pen = GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); + if( pen ){ + pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); + } GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); } break; @@ -973,8 +972,9 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if( PalGDI ){ XlateObj = (PXLATEOBJ)EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); brush = GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); - brush->iSolidColor = XLATEOBJ_iXlate(XlateObj, - brush->logbrush.lbColor); + if( brush ){ + brush->iSolidColor = XLATEOBJ_iXlate(XlateObj, brush->logbrush.lbColor); + } GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC); } break; @@ -1217,20 +1217,19 @@ HDC DC_FindOpenDC(LPCWSTR Driver) return NULL; } +/*! + * Initialize some common fields in the Device Context structure. +*/ void DC_InitDC(HDC DCHandle) { // W32kRealizeDefaultPalette(DCHandle); - PDC DCToInit; - if( (DCToInit = DC_HandleToPtr( DCHandle ) ) ){ - W32kSetTextColor(DCHandle, DCToInit->w.textColor); - W32kSetBkColor(DCHandle, DCToInit->w.backgroundColor); - W32kSelectObject(DCHandle, DCToInit->w.hPen); - W32kSelectObject(DCHandle, W32kGetStockObject( GRAY_BRUSH )); //FIXME: default should be WHITE_BRUSH - W32kSelectObject(DCHandle, DCToInit->w.hFont); - } - else - DPRINT("DC_InitDC: can't get dc for handle %d\n", DCHandle ); + + W32kSelectObject(DCHandle, W32kGetStockObject( WHITE_BRUSH )); + //W32kSelectObject(DCHandle, hPen); + //W32kSelectObject(DCHandle, hFont); + // CLIPPING_UpdateGCRegion(DCToInit); + } void DC_FreeDC(HDC DCToFree) diff --git a/subsys/win32k/objects/fillshap.c b/subsys/win32k/objects/fillshap.c index 0e06ee2..a5e424e 100644 --- a/subsys/win32k/objects/fillshap.c +++ b/subsys/win32k/objects/fillshap.c @@ -140,12 +140,12 @@ W32kRectangle(HDC hDC, if (BrushObj) { if (BrushObj->logbrush.lbStyle != BS_NULL) - { + { DestRect.left = LeftRect + 1; DestRect.right = RightRect - 1; DestRect.top = TopRect + 1; DestRect.bottom = BottomRect - 1; - ret = EngBitBlt(SurfObj, + ret = EngBitBlt(SurfObj, NULL, NULL, NULL, @@ -158,7 +158,7 @@ W32kRectangle(HDC hDC, PATCOPY); } } - GDIOBJ_UnlockObj( dc->w.hBrush, GO_PEN_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); } // FIXME: Move current position in DC? diff --git a/subsys/win32k/objects/gdiobj.c b/subsys/win32k/objects/gdiobj.c index 0d305ce..f7c85c4 100644 --- a/subsys/win32k/objects/gdiobj.c +++ b/subsys/win32k/objects/gdiobj.c @@ -101,14 +101,22 @@ static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statical // the way handles work, so it's more dynamic now -HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */ +HBITMAP hPseudoStockBitmap; /*! 1x1 bitmap for memory DCs */ static PGDI_HANDLE_TABLE HandleTable = 0; static FAST_MUTEX HandleTableMutex; static FAST_MUTEX RefCountHandling; +/*! Size of the GDI handle table + * per http://www.wd-mag.com/articles/1999/9902/9902b/9902b.htm?topic=articles + * gdi handle table can hold 0x4000 handles +*/ #define GDI_HANDLE_NUMBER 0x4000 +/*! + * Allocate GDI object table. + * \param Size - number of entries in the object table. +*/ static PGDI_HANDLE_TABLE GDIOBJ_iAllocHandleTable (WORD Size) { @@ -128,6 +136,9 @@ GDIOBJ_iAllocHandleTable (WORD Size) return handleTable; } +/*! + * Returns the entry into the handle table by index. +*/ static PGDI_HANDLE_ENTRY GDIOBJ_iGetHandleEntryForIndex (WORD TableIndex) { @@ -137,6 +148,10 @@ GDIOBJ_iGetHandleEntryForIndex (WORD TableIndex) return ((PGDI_HANDLE_ENTRY)HandleTable->Handles+TableIndex); } +/*! + * Finds next free entry in the GDI handle table. + * \return index into the table is successful, zero otherwise. +*/ static WORD GDIOBJ_iGetNextOpenHandleIndex (void) { @@ -156,10 +171,17 @@ GDIOBJ_iGetNextOpenHandleIndex (void) return (tableIndex < HandleTable->wTableSize) ? tableIndex : 0; } -/*-----------------7/12/2002 11:38AM---------------- - * Allocate memory for GDI object and return handle to it - * Use GDIOBJ_Lock to obtain pointer to the new object. - * --------------------------------------------------*/ +/*! + * Allocate memory for GDI object and return handle to it. + * + * \param Size - size of the GDI object. This shouldn't to include the size of GDIOBJHDR. + * The actual amount of allocated memory is sizeof(GDIOBJHDR)+Size + * \param Magic - object magic (see GDI Magic) + * + * \return Handle of the allocated object. + * + * \note Use GDIOBJ_Lock() to obtain pointer to the new object. +*/ HGDIOBJ GDIOBJ_AllocObj(WORD Size, WORD Magic) { PGDIOBJHDR newObject; @@ -184,6 +206,20 @@ HGDIOBJ GDIOBJ_AllocObj(WORD Size, WORD Magic) return (HGDIOBJ) newObject->wTableIndex; } +/*! + * Free memory allocated for the GDI object. For each object type this function calls the + * appropriate cleanup routine. + * + * \param hObj - handle of the object to be deleted. + * \param Magic - object magic or GO_MAGIC_DONTCARE. + * \param Flag - if set to GDIOBJFLAG_IGNOREPID then the routine doesn't check if the process that + * tries to delete the object is the same one that created it. + * + * \return Returns TRUE if succesful. + * + * \note You should only use GDIOBJFLAG_IGNOREPID if you are cleaning up after the process that terminated. + * \note This function deferres object deletion if it is still in use. +*/ BOOL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag) { PGDIOBJHDR objectHeader; @@ -193,8 +229,10 @@ BOOL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag) handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)hObj & 0xffff); DPRINT("GDIOBJ_FreeObj: hObj: %d, magic: %x, handleEntry: %x\n", (WORD)hObj & 0xffff, Magic, handleEntry ); + if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) || ((handleEntry->hProcessId != PsGetCurrentProcessId()) && !(Flag & GDIOBJFLAG_IGNOREPID))){ + DPRINT("Can't Delete hObj: %d, magic: %x, pid:%d\n currpid:%d, flag:%d, hmm:%d\n",(WORD)hObj & 0xffff, handleEntry->wMagic, handleEntry->hProcessId, PsGetCurrentProcessId(), (Flag&GDIOBJFLAG_IGNOREPID), ((handleEntry->hProcessId != PsGetCurrentProcessId()) && !(Flag&GDIOBJFLAG_IGNOREPID)) ); return FALSE; } @@ -243,13 +281,22 @@ BOOL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag) handleEntry->hProcessId = 0; ExFreePool (handleEntry->pObject); handleEntry->pObject = 0; - // (RJJ) set wMagic last to avoid race condition handleEntry->wMagic = 0; - return TRUE; } +/*! + * Return pointer to the object by handle. + * + * \param hObj Object handle + * \param Magic one of the magic numbers defined in \ref GDI Magic + * \return Pointer to the object. + * + * \note Process can only get pointer to the objects it created or global objects. + * + * \todo Don't allow to lock the objects twice! Synchronization! +*/ PGDIOBJ GDIOBJ_LockObj( HGDIOBJ hObj, WORD Magic ) { PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff); @@ -265,15 +312,62 @@ PGDIOBJ GDIOBJ_LockObj( HGDIOBJ hObj, WORD Magic ) objectHeader = (PGDIOBJHDR) handleEntry->pObject; ASSERT(objectHeader); + if( objectHeader->dwCount > 0 ){ + DbgPrint("Caution! GDIOBJ_LockObj trying to lock object second time\n" ); + DbgPrint("\t called from: %x\n", __builtin_return_address(0)); + } ExAcquireFastMutex(&RefCountHandling); objectHeader->dwCount++; ExReleaseFastMutex(&RefCountHandling); - - DPRINT("GDIOBJ_LockObj: PGDIOBJ %x\n", ((PCHAR)objectHeader + sizeof(GDIOBJHDR)) ); return (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR)); } +/*! + * Lock multiple objects. Use this function when you need to lock multiple objects and some of them may be + * duplicates. You should use this function to avoid trying to lock the same object twice! + * + * \param pList pointer to the list that contains handles to the objects. You should set hObj and Magic fields. + * \param nObj number of objects to lock + * \return for each entry in pList this function sets pObj field to point to the object. + * + * \note this function uses an O(n^2) algoritm because we shouldn't need to call it with more than 3 or 4 objects. +*/ +BOOL GDIOBJ_LockMultipleObj( PGDIMULTILOCK pList, INT nObj ) +{ + INT i, j; + ASSERT( pList ); + //go through the list checking for duplicate objects + for( i = 0; i < nObj; i++ ){ + (pList+i)->pObj = NULL; + for( j = 0; j < i; j++ ){ + if( ((pList+i)->hObj == (pList+j)->hObj) + && ((pList+i)->Magic == (pList+j)->Magic) ){ + //already locked, so just copy the pointer to the object + (pList+i)->pObj = (pList+j)->pObj; + break; + } + } + if( (pList+i)->pObj == NULL ){ + //object hasn't been locked, so lock it. + (pList+i)->pObj = GDIOBJ_LockObj( (pList+i)->hObj, (pList+i)->Magic ); + } + } + return TRUE; +} + +/*! + * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. You should unlock the object + * as soon as you don't need to have access to it's data. + + * \param hObj Object handle + * \param Magic one of the magic numbers defined in \ref GDI Magic + * + * \note This function performs delayed cleanup. If the object is locked when GDI_FreeObj() is called + * then \em this function frees the object when reference count is zero. + * + * \todo Change synchronization algorithm. +*/ BOOL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic ) { PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff); @@ -312,80 +406,43 @@ BOOL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic ) return TRUE; } -/* -PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic) -{ - PGDIOBJHDR newObject; - PGDI_HANDLE_ENTRY handleEntry; - - newObject = ExAllocatePool (PagedPool, Size + sizeof (GDIOBJHDR)); - if (newObject == NULL) - { - return NULL; - } - RtlZeroMemory (newObject, Size + sizeof (GDIOBJHDR)); - - newObject->wTableIndex = GDIOBJ_iGetNextOpenHandleIndex (); - handleEntry = GDIOBJ_iGetHandleEntryForIndex (newObject->wTableIndex); - handleEntry->wMagic = Magic; - handleEntry->hProcessId = PsGetCurrentProcessId (); - handleEntry->pObject = newObject; - - return (PGDIOBJ)(((PCHAR) newObject) + sizeof (GDIOBJHDR)); -} - -BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic) -{ - PGDIOBJHDR objectHeader; - PGDI_HANDLE_ENTRY handleEntry; - objectHeader = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR)); - handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex); - if (handleEntry == 0 || handleEntry->wMagic != Magic) - return FALSE; - handleEntry->hProcessId = 0; - handleEntry->pObject = 0; - // (RJJ) set wMagic last to avoid race condition - handleEntry->wMagic = 0; - ExFreePool (objectHeader); - - return TRUE; -} - -HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic) +/*! + * Unlock multiple objects. Use this function when you need to unlock multiple objects and some of them may be + * duplicates. + * + * \param pList pointer to the list that contains handles to the objects. You should set hObj and Magic fields. + * \param nObj number of objects to lock + * + * \note this function uses O(n^2) algoritm because we shouldn't need to call it with more than 3 or 4 objects. +*/ +BOOL GDIOBJ_UnlockMultipleObj( PGDIMULTILOCK pList, INT nObj ) { - PGDIOBJHDR objectHeader; - PGDI_HANDLE_ENTRY handleEntry; - - if (Obj == NULL) - return NULL; - objectHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR)); - handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex); - if (handleEntry == 0 || - handleEntry->wMagic != Magic || - handleEntry->hProcessId != PsGetCurrentProcessId () ) - return NULL; - - return (HGDIOBJ) objectHeader->wTableIndex; + INT i, j; + ASSERT( pList ); + //go through the list checking for duplicate objects + for( i = 0; i < nObj; i++ ){ + if( (pList+i)->pObj != NULL ){ + for( j = i+1; j < nObj; j++ ){ + if( ((pList+i)->pObj == (pList+j)->pObj) ){ + //set the pointer to zero for all duplicates + (pList+j)->pObj = NULL; + } + } + GDIOBJ_UnlockObj( (pList+i)->hObj, (pList+i)->Magic ); + (pList+i)->pObj = NULL; + } + } + return TRUE; } -PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ ObjectHandle, WORD Magic) -{ - PGDI_HANDLE_ENTRY handleEntry; - - if (ObjectHandle == NULL) - return NULL; - - handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff); - if (handleEntry == 0 || - (Magic != GO_MAGIC_DONTCARE && Magic != Magic) || - handleEntry->hProcessId != PsGetCurrentProcessId () ) - return NULL; - - return (PGDIOBJ) (((PCHAR)handleEntry->pObject) + sizeof (GDIOBJHDR)); -} +/*! + * Marks the object as global. (Creator process ID is set to 0xFFFFFFFF). Global objects may be + * accessed by any process. + * \param ObjectHandle - handle of the object to make global. + * + * \note Only stock objects should be marked global. */ - VOID GDIOBJ_MarkObjectGlobal(HGDIOBJ ObjectHandle) { PGDI_HANDLE_ENTRY handleEntry; @@ -400,6 +457,11 @@ VOID GDIOBJ_MarkObjectGlobal(HGDIOBJ ObjectHandle) handleEntry->hProcessId = (HANDLE)0xFFFFFFFF; } +/*! + * Get the type (magic value) of the object. + * \param ObjectHandle - handle of the object. + * \return GDI Magic value. +*/ WORD GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle) { PGDI_HANDLE_ENTRY handleEntry; @@ -416,20 +478,25 @@ WORD GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle) return handleEntry->wMagic; } +/*! + * Initialization of the GDI object engine. +*/ VOID InitGdiObjectHandleTable (void) { DPRINT ("InitGdiObjectHandleTable\n"); ExInitializeFastMutex (&HandleTableMutex); ExInitializeFastMutex (&RefCountHandling); - //per http://www.wd-mag.com/articles/1999/9902/9902b/9902b.htm?topic=articles - //gdi handle table can hold 0x4000 handles + HandleTable = GDIOBJ_iAllocHandleTable (GDI_HANDLE_NUMBER); DPRINT("HandleTable: %x\n", HandleTable ); InitEngHandleTable(); } +/*! + * Creates a bunch of stock objects: brushes, pens, fonts. +*/ VOID CreateStockObjects(void) { // Create GDI Stock Objects from the logical structures we've defined @@ -471,24 +538,33 @@ VOID CreateStockObjects(void) StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); } +/*! + * Return stock object. + * \param Object - stock object id. + * \return Handle to the object. +*/ HGDIOBJ STDCALL W32kGetStockObject(INT Object) { - HGDIOBJ ret; - -/* if ((Object < 0) || (Object >= NB_STOCK_OBJECTS)) return 0; - if (!StockObjects[Object]) return 0; - ret = FIRST_STOCK_HANDLE + Object; - - return ret; */ - - return StockObjects[Object]; // FIXME........ + // check when adding new objects + if( (Object < 0) || (Object >= NB_STOCK_OBJECTS) ) + return NULL; + return StockObjects[Object]; } +/*! + * Delete GDI object + * \param hObject object handle + * \return if the function fails the returned value is NULL. +*/ BOOL STDCALL W32kDeleteObject(HGDIOBJ hObject) { return GDIOBJ_FreeObj( hObject, GO_MAGIC_DONTCARE, GDIOBJFLAG_DEFAULT ); } +/*! + * Internal function. Called when the process is destroyed to free the remaining GDI handles. + * \param Process - PID of the process that was destroyed. +*/ BOOL STDCALL W32kCleanupForProcess( INT Process ) { DWORD i; @@ -506,7 +582,11 @@ BOOL STDCALL W32kCleanupForProcess( INT Process ) return TRUE; } -// dump all the objects for process. if process == 0 dump all the objects +/*! + * Internal function. Dumps all the objects for the given process. + * \param If process == 0 dump all the objects. + * +*/ VOID STDCALL W32kDumpGdiObjects( INT Process ) { DWORD i; diff --git a/subsys/win32k/objects/line.c b/subsys/win32k/objects/line.c index 4c092fb..c4b1ac1 100644 --- a/subsys/win32k/objects/line.c +++ b/subsys/win32k/objects/line.c @@ -121,10 +121,12 @@ W32kLineTo(HDC hDC, ASSERT( pen ); // not yet implemented ASSERT( reg ); + /* Draw the line according to the DC origin */ ret = EngLineTo(SurfObj, NULL, // ClipObj PenToBrushObj(dc, pen), - dc->w.CursPosX, dc->w.CursPosY, XEnd, YEnd, + dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY, + dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd, reg, // Bounding rectangle dc->w.ROPmode); // MIX diff --git a/subsys/win32k/objects/region.c b/subsys/win32k/objects/region.c index 161b8ad..e81184d 100644 --- a/subsys/win32k/objects/region.c +++ b/subsys/win32k/objects/region.c @@ -300,10 +300,8 @@ empty: return TRUE; } -/*********************************************************************** - * REGION_CropRgn - * - * +/*! + * \param * hSrc: Region to crop and offset. * lpRect: Clipping rectangle. Can be NULL (no clipping). * lpPt: Points to offset the cropped region. Can be NULL (no offset). @@ -312,39 +310,27 @@ empty: * Allowed to be the same region as hSrc in which case everything * will be done in place, with no memory reallocations. * - * Returns: hDst if success, 0 otherwise. + * \return hDst if success, 0 otherwise. */ HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt) { - PROSRGNDATA objSrc = RGNDATA_LockRgn(hSrc); - HRGN hNewDst; + PROSRGNDATA objSrc, rgnDst; + HRGN hNewDst, hRet = NULL; + GDIMULTILOCK Lock[2] = {{hDst, 0, GO_REGION_MAGIC}, {hSrc, 0, GO_REGION_MAGIC}}; - if(objSrc) - { - PROSRGNDATA rgnDst; - - if(hDst) - { - if(!(rgnDst = RGNDATA_LockRgn(hDst))) - { - hDst = 0; - goto done; - } - } - else{ + if( !hDst ){ if( !( hNewDst = RGNDATA_AllocRgn(1) ) ){ - RGNDATA_UnlockRgn( hSrc ); return 0; } + Lock[0].hObj = hNewDst; + } - if(!(rgnDst = RGNDATA_LockRgn(hNewDst))) - { - RGNDATA_FreeRgn( hNewDst ); - RGNDATA_UnlockRgn( hSrc ); - return 0; - } - } + GDIOBJ_LockMultipleObj( &Lock, 2 ); + rgnDst = Lock[0].pObj; + objSrc = Lock[1].pObj; + if( objSrc && rgnDst ) + { if(rgnDst) { POINT pt = { 0, 0 }; @@ -354,44 +340,25 @@ HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt) if(REGION_CropAndOffsetRegion(lpPt, lpRect, objSrc, rgnDst) == FALSE) { // ve failed cleanup and return - RGNDATA_UnlockRgn( hSrc ); - - if(hDst) // unlock new region if allocated - RGNDATA_UnlockRgn( hDst ); - else - RGNDATA_UnlockRgn( hNewDst ); - - return 0; + hRet = NULL; } else{ // ve are fine. unlock the correct pointer and return correct handle - RGNDATA_UnlockRgn( hSrc ); - - if(hDst == 0){ - RGNDATA_UnlockRgn( hNewDst ); - return hNewDst; - } - else { - RGNDATA_UnlockRgn( hDst ); - return hDst; - } + hRet = Lock[0].hObj; } } -done: - RGNDATA_UnlockRgn( hSrc ); } - return 0; + GDIOBJ_UnlockMultipleObj( &Lock, 2 ); + return hRet; } -/*********************************************************************** - * REGION_Coalesce - * +/*! * Attempt to merge the rects in the current band with those in the * previous one. Used only by REGION_RegionOp. * * Results: * The new index for the previous band. * - * Side Effects: + * \note Side Effects: * If coalescing takes place: * - rectangles in the previous band will have their bottom fields * altered. @@ -517,9 +484,7 @@ static INT REGION_Coalesce ( return (curStart); } -/*********************************************************************** - * REGION_RegionOp - * +/*! * Apply an operation to two regions. Called by REGION_Union, * REGION_Inverse, REGION_Subtract, REGION_Intersect... * @@ -529,8 +494,7 @@ static INT REGION_Coalesce ( * Side Effects: * The new region is overwritten. * - * Notes: - * The idea behind this function is to view the two regions as sets. + *\note The idea behind this function is to view the two regions as sets. * Together they cover a rectangle of area that this function divides * into horizontal bands where points are covered only by one region * or by both. For the first case, the nonOverlapFunc is called with @@ -824,15 +788,13 @@ static void REGION_RegionOp( ***********************************************************************/ -/*********************************************************************** - * REGION_IntersectO - * +/*! * Handle an overlapping band for REGION_Intersect. * * Results: * None. * - * Side Effects: + * \note Side Effects: * Rectangles may be added to the region. * */ @@ -919,9 +881,7 @@ static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1, * Region Union ***********************************************************************/ -/*********************************************************************** - * REGION_UnionNonO - * +/*! * Handle a non-overlapping band for the union operation. Just * Adds the rectangles into the region. Doesn't have to check for * subsumption or anything. @@ -929,7 +889,7 @@ static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1, * Results: * None. * - * Side Effects: + * \note Side Effects: * pReg->numRects is incremented and the final rectangles overwritten * with the rectangles we're passed. * @@ -955,16 +915,14 @@ static void REGION_UnionNonO (ROSRGNDATA *pReg, RECT *r, RECT *rEnd, return; } -/*********************************************************************** - * REGION_UnionO - * +/*! * Handle an overlapping band for the union operation. Picks the * left-most rectangle each time and merges it into the region. * * Results: * None. * - * Side Effects: + * \note Side Effects: * Rectangles are overwritten in pReg->rects and pReg->numRects will * be changed. * @@ -1093,16 +1051,14 @@ static void REGION_UnionRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1, * Region Subtraction ***********************************************************************/ -/*********************************************************************** - * REGION_SubtractNonO1 - * +/*! * Deal with non-overlapping band for subtraction. Any parts from * region 2 we discard. Anything from region 1 we add to the region. * * Results: * None. * - * Side Effects: + * \note Side Effects: * pReg may be affected. * */ @@ -1128,16 +1084,14 @@ static void REGION_SubtractNonO1 (ROSRGNDATA *pReg, RECT *r, RECT *rEnd, } -/*********************************************************************** - * REGION_SubtractO - * +/*! * Overlapping band subtraction. x1 is the left-most point not yet * checked. * * Results: * None. * - * Side Effects: + * \note Side Effects: * pReg may have rectangles added to it. * */ @@ -1256,16 +1210,14 @@ static void REGION_SubtractO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End, return; } -/*********************************************************************** - * REGION_SubtractRegion - * +/*! * Subtract regS from regM and leave the result in regD. * S stands for subtrahend, M for minuend and D for difference. * * Results: * TRUE. * - * Side Effects: + * \note Side Effects: * regD is overwritten. * */ @@ -1332,9 +1284,8 @@ static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra, } -/*********************************************************************** - * REGION_UnionRectWithRegion - * Adds a rectangle to a WINEREGION +/*! + * Adds a rectangle to a REGION */ static void REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn) { @@ -1451,11 +1402,16 @@ W32kCombineRgn(HRGN hDest, INT CombineMode) { INT result = ERROR; - PROSRGNDATA destRgn = RGNDATA_LockRgn(hDest); + GDIMULTILOCK Lock[3] = {{hDest, 0, GO_REGION_MAGIC}, {hSrc1, 0, GO_REGION_MAGIC}, {hSrc2, 0, GO_REGION_MAGIC}}; + PROSRGNDATA destRgn, src1Rgn, src2Rgn; - if( destRgn ){ - PROSRGNDATA src1Rgn = RGNDATA_LockRgn(hSrc1); + GDIOBJ_LockMultipleObj( &Lock, 3 ); + destRgn = (PROSRGNDATA) Lock[0].pObj; + src1Rgn = (PROSRGNDATA) Lock[1].pObj; + src2Rgn = (PROSRGNDATA) Lock[2].pObj; + + if( destRgn ){ if( src1Rgn ){ if (CombineMode == RGN_COPY) { @@ -1465,7 +1421,6 @@ W32kCombineRgn(HRGN hDest, } else { - PROSRGNDATA src2Rgn = RGNDATA_LockRgn(hSrc2); if( src2Rgn ){ switch (CombineMode) { @@ -1483,17 +1438,15 @@ W32kCombineRgn(HRGN hDest, break; } result = destRgn->rdh.iType; - RGNDATA_UnlockRgn( hSrc2 ); } - RGNDATA_UnlockRgn( hSrc1 ); } - RGNDATA_UnlockRgn( hDest ); - } - else{ - DPRINT("W32kCombineRgn: hDest unavailable\n"); - return ERROR; } } + else{ + DPRINT("W32kCombineRgn: hDest unavailable\n"); + result = ERROR; + } + GDIOBJ_UnlockMultipleObj( &Lock, 3 ); return result; } @@ -1944,9 +1897,7 @@ W32kUnionRectWithRgn(HRGN hDest, const RECT* unsafeRect) return hDest; } -/*********************************************************************** - * GetRegionData (GDI32.@) - * +/*! * MSDN: GetRegionData, Return Values: * * "If the function succeeds and dwCount specifies an adequate number of bytes, diff --git a/subsys/win32k/win32k.rc b/subsys/win32k/win32k.rc index 20e669a..95c2d34 100644 --- a/subsys/win32k/win32k.rc +++ b/subsys/win32k/win32k.rc @@ -1,6 +1,5 @@ - -#include "../../include/defines.h" -#include "../../include/reactos/resource.h" +#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/system.hiv b/system.hiv index c1b3b6a..d1d5648 100644 --- a/system.hiv +++ b/system.hiv @@ -127,14 +127,14 @@ REGEDIT4 "ErrorControl"=dword:00000000 "Group"="Event log" "ImagePath"=expand:"%SystemRoot%\system32\eventlog.exe" -"Start"=dword:00000004 +"Start"=dword:00000002 "Type"=dword:00000010 [\Registry\Machine\SYSTEM\ControlSet001\Services\Floppy] "ErrorControl"=dword:00000000 "Group"="Primary Disk" "ImagePath"=expand:"system32\drivers\floppy.sys" -"Start"=dword:00000004 +"Start"=dword:00000001 "Type"=dword:00000001 [\Registry\Machine\SYSTEM\ControlSet001\Services\Fs_Rec] @@ -158,6 +158,13 @@ REGEDIT4 "Start"=dword:00000001 "Type"=dword:00000001 +[\Registry\Machine\SYSTEM\ControlSet001\Services\Mouse] +"ErrorControl"=dword:00000000 +"Group"="Pointer Class" +"ImagePath"=expand:"system32\drivers\mouclass.sys" +"Start"=dword:00000001 +"Type"=dword:00000001 + [\Registry\Machine\SYSTEM\ControlSet001\Services\Msfs] "ErrorControl"=dword:00000000 "Group"="File System" @@ -207,6 +214,17 @@ REGEDIT4 "Start"=dword:00000001 "Type"=dword:00000001 +[\Registry\Machine\SYSTEM\ControlSet001\Services\Packet] +"ErrorControl"=dword:00000001 +"Group"="PNP_TDI" +"ImagePath"=expand:"system32\drivers\packet.sys" +"Start"=dword:00000002 +"Type"=dword:00000001 + +[\Registry\Machine\SYSTEM\ControlSet001\Services\Packet\Linkage] +"Bind"=expand:"\Device\ne2000" +"Export"=expand:"\Device\packet" + [\Registry\Machine\SYSTEM\ControlSet001\Services\Pice] "ErrorControl"=dword:00000000 "Group"="Debug" @@ -214,6 +232,13 @@ REGEDIT4 "Start"=dword:00000004 "Type"=dword:00000001 +[\Registry\Machine\SYSTEM\ControlSet001\Services\Psaux] +"ErrorControl"=dword:00000000 +"Group"="Pointer Port" +"ImagePath"=expand:"system32\drivers\psaux.sys" +"Start"=dword:00000001 +"Type"=dword:00000001 + [\Registry\Machine\SYSTEM\ControlSet001\Services\RpcSs] "ErrorControl"=dword:00000001 "ImagePath"=expand:"%SystemRoot%\system32\rpcss.exe" @@ -234,41 +259,6 @@ REGEDIT4 "Start"=dword:00000002 "Type"=dword:00000001 -[\Registry\Machine\SYSTEM\ControlSet001\Services\Packet] -"ErrorControl"=dword:00000001 -"Group"="PNP_TDI" -"ImagePath"=expand:"system32\drivers\packet.sys" -"Start"=dword:00000002 -"Type"=dword:00000001 - -[\Registry\Machine\SYSTEM\ControlSet001\Services\Vfatfs] -"ErrorControl"=dword:00000000 -"Group"="Boot File System" -"ImagePath"=expand:"system32\drivers\vfatfs.sys" -"Start"=dword:00000000 -"Type"=dword:00000002 - -[\Registry\Machine\SYSTEM\ControlSet001\Services\Vga] -"ErrorControl"=dword:00000000 -"Group"="Video" -"ImagePath"=expand:"system32\drivers\vgamp.sys" -"Start"=dword:00000001 -"Type"=dword:00000001 - -[\Registry\Machine\SYSTEM\ControlSet001\Services\Mouse] -"ErrorControl"=dword:00000000 -"Group"="Pointer Class" -"ImagePath"=expand:"system32\drivers\mouclass.sys" -"Start"=dword:00000001 -"Type"=dword:00000001 - -[\Registry\Machine\SYSTEM\ControlSet001\Services\Psaux] -"ErrorControl"=dword:00000000 -"Group"="Pointer Port" -"ImagePath"=expand:"system32\drivers\psaux.sys" -"Start"=dword:00000001 -"Type"=dword:00000001 - [\Registry\Machine\SYSTEM\ControlSet001\Services\Tcpip\Linkage] "Bind"=expand:"\Device\ne2000" "Export"=expand:"\Device\tcpip" @@ -284,12 +274,22 @@ REGEDIT4 "SearchList"="" "EnableSecurityFilters"=dword:00000000 -[\Registry\Machine\SYSTEM\ControlSet001\Services\Packet\Linkage] -"Bind"=expand:"\Device\ne2000" -"Export"=expand:"\Device\packet" - [\Registry\Machine\SYSTEM\ControlSet001\Services\Tcpip\Parameters\PersistentRoutes] +[\Registry\Machine\SYSTEM\ControlSet001\Services\Vfatfs] +"ErrorControl"=dword:00000000 +"Group"="Boot File System" +"ImagePath"=expand:"system32\drivers\vfatfs.sys" +"Start"=dword:00000000 +"Type"=dword:00000002 + +[\Registry\Machine\SYSTEM\ControlSet001\Services\Vga] +"ErrorControl"=dword:00000000 +"Group"="Video" +"ImagePath"=expand:"system32\drivers\vgamp.sys" +"Start"=dword:00000001 +"Type"=dword:00000001 + [\Registry\Machine\SYSTEM\ControlSet002] [\Registry\Machine\SYSTEM\Select] @@ -303,3 +303,28 @@ REGEDIT4 "OsLoaderPath"="\" "SetupType"=dword:00000000 "SystemPartition"="\Device\HarddiskVolume1" +"SystemSetupInProgress"=dword:00000000 + +[\Registry\Machine\SOFTWARE] + +[\Registry\Machine\SOFTWARE\Classes] + +[\Registry\Machine\SOFTWARE\Classes\WinNT] + +[\Registry\Machine\SOFTWARE\Classes\WinNT\Clsid] +"Default" = "{8b20cd60-0f29-11cf-abc4-02608c9e7553}" + +[\Registry\Machine\SOFTWARE\Classes\NDS] + +[\Registry\Machine\SOFTWARE\Classes\NDS\Clsid] +"Default" = "{323991f0-7bad-11cf-b03d-00aa006e0975}" + +[\Registry\Machine\SOFTWARE\ReactOS] + +[\Registry\Machine\SOFTWARE\ReactOS\Windows NT] + +[\Registry\Machine\SOFTWARE\ReactOS\Windows NT\CurrentVersion] + +[\Registry\Machine\SOFTWARE\ReactOS\Windows NT\CurrentVersion\WinLogon] +"Shell"=expand:"%SystemRoot%\System32\Shell.exe" +"StartServices"=dword:00000001 diff --git a/tools/.cvsignore b/tools/.cvsignore index 7cc43f5..cea22db 100644 --- a/tools/.cvsignore +++ b/tools/.cvsignore @@ -7,3 +7,4 @@ rrmdir mkconfig rdel rsym +rtouch diff --git a/tools/Makefile b/tools/Makefile index 5f7f828..cee144c 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,7 +7,8 @@ TOOLS = \ rdel$(EXE_POSTFIX) \ rmkdir$(EXE_POSTFIX) \ rrmdir$(EXE_POSTFIX) \ - rsym$(EXE_POSTFIX) + rsym$(EXE_POSTFIX) \ + rtouch$(EXE_POSTFIX) CLEAN_FILES = $(TOOLS) @@ -59,6 +60,16 @@ rsym$(EXE_POSTFIX): rsym.c $(HOST_CC) $(CFLAGS) -DDOS_PATHS rsym.c -o rsym$(EXE_POSTFIX) endif +ifeq ($(HOST),mingw32-linux) +rtouch$(EXE_POSTFIX): rtouch.c + $(HOST_CC) $(CFLAGS) -DUNIX_PATHS rtouch.c -o rtouch$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +rtouch$(EXE_POSTFIX): rtouch.c + $(HOST_CC) $(CFLAGS) -DDOS_PATHS rtouch.c -o rtouch$(EXE_POSTFIX) +endif + + wmc_directory_target: make -C wmc wmc$(EXE_POSTFIX) diff --git a/tools/helper.mk b/tools/helper.mk index 326bcc0..646bdd9 100644 --- a/tools/helper.mk +++ b/tools/helper.mk @@ -39,6 +39,7 @@ # $TARGET_NORC = Do not include standard resource file (no,yes) (optional) # $TARGET_LIBPATH = Destination path for import libraries (optional) # $TARGET_INSTALLDIR = Destination path when installed (optional) +# $TARGET_PCH = Filename of header to use to generate a PCH if supported by the compiler (optional) # $WINE_MODE = Compile using WINE headers (no,yes) (optional) # $WINE_RC = Name of .rc file for WINE modules (optional) @@ -300,6 +301,26 @@ ifeq ($(TARGET_TYPE),program) endif endif +ifeq ($(TARGET_TYPE),proglib) + ifeq ($(TARGET_APPTYPE),windows) + MK_DEFENTRY := _WinMainCRTStartup + MK_SDKLIBS := ntdll.a kernel32.a gdi32.a user32.a + TARGET_LFLAGS += -Wl,--subsystem,windows + endif + + ifeq ($(TARGET_APPTYPE),native) + MK_DEFENTRY := _NtProcessStartup@4 + MK_SDKLIBS := ntdll.a + TARGET_LFLAGS += -Wl,--subsystem,native -nostartfiles + endif + + ifeq ($(TARGET_APPTYPE),console) + MK_DEFENTRY := _mainCRTStartup + MK_SDKLIBS := + TARGET_LFLAGS += -Wl,--subsystem,console + endif +endif + MK_RESOURCE := $(MK_RES_BASE).coff @@ -549,6 +570,12 @@ endif # MK_IMPLIBONLY $(MK_FULLRES): $(PATH_TO_TOP)/include/reactos/buildno.h $(TARGET_PATH)/$(MK_RES_BASE).rc +ifeq ($(MK_DEPENDS),yes) +depends: +else +depends: +endif + ifeq ($(MK_IMPLIB),yes) $(MK_IMPLIBPATH)/$(MK_BASENAME).a: $(MK_DEFNAME) $(DLLTOOL) --dllname $(MK_FULLNAME) \ @@ -565,7 +592,7 @@ endif MK_CLEANFILES := $(filter %.o,$(MK_OBJECTS)) clean: - - $(RM) *.o $(MK_BASENAME).sym $(MK_BASENAME).a $(TARGET_PATH)/$(MK_RES_BASE).coff \ + - $(RM) *.o depend.d *.pch $(MK_BASENAME).sym $(MK_BASENAME).a $(TARGET_PATH)/$(MK_RES_BASE).coff \ $(MK_FULLNAME) $(MK_NOSTRIPNAME) $(MK_CLEANFILES) \ junk.tmp base.tmp temp.exp \ $(TARGET_CLEAN) @@ -600,14 +627,40 @@ $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(CP) $(MK_FULLNAME) $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME) $(CP) $(MK_BASENAME).sym $(DIST_DIR)/symbols/$(MK_BASENAME).sym - endif # MK_IMPLIBONLY -.phony: all implib clean install dist +.phony: all depends implib clean install dist depends + + +# Precompiled header support +# When using PCHs, use dependency tracking to keep the .pch files up-to-date. + +MK_PCHNAME = +ifeq ($(ROS_USE_PCH),yes) +ifneq ($(TARGET_PCH),) +MK_PCHNAME = $(TARGET_PCH).pch + +# GCC generates wrong dependencies for header files. +MK_PCHFAKE = $(TARGET_PCH:.h=.o) +$(MK_PCHFAKE): + - $(RTOUCH) $(MK_PCHFAKE) + +$(MK_PCHNAME): depend.d + - $(RTOUCH) $(MK_PCHNAME) + - $(CC) $(TARGET_CFLAGS) $(TARGET_PCH) + +depend.d: $(MK_PCHFAKE) + - $(RTOUCH) depend.d + - $(CC) $(TARGET_CFLAGS) $(TARGET_PCH) -M -MF depend.d + +include depend.d + +endif # TARGET_PCH +endif # ROS_USE_PCH -%.o: %.c +%.o: %.c $(MK_PCHNAME) $(CC) $(TARGET_CFLAGS) -c $< -o $@ %.o: %.cc $(CC) $(TARGET_CPPFLAGS) -c $< -o $@ diff --git a/tools/rsym.c b/tools/rsym.c index cf2638a..50a31b3 100644 --- a/tools/rsym.c +++ b/tools/rsym.c @@ -5,8 +5,6 @@ #include #include -#define NULL ((void*)0) - #define IMAGE_DOS_MAGIC 0x5a4d #define IMAGE_PE_MAGIC 0x00004550 diff --git a/tools/rtouch.c b/tools/rtouch.c new file mode 100755 index 0000000..ce1773c --- /dev/null +++ b/tools/rtouch.c @@ -0,0 +1,81 @@ +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#include +#include + +char* convert_path(char* origpath) +{ + char* newpath; + int i; + + newpath = (char *)strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +int main(int argc, char* argv[]) +{ + char* path; + FILE* file; +#ifdef WIN32 + time_t now; + struct utimbuf fnow; +#endif + + if (argc != 2) + { + fprintf(stderr, "Wrong number of arguments.\n"); + exit(1); + } + + path = convert_path(argv[1]); + file = (FILE *)open(path, S_IWRITE); + if (file == (void*)-1) + { + file = (FILE *)open(path, S_IWRITE | O_CREAT); + if (file == (void*)-1) + { + fprintf(stderr, "Cannot create file.\n"); + exit(1); + } + } + + fclose(file); + +#ifdef WIN32 + now = time(); + fnow.actime = now; + fnow.modtime = now; + (int) utime(path, &fnow); +#else + (int) utimes(path, NULL); +#endif + + exit(0); +} diff --git a/tools/wmc/.cvsignore b/tools/wmc/.cvsignore index e0e1108..82c5194 100644 --- a/tools/wmc/.cvsignore +++ b/tools/wmc/.cvsignore @@ -4,3 +4,7 @@ wmc *.exe *.o *.sym +*.dsp +*.dsw +*.ncb +*.opt diff --git a/tools/wmc/lang.c b/tools/wmc/lang.c index 796ffd9..734173b 100644 --- a/tools/wmc/lang.c +++ b/tools/wmc/lang.c @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 #include diff --git a/tools/wmc/lang.h b/tools/wmc/lang.h index f6a17f1..b4d25dc 100644 --- a/tools/wmc/lang.h +++ b/tools/wmc/lang.h @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 __WMC_LANG_H diff --git a/tools/wmc/mcl.c b/tools/wmc/mcl.c index d0da376..41dd4ab 100644 --- a/tools/wmc/mcl.c +++ b/tools/wmc/mcl.c @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 #include diff --git a/tools/wmc/mcy.y b/tools/wmc/mcy.y index b9dd71d..3a8ad14 100644 --- a/tools/wmc/mcy.y +++ b/tools/wmc/mcy.y @@ -3,6 +3,22 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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: + * * The basic grammar of the file is yet another example of, humpf, * design. There is is mix of context-insensitive and -sentitive * stuff, which makes it rather complicated. diff --git a/tools/wmc/utils.c b/tools/wmc/utils.c index 1725ffd..125aa64 100644 --- a/tools/wmc/utils.c +++ b/tools/wmc/utils.c @@ -3,6 +3,19 @@ * * Copyright 1998,2000 Bertho A. Stultiens * + * 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" diff --git a/tools/wmc/utils.h b/tools/wmc/utils.h index 0394487..deaeacb 100644 --- a/tools/wmc/utils.h +++ b/tools/wmc/utils.h @@ -3,6 +3,19 @@ * * Copyright 1998,2000 Bertho A. Stultiens (BS) * + * 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 __WMC_UTILS_H diff --git a/tools/wmc/wmc.c b/tools/wmc/wmc.c index 6535d67..f4780db 100644 --- a/tools/wmc/wmc.c +++ b/tools/wmc/wmc.c @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 #include diff --git a/tools/wmc/wmc.h b/tools/wmc/wmc.h index 9ac5ad6..288a90b 100644 --- a/tools/wmc/wmc.h +++ b/tools/wmc/wmc.h @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 __WMC_WMC_H @@ -71,6 +84,15 @@ void add_token(tok_e type, const WCHAR *name, int tok, int cp, const WCHAR *alia token_t *lookup_token(const WCHAR *s); void get_tokentable(token_t **tab, int *len); + +#ifdef __GNUC__ #define _alloca alloca +//#define alloca __builtin_alloca +#else /* not GNU C. */ +//#define alloca __builtin_alloca + +#pragma warning (disable:4305) // 'initializing' : truncation from 'const int ' to 'const char ' + +#endif /*__GNUC__*/ #endif diff --git a/tools/wmc/wmctypes.h b/tools/wmc/wmctypes.h index 6ce6956..1692eed 100644 --- a/tools/wmc/wmctypes.h +++ b/tools/wmc/wmctypes.h @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 __WMC_WMCTYPES_H diff --git a/tools/wmc/write.c b/tools/wmc/write.c index 1dc7c1d..57371a5 100644 --- a/tools/wmc/write.c +++ b/tools/wmc/write.c @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 @@ -88,7 +101,8 @@ static char *dup_u2c(int cp, const WCHAR *uc) // if(!cpdef) // internal_error(__FILE__, __LINE__, "Codepage %d not found (vanished?)", cp); // if((len = cp_wcstombs(cpdef, 0, uc, unistrlen(uc)+1, cptr, len+1, NULL, NULL)) < 0) - if((len = WideCharToMultiByte(cp, 0, uc, unistrlen(uc)+1, cptr, len+1, NULL, NULL)) < 0) + if((len = WideCharToMultiByte(cp, 0, uc, unistrlen(uc)+1, cptr, len+1, NULL, NULL)) < 0) + internal_error(__FILE__, __LINE__, "Buffer overflow? code %d.", len); return cptr; } @@ -378,7 +392,8 @@ static char *make_string(WCHAR *uc, int len, int codepage) // assert(cpdef != NULL); // if((i = cp_wcstombs(cpdef, 0, uc, unistrlen(uc)+1, tmp, 2*len+1, NULL, NULL)) < 0) - if((i = WideCharToMultiByte(codepage, 0, uc, unistrlen(uc)+1, tmp, 2*len+1, NULL, NULL)) < 0) + if((i = WideCharToMultiByte(codepage, 0, uc, unistrlen(uc)+1, tmp, 2*len+1, NULL, NULL)) < 0) + internal_error(__FILE__, __LINE__, "Buffer overflow? code %d.", i); *cptr++ = ' '; *cptr++ = '"'; @@ -435,7 +450,8 @@ static char *make_string(WCHAR *uc, int len, int codepage) } -static char *make_bin_string(WCHAR *uc, int len, int *retlen, int codepage) +static char *make_bin_string(WCHAR *uc, int len, int *retlen, int codepage) + { char *str = xmalloc(7 * len + 1); int i; diff --git a/tools/wmc/write.h b/tools/wmc/write.h index 2d627d6..1797a68 100644 --- a/tools/wmc/write.h +++ b/tools/wmc/write.h @@ -3,6 +3,19 @@ * * Copyright 2000 Bertho A. Stultiens (BS) * + * 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 __WMC_WRITE_H #define __WMC_WRITE_H diff --git a/txtsetup.sif b/txtsetup.sif new file mode 100644 index 0000000..a4eb3f2 --- /dev/null +++ b/txtsetup.sif @@ -0,0 +1,98 @@ +[Version] +Signature = "$ReactOS$" + +[Directories] +1 = "\" +2 = system32 +3 = system32\drivers +4 = system32\config +5 = media +6 = media\fonts +7 = bin + +[SourceFiles] +ntoskrnl.exe = 2 +hal.dll = 2 + +acpi.sys = 3 +isapnp.sys = 3 + +beep.sys = 3 +blue.sys = 3 +floppy.sys = 3 +null.sys = 3 +serial.sys = 3 +vgaddi.dll = 3 +vgamp.sys = 3 +vidport.sys = 3 + +cdfs.sys = 3 +fs_rec.sys = 3 +msfs.sys = 3 +mup.sys = 3 +npfs.sys = 3 +ntfs.sys = 3 +vfatfs.sys = 3 + +keyboard.sys = 3 +mouclass.sys = 3 +psaux.sys = 3 + +unbzip2.sys = 3 + +afd.sys = 3 +ne2000.sys = 3 +ndis.sys = 3 +npf.sys = 3 +;packet.sys = 3 +tcpip.sys = 3 +tdi.sys = 3 + +atapi.sys = 3 +cdrom.sys = 3 +class2.sys = 3 +disk.sys = 3 +scsiport.sys = 3 + +advapi32.dll = 2 +crtdll.dll = 2 +fmifs.dll = 2 +gdi32.dll = 2 +kernel32.dll = 2 +msafd.dll = 2 +msvcrt.dll = 2 +ntdll.dll = 2 +;ole32.dll = 2 +;oleaut32.dll = 2 +packet.dll = 2 +secur32.dll = 2 +;shell32.dll = 2 +user32.dll = 2 +version.dll = 2 +winedbgc.dll = 2 +winmm.dll = 2 +ws2_32.dll = 2 +ws2help.dll = 2 +wshirda.dll = 2 + +eventlog.exe = 2 +rpcss.exe = 2 +csrss.exe = 2 +ntvdm.exe = 2 +smss.exe = 2 +autochk.exe = 2 +gstart.exe = 2 +;lsass.exe = 2 +services.exe = 2 +shell.exe = 2 +winlogon.exe = 2 + +win32k.sys = 3 + +helb____.ttf = 6 +timr____.ttf = 6 + +system.hiv = 4 + +[SetupData] +DefaultPath = \reactos -- 1.8.3.1