From 57e0e57420fe9673199d5d312559ab0c7b7c034a Mon Sep 17 00:00:00 2001 From: ahodgkinson Date: Thu, 23 Mar 2006 21:45:43 +0000 Subject: [PATCH] Added support for NetWare builds using the OpenWatcom compiler. git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@205 0109f412-320b-0410-ab79-c3e0c5ffbbe6 --- flaim/Makefile | 906 ++++++--- flaim/src/fcs.h | 40 - flaim/src/fcs_tcp.cpp | 14 +- flaim/src/flaim.h | 15 +- flaim/src/flprintf.cpp | 2 +- flaim/src/fnlm.cpp | 3937 ++++++++++++++++++++++++++++++++++++++ flaim/src/fnlm.h | 236 +++ flaim/src/ftk.h | 4103 +++++++++++++++------------------------- flaim/src/ftknlm.h | 1714 +++++++++++++++++ flaim/src/nlmload.cpp | 433 +++++ flaim/src/nwyield.cpp | 249 +++ flaim/util/dbshell.cpp | 20 +- flaim/util/sample.cpp | 2 +- 13 files changed, 8734 insertions(+), 2937 deletions(-) create mode 100644 flaim/src/fnlm.cpp create mode 100644 flaim/src/fnlm.h create mode 100644 flaim/src/ftknlm.h create mode 100644 flaim/src/nlmload.cpp create mode 100644 flaim/src/nwyield.cpp diff --git a/flaim/Makefile b/flaim/Makefile index 36901fb..8ac70fa 100644 --- a/flaim/Makefile +++ b/flaim/Makefile @@ -47,10 +47,12 @@ minor_version = 8 calc_svn_revision = ifneq (,$(findstring ignore-local-mods,$(MAKECMDGOALS))) + submake_targets += ignore-local-mods ignore_local_mods = 1 endif ifneq (,$(findstring ilm,$(MAKECMDGOALS))) + submake_targets += ilm ignore_local_mods = 1 endif @@ -171,15 +173,19 @@ package_proj_name_and_ver = $(package_proj_name)-$(version) target_build_type = usenativecc = yes target_os_family = -target_processor = +target_processor_family = target_word_size = -requested_target_word_size = +requested_word_size = win_target = unix_target = +netware_target = +submake_targets = +package_archive_format = tar # -- Enable command echoing -- ifneq (,$(findstring verbose,$(MAKECMDGOALS))) + submake_targets += verbose ec = else ec = @ @@ -249,12 +255,14 @@ endif ifndef target_build_type ifneq (,$(findstring debug,$(MAKECMDGOALS))) + submake_targets += debug target_build_type = debug endif endif ifndef target_build_type ifneq (,$(findstring release,$(MAKECMDGOALS))) + submake_targets += release target_build_type = release endif endif @@ -266,92 +274,28 @@ endif # -- Use non-native (i.e., gcc) compiler on Solaris, etc. ifneq (,$(findstring usegcc,$(MAKECMDGOALS))) + submake_targets += usegcc usenativecc = no endif # -- Override platform default word size? -- ifneq (,$(findstring 64bit,$(MAKECMDGOALS))) - requested_target_word_size = 64 + submake_targets += 64bit + requested_word_size = 64 endif ifneq (,$(findstring 32bit,$(MAKECMDGOALS))) - requested_target_word_size = 32 + submake_targets += 32bit + requested_word_size = 32 endif -# -- Target operating system and processor architecture -- +# -- Target operating system -- ifndef target_os_family ifeq ($(host_os_family),linux) unix_target = yes target_os_family = linux - - ifeq (,$(HOSTTYPE)) - ifneq (,$(RPM_ARCH)) - HOSTTYPE = $(RPM_ARCH) - endif - $(error HOSTTYPE environment variable has not been set) - endif - - ifeq (,$(HOSTTYPE)) - $(error HOSTTYPE environment variable has not been set) - endif - - ifdef requested_target_word_size - ifneq (,$(findstring x86,$(HOSTTYPE))) - ifeq ($(requested_target_word_size),64) - target_processor = x86 - target_word_size = 64 - else - target_processor = x86 - target_word_size = 32 - endif - else - $(error Platform not supported) - endif - else - ifneq (,$(findstring x86,$(HOSTTYPE))) - ifneq (,$(findstring x86_64,$(HOSTTYPE))) - target_processor = x86 - target_word_size = 64 - else - target_processor = x86 - target_word_size = 32 - endif - else - ifneq (,$(findstring 86,$(HOSTTYPE))) - target_processor = x86 - target_word_size = 32 - else - ifneq (,$(findstring s390,$(HOSTTYPE))) - ifneq (,$(findstring s390x,$(HOSTTYPE))) - target_processor = s390x - target_word_size = 64 - else - target_processor = s390 - target_word_size = 31 - endif - else - ifneq (,$(findstring ia64,$(HOSTTYPE))) - target_processor = ia64 - target_word_size = 64 - else - ifneq (,$(findstring ppc64,$(HOSTTYPE))) - target_processor = powerpc - target_word_size = 64 - else - ifneq (,$(findstring ppc,$(HOSTTYPE))) - target_processor = powerpc - target_word_size = 32 - else - $(error Platform not supported) - endif - endif - endif - endif - endif - endif - endif endif endif @@ -359,38 +303,6 @@ ifndef target_os_family ifeq ($(host_os_family),solaris) unix_target = yes target_os_family = solaris - - ifeq (,$(HOSTTYPE)) - $(error HOSTTYPE environment variable has not been set) - endif - - ifdef requested_target_word_size - ifneq (,$(findstring sparc,$(HOSTTYPE))) - ifeq ($(requested_target_word_size),64) - target_processor = sparc - target_word_size = 64 - else - target_processor = sparc - target_word_size = 32 - endif - else - ifeq ($(requested_target_word_size),64) - target_processor = x86 - target_word_size = 64 - else - target_processor = x86 - target_word_size = 32 - endif - endif - else - ifneq (,$(findstring sparc,$(HOSTTYPE))) - target_processor = sparc - target_word_size = 32 - else - target_processor = x86 - target_word_size = 32 - endif - endif endif endif @@ -398,31 +310,6 @@ ifndef target_os_family ifeq ($(host_os_family),osx) unix_target = yes target_os_family = osx - - ifeq (,$(HOSTTYPE)) - $(error HOSTTYPE environment variable has not been set) - endif - - ifdef requested_target_word_size - ifneq (,$(findstring powerpc,$(HOSTTYPE))) - ifeq ($(requested_target_word_size),64) - target_processor = powerpc - target_word_size = 64 - else - target_processor = powerpc - target_word_size = 32 - endif - else - $(error Platform not supported) - endif - else - ifneq (,$(findstring powerpc,$(HOSTTYPE))) - target_processor = powerpc - target_word_size = 32 - else - $(error Platform not supported) - endif - endif endif endif @@ -430,31 +317,6 @@ ifndef target_os_family ifeq ($(host_os_family),aix) unix_target = yes target_os_family = aix - - ifeq (,$(HOSTTYPE)) - $(error HOSTTYPE environment variable has not been set) - endif - - ifdef requested_target_word_size - ifneq (,$(findstring rs6000,$(HOSTTYPE))) - ifeq ($(requested_target_word_size),64) - target_processor = powerpc - target_word_size = 64 - else - target_processor = powerpc - target_word_size = 32 - endif - else - $(error Platform not supported) - endif - else - ifneq (,$(findstring rs6000,$(HOSTTYPE))) - target_processor = powerpc - target_word_size = 32 - else - $(error Platform not supported) - endif - endif endif endif @@ -462,40 +324,21 @@ ifndef target_os_family ifeq ($(host_os_family),hpux) unix_target = yes target_os_family = hpux - - ifeq (,$(HOSTTYPE)) - $(error HOSTTYPE environment variable has not been set) - endif - - ifdef requested_target_word_size - ifneq (,$(findstring hppa,$(HOSTTYPE))) - ifeq ($(requested_target_word_size),64) - target_processor = hppa - target_word_size = 64 - else - target_processor = hppa - target_word_size = 32 - endif - else - $(error Platform not supported) - endif - else - ifneq (,$(findstring hppa,$(HOSTTYPE))) - target_processor = hppa - target_word_size = 32 - else - $(error Platform not supported) - endif - endif endif endif +ifneq (,$(findstring nlm,$(MAKECMDGOALS))) + submake_targets += nlm + netware_target = yes + target_os_family = netware + package_archive_format = zip +endif + ifndef target_os_family ifeq ($(host_os_family),win) win_target = yes target_os_family = win - target_processor = x86 - target_word_size = 32 + package_archive_format = zip endif endif @@ -503,17 +346,205 @@ ifndef target_os_family $(error Target operating system could not be determined) endif +# -- Host word size and processor -- + +host_native_word_size = +host_processor_family = +host_supported_word_sizes = + +ifneq (,$(PROCESSOR_ARCHITECTURE)) + HOSTTYPE = $(PROCESSOR_ARCHITECTURE) +endif + +ifeq (,$(HOSTTYPE)) + ifneq (,$(RPM_ARCH)) + HOSTTYPE = $(RPM_ARCH) + endif + $(error HOSTTYPE environment variable has not been set) +endif + +ifeq (,$(HOSTTYPE)) + $(error HOSTTYPE environment variable has not been set) +endif + +ifndef host_native_word_size + ifneq (,$(findstring x86_64,$(HOSTTYPE))) + host_processor_family = x86 + host_native_word_size = 64 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring x86,$(HOSTTYPE))) + host_processor_family = x86 + host_native_word_size = 32 + host_supported_word_sizes = 32 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring 86,$(HOSTTYPE))) + host_processor_family = x86 + host_native_word_size = 32 + host_supported_word_sizes = 32 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring ia64,$(HOSTTYPE))) + host_processor_family = ia64 + host_native_word_size = 64 + host_supported_word_sizes = 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring s390x,$(HOSTTYPE))) + host_processor_family = s390 + host_native_word_size = 64 + host_supported_word_sizes = 31 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring s390,$(HOSTTYPE))) + host_processor_family = s390 + host_native_word_size = 31 + host_supported_word_sizes = 31 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring ppc64,$(HOSTTYPE))) + host_processor_family = powerpc + host_native_word_size = 64 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring ppc,$(HOSTTYPE))) + host_processor_family = powerpc + host_native_word_size = 32 + host_supported_word_sizes = 32 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring sparc,$(HOSTTYPE))) + host_processor_family = sparc + host_native_word_size = 64 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring powerpc,$(HOSTTYPE))) + host_processor_family = powerpc + host_native_word_size = 32 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring rs6000,$(HOSTTYPE))) + host_processor_family = powerpc + host_native_word_size = 64 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + ifneq (,$(findstring hppa,$(HOSTTYPE))) + host_processor_family = hppa + host_native_word_size = 64 + host_supported_word_sizes = 32 64 + endif +endif + +ifndef host_native_word_size + $(error Unable to determine host word size) +endif + +# -- Target word size and processor -- + +ifneq (,$(findstring nlm,$(MAKECMDGOALS))) + target_processor_family = x86 + target_word_size = 32 + target_supported_word_sizes = 32 +else + target_processor_family = $(host_processor_family) + target_word_size = $(host_native_word_size) + target_supported_word_sizes = $(host_supported_word_sizes) +endif + +ifdef requested_word_size + ifneq (,$(findstring $(requested_word_size),$(target_supported_word_sizes))) + target_word_size = $(requested_word_size) + else + $(error Unsupported target word size) + endif +endif + +# -- Helper functions -- + +define normpath +$(strip $(subst \,/,$(1))) +endef + +ifeq (win,$(host_os_family)) +define hostpath +$(strip $(subst /,\,$(1))) +endef +else +define hostpath +$(strip $(1)) +endef +endif + +ifeq (win,$(host_os_family)) +define ppath +$(strip $(subst \,\\,$(subst /,\,$(1)))) +endef +else +define ppath +$(strip $(1)) +endef +endif + +ifeq ($(package_archive_format),tar) + define create_archive + -$(ec)$(call rmcmd,$(2)) + $(ec)tar zcf $(2) -C $(1) $(3) + $(ec)chmod 775 $(2) + endef + + define extract_archive + $(ec)tar zxvf $(strip $(1))/$(2) -C $(1) + endef +else + define create_archive + -$(ec)$(call rmcmd,$(2)) + $(ec)cmd /C "cd $(call hostpath,$(1)) && $(call hostpath,$(topdir)/7za) a -tzip -r $(call hostpath,$(2)) $(call hostpath,$(3))" + endef + + define extract_archive + $(ec)cmd /C "cd $(call hostpath,$(1)) && $(call hostpath,$(topdir)/7za) x $(call hostpath,$(2)) + endef +endif + # Platform-specific commands, directories, etc. ifeq ($(host_os_family),win) - allprereqs = $(subst /,\,$+) - copycmd = copy /Y $(subst /,\,$(1)) $(subst /,\,$(2)) 1>NUL - dircopycmd = xcopy /Y /E /V /I $(subst /,\,$(1)) $(subst /,\,$(2)) - rmcmd = if exist $(subst /,\,$(1)) del /Q $(subst /,\,$(1)) 1>NUL - rmdircmd = if exist $(subst /,\,$(1)) rmdir /q /s $(subst /,\,$(1)) 1>NUL - mkdircmd = -if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) - runtest = cmd /C "cd $(subst /,\,$(test_dir)) && $(1) -d" - topdir := $(subst \,/,$(shell chdir)) + allprereqs = $(call hostpath,$+) + copycmd = copy /Y $(call hostpath,$(1)) $(call hostpath,$(2)) 1>NUL + dircopycmd = xcopy /Y /E /V /I $(call hostpath,$(1)) $(call hostpath,$(2)) + rmcmd = if exist $(call hostpath,$(1)) del /Q $(call hostpath,$(1)) 1>NUL + rmdircmd = if exist $(call hostpath,$(1)) rmdir /q /s $(call hostpath,$(1)) 1>NUL + mkdircmd = -if not exist $(call hostpath,$(1)) mkdir $(call hostpath,$(1)) + runtest = cmd /C "cd $(call hostpath,$(test_dir)) && $(1) -d" + topdir := $(call normpath,$(shell chdir)) else allprereqs = $+ copycmd = cp -f $(1) $(2) @@ -552,33 +583,45 @@ package_srpms_dir = $(package_dir)/SRPMS pkgconfig_file_name = $(package_proj_name).pc pkgconfig_file = $(package_dir)/$(pkgconfig_file_name) -target_path = $(build_output_dir)/$(target_os_family)-$(target_processor)-$(target_word_size)/$(target_build_type) +target_path = $(build_output_dir)/$(target_os_family)-$(target_processor_family)-$(target_word_size)/$(target_build_type) package_stage_parent_dir = $(package_dir)/stage package_stage_dir = $(package_stage_parent_dir)/$(package_proj_name_and_ver) -package_bin_stage_dir = $(package_stage_parent_dir)/$(package_proj_name_and_ver)/$(target_os_family)-$(target_processor)-$(target_word_size)/$(target_build_type) +package_bin_stage_dir = $(package_stage_parent_dir)/$(package_proj_name_and_ver)/$(target_os_family)-$(target_processor_family)-$(target_word_size)/$(target_build_type) package_lib_stage_dir = $(package_bin_stage_dir)/lib package_shared_lib_stage_dir = $(package_lib_stage_dir)/shared package_static_lib_stage_dir = $(package_lib_stage_dir)/static package_util_stage_dir = $(package_bin_stage_dir)/util package_inc_stage_dir = $(package_stage_parent_dir)/$(package_proj_name_and_ver)/include +src_package_prefix = $(package_proj_name_and_ver)-src +bin_package_prefix = $(package_proj_name_and_ver)-$(target_os_family)-$(target_processor_family)-$(target_word_size)-bin -ifdef win_target - src_package_name=$(package_proj_name_and_ver)-src.zip - bin_package_name=$(package_proj_name_and_ver)-bin.zip +ifeq ($(package_archive_format),tar) + src_package_name=$(src_package_prefix).tar.gz + bin_package_name=$(bin_package_prefix).tar.gz else - src_package_name=$(package_proj_name_and_ver)-src.tar.gz - bin_package_name=$(package_proj_name_and_ver)-bin.tar.gz + src_package_name=$(src_package_prefix).zip + bin_package_name=$(bin_package_prefix).zip endif inc_dirs = src util -static_obj_dir = $(target_path)/static_obj -obj_dir = $(target_path)/obj util_dir = $(target_path)/util test_dir = $(target_path)/test sample_dir = $(target_path)/sample -shared_lib_dir = $(target_path)/lib/shared -static_lib_dir = $(target_path)/lib/static +lib_dir = $(target_path)/$(lib_dir_name) +shared_lib_dir = $(lib_dir)/shared +static_lib_dir = $(lib_dir)/static + +util_obj_dir = $(util_dir)/obj +test_obj_dir = $(test_dir)/obj +sample_obj_dir = $(sample_dir)/obj + +lib_obj_dir = $(static_lib_dir)/obj +ifdef win_target + lib_sobj_dir = $(shared_lib_dir)/obj +else + lib_sobj_dir = $(lib_obj_dir) +endif # -- Utility variables -- @@ -598,40 +641,11 @@ compiler = gprintf = printf -# -- Helper functions -- - -ifdef win_target - define create_archive - -$(ec)$(call rmcmd,$(2)) - $(ec)cmd /C "cd $(subst /,\,$(1)) && $(subst /,\,$(topdir)/7za) a -tzip -r $(subst /,\,$(2)) $(subst /,\,$(3))" - endef - - define extract_archive - $(ec)cmd /C "cd $(subst /,\,$(1)) && $(subst /,\,$(topdir)/7za x $(2)) - endef -endif - -ifdef unix_target - define create_archive - -$(ec)$(call rmcmd,$(2)) - $(ec)tar zcf $(2) -C $(1) $(3) - $(ec)chmod 775 $(2) - endef - - define extract_archive - $(ec)tar zxvf $(strip $(1))/$(2) -C $(1) - endef -endif - # Compiler definitions and flags ccflags = ccdefs = -ifneq (,$(findstring flm_dbg_log,$(MAKECMDGOALS))) - ccdefs += FLM_DBG_LOG -endif - ifeq ($(target_word_size),64) ccdefs += FLM_64BIT endif @@ -667,19 +681,19 @@ ifdef win_target shared_link_flags = \ /DLL \ - /DEBUG /PDB:$(subst /,\,$(@:.dll=.pdb)) \ - /map:$(subst /,\,$(@:.dll=.map)) \ + /DEBUG /PDB:$(call hostpath,$(@:.dll=.pdb)) \ + /map:$(call hostpath,$(@:.dll=.map)) \ /INCREMENTAL:NO \ /NOLOGO \ - /OUT:$(subst /,\,$@) + /OUT:$(call hostpath,$@) exe_link_flags = \ - /DEBUG /PDB:$(subst /,\,$(@:.exe=.pdb)) \ - /map:$(subst /,\,$(@:.exe=.map)) \ + /DEBUG /PDB:$(call hostpath,$(@:.exe=.pdb)) \ + /map:$(call hostpath,$(@:.exe=.map)) \ /INCREMENTAL:NO \ /FIXED:NO \ /NOLOGO \ - /OUT:$(subst /,\,$@) + /OUT:$(call hostpath,$@) # Libraries that our various components need to link against @@ -694,7 +708,7 @@ ifdef win_target # Same thing for the include dirs - ccinclude = $(foreach inc_dir,$(strip $(inc_dirs)),/I$(subst /,\,$(inc_dir))) + ccinclude = $(foreach inc_dir,$(strip $(inc_dirs)),/I$(call hostpath,$(inc_dir))) # Concatenate everything into the ccflags variable @@ -754,7 +768,7 @@ ifdef unix_target ifeq ($(compiler),g++) ccflags += -Wall -Werror -fPIC - ifneq ($(target_processor),ia64) + ifneq ($(target_processor_family),ia64) ccflags += -m$(target_word_size) endif endif @@ -860,7 +874,7 @@ ifdef unix_target link_flags = -o $@ ifeq ($(compiler),g++) - ifneq ($(target_processor),ia64) + ifneq ($(target_processor_family),ia64) shared_link_flags += -m$(target_word_size) link_flags += -m$(target_word_size) endif @@ -906,6 +920,247 @@ ifdef unix_target exe_link_flags = $(link_flags) endif +############################################################################## +# NetWare settings +############################################################################## +ifdef netware_target + exe_suffix = .nlm + obj_suffix = .obj + lib_prefix = + static_lib_suffix = .lib + shared_lib_suffix = .nlm + + ifdef WATCOM + wc_dir = $(WATCOM) + endif + + ifdef watcom + wc_dir = $(watcom) + endif + + ifndef wc_dir + wc_dir = $(WC_DIR) + endif + + ifndef wc_dir + $(error Target operating system could not be determined) + endif + + libr = "$(call normpath,$(strip $(wc_dir)))/binnt/wlib.exe" + linker = "$(call normpath,$(strip $(wc_dir)))/binnt/wlink.exe" + shared_linker = "$(call normpath,$(strip $(wc_dir)))/binnt/wlink.exe" + compiler = "$(call normpath,$(wc_dir))/binnt/wpp386.exe" + + ifneq ($(build),release) + ccdefs += FLM_DEBUG + endif + + ccflags += /ez /6s /w4 /za /zp1 /zq /zm /s /ei /of+ /we /bt=NETWARE + + ifeq ($(build),release) + ccflags += /oair + else + ccflags += /hc + endif + + libflags += /b /q /p=256 + link_flags = /m /l /v /s + + export include = $(foreach inc_dir,$(strip $(inc_dirs)),$(call hostpath,$(inc_dir));) + export INCLUDE = $(include) + export wpp386 = /d$(subst $(sp), /d,$(strip $(ccdefs))) $(ccflags) + export wcc386 = /d$(subst $(sp), /d,$(strip $(ccdefs))) $(ccflags) + + define make_lis_file_cmd + $(ec)$(gprintf) "option verbose\n" > $(4) + $(ec)$(gprintf) "option stack=32k\n" >> $(4) + $(ec)$(gprintf) "option synchronize\n" >> $(4) + $(ec)$(gprintf) "option nod\n" >> $(4) + $(ec)$(gprintf) "option map\n" >> $(4) + $(ec)$(gprintf) "option start=FlmLoad, exit=FlmUnload, caseexact\n" >> $(4) + $(ec)$(gprintf) "option nodefaultlibs\n" >> $(4) + $(ec)$(gprintf) "option screenname 'NONE'\n" >> $(4) + $(ec)$(gprintf) "option threadname '$(2)'\n" >> $(4) + $(ec)$(gprintf) "debug all debug novell\n" >> $(4) + $(ec)$(gprintf) "form novell nlm '$(2)'\n" >> $(4) + $(ec)$(gprintf) "name $(call ppath,$(1)/$(2)$(exe_suffix))\n" >> $(4) + + $(ec)$(gprintf) "import __WSAFDIsSet\n" >> $(4) + $(ec)$(gprintf) "import ActivateScreen\n" >> $(4) + $(ec)$(gprintf) "import Alloc\n" >> $(4) + $(ec)$(gprintf) "import AllocateResourceTag\n" >> $(4) + $(ec)$(gprintf) "import atomic_dec\n" >> $(4) + $(ec)$(gprintf) "import atomic_inc\n" >> $(4) + $(ec)$(gprintf) "import atomic_xchg\n" >> $(4) + $(ec)$(gprintf) "import BitTest\n" >> $(4) + $(ec)$(gprintf) "import CEvaluateExpression\n" >> $(4) + $(ec)$(gprintf) "import CFindLoadModuleHandle\n" >> $(4) + $(ec)$(gprintf) "import CheckKeyStatus\n" >> $(4) + $(ec)$(gprintf) "import ClearScreen\n" >> $(4) + $(ec)$(gprintf) "import CloseFile\n" >> $(4) + $(ec)$(gprintf) "import CloseScreen\n" >> $(4) + $(ec)$(gprintf) "import CMovB\n" >> $(4) + $(ec)$(gprintf) "import CMoveFast\n" >> $(4) + $(ec)$(gprintf) "import ConvertPathString\n" >> $(4) + $(ec)$(gprintf) "import ConvertSecondsToTicks\n" >> $(4) + $(ec)$(gprintf) "import ConvertTicksToSeconds\n" >> $(4) + $(ec)$(gprintf) "import CpuCurrentProcessor\n" >> $(4) + $(ec)$(gprintf) "import CreateDirectory\n" >> $(4) + $(ec)$(gprintf) "import CreateFile\n" >> $(4) + $(ec)$(gprintf) "import CSetD\n" >> $(4) + $(ec)$(gprintf) "import DebuggerSymbolList\n" >> $(4) + $(ec)$(gprintf) "import DeleteDirectory\n" >> $(4) + $(ec)$(gprintf) "import DirectorySearch\n" >> $(4) + $(ec)$(gprintf) "import DirectReadFile\n" >> $(4) + $(ec)$(gprintf) "import DirectReadFile\n" >> $(4) + $(ec)$(gprintf) "import DirectWriteFile\n" >> $(4) + $(ec)$(gprintf) "import DirectWriteFile\n" >> $(4) + $(ec)$(gprintf) "import DirectWriteFileNoWait\n" >> $(4) + $(ec)$(gprintf) "import DirectWriteFileNoWait\n" >> $(4) + $(ec)$(gprintf) "import DisableInputCursor\n" >> $(4) + $(ec)$(gprintf) "import DisplayScreenTextWithAttribute\n" >> $(4) + $(ec)$(gprintf) "import DOSFirstByteBitMap\n" >> $(4) + $(ec)$(gprintf) "import EnableInputCursor\n" >> $(4) + $(ec)$(gprintf) "import EnterDebugger\n" >> $(4) + $(ec)$(gprintf) "import EraseFile\n" >> $(4) + $(ec)$(gprintf) "import ExpandFileInContiguousBlocks\n" >> $(4) + $(ec)$(gprintf) "import ExpandFileInContiguousBlocks\n" >> $(4) + $(ec)$(gprintf) "import ExportPublicSymbol\n" >> $(4) + $(ec)$(gprintf) "import FindAndLoadNLM\n" >> $(4) + $(ec)$(gprintf) "import Free\n" >> $(4) + $(ec)$(gprintf) "import FreeLimboVolumeSpace\n" >> $(4) + $(ec)$(gprintf) "import FreeLimboVolumeSpace\n" >> $(4) + $(ec)$(gprintf) "import GetCacheBufferSize\n" >> $(4) + $(ec)$(gprintf) "import GetClosestSymbol\n" >> $(4) + $(ec)$(gprintf) "import GetCurrentClock\n" >> $(4) + $(ec)$(gprintf) "import GetCurrentNumberOfCacheBuffers\n" >> $(4) + $(ec)$(gprintf) "import GetCurrentTime\n" >> $(4) + $(ec)$(gprintf) "import GetEntryFromPathStringBase\n" >> $(4) + $(ec)$(gprintf) "import GetEntryFromPathStringBase\n" >> $(4) + $(ec)$(gprintf) "import GetFileSize\n" >> $(4) + $(ec)$(gprintf) "import GetKey\n" >> $(4) + $(ec)$(gprintf) "import GetNLMAllocMemoryCounts\n" >> $(4) + $(ec)$(gprintf) "import GetOriginalNumberOfCacheBuffers\n" >> $(4) + $(ec)$(gprintf) "import GetProductMajorVersionNumber\n" >> $(4) + $(ec)$(gprintf) "import GetRunningProcess\n" >> $(4) + $(ec)$(gprintf) "import GetScreenSize\n" >> $(4) + $(ec)$(gprintf) "import GetSyncClockFields\n" >> $(4) + $(ec)$(gprintf) "import GetSystemConsoleScreen\n" >> $(4) + $(ec)$(gprintf) "import ImportPublicSymbol\n" >> $(4) + $(ec)$(gprintf) "import kCreateThread\n" >> $(4) + $(ec)$(gprintf) "import kCurrentThread\n" >> $(4) + $(ec)$(gprintf) "import kDelayThread\n" >> $(4) + $(ec)$(gprintf) "import kDestroyThread\n" >> $(4) + $(ec)$(gprintf) "import kExitThread\n" >> $(4) + $(ec)$(gprintf) "import kGetThreadName\n" >> $(4) + $(ec)$(gprintf) "import kGetThreadName\n" >> $(4) + $(ec)$(gprintf) "import KillMe\n" >> $(4) + $(ec)$(gprintf) "import kMutexAlloc\n" >> $(4) + $(ec)$(gprintf) "import kMutexFree\n" >> $(4) + $(ec)$(gprintf) "import kMutexLock\n" >> $(4) + $(ec)$(gprintf) "import kMutexUnlock\n" >> $(4) + $(ec)$(gprintf) "import kQueCount\n" >> $(4) + $(ec)$(gprintf) "import kReturnCurrentProcessorID\n" >> $(4) + $(ec)$(gprintf) "import kScheduleThread\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreAlloc\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreExamineCount\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreFree\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreSignal\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreTimedWait\n" >> $(4) + $(ec)$(gprintf) "import kSemaphoreWait\n" >> $(4) + $(ec)$(gprintf) "import kSetThreadLoadHandle\n" >> $(4) + $(ec)$(gprintf) "import kSetThreadName\n" >> $(4) + $(ec)$(gprintf) "import kYieldIfTimeSliceUp\n" >> $(4) + $(ec)$(gprintf) "import kYieldThread\n" >> $(4) + $(ec)$(gprintf) "import LoadModule\n" >> $(4) + $(ec)$(gprintf) "import LoadRules\n" >> $(4) + $(ec)$(gprintf) "import MapFileHandleToFCB\n" >> $(4) + $(ec)$(gprintf) "import MapPathToDirectoryNumber\n" >> $(4) + $(ec)$(gprintf) "import MapPathToDirectoryNumber\n" >> $(4) + $(ec)$(gprintf) "import MapVolumeNameToNumber\n" >> $(4) + $(ec)$(gprintf) "import ModifyDirectoryEntry\n" >> $(4) + $(ec)$(gprintf) "import ModifyDirectoryEntry\n" >> $(4) + $(ec)$(gprintf) "import MountVolume\n" >> $(4) + $(ec)$(gprintf) "import NDSCreateStreamFile\n" >> $(4) + $(ec)$(gprintf) "import NDSDeleteStreamFile\n" >> $(4) + $(ec)$(gprintf) "import NDSOpenStreamFile\n" >> $(4) + $(ec)$(gprintf) "import NWLocalToUnicode\n" >> $(4) + $(ec)$(gprintf) "import NWUnicodeToLocal\n" >> $(4) + $(ec)$(gprintf) "import OpenFile\n" >> $(4) + $(ec)$(gprintf) "import OpenScreen\n" >> $(4) + $(ec)$(gprintf) "import OutputToScreen\n" >> $(4) + $(ec)$(gprintf) "import PositionInputCursor\n" >> $(4) + $(ec)$(gprintf) "import PositionOutputCursor\n" >> $(4) + $(ec)$(gprintf) "import ReadFile\n" >> $(4) + $(ec)$(gprintf) "import RenameEntry\n" >> $(4) + $(ec)$(gprintf) "import RestartServer\n" >> $(4) + $(ec)$(gprintf) "import ReturnResourceTag\n" >> $(4) + $(ec)$(gprintf) "import ReturnVolumeMappingInformation\n" >> $(4) + $(ec)$(gprintf) "import ReturnVolumeMappingInformation\n" >> $(4) + $(ec)$(gprintf) "import RevokeFileHandleRights\n" >> $(4) + $(ec)$(gprintf) "import SetCursorStyle\n" >> $(4) + $(ec)$(gprintf) "import SetFileSize\n" >> $(4) + $(ec)$(gprintf) "import SetFileSize\n" >> $(4) + $(ec)$(gprintf) "import SGUIDCreate\n" >> $(4) + $(ec)$(gprintf) "import SizeOfAllocBlock\n" >> $(4) + $(ec)$(gprintf) "import StopBell\n" >> $(4) + $(ec)$(gprintf) "import SwitchToDirectFileMode\n" >> $(4) + $(ec)$(gprintf) "import SwitchToDirectFileMode\n" >> $(4) + $(ec)$(gprintf) "import UngetKey\n" >> $(4) + $(ec)$(gprintf) "import UnImportPublicSymbol\n" >> $(4) + $(ec)$(gprintf) "import UnloadRules\n" >> $(4) + $(ec)$(gprintf) "import VMGetDirectoryEntry\n" >> $(4) + $(ec)$(gprintf) "import WorkToDoListHead\n" >> $(4) + $(ec)$(gprintf) "import WriteFile\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_bind\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_closesocket\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_gethostbyaddr\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_gethostbyname\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_gethostname\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_htonl\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_htons\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_inet_addr\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_inet_ntoa\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_listen\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_recv\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_select\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_send\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_setsockopt\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_shutdown\n" >> $(4) + $(ec)$(gprintf) "import WS2_32_socket\n" >> $(4) + $(ec)$(gprintf) "import WSAAccept\n" >> $(4) + $(ec)$(gprintf) "import WSACleanup\n" >> $(4) + $(ec)$(gprintf) "import WSAConnect\n" >> $(4) + $(ec)$(gprintf) "import WSAGetLastError\n" >> $(4) + $(ec)$(gprintf) "import WSAStartup\n" >> $(4) + + $(ec)$(gprintf) "file $(subst $(sp),\nfile ,$(call ppath,$(3)))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(ctorarst))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(dtorarst))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(undefed))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(undefmbd))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(pure_err))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(stablcl))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(stabact))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(stabactv))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(stabmod))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(prwdata))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(moddtorr))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/plib3s.lib(stabadt))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/netware/clib3s.lib(i8d))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/netware/clib3s.lib(i8m))\n" >> $(4) + $(ec)$(gprintf) "file $(call ppath,$(wc_dir)/lib386/netware/clib3s.lib(i8s))\n" >> $(4) + $(ec)$(gprintf) "library $(call ppath,$(static_flaim_lib))\n" >> $(4) + endef + + define flm_exe_link_cmd + $(call make_lis_file_cmd,$(1),$(2),$(3),$(call hostpath,$(1)/$(2).lis)) + $(ec)$(call hostpath,$(linker)) @$(call hostpath,$(1)/$(2).lis) + $(ec)$(call rmcmd,$(target_path)/$(1).lis) + endef + +endif + # -- File lists -- flaim_src = \ @@ -920,10 +1175,12 @@ utilsup_src = \ wpscrnkb.cpp checkdb_src = \ - checkdb.cpp + checkdb.cpp \ + $(utilsup_src) rebuild_src = \ - rebuild.cpp + rebuild.cpp \ + $(utilsup_src) view_src = \ view.cpp \ @@ -934,54 +1191,53 @@ view_src = \ viewlhdr.cpp \ viewlfil.cpp \ viewmenu.cpp \ - viewsrch.cpp + viewsrch.cpp \ + $(utilsup_src) sample_src = \ sample.cpp dbshell_src = \ dbshell.cpp \ - flm_edit.cpp + flm_edit.cpp \ + $(utilsup_src) ut_basictest_src = \ flmunittest.cpp \ - basic_test.cpp + basic_test.cpp \ + $(utilsup_src) # -- FLAIM library -- -flaim_obj = $(patsubst src/%.cpp,$(obj_dir)/%$(obj_suffix),$(flaim_src)) -ifdef win_target - flaim_static_obj = $(patsubst src/%.cpp,$(static_obj_dir)/%$(obj_suffix),$(flaim_src)) -else - flaim_static_obj = $(flaim_obj) -endif +flaim_static_obj = $(patsubst src/%.cpp,$(lib_obj_dir)/%$(obj_suffix),$(flaim_src)) +flaim_shared_obj = $(patsubst src/%.cpp,$(lib_sobj_dir)/%$(obj_suffix),$(flaim_src)) static_flaim_lib = $(static_lib_dir)/$(lib_prefix)$(project_name)$(static_lib_suffix) -shared_flaim_lib = $(shared_lib_dir)/$(lib_prefix)$(project_name)$(shared_lib_suffix)$(suffix_version) -shared_flaim_imp_lib = $(shared_lib_dir)/$(lib_prefix)$(project_name)$(static_lib_suffix)$(suffix_version) +ifndef netware_target + shared_flaim_lib = $(shared_lib_dir)/$(lib_prefix)$(project_name)$(shared_lib_suffix)$(suffix_version) + shared_flaim_imp_lib = $(shared_lib_dir)/$(lib_prefix)$(project_name)$(static_lib_suffix)$(suffix_version) +endif # -- Unit tests -- -ut_basictest_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(ut_basictest_src)) +ut_basictest_obj = $(patsubst %.cpp,$(test_obj_dir)/%$(obj_suffix),$(ut_basictest_src)) # -- Utilities -- -checkdb_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(checkdb_src)) +checkdb_obj = $(patsubst %.cpp,$(util_obj_dir)/%$(obj_suffix),$(checkdb_src)) checkdb_exe = $(util_dir)/checkdb$(exe_suffix) -rebuild_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(rebuild_src)) +rebuild_obj = $(patsubst %.cpp,$(util_obj_dir)/%$(obj_suffix),$(rebuild_src)) rebuild_exe = $(util_dir)/rebuild$(exe_suffix) -view_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(view_src)) +view_obj = $(patsubst %.cpp,$(util_obj_dir)/%$(obj_suffix),$(view_src)) view_exe = $(util_dir)/view$(exe_suffix) -dbshell_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(dbshell_src)) +dbshell_obj = $(patsubst %.cpp,$(util_obj_dir)/%$(obj_suffix),$(dbshell_src)) dbshell_exe = $(util_dir)/dbshell$(exe_suffix) -sample_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(sample_src)) +sample_obj = $(patsubst %.cpp,$(sample_obj_dir)/%$(obj_suffix),$(sample_src)) sample_exe = $(sample_dir)/sample$(exe_suffix) -utilsup_obj = $(patsubst %.cpp,$(obj_dir)/%$(obj_suffix),$(utilsup_src)) - # -- Make system pattern search paths -- vpath %.cpp src util sample @@ -993,19 +1249,36 @@ libs: status dircheck $(static_flaim_lib) $(shared_flaim_lib) # -- *.cpp -> *$(obj_suffix) -- -$(obj_dir)/%$(obj_suffix) : %.cpp ifdef win_target - $(ec)$(compiler) $(ccflags) /DFLM_SRC /DFLM_DLL /Fd$(subst /,\,$(obj_dir))\tmp.pdb \ - /Fo$(subst /,\,$@) $(subst /,\,$<) -else - $(ec)$(gprintf) "$<\n" - $(ec)$(compiler) $(ccflags) -c $< -o $@ +define cpp_to_obj_template +$$($(1)_obj_dir)/%$$(obj_suffix) : %.cpp + $$(ec)$$(compiler) $$(ccflags) /Fo$$(call hostpath,$$@) $$(call hostpath,$$<) +endef endif +ifdef unix_target +define cpp_to_obj_template +$$($(1)_obj_dir)/%$$(obj_suffix) : %.cpp + $$(ec)$$(gprintf) "$$<\n" + $$(ec)$$(compiler) $$(ccflags) -c $$< -o $$@ +endef +endif + +ifdef netware_target +define cpp_to_obj_template +$$($(1)_obj_dir)/%$(obj_suffix) : %.cpp + $$(ec)$$(gprintf) "$$(notdir $$(strip $$@))\n" + $$(ec)$$(call hostpath,$$(compiler)) $$(call hostpath,$$<) /fo=$$(call hostpath,$$@) +endef +endif + +$(foreach tmpl,lib util sample test,$(eval $(call cpp_to_obj_template,$(tmpl)))) + ifdef win_target -$(static_obj_dir)/%$(obj_suffix) : %.cpp - $(ec)$(compiler) $(ccflags) /Fd$(subst /,\,$(obj_dir))\tmp.pdb \ - /Fo$(subst /,\,$@) $(subst /,\,$<) +$(lib_sobj_dir)/%$(obj_suffix) : %.cpp + $(ec)$(compiler) $(ccflags) /DFLM_SRC /DFLM_DLL \ + /Fd$(call hostpath,$(lib_sobj_dir)/tmp.pdb) \ + /Fo$(call hostpath,$@) $(call hostpath,$<) endif # -- flaim.lib and libflaim.a -- @@ -1013,8 +1286,9 @@ endif $(static_flaim_lib) : $(flaim_static_obj) $(ec)$(gprintf) "Building $@ ...\n" ifdef win_target - $(ec)$(libr) /NOLOGO $(subst /,\,$+) /OUT:$(subst /,\,$@) -else + $(ec)$(libr) /NOLOGO $(call hostpath,$+) /OUT:$(call hostpath,$@) +endif +ifdef unix_target $(ec)rm -f $@ ifeq ($(target_os_family),osx) $(ec)$(libr) -static -o $@ $+ @@ -1022,14 +1296,19 @@ else $(ec)$(libr) -rcs $@ $+ endif endif +ifdef netware_target + $(ec)dir /s/b $(call hostpath,$(lib_obj_dir)/*$(obj_suffix)) > $(call hostpath,$(static_lib_dir)/flmlib.lis) + $(ec)$(call hostpath,$(libr)) $(libflags) $(call hostpath,$(static_flaim_lib)) @$(call hostpath,$(static_lib_dir)/flmlib.lis) +endif # -- flaim.dll and libflaim.so -- -$(shared_flaim_lib) : $(flaim_obj) +$(shared_flaim_lib) : $(flaim_shared_obj) $(ec)$(gprintf) "Building $@ ...\n" ifdef win_target - $(ec)$(linker) $(subst /,\,$+) $(shared_link_flags) $(lib_link_libs) -else + $(ec)$(linker) $(call hostpath,$+) $(shared_link_flags) $(lib_link_libs) +endif +ifdef unix_target $(ec)rm -f $@ ifeq ($(target_os_family),linux) $(ec)$(linker) $+ $(shared_link_flags) $(lib_link_libs) @@ -1048,49 +1327,51 @@ endif .PHONY : checkdb checkdb: status dircheck $(static_flaim_lib) $(checkdb_exe) -$(checkdb_exe): $(checkdb_obj) $(utilsup_obj) $(static_flaim_lib) +$(checkdb_exe): $(checkdb_obj) $(static_flaim_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) + $(call flm_exe_link_cmd,$(util_dir),checkdb,$(checkdb_obj)) # -- rebuild -- .PHONY : rebuild rebuild: status dircheck $(static_flaim_lib) $(rebuild_exe) -$(rebuild_exe): $(rebuild_obj) $(utilsup_obj) $(static_flaim_lib) +$(rebuild_exe): $(rebuild_obj) $(static_flaim_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) + $(call flm_exe_link_cmd,$(util_dir),rebuild,$(rebuild_obj)) # -- view -- .PHONY : view view: status dircheck $(static_flaim_lib) $(view_exe) -$(view_exe): $(view_obj) $(utilsup_obj) $(static_flaim_lib) +$(view_exe): $(view_obj) $(static_flaim_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) - -# -- sample -- - -.PHONY : sample -sample: status dircheck $(static_flaim_lib) $(sample_exe) -$(sample_exe): $(sample_obj) $(static_flaim_lib) - $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) + $(call flm_exe_link_cmd,$(util_dir),view,$(view_obj)) # -- dbshell -- .PHONY : dbshell dbshell: status dircheck $(static_flaim_lib) $(dbshell_exe) -$(dbshell_exe): $(dbshell_obj) $(utilsup_obj) $(static_flaim_lib) +$(dbshell_exe): $(dbshell_obj) $(static_flaim_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) + $(call flm_exe_link_cmd,$(util_dir),dbshell,$(dbshell_obj)) + +# -- sample -- + +.PHONY : sample +ifndef netware_target +sample: status dircheck $(static_flaim_lib) $(sample_exe) +$(sample_exe): $(sample_obj) $(static_flaim_lib) + $(ec)$(gprintf) "Linking $@ ...\n" + $(call flm_exe_link_cmd,$(sample_dir),sample,$(sample_obj)) +endif # -- basictest -- .PHONY : basictest basictest: status dircheck $(static_flaim_lib) $(test_dir)/basictest$(exe_suffix) -$(test_dir)/basictest$(exe_suffix): $(ut_basictest_obj) $(utilsup_obj) $(static_flaim_lib) +$(test_dir)/basictest$(exe_suffix): $(ut_basictest_obj) $(static_flaim_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(flm_exe_link_cmd) + $(call flm_exe_link_cmd,$(test_dir)basictest,$(ut_basictest_obj)) # -- version -- @@ -1120,7 +1401,7 @@ srcdist: status dircheck docs $(ec)$(call dircopycmd,util,$(package_stage_dir)/util) -$(ec)$(call rmdircmd,$(package_stage_dir)/util/.svn) $(ec)$(call dircopycmd,$(docs_output_dir),$(package_stage_dir)/docs) -ifdef win_target +ifeq ($(host_os_family),win) $(ec)$(call copycmd,make.exe,$(package_stage_dir)) $(ec)$(call copycmd,printf.exe,$(package_stage_dir)) $(ec)$(call dircopycmd,external/w32,$(package_stage_dir)/external/w32) @@ -1155,7 +1436,9 @@ binpackage: status $(ec)$(call copycmd,COPYING,$(package_stage_dir)) $(ec)$(call copycmd,src/flaim.h,$(package_inc_stage_dir)) $(ec)$(call copycmd,$(static_flaim_lib),$(package_static_lib_stage_dir)) +ifdef shared_flaim_lib $(ec)$(call copycmd,$(shared_flaim_lib),$(package_shared_lib_stage_dir)) +endif ifdef win_target $(ec)$(call copycmd,$(shared_flaim_imp_lib),$(package_shared_lib_stage_dir)) endif @@ -1179,11 +1462,11 @@ dist: status dircheck srcdist $(ec)$(gprintf) "Creating distribution (SVN revision $(svn_revision)) ...\n" endif $(ec)$(call extract_archive,$(package_dir),$(src_package_name)) -ifdef win_target +ifeq ($(host_os_family),win) $(ec)$(call copycmd,7za.exe,$(package_dir)/$(package_proj_name_and_ver)) endif - $(ec)make -C $(package_dir)/$(package_proj_name_and_ver) all - $(ec)make -C $(package_dir)/$(package_proj_name_and_ver) binpackage package_dir="$(package_dir)" + $(ec)$(MAKE) -C $(package_dir)/$(package_proj_name_and_ver) $(submake_targets) all + $(ec)$(MAKE) -C $(package_dir)/$(package_proj_name_and_ver) $(submake_targets) binpackage package_dir="$(package_dir)" $(ec)$(call rmdircmd,$(package_dir)/$(package_proj_name_and_ver)) $(ec)$(gprintf) "Distribution created.\n" @@ -1201,7 +1484,7 @@ changelog: .PHONY : install install: libs pkgconfig -ifndef win_target +ifneq ($(host_os_family),win) $(ec)$(gprintf) "Installing ...\n" mkdir -p $(lib_install_dir)/pkgconfig mkdir -p $(include_install_dir) @@ -1217,7 +1500,7 @@ endif .PHONY : uninstall uninstall: -ifndef win_target +ifneq ($(host_os_family),win) $(ec)$(gprintf) "Uninstalling ...\n" -rm -rf $(lib_install_dir)/$(lib_prefix)$(project_name)$(shared_lib_suffix)* -rm -rf $(lib_install_dir)/$(lib_prefix)$(project_name)$(static_lib_suffix) @@ -1278,10 +1561,10 @@ spec: dircheck $(ec)$(gprintf) "$(percent)setup -q\n" >> $(spec_file) $(ec)$(gprintf) "\n" >> $(spec_file) $(ec)$(gprintf) "$(percent)build\n" >> $(spec_file) - $(ec)$(gprintf) "make lib_dir_name=$(percent){_lib} libs\n" >> $(spec_file) + $(ec)$(gprintf) "$(MAKE) lib_dir_name=$(percent){_lib} $(submake_targets) libs\n" >> $(spec_file) $(ec)$(gprintf) "\n" >> $(spec_file) $(ec)$(gprintf) "$(percent)install\n" >> $(spec_file) - $(ec)$(gprintf) "make rpm_build_root=$(dollar)RPM_BUILD_ROOT install_prefix=$(percent){prefix} lib_dir_name=$(percent){_lib} install\n" >> $(spec_file) + $(ec)$(gprintf) "$(MAKE) rpm_build_root=$(dollar)RPM_BUILD_ROOT install_prefix=$(percent){prefix} lib_dir_name=$(percent){_lib} $(submake_targets) install\n" >> $(spec_file) $(ec)$(gprintf) "rm -rf $(build_output_dir)\n" >> $(spec_file) $(ec)$(gprintf) "\n" >> $(spec_file) $(ec)$(gprintf) "$(percent)clean\n" >> $(spec_file) @@ -1344,28 +1627,33 @@ status: $(ec)$(gprintf) "===============================================================================\n" $(ec)$(gprintf) "SVN Revision = $(svn_revision)\n" $(ec)$(gprintf) "Host Operating System Family = $(host_os_family)\n" - $(ec)$(gprintf) "Top Directory = $(topdir)\n" + $(ec)$(gprintf) "Top Directory = $(call ppath,$(topdir))\n" $(ec)$(gprintf) "Target Operating System Family = $(target_os_family)\n" - $(ec)$(gprintf) "Target Processor = $(target_processor)\n" + $(ec)$(gprintf) "Target Processor Family = $(target_processor_family)\n" $(ec)$(gprintf) "Target Word Size = $(target_word_size)\n" $(ec)$(gprintf) "Target Build Type = $(target_build_type)\n" - $(ec)$(gprintf) "Target Path = $(target_path)\n" - $(ec)$(gprintf) "Compiler = $(compiler)\n" - $(ec)$(gprintf) "Librarian = $(libr)\n" + $(ec)$(gprintf) "Target Path = $(call ppath,$(target_path))\n" + $(ec)$(gprintf) "Compiler = $(call ppath,$(compiler))\n" + $(ec)$(gprintf) "Librarian = $(call ppath,$(libr))\n" $(ec)$(gprintf) "Defines = $(strip $(ccdefs))\n" $(ec)$(gprintf) "===============================================================================\n" .PHONY : dircheck dircheck: - $(ec)$(call mkdircmd,$(obj_dir)) - $(ec)$(call mkdircmd,$(static_obj_dir)) + $(ec)$(call mkdircmd,$(util_obj_dir)) + $(ec)$(call mkdircmd,$(test_obj_dir)) + $(ec)$(call mkdircmd,$(sample_obj_dir)) + $(ec)$(call mkdircmd,$(lib_obj_dir)) +ifneq ($(lib_sobj_dir),$(lib_obj_dir)) + $(ec)$(call mkdircmd,$(lib_sobj_dir)) +endif $(ec)$(call mkdircmd,$(util_dir)) $(ec)$(call mkdircmd,$(test_dir)) $(ec)$(call mkdircmd,$(sample_dir)) $(ec)$(call mkdircmd,$(static_lib_dir)) $(ec)$(call mkdircmd,$(shared_lib_dir)) $(ec)$(call mkdircmd,$(package_dir)) -ifndef win_target +ifneq ($(host_os_family),win) $(ec)$(call mkdircmd,$(spec_dir)) $(ec)$(call mkdircmd,$(package_sources_dir)) $(ec)$(call mkdircmd,$(package_build_dir)) @@ -1426,6 +1714,10 @@ solaris: .PHONY : osx osx: $(ec)$(gprintf) "" + +.PHONY : nlm +nlm: + $(ec)$(gprintf) "" .PHONY : verbose verbose: diff --git a/flaim/src/fcs.h b/flaim/src/fcs.h index 612d4a2..42d8557 100644 --- a/flaim/src/fcs.h +++ b/flaim/src/fcs.h @@ -1410,50 +1410,10 @@ private: FLMBOOL m_bOpen; }; -#if defined( FLM_NLM) - #pragma pack(push,1) - - #ifndef _WCHAR_T - #define _WCHAR_T - typedef unsigned short wchar_t; - #endif - - extern "C" - { - #include "ws2nlm.h" - } - - // Need to undefine things defined in ws2nlm.h that will create conflicts - // when compiling SMI - - #undef HANDLE - #undef unicode - - #pragma pack(pop) - -#elif defined( FLM_UNIX) - #ifndef INVALID_SOCKET - #define INVALID_SOCKET (-1) - #endif - - #ifndef INADDR_NONE - #define INADDR_NONE (-1) - #endif - - #ifndef SOCKET - #define SOCKET int - #endif -#elif !defined( FLM_WIN) - #error Platform not supported -#endif - #include "fpackon.h" // IMPORTANT NOTE: No other include files should follow this one except // for fpackoff.h - -// Forward declarations - class FCS_TCP_SERVER; class FCS_TCP_CLIENT; diff --git a/flaim/src/fcs_tcp.cpp b/flaim/src/fcs_tcp.cpp index 0d2bf0f..e557823 100644 --- a/flaim/src/fcs_tcp.cpp +++ b/flaim/src/fcs_tcp.cpp @@ -109,7 +109,7 @@ RCODE FCS_TCP::_GetLocalInfo( void) if( m_pszIp[ 0] == '\0' && (pHostEnt = gethostbyname( m_pszName)) != NULL) { - ui32IPAddr = (FLMUINT32)(*((u_long*)pHostEnt->h_addr)); + ui32IPAddr = (FLMUINT32)(*((unsigned long *)pHostEnt->h_addr)); if( ui32IPAddr != (FLMUINT32)-1) { struct in_addr InAddr; @@ -161,7 +161,7 @@ RCODE FCS_TCP::_GetRemoteInfo( void) */ HostsName = gethostbyaddr( (char *)&SockAddrIn.sin_addr.s_addr, - (unsigned)sizeof( u_long), AF_INET ); + (unsigned)sizeof( unsigned long), AF_INET ); if( HostsName != NULL) { @@ -618,7 +618,7 @@ RCODE FCS_TCP_CLIENT::openConnection( FLMINT iMaxTries = 5; struct sockaddr_in address; struct hostent * pHostEntry; - u_long ulIPAddr; + unsigned long ulIPAddr; RCODE rc = FERR_OK; flmAssert( !m_bConnected); @@ -627,7 +627,7 @@ RCODE FCS_TCP_CLIENT::openConnection( if( pucHostName && pucHostName[ 0] != '\0') { ulIPAddr = inet_addr( (char *)pucHostName); - if( ulIPAddr == (u_long)INADDR_NONE) + if( ulIPAddr == (unsigned long)INADDR_NONE) { pHostEntry = gethostbyname( (char *)pucHostName); @@ -638,7 +638,7 @@ RCODE FCS_TCP_CLIENT::openConnection( } else { - ulIPAddr = *((u_long*)pHostEntry->h_addr); + ulIPAddr = *((unsigned long *)pHostEntry->h_addr); } } @@ -655,7 +655,7 @@ RCODE FCS_TCP_CLIENT::openConnection( f_memset( (char*)&address, 0, sizeof( struct sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = (unsigned)ulIPAddr; - address.sin_port = htons( (u_short)uiPort); + address.sin_port = htons( (unsigned short)uiPort); /* Allocate a socket, then attempt to connect to it! @@ -854,7 +854,7 @@ RCODE FCS_TCP_SERVER::bind( { address.sin_addr.s_addr = inet_addr( (char *)pucBindAddr); } - address.sin_port = htons( (u_short)uiBindPort); + address.sin_port = htons( (unsigned short)uiBindPort); // Bind to the address+port diff --git a/flaim/src/flaim.h b/flaim/src/flaim.h index c5e6e6b..4a46711 100644 --- a/flaim/src/flaim.h +++ b/flaim/src/flaim.h @@ -270,19 +270,16 @@ #endif #if defined( FLM_WIN) - #if defined( FLM_DLL) // user must define for DLL linkage on Windows + #if defined( FLM_DLL) #if defined( FLM_SRC) - #define FLM_IX dllexport + #define FLMEXP __declspec(dllexport) #else - #define FLM_IX dllimport + #define FLMEXP __declspec(dllimport) #endif - #define FLMEXP __declspec(FLM_IX) #else #define FLMEXP #endif - #define FLMCDECL __cdecl #define FLMAPI __cdecl - #define FLMCOM __stdcall #ifdef FLM_DEBUG #define FINLINE inline #else @@ -290,15 +287,11 @@ #endif #elif defined( FLM_NLM) #define FLMEXP - #define FLMCDECL __cdecl #define FLMAPI __cdecl - #define FLMCOM __stdcall #define FINLINE inline #elif defined( FLM_UNIX) #define FLMEXP - #define FLMCDECL #define FLMAPI - #define FLMCOM #if defined( FLM_GNUC) #define FINLINE __attribute__((always_inline)) inline #else @@ -6667,7 +6660,7 @@ FLMEXP RCODE FLMAPI FlmAllocFileSystem( F_FileSystem ** ppFileSystem); - FLMEXP FLMINT FLMCDECL f_sprintf( + FLMEXP FLMINT FLMAPI f_sprintf( char * pszDestStr, const char * pszFormat, ...); diff --git a/flaim/src/flprintf.cpp b/flaim/src/flprintf.cpp index 5f53ce8..ef78466 100644 --- a/flaim/src/flprintf.cpp +++ b/flaim/src/flprintf.cpp @@ -810,7 +810,7 @@ FLMINT f_vsprintf( /**************************************************************************** Desc: FLAIM's sprintf ****************************************************************************/ -FLMEXP FLMINT FLMCDECL f_sprintf( +FLMEXP FLMINT FLMAPI f_sprintf( char * pszDestStr, const char * pszFormat, ...) diff --git a/flaim/src/fnlm.cpp b/flaim/src/fnlm.cpp new file mode 100644 index 0000000..64cc203 --- /dev/null +++ b/flaim/src/fnlm.cpp @@ -0,0 +1,3937 @@ +//------------------------------------------------------------------------- +// Desc: I/O for Netware OS +// Tabs: 3 +// +// Copyright (c) 1998-2003,2005-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: fnlm.cpp 12362 2006-03-09 12:11:37 -0700 (Thu, 09 Mar 2006) dsanders $ +//------------------------------------------------------------------------- + +#include "flaimsys.h" + +#if defined( FLM_NLM) + +#define F_IO_MAX_CREATION_TRIES 10 +#define zMAX_COMPONENT_NAME 256 +#define zGET_INFO_VARIABLE_DATA_SIZE (zMAX_COMPONENT_NAME * 2) + +#define zOK 0 // the operation succeeded +#define zERR_NO_MEMORY 20000 // insufficent memory to complete the request +#define zERR_NOT_SUPPORTED 20011 // the operation is not supported +#define zERR_CONNECTION_NOT_LOGGED_IN 20007 // the connection has not been logged in +#define zERR_END_OF_FILE 20100 // read past the end of file +#define zERR_OUT_OF_SPACE 20103 // no available disk space is left +#define zERR_BAD_FILE_HANDLE 20401 // the file handle is out of range, bad instance, or doesn't exist +#define zERR_INVALID_NAME 20403 // path name is invalid -- bad syntax +#define zERR_INVALID_CHAR_IN_NAME 20404 // path name had an invalid character +#define zERR_INVALID_PATH 20405 // the path is syntactically incorrect +#define zERR_NAME_NOT_FOUND_IN_DIRECTORY 20407 // name does not exist in the direcory being searched +#define zERR_NO_NAMES_IN_PATH 20409 // a NULL file name was given +#define zERR_NO_MORE_NAMES_IN_PATH 20410 // doing a wild search but ran out of names to search +#define zERR_PATH_MUST_BE_FULLY_QUALIFIED 20411 // path name must be fully qualified in this context +#define zERR_FILE_ALREADY_EXISTS 20412 // the given file already exists +#define zERR_NAME_NO_LONGER_VALID 20413 // the dir/file name is no longer valid +#define zERR_DIRECTORY_NOT_EMPTY 20417 // the directory still has files in it +#define zERR_NO_FILES_FOUND 20424 // no files matched the given wildcard pattern +#define zERR_DIR_CANNOT_BE_OPENED 20435 // the requested parent was not found +#define zERR_NO_OPEN_PRIVILEGE 20438 // no the right privileges to open the file +#define zERR_NO_MORE_CONTEXT_HANDLE_IDS 20439 // there are no more available context handle IDs +#define zERR_INVALID_PATH_FORMAT 20441 // the pathFormat is either invalid or unsupported +#define zERR_ALL_FILES_IN_USE 20500 // all files were in use +#define zERR_SOME_FILES_IN_USE 20501 // some of the files were in use +#define zERR_ALL_FILES_READ_ONLY 20502 // all files were READONLY +#define zERR_SOME_FILES_READ_ONLY 20503 // some of the files were READONLY +#define zERR_ALL_NAMES_EXIST 20504 // all of the names already existed +#define zERR_SOME_NAMES_EXIST 20505 // some of the names already existed +#define zERR_NO_RENAME_PRIVILEGE 20506 // you do not have privilege to rename the file +#define zERR_RENAME_DIR_INVALID 20507 // the selected directory may not be renamed +#define zERR_RENAME_TO_OTHER_VOLUME 20508 // a rename/move may not move the beast to a different volume +#define zERR_CANT_RENAME_DATA_STREAMS 20509 // not allowed to rename a data stream +#define zERR_FILE_RENAME_IN_PROGRESS 20510 // the file is already being renamed by a different process +#define zERR_CANT_RENAME_TO_DELETED 20511 // only deleted files may be renamed to a deleted state +#define zERR_HOLE_IN_DIO_FILE 20651 // DIO files cannot have holes +#define zERR_BEYOND_EOF 20652 // DIO files cannot be read beyond EOF +#define zERR_INVALID_PATH_SEPARATOR 20704 // the name space does not support the requested path separator type +#define zERR_VOLUME_SEPARATOR_NOT_SUPPORTED 20705 // the name space does not support volume separators +#define zERR_BAD_VOLUME_NAME 20800 // the given volume name is syntactically incorrect +#define zERR_VOLUME_NOT_FOUND 20801 // the given volume name could not be found +#define zERR_NO_SET_PRIVILEGE 20850 // does not have rights to modify metadata +#define zERR_NO_CREATE_PRIVILEGE 20851 // does not have rights to create an object +#define zERR_ACCESS_DENIED 20859 // authorization/attributes denied access +#define zERR_NO_WRITE_PRIVILEGE 20860 // no granted write privileges +#define zERR_NO_READ_PRIVILEGE 20861 // no granted read privileges +#define zERR_NO_DELETE_PRIVILEGE 20862 // no delete privileges +#define zERR_SOME_NO_DELETE_PRIVILEGE 20863 // on wildcard some do not have delete privileges +#define zERR_NO_SUCH_OBJECT 20867 // no such object in the naming services +#define zERR_CANT_DELETE_OPEN_FILE 20868 // cant delete an open file without rights +#define zERR_NO_CREATE_DELETE_PRIVILEGE 20869 // no delete on create privileges +#define zERR_NO_SALVAGE_PRIVILEGE 20870 // no privileges to salvage this file +#define zERR_FILE_READ_LOCKED 20905 // cant grant read access to the file +#define zERR_FILE_WRITE_LOCKED 20906 // cant grant write access to the file + +#define zRR_READ_ACCESS 0x00000001 +#define zRR_WRITE_ACCESS 0x00000002 +#define zRR_DENY_READ 0x00000004 +#define zRR_DENY_WRITE 0x00000008 +#define zRR_SCAN_ACCESS 0x00000010 +#define zRR_ENABLE_IO_ON_COMPRESSED_DATA 0x00000100 +#define zRR_LEAVE_FILE_COMPRESSED 0x00000200 +#define zRR_DELETE_FILE_ON_CLOSE 0x00000400 +#define zRR_FLUSH_ON_CLOSE 0x00000800 +#define zRR_PURGE_IMMEDIATE_ON_CLOSE 0x00001000 +#define zRR_DIO_MODE 0x00002000 +#define zRR_ALLOW_SECURE_DIRECTORY_ACCESS 0x00020000 +#define zRR_TRANSACTION_ACTIVE 0x00100000 +#define zRR_READ_ACCESS_TO_SNAPSHOT 0x04000000 +#define zRR_DENY_RW_OPENER_CAN_REOPEN 0x08000000 +#define zRR_CREATE_WITHOUT_READ_ACCESS 0x10000000 +#define zRR_OPENER_CAN_DELETE_WHILE_OPEN 0x20000000 +#define zRR_CANT_DELETE_WHILE_OPEN 0x40000000 +#define zRR_DONT_UPDATE_ACCESS_TIME 0x80000000 + +#define zFA_READ_ONLY 0x00000001 +#define zFA_HIDDEN 0x00000002 +#define zFA_SYSTEM 0x00000004 +#define zFA_EXECUTE 0x00000008 +#define zFA_SUBDIRECTORY 0x00000010 +#define zFA_ARCHIVE 0x00000020 +#define zFA_SHAREABLE 0x00000080 +#define zFA_SMODE_BITS 0x00000700 +#define zFA_NO_SUBALLOC 0x00000800 +#define zFA_TRANSACTION 0x00001000 +#define zFA_NOT_VIRTUAL_FILE 0x00002000 +#define zFA_IMMEDIATE_PURGE 0x00010000 +#define zFA_RENAME_INHIBIT 0x00020000 +#define zFA_DELETE_INHIBIT 0x00040000 +#define zFA_COPY_INHIBIT 0x00080000 +#define zFA_IS_ADMIN_LINK 0x00100000 +#define zFA_IS_LINK 0x00200000 +#define zFA_REMOTE_DATA_INHIBIT 0x00800000 +#define zFA_COMPRESS_FILE_IMMEDIATELY 0x02000000 +#define zFA_DATA_STREAM_IS_COMPRESSED 0x04000000 +#define zFA_DO_NOT_COMPRESS_FILE 0x08000000 +#define zFA_CANT_COMPRESS_DATA_STREAM 0x20000000 +#define zFA_ATTR_ARCHIVE 0x40000000 +#define zFA_VOLATILE 0x80000000 + +#define zNSPACE_DOS 0 +#define zNSPACE_MAC 1 +#define zNSPACE_UNIX 2 +#define zNSPACE_LONG 4 +#define zNSPACE_DATA_STREAM 6 +#define zNSPACE_EXTENDED_ATTRIBUTE 7 +#define zNSPACE_INVALID (-1) +#define zNSPACE_DOS_MASK (1 << zNSPACE_DOS) +#define zNSPACE_MAC_MASK (1 << zNSPACE_MAC) +#define zNSPACE_UNIX_MASK (1 << zNSPACE_UNIX) +#define zNSPACE_LONG_MASK (1 << zNSPACE_LONG) +#define zNSPACE_DATA_STREAM_MASK (1 << zNSPACE_DATA_STREAM) +#define zNSPACE_EXTENDED_ATTRIBUTE_MASK (1 << zNSPACE_EXTENDED_ATTRIBUTE) +#define zNSPACE_ALL_MASK (0xffffffff) + +#define zMODE_VOLUME_ID 0x80000000 +#define zMODE_UTF8 0x40000000 +#define zMODE_DELETED 0x20000000 +#define zMODE_LINK 0x10000000 + +#define zCREATE_OPEN_IF_THERE 0x00000001 +#define zCREATE_TRUNCATE_IF_THERE 0x00000002 +#define zCREATE_DELETE_IF_THERE 0x00000004 + +#define zMATCH_ALL_DERIVED_TYPES 0x00000001 +#define zMATCH_HIDDEN 0x1 +#define zMATCH_NON_HIDDEN 0x2 +#define zMATCH_DIRECTORY 0x4 +#define zMATCH_NON_DIRECTORY 0x8 +#define zMATCH_SYSTEM 0x10 +#define zMATCH_NON_SYSTEM 0x20 +#define zMATCH_ALL (~0) + +#define zSETSIZE_NON_SPARSE_FILE 0x00000001 +#define zSETSIZE_NO_ZERO_FILL 0x00000002 +#define zSETSIZE_UNDO_ON_ERR 0x00000004 +#define zSETSIZE_PHYSICAL_ONLY 0x00000008 +#define zSETSIZE_LOGICAL_ONLY 0x00000010 +#define zSETSIZE_COMPRESSED 0x00000020 + +#define zMOD_FILE_ATTRIBUTES 0x00000001 +#define zMOD_CREATED_TIME 0x00000002 +#define zMOD_ARCHIVED_TIME 0x00000004 +#define zMOD_MODIFIED_TIME 0x00000008 +#define zMOD_ACCESSED_TIME 0x00000010 +#define zMOD_METADATA_MODIFIED_TIME 0x00000020 +#define zMOD_OWNER_ID 0x00000040 +#define zMOD_ARCHIVER_ID 0x00000080 +#define zMOD_MODIFIER_ID 0x00000100 +#define zMOD_METADATA_MODIFIER_ID 0x00000200 +#define zMOD_PRIMARY_NAMESPACE 0x00000400 +#define zMOD_DELETED_INFO 0x00000800 +#define zMOD_MAC_METADATA 0x00001000 +#define zMOD_UNIX_METADATA 0x00002000 +#define zMOD_EXTATTR_FLAGS 0x00004000 +#define zMOD_VOL_ATTRIBUTES 0x00008000 +#define zMOD_VOL_NDS_OBJECT_ID 0x00010000 +#define zMOD_VOL_MIN_KEEP_SECONDS 0x00020000 +#define zMOD_VOL_MAX_KEEP_SECONDS 0x00040000 +#define zMOD_VOL_LOW_WATER_MARK 0x00080000 +#define zMOD_VOL_HIGH_WATER_MARK 0x00100000 +#define zMOD_POOL_ATTRIBUTES 0x00200000 +#define zMOD_POOL_NDS_OBJECT_ID 0x00400000 +#define zMOD_VOL_DATA_SHREDDING_COUNT 0x00800000 +#define zMOD_VOL_QUOTA 0x01000000 + +/*************************************************************************** +Desc: +***************************************************************************/ +enum zGetInfoMask_t +{ + zGET_STD_INFO = 0x1, + zGET_NAME = 0x2, + zGET_ALL_NAMES = 0x4, + zGET_PRIMARY_NAMESPACE = 0x8, + zGET_TIMES_IN_SECS = 0x10, + zGET_TIMES_IN_MICROS = 0x20, + zGET_IDS = 0x40, + zGET_STORAGE_USED = 0x80, + zGET_BLOCK_SIZE = 0x100, + zGET_COUNTS = 0x200, + zGET_EXTENDED_ATTRIBUTE_INFO = 0x400, + zGET_DATA_STREAM_INFO = 0x800, + zGET_DELETED_INFO = 0x1000, + zGET_MAC_METADATA = 0x2000, + zGET_UNIX_METADATA = 0x4000, + zGET_EXTATTR_FLAGS = 0x8000, + zGET_VOLUME_INFO = 0x10000, + zGET_VOL_SALVAGE_INFO = 0x20000, + zGET_POOL_INFO = 0x40000 +}; + +/*************************************************************************** +Desc: +***************************************************************************/ +enum +{ + zINFO_VERSION_A = 1 +}; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef enum FileType_t +{ + zFILE_UNKNOWN, + zFILE_REGULAR, + zFILE_EXTENDED_ATTRIBUTE, + zFILE_NAMED_DATA_STREAM, + zFILE_PIPE, + zFILE_VOLUME, + zFILE_POOL, + zFILE_MAX +} FileType_t; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef struct GUID_t +{ + LONG timeLow; + WORD timeMid; + WORD timeHighAndVersion; + BYTE clockSeqHighAndReserved; + BYTE clockSeqLow; + BYTE node[ 6]; +} GUID_t; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef struct zMacInfo_s +{ + BYTE finderInfo[32]; + BYTE proDOSInfo[6]; + BYTE filler[2]; + LONG dirRightsMask; +} zMacInfo_s; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef struct zUnixInfo_s +{ + LONG fMode; + LONG rDev; + LONG myFlags; + LONG nfsUID; + LONG nfsGID; + LONG nwUID; + LONG nwGID; + LONG nwEveryone; + LONG nwUIDRights; + LONG nwGIDRights; + LONG nwEveryoneRights; + BYTE acsFlags; + BYTE firstCreated; + FLMINT16 variableSize; +} zUnixInfo_s; + +typedef struct zVolumeInfo_s +{ + GUID_t volumeID; + GUID_t ndsObjectID; + LONG volumeState; + LONG nameSpaceMask; + + struct + { + FLMUINT64 enabled; + FLMUINT64 enableModMask; + FLMUINT64 supported; + } features; + + FLMUINT64 maximumFileSize; + FLMUINT64 totalSpaceQuota; + FLMUINT64 numUsedBytes; + FLMUINT64 numObjects; + FLMUINT64 numFiles; + LONG authModelID; + LONG dataShreddingCount; + + struct + { + FLMUINT64 purgeableBytes; + FLMUINT64 nonPurgeableBytes; + FLMUINT64 numDeletedFiles; + FLMUINT64 oldestDeletedTime; + LONG minKeepSeconds; + LONG maxKeepSeconds; + LONG lowWaterMark; + LONG highWaterMark; + } salvage; + + struct + { + FLMUINT64 numCompressedFiles; + FLMUINT64 numCompDelFiles; + FLMUINT64 numUncompressibleFiles; + FLMUINT64 numPreCompressedBytes; + FLMUINT64 numCompressedBytes; + } comp; + +} zVolumeInfo_s; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef struct zPoolInfo_s +{ + GUID_t poolID; + GUID_t ndsObjectID; + LONG poolState; + LONG nameSpaceMask; + + struct + { + FLMUINT64 enabled; + FLMUINT64 enableModMask; + FLMUINT64 supported; + } features; + + FLMUINT64 totalSpace; + FLMUINT64 numUsedBytes; + FLMUINT64 purgeableBytes; + FLMUINT64 nonPurgeableBytes; +} zPoolInfo_s; + +/*************************************************************************** +Desc: +***************************************************************************/ +typedef struct zInfo_s +{ + LONG infoVersion; + FLMINT totalBytes; + FLMINT nextByte; + LONG padding; + FLMUINT64 retMask; + + struct + { + FLMUINT64 zid; + FLMUINT64 dataStreamZid; + FLMUINT64 parentZid; + FLMUINT64 logicalEOF; + GUID_t volumeID; + LONG fileType; + LONG fileAttributes; + LONG fileAttributesModMask; + LONG padding; + } std; + + struct + { + FLMUINT64 physicalEOF; + FLMUINT64 dataBytes; + FLMUINT64 metaDataBytes; + } storageUsed; + + LONG primaryNameSpaceID; + LONG nameStart; + + struct + { + LONG numEntries; + LONG fileNameArray; + } names; + + struct + { + FLMUINT64 created; + FLMUINT64 archived; + FLMUINT64 modified; + FLMUINT64 accessed; + FLMUINT64 metaDataModified; + } time; + + struct + { + GUID_t owner; + GUID_t archiver; + GUID_t modifier; + GUID_t metaDataModifier; + } id; + + struct + { + LONG size; + LONG sizeShift; + } blockSize; + + struct + { + LONG open; + LONG hardLink; + } count; + + struct + { + LONG count; + LONG totalNameSize; + FLMUINT64 totalDataSize; + } dataStream; + + struct + { + LONG count; + LONG totalNameSize; + FLMUINT64 totalDataSize; + } extAttr; + + struct + { + FLMUINT64 time; + GUID_t id; + } deleted; + + struct + { + zMacInfo_s info; + } macNS; + + struct + { + zUnixInfo_s info; + LONG offsetToData; + } unixNS; + + zVolumeInfo_s vol; + zPoolInfo_s pool; + LONG extAttrUserFlags; + BYTE variableData[zGET_INFO_VARIABLE_DATA_SIZE]; + +} zInfo_s; + +RCODE DfsMapError( + LONG lResult, + RCODE defaultRc); + +LONG FlaimToNDSOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo); + +FLMUINT FlaimToNSSOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo); + +typedef FLMINT (* zROOT_KEY_FUNC)( + FLMUINT connectionID, + FLMINT64 * retRootKey); + +typedef FLMINT (* zCLOSE_FUNC)( + FLMINT64 key); + +typedef FLMINT (* zCREATE_FUNC)( + FLMINT64 key, + FLMUINT taskID, + FLMUINT64 xid, + FLMUINT nameSpace, + const void * path, + FLMUINT fileType, + FLMUINT64 fileAttributes, + FLMUINT createFlags, + FLMUINT requestedRights, + FLMINT64 * retKey); + +typedef FLMINT (* zOPEN_FUNC)( + FLMINT64 key, + FLMUINT taskID, + FLMUINT nameSpace, + const void * path, + FLMUINT requestedRights, + FLMINT64 * retKey); + +typedef FLMINT (* zDELETE_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT nameSapce, + const void * path, + FLMUINT match, + FLMUINT deleteFlags); + +typedef FLMINT (* zREAD_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT64 startingOffset, + FLMUINT bytesToRead, + void * retBuffer, + FLMUINT * retBytesRead); + +typedef FLMINT (* zDIO_READ_FUNC)( + FLMINT64 key, + FLMUINT64 unitOffset, + FLMUINT unitsToRead, + FLMUINT callbackData, + void (*dioReadCallBack)( + FLMUINT reserved, + FLMUINT callbackData, + FLMUINT retStatus), + void * retBuffer); + +typedef FLMINT (* zGET_INFO_FUNC)( + FLMINT64 key, + FLMUINT64 getInfoMask, + FLMUINT sizeRetGetInfo, + FLMUINT infoVersion, + zInfo_s * retGetInfo); + +typedef FLMINT (* zMODIFY_INFO_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT64 modifyInfoMask, + FLMUINT sizeModifyInfo, + FLMUINT infoVersion, + const zInfo_s * modifyInfo); + +typedef FLMINT (* zSET_EOF_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT64 startingOffset, + FLMUINT flags); + +typedef FLMINT (* zWRITE_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT64 startingOffset, + FLMUINT bytesToWrite, + const void * buffer, + FLMUINT * retBytesWritten); + +typedef FLMINT (* zDIO_WRITE_FUNC)( + FLMINT64 key, + FLMUINT64 unitOffset, + FLMUINT unitsToWrite, + FLMUINT callbackData, + void (*dioWriteCallBack)( + FLMUINT reserved, + FLMUINT callbackData, + FLMUINT retStatus), + const void * buffer); + +typedef FLMINT (* zRENAME_FUNC)( + FLMINT64 key, + FLMUINT64 xid, + FLMUINT srcNameSpace, + const void * srcPath, + FLMUINT srcMatchAttributes, + FLMUINT dstNameSpace, + const void * dstPath, + FLMUINT renameFlags); + +typedef BOOL (* zIS_NSS_VOLUME_FUNC)( + const char * path); + +FSTATIC zIS_NSS_VOLUME_FUNC gv_zIsNSSVolumeFunc = NULL; +FSTATIC zROOT_KEY_FUNC gv_zRootKeyFunc = NULL; +FSTATIC zCLOSE_FUNC gv_zCloseFunc = NULL; +FSTATIC zCREATE_FUNC gv_zCreateFunc = NULL; +FSTATIC zOPEN_FUNC gv_zOpenFunc = NULL; +FSTATIC zDELETE_FUNC gv_zDeleteFunc = NULL; +FSTATIC zREAD_FUNC gv_zReadFunc = NULL; +FSTATIC zDIO_READ_FUNC gv_zDIOReadFunc = NULL; +FSTATIC zGET_INFO_FUNC gv_zGetInfoFunc = NULL; +FSTATIC zMODIFY_INFO_FUNC gv_zModifyInfoFunc = NULL; +FSTATIC zSET_EOF_FUNC gv_zSetEOFFunc = NULL; +FSTATIC zWRITE_FUNC gv_zWriteFunc = NULL; +FSTATIC zDIO_WRITE_FUNC gv_zDIOWriteFunc = NULL; +FSTATIC zRENAME_FUNC gv_zRenameFunc = NULL; +extern RCODE gv_CriticalFSError; + +FSTATIC void ConvertToQualifiedNWPath( + const char * pInputPath, + char * pQualifiedPath); + +FSTATIC RCODE nssTurnOffRenameInhibit( + const char * pszFileName); + +FSTATIC LONG ConvertPathToLNameFormat( + const char * pPath, + LONG * plVolumeID, + FLMBOOL * pbNssVolume, + FLMBYTE * pLNamePath, + LONG * plLNamePathCount); + +FSTATIC void DirectIONoWaitCallBack( + LONG unknownAlwaysZero, + LONG callbackData, + LONG completionCode); + +FSTATIC void nssDioCallback( + FLMUINT reserved, + FLMUINT UserData, + FLMUINT retStatus); + +FSTATIC RCODE MapNSSToFlaimError( + FLMINT lStatus, + RCODE defaultRc); + +FLMINT64 gv_NssRootKey; +FLMBOOL gv_bNSSKeyInitialized = FALSE; + +/*************************************************************************** +Desc: Initialize the root NSS key. +***************************************************************************/ +RCODE nssInitialize( void) +{ + RCODE rc = FERR_OK; + FLMINT lStatus; + + if (!gv_bNSSKeyInitialized) + { + // Import the required NSS functions + + if( (gv_zIsNSSVolumeFunc = (zIS_NSS_VOLUME_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x0C" "zIsNSSVolume")) == NULL) + { + // NSS is not available on this server. Jump to exit. + goto Exit; + } + + if( (gv_zRootKeyFunc = (zROOT_KEY_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x08" "zRootKey")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zCloseFunc = (zCLOSE_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x06" "zClose")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zCreateFunc = (zCREATE_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x07" "zCreate")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zOpenFunc = (zOPEN_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x05" "zOpen")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zDeleteFunc = (zDELETE_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x07" "zDelete")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zReadFunc = (zREAD_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x05" "zRead")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zDIOReadFunc = (zDIO_READ_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x08" "zDIORead")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zGetInfoFunc = (zGET_INFO_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x08" "zGetInfo")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zModifyInfoFunc = (zMODIFY_INFO_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x0B" "zModifyInfo")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zSetEOFFunc = (zSET_EOF_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x07" "zSetEOF")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zWriteFunc = (zWRITE_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x06" "zWrite")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zDIOWriteFunc = (zDIO_WRITE_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x09" "zDIOWrite")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + if( (gv_zRenameFunc = (zRENAME_FUNC)ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x07" "zRename")) == NULL) + { + flmAssert( 0); + rc = RC_SET( FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + // Get the NSS root key + + if ((lStatus = gv_zRootKeyFunc( 0, &gv_NssRootKey)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + gv_bNSSKeyInitialized = TRUE; + } + +Exit: + + return( rc); +} + +/*************************************************************************** +Desc: Close the root NSS key. +***************************************************************************/ +void nssUninitialize( void) +{ + if (gv_bNSSKeyInitialized) + { + (void)gv_zCloseFunc( gv_NssRootKey); + gv_bNSSKeyInitialized = FALSE; + } +} + +/*************************************************************************** +Desc: Maps NDS errors to IO errors. + fix: The set of return codes returned by the NDS I/O functions (like + NDSOpenStreamFile) is defined in "nw500\errors.h" Unfortunately, + some of the names used for the return codes are used in other include + files. Because of the conflict, it has been decided to use the + integers associated with the names, rather than the names + themselves. This needs to be fixed. +***************************************************************************/ +RCODE MapNWtoFlaimError( + LONG lResult, + RCODE defaultRc + ) +{ + RCODE rc; + switch (lResult) + { + case 128: // ERR_LOCK_FAIL + case 147: // ERR_NO_READ_PRIVILEGE + case 148: // ERR_NO_WRITE_PRIVILEGE + case 168: // ERR_ACCESS_DENIED + rc = RC_SET( FERR_IO_ACCESS_DENIED); + break; + + case 136: //ERR_INVALID_FILE_HANDLE + rc = RC_SET( FERR_IO_BAD_FILE_HANDLE); + break; + + case 001: //ERR_INSUFFICIENT_SPACE + case 153: //ERR_DIRECTORY_FULL + rc = RC_SET( FERR_IO_DISK_FULL); + break; + + case 130: //ERR_NO_OPEN_PRIVILEGE + case 165: //ERR_INVALID_OPENCREATE_MODE + rc = RC_SET( FERR_IO_OPEN_ERR); + break; + + case 158: //ERR_BAD_FILE_NAME + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + break; + + case 129: //ERR_OUT_OF_HANDLES + rc = RC_SET( FERR_IO_TOO_MANY_OPEN_FILES); + break; + + case 139: //ERR_NO_RENAME_PRIVILEGE + case 154: //ERR_RENAME_ACROSS_VOLUME + case 164: //ERR_RENAME_DIR_INVALID + rc = RC_SET( FERR_IO_RENAME_FAILURE); + break; + + case 222: //ERR_BAD_PASSWORD + case 223: //ERR_PASSWORD_EXPIRED + rc = RC_SET( FERR_IO_INVALID_PASSWORD); + break; + + case 156: //ERR_INVALID_PATH + rc = RC_SET( FERR_IO_INVALID_PATH); + break; + + case 122: //ERR_CONNECTION_ALREADY_TEMPORARY + case 123: //ERR_CONNECTION_ALREADY_LOGGED_IN + case 124: //ERR_CONNECTION_NOT_AUTHENTICATED + case 125: //ERR_CONNECTION_NOT_LOGGED_IN + case 224: //ERR_NO_LOGIN_CONNECTIONS_AVAILABLE + rc = RC_SET( FERR_IO_CONNECT_ERROR); + break; + + default: + rc = RC_SET( defaultRc); + break; + } + return( rc ); +} + +/*************************************************************************** +Desc: Maps NSS errors to IO errors. +***************************************************************************/ +FSTATIC RCODE MapNSSToFlaimError( + FLMINT lStatus, + RCODE defaultRc) +{ + RCODE rc; + + switch (lStatus) + { + case zERR_FILE_ALREADY_EXISTS: + case zERR_DIRECTORY_NOT_EMPTY: + case zERR_DIR_CANNOT_BE_OPENED: + case zERR_NO_SET_PRIVILEGE: + case zERR_NO_CREATE_PRIVILEGE: + case zERR_ACCESS_DENIED: + case zERR_NO_WRITE_PRIVILEGE: + case zERR_NO_READ_PRIVILEGE: + case zERR_NO_DELETE_PRIVILEGE: + case zERR_SOME_NO_DELETE_PRIVILEGE: + case zERR_CANT_DELETE_OPEN_FILE: + case zERR_NO_CREATE_DELETE_PRIVILEGE: + case zERR_NO_SALVAGE_PRIVILEGE: + case zERR_FILE_READ_LOCKED: + case zERR_FILE_WRITE_LOCKED: + rc = RC_SET( FERR_IO_ACCESS_DENIED); + break; + + case zERR_BAD_FILE_HANDLE: + rc = RC_SET( FERR_IO_BAD_FILE_HANDLE); + break; + + case zERR_OUT_OF_SPACE: + rc = RC_SET( FERR_IO_DISK_FULL); + break; + + case zERR_NO_OPEN_PRIVILEGE: + rc = RC_SET( FERR_IO_OPEN_ERR); + break; + + case zERR_NAME_NOT_FOUND_IN_DIRECTORY: + case zERR_NO_FILES_FOUND: + case zERR_VOLUME_NOT_FOUND: + case zERR_NO_SUCH_OBJECT: + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + break; + + case zERR_NO_MORE_CONTEXT_HANDLE_IDS: + rc = RC_SET( FERR_IO_TOO_MANY_OPEN_FILES); + break; + case zERR_ALL_FILES_IN_USE: + case zERR_SOME_FILES_IN_USE: + case zERR_ALL_FILES_READ_ONLY: + case zERR_SOME_FILES_READ_ONLY: + case zERR_ALL_NAMES_EXIST: + case zERR_SOME_NAMES_EXIST: + case zERR_NO_RENAME_PRIVILEGE: + case zERR_RENAME_DIR_INVALID: + case zERR_RENAME_TO_OTHER_VOLUME: + case zERR_CANT_RENAME_DATA_STREAMS: + case zERR_FILE_RENAME_IN_PROGRESS: + case zERR_CANT_RENAME_TO_DELETED: + rc = RC_SET( FERR_IO_RENAME_FAILURE); + break; + + case zERR_INVALID_NAME: + case zERR_INVALID_CHAR_IN_NAME: + case zERR_INVALID_PATH: + case zERR_NO_NAMES_IN_PATH: + case zERR_NO_MORE_NAMES_IN_PATH: + case zERR_PATH_MUST_BE_FULLY_QUALIFIED: + case zERR_NAME_NO_LONGER_VALID: + case zERR_INVALID_PATH_FORMAT: + case zERR_INVALID_PATH_SEPARATOR: + case zERR_VOLUME_SEPARATOR_NOT_SUPPORTED: + case zERR_BAD_VOLUME_NAME: + rc = RC_SET( FERR_IO_INVALID_PATH); + break; + case zERR_CONNECTION_NOT_LOGGED_IN: + rc = RC_SET( FERR_IO_CONNECT_ERROR); + break; + case zERR_NO_MEMORY: + rc = RC_SET( FERR_MEM); + break; + case zERR_NOT_SUPPORTED: + rc = RC_SET( FERR_NOT_IMPLEMENTED); + break; + case zERR_END_OF_FILE: + case zERR_BEYOND_EOF: + rc = RC_SET( FERR_IO_END_OF_FILE); + break; + + default: + rc = RC_SET( defaultRc); + break; + } + return( rc ); +} + +/*************************************************************************** +Desc: Maps direct IO errors to IO errors. +fix: we shouldn't have 2 copies of this function. this is just temporary. + long term, we need to make the FDFS.CPP version public. +***************************************************************************/ +RCODE DfsMapError( + LONG lResult, + RCODE defaultRc + ) +{ + switch (lResult) + { + case DFSHoleInFileError: + case DFSOperationBeyondEndOfFile: + return( RC_SET( FERR_IO_END_OF_FILE)); + case DFSHardIOError: + case DFSInvalidFileHandle: + return( RC_SET( FERR_IO_BAD_FILE_HANDLE)); + case DFSNoReadPrivilege: + return( RC_SET( FERR_IO_ACCESS_DENIED)); + case DFSInsufficientMemory: + return( RC_SET( FERR_MEM)); + default: + return( RC_SET( defaultRc)); + } +} + + +/**************************************************************************** +Desc: Map flaim I/O flags to NDS I/O flags +****************************************************************************/ +LONG FlaimToNDSOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo + ) +{ + LONG lFlags = NO_RIGHTS_CHECK_ON_OPEN_BIT | ALLOW_SECURE_DIRECTORY_ACCESS_BIT; + + if (uiAccess & (F_IO_RDONLY | F_IO_RDWR)) + { + lFlags |= READ_ACCESS_BIT; + } + if (uiAccess & F_IO_RDWR) + { + lFlags |= WRITE_ACCESS_BIT; + } + + if (uiAccess & F_IO_SH_DENYRW ) + { + lFlags |= DENY_READ_BIT; + } + if (uiAccess & (F_IO_SH_DENYWR | F_IO_SH_DENYRW)) + { + lFlags |= DENY_WRITE_BIT; + } + if (bDoDirectIo) + { + lFlags |= NEVER_READ_AHEAD_BIT; + } + return( lFlags ); +} + +/**************************************************************************** +Desc: Map flaim I/O flags to NDS I/O flags for NSS volumes +****************************************************************************/ +FLMUINT FlaimToNSSOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo) +{ + FLMUINT lFlags = zRR_ALLOW_SECURE_DIRECTORY_ACCESS | + zRR_CANT_DELETE_WHILE_OPEN; + + if (uiAccess & (F_IO_RDONLY | F_IO_RDWR)) + { + lFlags |= zRR_READ_ACCESS; + } + if (uiAccess & F_IO_RDWR) + { + lFlags |= zRR_WRITE_ACCESS; + } + + if (uiAccess & F_IO_SH_DENYRW) + { + lFlags |= zRR_DENY_READ; + } + if (uiAccess & (F_IO_SH_DENYWR | F_IO_SH_DENYRW)) + { + lFlags |= zRR_DENY_WRITE; + } + if (bDoDirectIo) + { + lFlags |= zRR_DIO_MODE; + } + return( lFlags ); +} + +/**************************************************************************** +Desc: Map flaim I/O flags to NetWare I/O flags +****************************************************************************/ +LONG FlaimToNWOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo + ) +{ + LONG lFlags = 0; + + if (uiAccess & (F_IO_RDONLY | F_IO_RDWR)) + { + lFlags |= READ_ACCESS_BIT; + } + if (uiAccess & F_IO_RDWR) + { + lFlags |= WRITE_ACCESS_BIT; + } + + if (uiAccess & F_IO_SH_DENYRW ) + { + lFlags |= DENY_READ_BIT; + } + if (uiAccess & (F_IO_SH_DENYWR | F_IO_SH_DENYRW)) + { + lFlags |= DENY_WRITE_BIT; + } + if (bDoDirectIo) + { + lFlags |= NEVER_READ_AHEAD_BIT; + } + return( lFlags ); +} + +/**************************************************************************** +Desc: Default Constructor for F_FileHdl class +****************************************************************************/ +F_FileHdlImp::F_FileHdlImp() +{ + // Should call the base class constructor automatically. + + m_lFileHandle = -1; + m_lOpenAttr = 0; + m_uiCurrentPos = 0; + m_lVolumeID = F_NW_DEFAULT_VOLUME_NUMBER; + m_bDoSuballocation = FALSE; + m_lLNamePathCount = 0; + m_pszIoPath = NULL; + m_uiExtendSize = 0; + m_uiMaxAutoExtendSize = gv_FlmSysData.uiMaxFileSize; + + // Direct IO members + m_bDoDirectIO = FALSE; // TRUE = do direct IO-style read/writes + m_lSectorsPerBlock = 0; + m_lMaxBlocks = 0; + + m_bNSS = FALSE; + m_bNSSFileOpen = FALSE; +} + +/*************************************************************************** +Desc: Open or create a file. +***************************************************************************/ +RCODE F_FileHdlImp::OpenOrCreate( + const char * pFileName, + FLMUINT uiAccess, + FLMBOOL bCreateFlag) +{ + RCODE rc = FERR_OK; + LONG unused; + void * unused2; + char * pszQualifiedPath = NULL; + LONG lErrorCode; + FLMBYTE * pTmpLNamePath; + char * pSaveFileName; + FLMBYTE * pLNamePath; + LONG * plLNamePathCount; + LONG LNamePathCount; + struct VolumeInformationStructure * + pVolumeInfo; + char * pszTemp; + char * pIoDirPath; + FLMBOOL bNssVolume = FALSE; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + m_bDoDirectIO = (uiAccess & F_IO_DIRECT) ? TRUE : FALSE; + + if( uiAccess & F_IO_DELETE_ON_CLOSE) + { + if( !m_pszIoPath) + { + if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE, &m_pszIoPath))) + { + goto Exit; + } + } + f_strcpy( m_pszIoPath, pFileName); + m_bDeleteOnClose = TRUE; + } + else + { + m_bDeleteOnClose = FALSE; + } + + if (RC_BAD( rc = f_alloc( + (FLMUINT)(F_PATH_MAX_SIZE + + F_PATH_MAX_SIZE + + F_PATH_MAX_SIZE + + F_PATH_MAX_SIZE + + sizeof( struct VolumeInformationStructure) + + F_PATH_MAX_SIZE), + &pszQualifiedPath))) + { + goto Exit; + } + + pTmpLNamePath = (((FLMBYTE *)pszQualifiedPath) + F_PATH_MAX_SIZE); + pSaveFileName = (((char *)pTmpLNamePath) + F_PATH_MAX_SIZE); + pIoDirPath = (((char *)pSaveFileName) + F_PATH_MAX_SIZE); + pVolumeInfo = (struct VolumeInformationStructure *) + (((char *)pIoDirPath) + F_PATH_MAX_SIZE); + pszTemp = (char *)(((char *)(pVolumeInfo)) + + sizeof( struct VolumeInformationStructure)); + + + /* Save the file name in case we have to create the directory. */ + + if((bCreateFlag) && (uiAccess & F_IO_CREATE_DIR)) + { + f_strcpy( pSaveFileName, pFileName); + } + + if( !m_pszIoPath) + { + pLNamePath = pTmpLNamePath; + plLNamePathCount = &LNamePathCount; + } + else + { + pLNamePath = (FLMBYTE *)m_pszIoPath; + plLNamePathCount = &m_lLNamePathCount; + } + + ConvertToQualifiedNWPath( pFileName, pszQualifiedPath); + + lErrorCode = ConvertPathToLNameFormat( + pszQualifiedPath, + &m_lVolumeID, + &bNssVolume, + pLNamePath, + plLNamePathCount); + if( lErrorCode != 0) + { + rc = MapNWtoFlaimError( lErrorCode, FERR_PARSING_FILE_NAME); + goto Exit; + } + + // Determine if the volume is NSS or not + + if (gv_bNSSKeyInitialized && bNssVolume) + { + m_bNSS = TRUE; + } + + if ( m_bDoDirectIO ) + { + if (!m_bNSS) + { + lErrorCode = + ReturnVolumeMappingInformation( m_lVolumeID, pVolumeInfo); + if (lErrorCode != 0) + { + rc = DfsMapError( lErrorCode, FERR_INITIALIZING_IO_SYSTEM); + goto Exit; + } + + m_lSectorsPerBlock = (LONG)(pVolumeInfo->VolumeAllocationUnitSizeInBytes / + NLM_SECTOR_SIZE); + m_lMaxBlocks = (LONG)(gv_FlmSysData.uiMaxFileSize / + (FLMUINT)pVolumeInfo->VolumeAllocationUnitSizeInBytes); + } + else + { + m_lMaxBlocks = (LONG)(gv_FlmSysData.uiMaxFileSize / (FLMUINT)65536); + } + } + + /* + Set up the file characteristics requested by caller. + */ + + if (bCreateFlag) + { + + // File is to be created + + if (NWTestIfFileExists( pszQualifiedPath ) == FERR_OK) + { + if (uiAccess & F_IO_EXCL) + { + rc = RC_SET( FERR_IO_ACCESS_DENIED); + goto Exit; + } + + (void)NWDeleteFile( pszQualifiedPath); + } + } + + /* Try to create or open the file */ + + if (m_bNSS) + { + FLMINT lStatus; + + if (bCreateFlag) + { + FLMUINT64 qFileAttr; + + qFileAttr = (FLMUINT64)(((m_bDoSuballocation) + ? (FLMUINT)(zFA_DO_NOT_COMPRESS_FILE) + : (FLMUINT)(zFA_NO_SUBALLOC | + zFA_DO_NOT_COMPRESS_FILE)) | + zFA_IMMEDIATE_PURGE); + +Retry_NSS_Create: + + m_lOpenAttr = FlaimToNSSOpenFlags( uiAccess, m_bDoDirectIO); + if ((lStatus = gv_zCreateFunc( gv_NssRootKey, 1, 0, + zNSPACE_LONG | zMODE_UTF8, pszQualifiedPath, zFILE_REGULAR, + qFileAttr, zCREATE_DELETE_IF_THERE, (FLMUINT)m_lOpenAttr, + &m_NssKey)) != zOK) + { + if (uiAccess & F_IO_CREATE_DIR) + { + uiAccess &= ~F_IO_CREATE_DIR; + + // Remove the file name for which we are creating the directory. + + if( f_pathReduce( pSaveFileName, pIoDirPath, pszTemp) == FERR_OK) + { + F_FileSystemImp FileSystem; + + if (RC_OK( FileSystem.CreateDir( pIoDirPath))) + goto Retry_NSS_Create; + } + } + rc = MapNSSToFlaimError( lStatus, + (RCODE)(m_bDoDirectIO + ? (RCODE)FERR_DIRECT_CREATING_FILE + : (RCODE)FERR_CREATING_FILE)); + goto Exit; + } + } + else + { + m_lOpenAttr = FlaimToNSSOpenFlags( uiAccess, m_bDoDirectIO); + if ((lStatus = gv_zOpenFunc( + gv_NssRootKey, // FLMINT64 key + 1, // FLMUINT taskID + zNSPACE_LONG | zMODE_UTF8, // FLMUINT nameSpace + pszQualifiedPath, // const void * path + (FLMUINT)m_lOpenAttr, // FLMUINT requestedRights + &m_NssKey)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, + (RCODE)(m_bDoDirectIO + ? (RCODE)FERR_DIRECT_OPENING_FILE + : (RCODE)FERR_OPENING_FILE)); + goto Exit; + } + } + m_bNSSFileOpen = TRUE; + } + else + { + if (bCreateFlag) + { + m_lOpenAttr = (LONG)(((m_bDoSuballocation) + ? (LONG)(DO_NOT_COMPRESS_FILE_BIT) + : (LONG)(NO_SUBALLOC_BIT | + DO_NOT_COMPRESS_FILE_BIT)) | + IMMEDIATE_PURGE_BIT); + +Retry_Create: + lErrorCode = CreateFile( + 0, // Connection ID + 1, // Task ID + m_lVolumeID, // Volume ID + 0, // (path base) 0 because we supply fully-qualified path + (BYTE *)pLNamePath,// LNAME-array format path + *plLNamePathCount, // LNAME-array size + LONGNameSpace, // LONGNameSpace + m_lOpenAttr, + 0xff, // 0xff, 0, DELETE_FILE_ON_CREATE_BIT, READ_ACCESS_BIT|WRITE_ACCESS_BIT + PrimaryDataStream, // PrimaryDataStream + &m_lFileHandle, + &unused, // return the directory number + &unused2 // union DirUnion *Entry; + ); + + if ((lErrorCode != 0) && (uiAccess & F_IO_CREATE_DIR)) + { + uiAccess &= ~F_IO_CREATE_DIR; + + /* Remove the file name for which we are creating the directory. */ + + if( f_pathReduce( pSaveFileName, pIoDirPath, pszTemp) == FERR_OK) + { + F_FileSystemImp FileSystem; + + if (RC_OK( FileSystem.CreateDir( pIoDirPath))) + goto Retry_Create; + } + } + + // Too many error codes map to 255, so we put in a special + // case check here. + + if( lErrorCode == 255) + { + rc = RC_SET( FERR_IO_ACCESS_DENIED); + goto Exit; + } + } + else + { + m_lOpenAttr = FlaimToNWOpenFlags(uiAccess, m_bDoDirectIO); + lErrorCode = OpenFile( + 0, // Connection ID + 1, // Task ID + m_lVolumeID, // Volume ID + 0, // (path base) 0 because we supply fully-qualified path + (BYTE *)pLNamePath, // LNAME-array format path + *plLNamePathCount, // LNAME-array size + LONGNameSpace, // LONGNameSpace + 0, // ?? LONG MatchBits, + m_lOpenAttr, + PrimaryDataStream, + &m_lFileHandle, + &unused, // return the directory number + &unused2 // union DirUnion *Entry; + ); + + /* + Too many error codes map to 255, so we put in a special + case check here. + */ + + if( lErrorCode == 255) + { + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + goto Exit; + } + } + + /* Check if the file operation was successful */ + + if ( lErrorCode != 0) + { + rc = MapNWtoFlaimError( lErrorCode, + (RCODE)(bCreateFlag + ? (RCODE)(m_bDoDirectIO + ? (RCODE)FERR_DIRECT_CREATING_FILE + : (RCODE)FERR_CREATING_FILE) + : (RCODE)(m_bDoDirectIO + ? (RCODE)FERR_DIRECT_OPENING_FILE + : (RCODE)FERR_OPENING_FILE))); + goto Exit; + } + + if (bCreateFlag) + { + /* Close and reopen the file after creating it. */ + + // Revoke the file handle rights and close the file + // (signified by passing 2 for the QueryFlag parameter). + // If this call fails and returns a 255 error, it may + // indicate that the FILESYS.NLM being used on the server + // does not implement option 2 for the QueryFlag parameter. + // In this case, we will default to our old behavior + // and simply call CloseFile. This, potentially, will + // not free all of the lock objects and could result in + // a memory leak in filesys.nlm. However, we want to + // at least make sure that there is a corresponding + // RevokeFileHandleRights or CloseFile call for every + // file open / create call. + + if( (lErrorCode = RevokeFileHandleRights( 0, 1, + m_lFileHandle, 2, m_lOpenAttr & 0x0000000F, &unused)) == 0xFF) + { + lErrorCode = CloseFile( 0, 1, m_lFileHandle); + } + m_lOpenAttr = 0; + + if ( lErrorCode != 0 ) + { + rc = MapNWtoFlaimError(lErrorCode, FERR_CLOSING_FILE); + goto Exit; + } + + m_lOpenAttr = FlaimToNWOpenFlags(uiAccess, m_bDoDirectIO); + lErrorCode = OpenFile( /* moved to vswitch.386 */ + 0, // Connection ID + 1, // Task ID + m_lVolumeID, // Volume ID + 0, // (path base) 0 because we supply fully-qualified path + (BYTE *)pLNamePath,// LNAME-array format path + *plLNamePathCount,// LNAME-array size + LONGNameSpace, // LONGNameSpace + 0, // ?? LONG MatchBits, + m_lOpenAttr, + PrimaryDataStream, + &m_lFileHandle, + &unused, // return the directory number + &unused2 // union DirUnion *Entry; + ); + + if ( lErrorCode != 0 ) + { + /* + Too many error codes map to 255, so we put in a special + case check here. + */ + + if( lErrorCode == 255) + { + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + } + else + { + rc = MapNWtoFlaimError( lErrorCode, + (RCODE)(m_bDoDirectIO + ? (RCODE)FERR_DIRECT_OPENING_FILE + : (RCODE)FERR_OPENING_FILE)); + } + goto Exit; + } + } + + if ( m_bDoDirectIO ) + { + lErrorCode = SwitchToDirectFileMode(0, m_lFileHandle); + if (lErrorCode != 0) + { + if (RevokeFileHandleRights( 0, 1, + m_lFileHandle, 2, m_lOpenAttr & 0x0000000F, &unused) == 0xFF) + { + (void)CloseFile( 0, 1, m_lFileHandle); + } + rc = MapNWtoFlaimError( lErrorCode, + (RCODE)(bCreateFlag + ? (RCODE)FERR_DIRECT_CREATING_FILE + : (RCODE)FERR_DIRECT_OPENING_FILE)); + goto Exit; + } + } + } + +Exit: + + if (RC_BAD( rc)) + { + m_lFileHandle = -1; + m_lOpenAttr = 0; + m_bNSSFileOpen = FALSE; + } + + if (pszQualifiedPath) + { + f_free( &pszQualifiedPath); + } + + return( rc ); +} + +/**************************************************************************** +Desc: Create a file +****************************************************************************/ +RCODE F_FileHdlImp::Create( + const char * pIoPath, + FLMUINT uiIoFlags) +{ + RCODE rc = FERR_OK; + + flmAssert( m_bFileOpened == FALSE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if( RC_BAD( rc = OpenOrCreate( pIoPath, uiIoFlags, TRUE))) + { + goto Exit; + } + + m_bFileOpened = TRUE; + m_uiCurrentPos = 0; + m_bOpenedExclusive = (uiIoFlags & F_IO_SH_DENYRW) ? TRUE : FALSE; + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE F_FileHdlImp::CreateUnique( + char * pIoPath, + const char * pszFileExtension, + FLMUINT uiIoFlags) +{ + RCODE rc = FERR_OK; + char * pszTmp; + FLMBOOL bModext = TRUE; + FLMUINT uiBaseTime = 0; + char ucHighByte = 0; + char ucFileName[ F_FILENAME_SIZE]; + char szDirPath[ F_PATH_MAX_SIZE]; + char szTmpPath[ F_PATH_MAX_SIZE]; + FLMUINT uiCount; + + f_memset( ucFileName, 0, sizeof( ucFileName)); + + flmAssert( m_bFileOpened == FALSE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + f_strcpy( szDirPath, pIoPath); + + // Search backwards replacing trailing spaces with NULLs. + + pszTmp = szDirPath; + pszTmp += (f_strlen( pszTmp) - 1); + while ((*pszTmp == 0x20) && pszTmp >= szDirPath) + { + *pszTmp = 0; + pszTmp--; + } + + /* Append a backslash if one isn't already there. */ + + if (pszTmp >= szDirPath && *pszTmp != '\\') + { + pszTmp++; + *pszTmp++ = '\\'; + } + else + { + pszTmp++; + } + *pszTmp = 0; + + if ((pszFileExtension) && (f_strlen( pszFileExtension) >= 3)) + { + bModext = FALSE; + } + + uiCount = 0; + do + { + f_pathCreateUniqueName( &uiBaseTime, ucFileName, pszFileExtension, + &ucHighByte, bModext); + + f_strcpy( szTmpPath, szDirPath); + f_pathAppend( szTmpPath, ucFileName); + + rc = Create( szTmpPath, uiIoFlags | F_IO_EXCL); + + if (rc == FERR_IO_DISK_FULL) + { + (void)NWDeleteFile( szTmpPath); + goto Exit; + } + + if ((rc == FERR_IO_PATH_NOT_FOUND) || (rc == FERR_IO_INVALID_PASSWORD)) + { + goto Exit; + } + } while ((rc != FERR_OK) && (uiCount++ < F_IO_MAX_CREATION_TRIES)); + + // Check if the path was created + + if ((uiCount >= F_IO_MAX_CREATION_TRIES) && (rc != FERR_OK)) + { + rc = RC_SET( FERR_IO_PATH_CREATE_FAILURE); + goto Exit; + } + + m_bFileOpened = TRUE; + m_bOpenedExclusive = (uiIoFlags & F_IO_SH_DENYRW) ? TRUE : FALSE; + + // Created file name needs to be returned. + + f_strcpy( pIoPath, szTmpPath); + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Open a file +****************************************************************************/ +RCODE F_FileHdlImp::Open( + const char * pIoPath, + FLMUINT uiIoFlags) +{ + RCODE rc = FERR_OK; + FLMUINT uiStartTime; + FLMUINT ui15Secs; + FLMUINT uiCurrTime; + + flmAssert( m_bFileOpened == FALSE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + // Loop on error open conditions. + + FLM_SECS_TO_TIMER_UNITS(15 /*seconds*/, ui15Secs); + uiStartTime = FLM_GET_TIMER(); + + do + { + if( RC_OK( rc = OpenOrCreate( pIoPath, uiIoFlags, FALSE))) + break; + + if( rc != FERR_IO_TOO_MANY_OPEN_FILES) + { + goto Exit; + } + + // If for some reason we cannot open the file, then + // try to close some other file handle in the list. + + if( RC_BAD( gv_FlmSysData.pFileHdlMgr->ReleaseOneAvail())) + { + goto Exit; + } + + f_sleep( 50); + uiCurrTime = FLM_GET_TIMER(); + } while( FLM_ELAPSED_TIME( uiCurrTime, uiStartTime) < ui15Secs); + + if ( RC_BAD(rc) ) + { + goto Exit; + } + + m_bFileOpened = TRUE; + m_uiCurrentPos = 0; + m_bOpenedReadOnly = (uiIoFlags & F_IO_RDONLY) ? TRUE : FALSE; + m_bOpenedExclusive = (uiIoFlags & F_IO_SH_DENYRW) ? TRUE : FALSE; + +Exit: + + return( rc); +} + + +/**************************************************************************** +Desc: Close a file +****************************************************************************/ +RCODE F_FileHdlImp::Close() +{ + LONG unused; + FLMBOOL bDeleteAllowed = TRUE; + RCODE rc = FERR_OK; + + if( !m_bFileOpened) + { + goto Exit; + } + + if( RC_BAD( rc = GET_FS_ERROR())) + { + bDeleteAllowed = FALSE; + } + + if (m_bNSS) + { + if (m_bNSSFileOpen) + { + (void)gv_zCloseFunc( m_NssKey); + m_bNSSFileOpen = FALSE; + } + } + else + { + // Revoke the file handle rights and close the file + // (signified by passing 2 for the QueryFlag parameter). + // If this call fails and returns a 255 error, it may + // indicate that the FILESYS.NLM being used on the server + // does not implement option 2 for the QueryFlag parameter. + // In this case, we will default to our old behavior + // and simply call CloseFile. This, potentially, will + // not free all of the lock objects and could result in + // a memory leak in filesys.nlm. However, we want to + // at least make sure that there is a corresponding + // RevokeFileHandleRights or CloseFile call for every + // file open / create call. + + if( RevokeFileHandleRights( 0, 1, + m_lFileHandle, 2, m_lOpenAttr & 0x0000000F, &unused) == 0xFF) + { + (void)CloseFile( 0, 1, m_lFileHandle); + } + } + + m_lOpenAttr = 0; + m_lFileHandle = -1; + m_bFileOpened = m_bOpenedReadOnly = m_bOpenedExclusive = FALSE; + + if( m_bDeleteOnClose) + { + if( bDeleteAllowed) + { + if (m_bNSS) + { + (void)gv_zDeleteFunc( gv_NssRootKey, 0, zNSPACE_LONG | zMODE_UTF8, + m_pszIoPath, zMATCH_ALL, 0); + } + else + { + (void)EraseFile( 0, 1, m_lVolumeID, 0, (BYTE *)m_pszIoPath, + m_lLNamePathCount, LONGNameSpace, 0); + } + } + + m_bDeleteOnClose = FALSE; + m_lLNamePathCount = 0; + } + + if( m_pszIoPath) + { + f_free( &m_pszIoPath); + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Read from a file +****************************************************************************/ +RCODE F_FileHdlImp::Read( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) +{ + RCODE rc; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if ( m_bDoDirectIO ) + { + rc = _DirectIORead( uiReadOffset, uiBytesToRead, pvBuffer, puiBytesReadRV ); + } + else + { + rc = _Read( uiReadOffset, uiBytesToRead, pvBuffer, puiBytesReadRV ); + } + +Exit: + + return( rc ); +} + + +/**************************************************************************** +Desc: Read from a file +****************************************************************************/ +RCODE F_FileHdlImp::_Read( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) +{ + RCODE rc = FERR_OK; + FCBType * fcb; + LONG lBytesRead; + LONG lErr; + + flmAssert( m_bFileOpened == TRUE); + + if( puiBytesReadRV) + { + *puiBytesReadRV = 0; + } + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (uiReadOffset == F_IO_CURRENT_POS) + uiReadOffset = m_uiCurrentPos; + + if (m_bNSS) + { + FLMINT lStatus; + FLMUINT nBytesRead; + + if ((lStatus = gv_zReadFunc( m_NssKey, 0, (FLMUINT64)uiReadOffset, + (FLMUINT)uiBytesToRead, pvBuffer, + &nBytesRead)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_READING_FILE); + goto Exit; + } + + if( puiBytesReadRV) + { + *puiBytesReadRV = (FLMUINT)nBytesRead; + } + + if ((FLMUINT)nBytesRead < uiBytesToRead) + { + rc = RC_SET( FERR_IO_END_OF_FILE); + } + m_uiCurrentPos = uiReadOffset + (FLMUINT)nBytesRead; + } + else + { + lErr = MapFileHandleToFCB( m_lFileHandle, &fcb ); + if ( lErr != 0 ) + { + rc = MapNWtoFlaimError( lErr, FERR_SETTING_UP_FOR_READ); + goto Exit; + } + lErr = ReadFile( fcb->Station, m_lFileHandle, uiReadOffset, + uiBytesToRead, &lBytesRead, pvBuffer); + if ( lErr == 0 ) + { + if( puiBytesReadRV) + { + *puiBytesReadRV = (FLMUINT) lBytesRead; + } + + if (lBytesRead < (LONG)uiBytesToRead) + { + rc = RC_SET( FERR_IO_END_OF_FILE); + } + m_uiCurrentPos = uiReadOffset + lBytesRead; + } + else + { + rc = MapNWtoFlaimError(lErr, FERR_READING_FILE); + } + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Returns m_uiCurrentPos +****************************************************************************/ +RCODE F_FileHdlImp::Tell( + FLMUINT * puiOffset) +{ + RCODE rc; + + if( RC_OK( rc = GET_FS_ERROR())) + { + *puiOffset = m_uiCurrentPos; + } + + return( rc); +} + +/**************************************************************************** +Desc: Calls the Direct IO-style read routine +Note: Where possible, the caller should attempt to read on sector + boundaries and full sectors. This routine will do the + necessary work if this is not done, but it will be less + efficient. +****************************************************************************/ +RCODE F_FileHdlImp::_DirectIORead( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) +{ + RCODE rc = FERR_OK; + FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; + LONG lStartSector; + LONG lSectorCount; + LONG lResult; + BYTE ucSectorBuf [NLM_SECTOR_SIZE]; + FLMUINT uiBytesToCopy; + FLMUINT uiSectorOffset; + FLMUINT uiTotal; + FLMINT lStatus; + + flmAssert( m_bFileOpened == TRUE); + + if( puiBytesReadRV) + { + *puiBytesReadRV = 0; + } + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (uiReadOffset == F_IO_CURRENT_POS) + uiReadOffset = m_uiCurrentPos; + + /* Calculate the starting sector. */ + + lStartSector = uiReadOffset / NLM_SECTOR_SIZE; + + /* + See if the offset is on a sector boundary. If not, we must read + into the local sector buffer and then copy into the buffer. + We must also read into the local buffer if our read size is less + than the sector size. + */ + + if ((uiReadOffset % NLM_SECTOR_SIZE != 0) || + (uiBytesToRead < NLM_SECTOR_SIZE)) + { + if (m_bNSS) + { + if ((lStatus = gv_zDIOReadFunc( m_NssKey, + (FLMUINT64)lStartSector, 1, + (FLMUINT)0, NULL, ucSectorBuf)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + else + { + lResult = DirectReadFile( + 0, + m_lFileHandle, + lStartSector, + 1, + ucSectorBuf + ); + if (lResult != 0) + { + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + + /* Copy the part of the sector that was requested into the buffer. */ + + uiSectorOffset = uiReadOffset % NLM_SECTOR_SIZE; + + if ((uiBytesToCopy = uiBytesToRead) > NLM_SECTOR_SIZE - uiSectorOffset) + uiBytesToCopy = NLM_SECTOR_SIZE - uiSectorOffset; + f_memcpy( pucBuffer, &ucSectorBuf [uiSectorOffset], uiBytesToCopy); + pucBuffer += uiBytesToCopy; + uiBytesToRead -= (FLMUINT)uiBytesToCopy; + m_uiCurrentPos += (FLMUINT)uiBytesToCopy; + + if( puiBytesReadRV) + { + (*puiBytesReadRV) += (FLMUINT)uiBytesToCopy; + } + + /* See if we got everything we wanted to with this read. */ + + if (!uiBytesToRead) + goto Exit; + + /* Go to the next sector boundary */ + + lStartSector++; + } + + /* + At this point, we are poised to read on a sector boundary. See if we + have at least one full sector to read. If so, we can read it directly + into the provided buffer. If not, we must use the temporary sector + buffer. + */ + + if (uiBytesToRead >= NLM_SECTOR_SIZE) + { + lSectorCount = (LONG)(uiBytesToRead / NLM_SECTOR_SIZE); +Try_Read: + if (m_bNSS) + { + if ((lStatus = gv_zDIOReadFunc( m_NssKey, + (FLMUINT64)lStartSector, + (FLMUINT)lSectorCount, + (FLMUINT)0, NULL, pucBuffer)) != zOK) + { + if ((lStatus == zERR_END_OF_FILE || lStatus == zERR_BEYOND_EOF) && + (lSectorCount > 1)) + { + + // See if we can read one less sector. We will return + // FERR_IO_END_OF_FILE in this case. + + lSectorCount--; + rc = RC_SET( FERR_IO_END_OF_FILE); + goto Try_Read; + } + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + else + { + lResult = DirectReadFile( + 0, + m_lFileHandle, + lStartSector, + lSectorCount, + pucBuffer + ); + if (lResult != 0) + { + if ((lResult == DFSOperationBeyondEndOfFile) && + (lSectorCount > 1)) + { + + // See if we can read one less sector. We will return + // FERR_IO_END_OF_FILE in this case. + + lSectorCount--; + rc = RC_SET( FERR_IO_END_OF_FILE); + goto Try_Read; + } + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + uiTotal = (FLMUINT)(lSectorCount * NLM_SECTOR_SIZE); + pucBuffer += uiTotal; + m_uiCurrentPos += uiTotal; + + if( puiBytesReadRV) + { + (*puiBytesReadRV) += uiTotal; + } + uiBytesToRead -= uiTotal; + + /* + See if we got everything we wanted to or could with this read. + */ + + if ((!uiBytesToRead) || (rc == FERR_IO_END_OF_FILE)) + goto Exit; + + /* Go to the next sector after the ones we just read. */ + + lStartSector += lSectorCount; + } + + /* + At this point, we have less than a sector's worth to read, so we must + read it into a local buffer. + */ + + if (m_bNSS) + { + if ((lStatus = gv_zDIOReadFunc( m_NssKey, + (FLMUINT64)lStartSector, 1, + (FLMUINT)0, NULL, ucSectorBuf)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + else + { + lResult = DirectReadFile( + 0, + m_lFileHandle, + lStartSector, + 1, + ucSectorBuf + ); + if (lResult != 0) + { + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + + /* Copy the part of the sector that was requested into the buffer. */ + + m_uiCurrentPos += uiBytesToRead; + + if( puiBytesReadRV) + { + (*puiBytesReadRV) += uiBytesToRead; + } + + f_memcpy( pucBuffer, ucSectorBuf, uiBytesToRead); + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Might call the direct IO routine in the future +Note: This function assumes that the pvBuffer that is passed in is + a multiple of a sector size (512 bytes). +****************************************************************************/ +RCODE F_FileHdlImp::SectorRead( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) +{ + RCODE rc = FERR_OK; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if ( m_bDoDirectIO ) + { + rc = _DirectIOSectorRead( uiReadOffset, uiBytesToRead, + pvBuffer, puiBytesReadRV); + } + else + { + rc = _Read( uiReadOffset, uiBytesToRead, pvBuffer, puiBytesReadRV); + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Calls the direct IO Read routine +Note: This function assumes that the pvBuffer that is passed in is + a multiple of a sector size (512 bytes). +****************************************************************************/ +RCODE F_FileHdlImp::_DirectIOSectorRead( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) +{ + RCODE rc = FERR_OK; + LONG lStartSector; + LONG lSectorCount; + LONG lResult; + FLMINT lStatus; + + flmAssert( m_bFileOpened == TRUE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (uiReadOffset == F_IO_CURRENT_POS) + uiReadOffset = m_uiCurrentPos; + + if (uiReadOffset % NLM_SECTOR_SIZE != 0) + { + rc = _Read( uiReadOffset, uiBytesToRead, pvBuffer, puiBytesReadRV); + goto Exit; + } + + /* Calculate the starting sector. */ + + lStartSector = uiReadOffset / NLM_SECTOR_SIZE; + lSectorCount = (LONG)(uiBytesToRead / NLM_SECTOR_SIZE); + if (uiBytesToRead % NLM_SECTOR_SIZE != 0) + lSectorCount++; + +Try_Read: + if (m_bNSS) + { + if ((lStatus = gv_zDIOReadFunc( m_NssKey, + (FLMUINT64)lStartSector, + (FLMUINT)lSectorCount, + (FLMUINT)0, NULL, pvBuffer)) != zOK) + { + if ((lStatus == zERR_END_OF_FILE || lStatus == zERR_BEYOND_EOF) && + (lSectorCount > 1)) + { + + // See if we can read one less sector. We will return + // FERR_IO_END_OF_FILE in this case. + + lSectorCount--; + uiBytesToRead = (FLMUINT)(lSectorCount * NLM_SECTOR_SIZE); + rc = RC_SET( FERR_IO_END_OF_FILE); + goto Try_Read; + } + uiBytesToRead = 0; + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + else + { + lResult = DirectReadFile( 0, m_lFileHandle, + lStartSector, lSectorCount,(BYTE *)pvBuffer); + if (lResult != 0) + { + if ((lResult == DFSOperationBeyondEndOfFile) && + (lSectorCount > 1)) + { + // See if we can read one less sector. We will return + // FERR_IO_END_OF_FILE in this case. + + lSectorCount--; + uiBytesToRead = (FLMUINT)(lSectorCount * NLM_SECTOR_SIZE); + rc = RC_SET( FERR_IO_END_OF_FILE); + goto Try_Read; + } + uiBytesToRead = 0; + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + m_uiCurrentPos += uiBytesToRead; + +Exit: + + if( puiBytesReadRV) + { + *puiBytesReadRV = uiBytesToRead; + } + + return( rc); +} + + +/**************************************************************************** +Desc: Sets current position of file. +****************************************************************************/ +RCODE F_FileHdlImp::Seek( + FLMUINT uiOffset, + FLMINT iWhence, + FLMUINT * puiNewOffset) +{ + RCODE rc = FERR_OK; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + switch (iWhence) + { + case F_IO_SEEK_CUR: + m_uiCurrentPos += uiOffset; + break; + case F_IO_SEEK_SET: + m_uiCurrentPos = uiOffset; + break; + case F_IO_SEEK_END: + rc = Size( &m_uiCurrentPos ); + if( rc) + { + goto Exit; + } + break; + default: + rc = RC_SET( FERR_NOT_IMPLEMENTED); + goto Exit; + } + *puiNewOffset = m_uiCurrentPos; +Exit: + return( rc); +} + +/**************************************************************************** +Desc: Return the size of the file +****************************************************************************/ +RCODE F_FileHdlImp::Size( + FLMUINT * puiSize) +{ + LONG lErr; + LONG lSize; + RCODE rc = FERR_OK; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (m_bNSS) + { + FLMINT lStatus; + zInfo_s Info; + + if ((lStatus = gv_zGetInfoFunc( m_NssKey, + zGET_STORAGE_USED, + sizeof( Info), zINFO_VERSION_A, + &Info)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_GETTING_FILE_INFO); + goto Exit; + } + flmAssert( Info.infoVersion == zINFO_VERSION_A); + *puiSize = (FLMUINT)Info.std.logicalEOF; + } + else + { + lErr = GetFileSize( 0, m_lFileHandle, &lSize); + if ( lErr != 0 ) + { + rc = MapNWtoFlaimError( lErr, FERR_GETTING_FILE_SIZE); + } + *puiSize = (FLMUINT)lSize; + } + +Exit: + + return( rc ); +} + +/**************************************************************************** +Desc: Truncate the file to the indicated size +WARNING: Direct IO methods are calling this method. Make sure that all changes + to this method work in direct IO mode. +****************************************************************************/ +RCODE F_FileHdlImp::Truncate( + FLMUINT uiSize) +{ + LONG lErr; + RCODE rc = FERR_OK; + + flmAssert( m_bFileOpened == TRUE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (m_bNSS) + { + FLMINT lStatus; + + if ((lStatus = gv_zSetEOFFunc( m_NssKey, 0, (FLMUINT64)uiSize, + zSETSIZE_NON_SPARSE_FILE | + zSETSIZE_NO_ZERO_FILL | + zSETSIZE_UNDO_ON_ERR)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_TRUNCATING_FILE); + goto Exit; + } + } + else + { + if ((lErr = SetFileSize( + 0, + m_lFileHandle, + uiSize, + TRUE // Return freed sectors to the OS + )) != 0) + { + rc = MapNWtoFlaimError( lErr, FERR_TRUNCATING_FILE); + goto Exit; + } + } + if (m_uiCurrentPos > uiSize) + { + m_uiCurrentPos = uiSize; + } +Exit: + return( rc); +} + +/**************************************************************************** +Desc: Write to a file +****************************************************************************/ +RCODE F_FileHdlImp::Write( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT * puiBytesWrittenRV) +{ + RCODE rc = FERR_OK; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if( m_bDoDirectIO) + { + rc = _DirectIOWrite( uiWriteOffset, uiBytesToWrite, + pvBuffer, puiBytesWrittenRV); + } + else + { + rc = _Write( uiWriteOffset, uiBytesToWrite, + pvBuffer, puiBytesWrittenRV); + } + +Exit: + + return( rc ); +} + + +/**************************************************************************** +Desc: Write to a file +****************************************************************************/ +RCODE F_FileHdlImp::_Write( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT * puiBytesWrittenRV) +{ + RCODE rc = FERR_OK; + LONG lErr; + FCBType * fcb; + + flmAssert( m_bFileOpened == TRUE); + + *puiBytesWrittenRV = 0; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (uiWriteOffset == F_IO_CURRENT_POS) + { + uiWriteOffset = m_uiCurrentPos; + } + else + { + m_uiCurrentPos = uiWriteOffset; + } + + if( m_bNSS) + { + FLMINT lStatus; + FLMUINT nBytesWritten; + + if( (lStatus = gv_zWriteFunc( m_NssKey, 0, (FLMUINT64)uiWriteOffset, + (FLMUINT)uiBytesToWrite, pvBuffer, &nBytesWritten)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_WRITING_FILE); + goto Exit; + } + + if( nBytesWritten != (FLMUINT)uiBytesToWrite) + { + rc = RC_SET( FERR_IO_DISK_FULL); + goto Exit; + } + } + else + { + if( (lErr = MapFileHandleToFCB( m_lFileHandle, &fcb )) != 0) + { + rc = MapNWtoFlaimError( lErr, FERR_SETTING_UP_FOR_WRITE); + goto Exit; + } + + if( (lErr = WriteFile( fcb->Station, m_lFileHandle, uiWriteOffset, + uiBytesToWrite, (void *)pvBuffer)) != 0) + { + rc = MapNWtoFlaimError( lErr, FERR_WRITING_FILE); + goto Exit; + } + } + + *puiBytesWrittenRV = uiBytesToWrite; + m_uiCurrentPos = uiWriteOffset + uiBytesToWrite; + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Calls the direct IO Write routine. +****************************************************************************/ +RCODE F_FileHdlImp::_DirectIOWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT * puiBytesWrittenRV) +{ + RCODE rc = FERR_OK; + FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; + LONG lStartSector; + LONG lSectorCount; + LONG lResult; + BYTE ucSectorBuf[ NLM_SECTOR_SIZE]; + FLMUINT uiBytesToCopy; + FLMUINT uiSectorOffset; + FLMUINT uiTotal; + FLMINT lStatus; + + flmAssert( m_bFileOpened == TRUE); + + *puiBytesWrittenRV = 0; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if( uiWriteOffset == F_IO_CURRENT_POS) + { + uiWriteOffset = m_uiCurrentPos; + } + else + { + m_uiCurrentPos = uiWriteOffset; + } + + // Calculate the starting sector + + lStartSector = uiWriteOffset / NLM_SECTOR_SIZE; + + + // See if the offset is on a sector boundary. If not, we must first read + // the sector into memory, overwrite it with data from the input + // buffer and write it back out again. + + if( (uiWriteOffset % NLM_SECTOR_SIZE != 0) || + (uiBytesToWrite < NLM_SECTOR_SIZE)) + { + if( m_bNSS) + { + if( (lStatus = gv_zDIOReadFunc( m_NssKey, + (FLMUINT64)lStartSector, + (FLMUINT)1, (FLMUINT)0, NULL, ucSectorBuf)) != zOK) + { + if (lStatus == zERR_END_OF_FILE || lStatus == zERR_BEYOND_EOF) + { + f_memset( ucSectorBuf, 0, sizeof( ucSectorBuf)); + + // Expand the file + + if( RC_BAD( rc = Expand( lStartSector, 1))) + { + goto Exit; + } + } + else + { + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + } + else + { + lResult = DirectReadFile( 0, m_lFileHandle, lStartSector, + 1, ucSectorBuf); + + if( lResult == DFSHoleInFileError || + lResult == DFSOperationBeyondEndOfFile ) + { + f_memset( ucSectorBuf, 0, sizeof( ucSectorBuf)); + + // Expand the file + + if( RC_BAD( rc = Expand( lStartSector, 1))) + { + goto Exit; + } + } + else if( lResult != 0) + { + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + + // Copy the part of the buffer that is being written back into + // the sector buffer. + + uiSectorOffset = uiWriteOffset % NLM_SECTOR_SIZE; + + if( (uiBytesToCopy = uiBytesToWrite) > NLM_SECTOR_SIZE - uiSectorOffset) + { + uiBytesToCopy = NLM_SECTOR_SIZE - uiSectorOffset; + } + + f_memcpy( &ucSectorBuf [uiSectorOffset], pucBuffer, uiBytesToCopy); + pucBuffer += uiBytesToCopy; + uiBytesToWrite -= (FLMUINT)uiBytesToCopy; + m_uiCurrentPos += (FLMUINT)uiBytesToCopy; + (*puiBytesWrittenRV) += (FLMUINT)uiBytesToCopy; + + // Write the sector buffer back out + + if( RC_BAD( rc = WriteSectors( &ucSectorBuf [0], lStartSector, 1, NULL))) + { + goto Exit; + } + + // See if we wrote everything we wanted to with this write + + if (!uiBytesToWrite) + { + goto Exit; + } + + // Go to the next sector boundary + + lStartSector++; + } + + // At this point, we are poised to write on a sector boundary. See if we + // have at least one full sector to write. If so, we can write it directly + // from the provided buffer. If not, we must use the temporary sector + // buffer. + + if( uiBytesToWrite >= NLM_SECTOR_SIZE) + { + lSectorCount = (LONG)(uiBytesToWrite / NLM_SECTOR_SIZE); + + if( RC_BAD( rc = WriteSectors( (void *)pucBuffer, lStartSector, + lSectorCount, NULL))) + { + goto Exit; + } + + uiTotal = (FLMUINT)(lSectorCount * NLM_SECTOR_SIZE); + pucBuffer += uiTotal; + m_uiCurrentPos += uiTotal; + (*puiBytesWrittenRV) += uiTotal; + uiBytesToWrite -= uiTotal; + + // See if we wrote everything we wanted to with this write + + if( !uiBytesToWrite) + { + goto Exit; + } + + // Go to the next sector after the ones we just wrote + + lStartSector += lSectorCount; + } + + // At this point, we have less than a sector's worth to write, so we must + // first read the sector from disk, alter it, and then write it back out. + + if( m_bNSS) + { + if( (lStatus = gv_zDIOReadFunc( m_NssKey, (FLMUINT64)lStartSector, + (FLMUINT)1, (FLMUINT)0, NULL, ucSectorBuf)) != zOK) + { + if( lStatus == zERR_END_OF_FILE || lStatus == zERR_BEYOND_EOF) + { + f_memset( ucSectorBuf, 0, sizeof( ucSectorBuf)); + + // Expand the file + + if( RC_BAD( rc = Expand( lStartSector, 1))) + { + goto Exit; + } + } + else + { + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + } + else + { + lResult = DirectReadFile( 0, m_lFileHandle, lStartSector, + 1, ucSectorBuf); + + if( lResult == DFSHoleInFileError) + { + f_memset( ucSectorBuf, 0, sizeof( ucSectorBuf)); + + // Expand the file + + if( RC_BAD( rc = Expand( lStartSector, 1))) + { + goto Exit; + } + } + else if( lResult != 0) + { + rc = DfsMapError( lResult, FERR_DIRECT_READING_FILE); + goto Exit; + } + } + + // Copy the rest of the output buffer into the sector buffer + + f_memcpy( ucSectorBuf, pucBuffer, uiBytesToWrite); + + // Write the sector back to disk + + if( RC_BAD( rc = WriteSectors( &ucSectorBuf [0], lStartSector, 1, NULL))) + { + goto Exit; + } + + m_uiCurrentPos += uiBytesToWrite; + (*puiBytesWrittenRV) += uiBytesToWrite; + +Exit: + + return( rc); +} + +/*************************************************************************** +Desc: Expand a file for writing. +***************************************************************************/ +RCODE F_FileHdlImp::Expand( + LONG lStartSector, + LONG lSectorsToAlloc) +{ + RCODE rc = FERR_OK; + LONG lResult; + LONG lBlockNumber; + LONG lStartBlockNumber; + LONG lNumBlocksToAlloc; + LONG lNumBlocksAllocated; + LONG lMinToAlloc; + LONG lLastBlockNumber; + LONG lTotalToAlloc; + LONG lExtendSize; + FLMUINT uiFileSize; + FLMUINT uiRequestedExtendSize = m_uiExtendSize; + FLMBOOL bVerifyFileSize = FALSE; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + // If the requested extend size is the "special" value of ~0, + // we will set the requested size to 0, so that we will use the + // minimum default below. This allows us to somewhat emulate what + // the Window's code does. + + if( uiRequestedExtendSize == (FLMUINT)(~0)) + { + uiRequestedExtendSize = 0; + } + + if( m_bNSS) + { + lStartBlockNumber = lStartSector / (65536 / NLM_SECTOR_SIZE); + lLastBlockNumber = (lStartSector + lSectorsToAlloc) / (65536 / NLM_SECTOR_SIZE); + lExtendSize = uiRequestedExtendSize / 65536; + } + else + { + lStartBlockNumber = lStartSector / m_lSectorsPerBlock; + lLastBlockNumber = (lStartSector + lSectorsToAlloc) / m_lSectorsPerBlock; + lExtendSize = uiRequestedExtendSize / (m_lSectorsPerBlock * NLM_SECTOR_SIZE); + } + + // Last block number better be greater than or equal to + // start block number. + + flmAssert( lLastBlockNumber >= lStartBlockNumber); + lMinToAlloc = (lLastBlockNumber - lStartBlockNumber) + 1; + + if( lExtendSize < 5) + { + lExtendSize = 5; + } + + // Allocate up to lExtendSize blocks at a time - hopefully this will be + // more efficient. + + if( lMinToAlloc < lExtendSize) + { + lTotalToAlloc = lExtendSize; + } + else if( lMinToAlloc % lExtendSize == 0) + { + lTotalToAlloc = lMinToAlloc; + } + else + { + // Keep the total blocks to allocate a multiple of lExtendSize. + + lTotalToAlloc = lMinToAlloc - + (lMinToAlloc % lExtendSize) + lExtendSize; + } + + lNumBlocksToAlloc = lTotalToAlloc; + lBlockNumber = lStartBlockNumber; + lNumBlocksAllocated = 0; + + // Must not go over maximum file size. + + if( lStartBlockNumber + lTotalToAlloc > m_lMaxBlocks) + { + lNumBlocksToAlloc = lTotalToAlloc = m_lMaxBlocks - lStartBlockNumber; + + if( lTotalToAlloc < lMinToAlloc) + { + rc = RC_SET( FERR_IO_DISK_FULL); + goto Exit; + } + } + + if( m_bNSS) + { + FLMINT lStatus; + + for( ;;) + { + if( (lStatus = gv_zSetEOFFunc( m_NssKey, 0, + (FLMUINT64)lBlockNumber * 65536 + lNumBlocksToAlloc * 65536, + zSETSIZE_NO_ZERO_FILL | zSETSIZE_NON_SPARSE_FILE)) != zOK) + { + if( lStatus == zERR_OUT_OF_SPACE) + { + if( lNumBlocksToAlloc > lMinToAlloc) + { + lNumBlocksToAlloc--; + continue; + } + } + + rc = MapNSSToFlaimError( lStatus, FERR_EXPANDING_FILE); + goto Exit; + } + else + { + break; + } + } + } + else + { + for (;;) + { + lResult = ExpandFileInContiguousBlocks( 0, m_lFileHandle, + lBlockNumber, lNumBlocksToAlloc, -1, -1); + + // If we couldn't allocate space, see if we can free some of + // the limbo space on the volume. + + if( lResult == DFSInsufficientSpace || lResult == DFSBoundryError) + { + // May not have been able to get contiguous space for + // multiple blocks. If we were asking for more than + // one, reduce the number we are asking for and try + // again. + + if( lNumBlocksToAlloc > 1) + { + lNumBlocksToAlloc--; + continue; + } + + // If we could not even get one block, it is time to + // try and free some limbo space. + + lResult = FreeLimboVolumeSpace( (LONG)m_lVolumeID, 1); + if( lResult == DFSInsufficientLimboFileSpace) + { + // It is not an error to be out of space if + // we successfully allocated at least the minimum + // number of blocks needed. + + if( lNumBlocksAllocated >= lMinToAlloc) + { + break; + } + else + { + rc = RC_SET( FERR_IO_DISK_FULL); + goto Exit; + } + } + + continue; + } + else if( lResult == DFSOverlapError) + { + lResult = 0; + bVerifyFileSize = TRUE; + + // If lNumBlocksToAlloc is greater than one, we + // don't know exactly where the hole is, so we need + // to try filling exactly one block right where + // we are at. + + // If lNumBlocksToAlloc is exactly one, we know that + // we have a block right where we are at, so we let + // the code fall through as if the expand had + // succeeded. + + if( lNumBlocksToAlloc > 1) + { + // If we have an overlap, try getting one block at + // the current block number - need to make sure this + // is not where the hole is at. + + lNumBlocksToAlloc = 1; + continue; + } + } + else if (lResult != 0) + { + rc = DfsMapError( lResult, FERR_EXPANDING_FILE); + goto Exit; + } + + lNumBlocksAllocated += lNumBlocksToAlloc; + lBlockNumber += lNumBlocksToAlloc; + + if( lNumBlocksAllocated >= lTotalToAlloc) + { + break; + } + else if( lNumBlocksToAlloc > lTotalToAlloc - lNumBlocksAllocated) + { + lNumBlocksToAlloc = lTotalToAlloc - lNumBlocksAllocated; + } + } + + // If bVerifyFileSize is TRUE, we had an overlap error, which means + // that we may have had a hole in the file. In that case, we + // do NOT want to truncate the file to an incorrect size, so we + // get the current file size to make sure we are not reducing it + // down inappropriately. NOTE: This is not foolproof - if we have + // a hole that is exactly the size we asked for, we will not verify + // the file size. + + uiFileSize = (FLMUINT)(lStartBlockNumber + lNumBlocksAllocated) * + (FLMUINT)m_lSectorsPerBlock * (FLMUINT)NLM_SECTOR_SIZE; + + if( bVerifyFileSize) + { + LONG lCurrFileSize; + + lResult = GetFileSize( 0, m_lFileHandle, &lCurrFileSize); + + if( lResult != DFSNormalCompletion) + { + rc = DfsMapError( lResult, FERR_GETTING_FILE_SIZE); + goto Exit; + } + + if( (FLMUINT)lCurrFileSize > uiFileSize) + { + uiFileSize = (FLMUINT)lCurrFileSize; + } + } + + // This call of SetFileSize is done to force the directory entry file size + // to account for the newly allocated blocks. It also forces the directory + // entry to be updated on disk. If we didn't do this here, the directory + // entry's file size on disk would not account for this block. + // Thus, if we crashed after writing data to this + // newly allocated block, we would lose the data in the block. + + lResult = SetFileSize( 0, m_lFileHandle, uiFileSize, FALSE); + + if( lResult != DFSNormalCompletion) + { + rc = DfsMapError( lResult, FERR_TRUNCATING_FILE); + goto Exit; + } + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Calls the direct IO Write routine. Handles both asynchronous writes + and synchronous writes. +****************************************************************************/ +RCODE F_FileHdlImp::WriteSectors( + void * pvBuffer, + LONG lStartSector, + LONG lSectorCount, + F_IOBuffer * pBufferObj, + FLMBOOL * pbDidAsync) +{ + RCODE rc = FERR_OK; + LONG lResult; + FLMBOOL bAlreadyExpanded = FALSE; + FLMINT lStatus; + FLMBOOL bMadePending; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + // Keep trying write until we succeed or get an error we can't deal with. + // Actually, this will NOT loop forever. At most, it will try twice - + // and then it is only when we get a hole in the file error. + + bMadePending = FALSE; + for (;;) + { + if (m_bNSS) + { + if( pBufferObj) + { + if (!bMadePending) + { + flmAssert( pbDidAsync); + pBufferObj->makePending(); + bMadePending = TRUE; + } + lStatus = gv_zDIOWriteFunc( m_NssKey, + (FLMUINT64)lStartSector, + (FLMUINT)lSectorCount, + (FLMUINT)pBufferObj, + nssDioCallback, + pvBuffer); + } + else + { + lStatus = gv_zDIOWriteFunc( m_NssKey, + (FLMUINT64)lStartSector, + (FLMUINT)lSectorCount, (FLMUINT)0, NULL, pvBuffer); + } + + // We may need to allocate space to do this write + + if (lStatus == zERR_END_OF_FILE || + lStatus == zERR_BEYOND_EOF || + lStatus == zERR_HOLE_IN_DIO_FILE) + { + if (bAlreadyExpanded) + { + flmAssert( 0); + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_WRITING_FILE); + goto Exit; + } + + // Expand the file + + if (RC_BAD( rc = Expand( lStartSector, lSectorCount))) + { + goto Exit; + } + bAlreadyExpanded = TRUE; + continue; + } + else if (lStatus != 0) + { + rc = MapNSSToFlaimError( lStatus, FERR_DIRECT_WRITING_FILE); + goto Exit; + } + else + { + if (pBufferObj) + { + *pbDidAsync = TRUE; + } + break; + } + } + else + { + LONG lSize; + FLMBOOL bNeedToWriteEOF; + + // Determine if this write will change the EOF. If so, pre-expand + // the file. + + lResult = GetFileSize( 0, m_lFileHandle, &lSize); + if (lResult != 0) + { + rc = MapNWtoFlaimError( lResult, FERR_GETTING_FILE_SIZE); + goto Exit; + } + + bNeedToWriteEOF = (lSize < (lStartSector + lSectorCount) * NLM_SECTOR_SIZE) + ? TRUE + : FALSE; + + if( pBufferObj) + { + if (!bMadePending) + { + flmAssert( pbDidAsync); + pBufferObj->makePending(); + bMadePending = TRUE; + } + + lResult = DirectWriteFileNoWait( 0, m_lFileHandle, + lStartSector,lSectorCount, + (BYTE *)pvBuffer, DirectIONoWaitCallBack, + (LONG)pBufferObj); + } + else + { + lResult = DirectWriteFile( 0, m_lFileHandle, + lStartSector, lSectorCount, (BYTE *)pvBuffer); + } + + // We may need to allocate space to do this write + + if( lResult == DFSHoleInFileError || + lResult == DFSOperationBeyondEndOfFile) + { + if( bAlreadyExpanded) + { + flmAssert( 0); + rc = DfsMapError( lResult, FERR_DIRECT_WRITING_FILE); + goto Exit; + } + + // Expand the file + + if( RC_BAD( rc = Expand( lStartSector, lSectorCount))) + { + goto Exit; + } + + bAlreadyExpanded = TRUE; + + // The Expand method forces the file EOF in the directory + // entry to be written to disk. + + bNeedToWriteEOF = FALSE; + continue; + } + else if (lResult != 0) + { + rc = DfsMapError( lResult, FERR_DIRECT_WRITING_FILE); + goto Exit; + } + else + { + if( pBufferObj) + { + *pbDidAsync = TRUE; + } + + // If bNeedToWriteEOF is TRUE, we need to force EOF to disk. + + if( bNeedToWriteEOF) + { + LONG lFileSizeInSectors; + LONG lExtraSectors; + + // Set the EOF to the nearest block boundary - so we don't + // have to do this very often. + + lFileSizeInSectors = lStartSector + lSectorCount; + lExtraSectors = lFileSizeInSectors % m_lSectorsPerBlock; + + if (lExtraSectors) + { + lFileSizeInSectors += (m_lSectorsPerBlock - lExtraSectors); + } + + if ((lResult = SetFileSize( 0, m_lFileHandle, + (FLMUINT)lFileSizeInSectors * NLM_SECTOR_SIZE, + FALSE)) != 0) + { + rc = DfsMapError( lResult, FERR_TRUNCATING_FILE); + goto Exit; + } + } + + break; + } + } + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Legacy async I/O completion callback +****************************************************************************/ +FSTATIC void DirectIONoWaitCallBack( + LONG unknownAlwaysZero, + LONG callbackData, + LONG completionCode) +{ + F_IOBuffer * pIOBuffer = (F_IOBuffer *)callbackData; + + F_UNREFERENCED_PARM( unknownAlwaysZero); + + pIOBuffer->signalComplete( + (RCODE)(completionCode == DFSNormalCompletion + ? FERR_OK + : DfsMapError( completionCode, FERR_DIRECT_WRITING_FILE))); +} + +/**************************************************************************** +Desc: NSS async I/O completion callback +****************************************************************************/ +FSTATIC void nssDioCallback( + FLMUINT reserved, + FLMUINT callbackData, + FLMUINT completionCode) +{ + F_IOBuffer * pIOBuffer = (F_IOBuffer *)callbackData; + + F_UNREFERENCED_PARM( reserved); + + pIOBuffer->signalComplete( + (RCODE)(completionCode == zOK + ? FERR_OK + : MapNSSToFlaimError( completionCode, FERR_DIRECT_WRITING_FILE))); +} + +/**************************************************************************** +Desc: Might call the direct IO Write routine in the future +Note: This routine assumes that the size of pvBuffer is a multiple of + sector size (512 bytes) and can be used to write out full + sectors. Even if uiBytesToWrite does not account for full sectors, + data from the buffer will still be written out - a partial sector + on disk will not be preserved. +****************************************************************************/ +RCODE F_FileHdlImp::SectorWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT uiBufferSize, + F_IOBuffer * pBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill) +{ + RCODE rc = FERR_OK; + + F_UNREFERENCED_PARM( uiBufferSize); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if ( m_bDoDirectIO) + { + rc = _DirectIOSectorWrite( uiWriteOffset, uiBytesToWrite, pvBuffer, + pBufferObj, puiBytesWrittenRV, bZeroFill); + } + else + { + flmAssert( pBufferObj == NULL); + rc = _Write( uiWriteOffset, uiBytesToWrite, pvBuffer, puiBytesWrittenRV); + } + +Exit: + + return( rc); +} + + +/**************************************************************************** +Desc: Calls the direct IO-style write routine. +Note: This routine assumes that the size of pvBuffer is a multiple of + sector size (512 bytes) and can be used to write out full + sectors. Even if uiBytesToWrite does not account for full sectors, + data from the buffer will still be written out - a partial sector + on disk will not be preserved. +****************************************************************************/ +RCODE F_FileHdlImp::_DirectIOSectorWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + F_IOBuffer * pBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill) +{ + RCODE rc = FERR_OK; + LONG lStartSector; + LONG lSectorCount; + FLMBOOL bDidAsync = FALSE; + + flmAssert( m_bFileOpened == TRUE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if (uiWriteOffset == F_IO_CURRENT_POS) + { + uiWriteOffset = m_uiCurrentPos; + } + else + { + m_uiCurrentPos = uiWriteOffset; + } + + if (uiWriteOffset % NLM_SECTOR_SIZE != 0) + { + rc = Write( uiWriteOffset, uiBytesToWrite, pvBuffer, + puiBytesWrittenRV); + goto Exit; + } + + // Calculate the starting sector and number of sectors to write + + lStartSector = uiWriteOffset / NLM_SECTOR_SIZE; + lSectorCount = (LONG)(uiBytesToWrite / NLM_SECTOR_SIZE); + if (uiBytesToWrite % NLM_SECTOR_SIZE != 0) + { + FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; + + lSectorCount++; + + if (bZeroFill) + { + // Zero out the part of the buffer that was not included in + // uiBytesToWrite - because it will still be written to disk. + + f_memset( &pucBuffer [uiBytesToWrite], 0, + (FLMUINT)(NLM_SECTOR_SIZE - (uiBytesToWrite % NLM_SECTOR_SIZE))); + } + } + + if( RC_BAD( rc = WriteSectors( (void *)pvBuffer, lStartSector, lSectorCount, + pBufferObj, &bDidAsync))) + { + goto Exit; + } + + m_uiCurrentPos += uiBytesToWrite; + + if( puiBytesWrittenRV) + { + *puiBytesWrittenRV = uiBytesToWrite; + } + +Exit: + + if( !bDidAsync && pBufferObj) + { + pBufferObj->notifyComplete( rc); + } + + return( rc); +} + +/**************************************************************************** +Desc: Determine if a file or directory exists +****************************************************************************/ +RCODE NWTestIfFileExists( + const char * pPath) +{ + RCODE rc = FERR_OK; + LONG unused; + FLMBYTE ucPseudoLNamePath[ F_PATH_MAX_SIZE + 1]; + FLMBYTE ucLNamePath[ F_PATH_MAX_SIZE]; + LONG lVolumeID; + LONG lPathID; + LONG lLNamePathCount; + LONG lDirectoryID; + LONG lErrorCode; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + f_strcpy( (char *)&ucPseudoLNamePath[1], pPath); + ucPseudoLNamePath[0] = (char)f_strlen( pPath); + + if( (lErrorCode = ConvertPathString( 0, 0, ucPseudoLNamePath, &lVolumeID, + &lPathID, ucLNamePath, &lLNamePathCount)) != 0) + { + goto Exit; + } + + if( (lErrorCode = MapPathToDirectoryNumber( 0, lVolumeID, 0, ucLNamePath, + lLNamePathCount, LONGNameSpace, &lDirectoryID, &unused)) != 0) + { + goto Exit; + } + +Exit: + + if( lErrorCode == 255 || lErrorCode == 156) + { + // Too many error codes map to 255, so we put in a special + // case check here + + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + } + else if( lErrorCode ) + { + rc = MapNWtoFlaimError( lErrorCode, FERR_CHECKING_FILE_EXISTENCE); + } + + return( rc); +} + +/**************************************************************************** +Desc: Delete a file +****************************************************************************/ +RCODE NWDeleteFile( + const char * pPath) +{ + RCODE rc = FERR_OK; + LONG lErrorCode; + char pszQualifiedPath[ F_PATH_MAX_SIZE]; + FLMBYTE ucLNamePath[ F_PATH_MAX_SIZE + 1]; + LONG lLNamePathCount; + LONG lVolumeID; + FLMBOOL bNssVolume = FALSE; + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + ConvertToQualifiedNWPath( pPath, pszQualifiedPath); + + if( (lErrorCode = ConvertPathToLNameFormat( pszQualifiedPath, &lVolumeID, + &bNssVolume, ucLNamePath, &lLNamePathCount)) != 0) + { + rc = MapNWtoFlaimError( lErrorCode, FERR_RENAMING_FILE); + goto Exit; + } + + if( gv_bNSSKeyInitialized && bNssVolume) + { + if( (lErrorCode = gv_zDeleteFunc( gv_NssRootKey, 0, + zNSPACE_LONG | zMODE_UTF8, + pszQualifiedPath, zMATCH_ALL, 0)) != zOK) + { + rc = MapNSSToFlaimError( lErrorCode, FERR_DELETING_FILE); + goto Exit; + } + } + else + { + if( (lErrorCode = EraseFile( 0, 1, lVolumeID, 0, ucLNamePath, + lLNamePathCount, LONGNameSpace, 0)) != 0) + { + // Too many error codes map to 255, so we put in a special + // case check here. + + if( lErrorCode == 255) + { + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + } + else + { + rc = MapNWtoFlaimError( lErrorCode, FERR_DELETING_FILE); + } + + goto Exit; + } + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Turn off the rename inhibit bit for a file in an NSS volume. +****************************************************************************/ +FSTATIC RCODE nssTurnOffRenameInhibit( + const char * pszFileName) +{ + RCODE rc = FERR_OK; + zInfo_s Info; + FLMINT64 NssKey; + FLMBOOL bFileOpened = FALSE; + FLMINT lStatus; + FLMUINT nOpenAttr; + + nOpenAttr = FlaimToNSSOpenFlags( (FLMUINT)(F_IO_RDWR | + F_IO_SH_DENYNONE), FALSE); + + if( (lStatus = gv_zOpenFunc( gv_NssRootKey, 1, zNSPACE_LONG | zMODE_UTF8, + pszFileName, nOpenAttr, &NssKey)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_OPENING_FILE); + goto Exit; + } + + bFileOpened = TRUE; + + // Get the file attributes. + + if( (lStatus = gv_zGetInfoFunc( NssKey, zGET_STD_INFO, sizeof( Info), + zINFO_VERSION_A, &Info)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_GETTING_FILE_INFO); + goto Exit; + } + + flmAssert( Info.infoVersion == zINFO_VERSION_A); + + // See if the rename inhibit bit is set. + + if( Info.std.fileAttributes & zFA_RENAME_INHIBIT) + { + // Turn bit off + + Info.std.fileAttributes = 0; + + // Specify which bits to modify - only rename inhibit in this case + + Info.std.fileAttributesModMask = zFA_RENAME_INHIBIT; + + if( (lStatus = gv_zModifyInfoFunc( NssKey, 0, zMOD_FILE_ATTRIBUTES, + sizeof( Info), zINFO_VERSION_A, &Info)) != zOK) + { + rc = MapNSSToFlaimError( lStatus, FERR_SETTING_FILE_INFO); + goto Exit; + } + } + +Exit: + + if( bFileOpened) + { + (void)gv_zCloseFunc( NssKey); + } + + return( rc); +} + +/**************************************************************************** +Desc: Rename a file +Notes: Currently, this function doesn't support moving the file from one + volume to another. (There is a CopyFileToFile function that could + be used to do the move.) The toolkit function does appear to + support moving (copy/delete) the file. + + This function does support renaming directories. +****************************************************************************/ +RCODE NWRenameFile( + const char * pOldFilePath, + const char * pNewFilePath) +{ + RCODE rc = FERR_OK; + LONG unused; + FLMBYTE ucOldLNamePath[ F_PATH_MAX_SIZE + 1]; + LONG lOldLNamePathCount; + FLMBYTE ucNewLNamePath[ F_PATH_MAX_SIZE + 1]; + LONG lNewLNamePathCount; + LONG lVolumeID; + LONG lErrorCode; + FLMBYTE ucPseudoLNamePath[ F_PATH_MAX_SIZE + 1]; + LONG lPathID; + LONG lIsFile; + FLMBOOL bIsDirectory; + struct ModifyStructure modifyStruct; + LONG lDirectoryID; + LONG lFileAttributes; + LONG lMatchBits; + FLMBOOL bNssVolume = + (FLMBOOL)(gv_zIsNSSVolumeFunc + ? (gv_zIsNSSVolumeFunc( (const char *)pOldFilePath) + ? TRUE + : FALSE) + : FALSE); + + if( RC_BAD( rc = GET_FS_ERROR())) + { + goto Exit; + } + + if( gv_bNSSKeyInitialized && bNssVolume) + { + FLMINT lStatus; + FLMBOOL bTurnedOffRenameInhibit = FALSE; + +Retry_Nss_Rename: + + if( (lStatus = gv_zRenameFunc( gv_NssRootKey, 0, + zNSPACE_LONG | zMODE_UTF8, pOldFilePath, zMATCH_ALL, + zNSPACE_LONG | zMODE_UTF8, pNewFilePath, 0)) != zOK) + { + if( lStatus == zERR_NO_RENAME_PRIVILEGE && !bTurnedOffRenameInhibit) + { + // Attempt to turn off rename inhibit. This isn't always the + // reason for zERR_NO_RENAME_PRIVILEGE, but it is one we + // definitely need to take care of. + + if( RC_BAD( rc = nssTurnOffRenameInhibit( pOldFilePath))) + { + goto Exit; + } + + bTurnedOffRenameInhibit = TRUE; + goto Retry_Nss_Rename; + } + + rc = MapNSSToFlaimError( lStatus, FERR_RENAMING_FILE); + goto Exit; + } + } + else + { + f_strcpy( (char *)&ucPseudoLNamePath[1], pOldFilePath); + ucPseudoLNamePath[0] = (char)f_strlen( (const char *)&ucPseudoLNamePath[1] ); + + if( (lErrorCode = ConvertPathString( 0, 0, ucPseudoLNamePath, &lVolumeID, + &lPathID, (BYTE *)ucOldLNamePath, &lOldLNamePathCount)) != 0) + { + goto Exit; + } + + if( (lErrorCode = MapPathToDirectoryNumber( 0, lVolumeID, 0, + (BYTE *)ucOldLNamePath, lOldLNamePathCount, LONGNameSpace, + &lDirectoryID, &lIsFile)) != 0) + { + goto Exit; + } + + if( lIsFile) + { + bIsDirectory = FALSE; + lMatchBits = 0; + } + else + { + bIsDirectory = TRUE; + lMatchBits = SUBDIRECTORY_BIT; + } + + f_strcpy( (char *)&ucPseudoLNamePath[1], pNewFilePath); + ucPseudoLNamePath[0] = (char)f_strlen( (const char *)&ucPseudoLNamePath[1]); + + if( (lErrorCode = ConvertPathString( 0, 0, ucPseudoLNamePath, &unused, + &lPathID, (BYTE *)ucNewLNamePath, &lNewLNamePathCount)) != 0) + { + goto Exit; + } + + { + struct DirectoryStructure * pFileInfo; + + if( (lErrorCode = VMGetDirectoryEntry( lVolumeID, + lDirectoryID & 0x00ffffff, &pFileInfo)) != 0) + { + goto Exit; + } + + lFileAttributes = pFileInfo->DFileAttributes; + } + + if( lFileAttributes & RENAME_INHIBIT_BIT ) + { + f_memset(&modifyStruct, 0, sizeof(modifyStruct)); + modifyStruct.MFileAttributesMask = RENAME_INHIBIT_BIT; + + if( (lErrorCode = ModifyDirectoryEntry( 0, 1, lVolumeID, 0, + (BYTE *)ucOldLNamePath, lOldLNamePathCount, LONGNameSpace, + lMatchBits, LONGNameSpace, &modifyStruct, + MFileAttributesBit, 0)) != 0) + { + goto Exit; + } + } + + lErrorCode = RenameEntry( 0, 1, lVolumeID, 0, ucOldLNamePath, + lOldLNamePathCount, LONGNameSpace, lMatchBits, + (BYTE)bIsDirectory ? 1 : 0, 0, ucNewLNamePath, lNewLNamePathCount, + TRUE, TRUE); + + if( lFileAttributes & RENAME_INHIBIT_BIT ) + { + FLMBYTE * pFileName; + + if( lErrorCode ) + { + pFileName = ucOldLNamePath; + lNewLNamePathCount = lOldLNamePathCount; + } + else + { + pFileName = ucNewLNamePath; + } + + // Turn the RENAME_INHIBIT_BIT back on + + f_memset(&modifyStruct, 0, sizeof(modifyStruct)); + modifyStruct.MFileAttributes = RENAME_INHIBIT_BIT; + modifyStruct.MFileAttributesMask = RENAME_INHIBIT_BIT; + + (void)ModifyDirectoryEntry( 0, 1, lVolumeID, 0, (BYTE *)pFileName, + lNewLNamePathCount, LONGNameSpace, lMatchBits, LONGNameSpace, + &modifyStruct, MFileAttributesBit, 0); + } + } + +Exit: + + if( !gv_bNSSKeyInitialized || !bNssVolume) + { + if( lErrorCode ) + { + // Too many error codes map to 255, so we put in a special + // case check here. + + if( lErrorCode == 255) + { + rc = RC_SET( FERR_IO_PATH_NOT_FOUND); + } + else + { + rc = MapNWtoFlaimError( lErrorCode, FERR_RENAMING_FILE); + } + } + } + + return( rc); +} + +/**************************************************************************** +Desc: Convert the given path to NetWare LName format. +Input: pPath = qualified netware path of the format: + volume:directory_1\...\directory_n\filename.ext +Output: plVolumeID = NetWare volume ID + pLNamePath = NetWare LName format path + + Netware expects paths to be in LName format: + ... + where is a one-byte length and is a path component. + + Example: 6SYSTEM4Fred + note that the 6 and 4 are binary, not ASCII + + plLNamePathCount = number of path components in pLNamePath +****************************************************************************/ +FSTATIC LONG ConvertPathToLNameFormat( + const char * pPath, + LONG * plVolumeID, + FLMBOOL * pbNssVolume, + FLMBYTE * pLNamePath, + LONG * plLNamePathCount) +{ + FLMBYTE ucPseudoLNamePath[ F_PATH_MAX_SIZE + 1]; + LONG lPathID; + LONG lErrorCode = 0; + + *pLNamePath = 0; + *plLNamePathCount = 0; + +#ifdef FLM_DEBUG + if( RC_BAD( GET_FS_ERROR())) + { + lErrorCode = 255; + goto Exit; + } +#endif + + *pbNssVolume = (FLMBOOL)(gv_zIsNSSVolumeFunc + ? (gv_zIsNSSVolumeFunc( (const char *)pPath) + ? TRUE + : FALSE) + : FALSE); + + if( gv_bNSSKeyInitialized && *pbNssVolume) + { + f_strcpy( (char *)pLNamePath, pPath); + *plLNamePathCount = 1; + } + else + { + f_strcpy( (char *)&ucPseudoLNamePath[1], pPath); + ucPseudoLNamePath[0] = (FLMBYTE)f_strlen( (const char *)&ucPseudoLNamePath[1]); + + if( (lErrorCode = ConvertPathString( 0, 0, ucPseudoLNamePath, plVolumeID, + &lPathID, (BYTE *)pLNamePath, plLNamePathCount)) != 0) + { + goto Exit; + } + } + +Exit: + + return( lErrorCode ); +} + +/**************************************************************************** +Desc: Convert the given path to a NetWare format. The format isn't + critical, it just needs to be consistent. See below for a + description of the format chosen. +Input: pInputPath = a path to a file +Output: pszQualifiedPath = qualified netware path of the format: + volume:directory_1\...\directory_n\filename.ext + + If no volume is given, "SYS:" is the default. +****************************************************************************/ +FSTATIC void ConvertToQualifiedNWPath( + const char * pInputPath, + char * pszQualifiedPath) +{ + char ucFileName [F_FILENAME_SIZE]; + char ucVolume [MAX_NETWARE_VOLUME_NAME+1]; + char ucPath [F_PATH_MAX_SIZE + 1]; + + // Separate path into its components: volume, path... + + f_pathParse( pInputPath, NULL, ucVolume, ucPath, ucFileName); + + // Rebuild path to a standard, fully-qualified format, defaulting the + // volume if one isn't specified. + + *pszQualifiedPath = 0; + if( ucVolume [0]) + { + // Append the volume specified by the user. + + f_strcat( pszQualifiedPath, ucVolume ); + } + else + { + // No volume specified, use the default + + f_strcat( pszQualifiedPath, "SYS:"); + } + + if( ucPath [0]) + { + // User specified a path... + + if( ucPath[0] == '\\' || ucPath[0] == '/' ) + { + // Append the path to the volume without the leading slash + + f_strcat( pszQualifiedPath, &ucPath [1]); + } + else + { + // Append the path to the volume + + f_strcat( pszQualifiedPath, ucPath); + } + } + + if( ucFileName [0]) + { + // Append the file name to the path + + f_pathAppend( pszQualifiedPath, ucFileName); + } +} + +#endif diff --git a/flaim/src/fnlm.h b/flaim/src/fnlm.h new file mode 100644 index 0000000..31ab254 --- /dev/null +++ b/flaim/src/fnlm.h @@ -0,0 +1,236 @@ +//------------------------------------------------------------------------- +// Desc: I/O for Netware OS - class definitions +// Tabs: 3 +// +// Copyright (c) 2000-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: fnlm.h 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $ +//------------------------------------------------------------------------- + +#ifndef FNLM_H +#define FNLM_H + +#include "fpackon.h" + +// IMPORTANT NOTE: No other include files should follow this one except +// for fpackoff.h + +// NOTE: We WANT this header file to come after fpackon.h so that it will +// be byte packed. + +// #include "zomni.h" + +#define NLM_SECTOR_SIZE 512 + +RCODE NWTestIfFileExists( + const char * pPath); + +RCODE NWDeleteFile( + const char * pPath); + +RCODE NWRenameFile( + const char * pOldFilePath, + const char * pNewFilePath); + +class F_FileHdlImp : public F_FileHdlImpBase +{ +public: + + F_FileHdlImp(); // F_FileHdlImp Constructor + + virtual ~F_FileHdlImp( void) + { + if( m_bFileOpened) + { + (void)Close(); + } + } + + RCODE Setup( + FLMUINT uiFileId); + + RCODE Close(); + + RCODE Create( + const char * pIoPath, + FLMUINT uiIoFlags); + + RCODE CreateUnique( + char * pIoPath, + const char * pszFileExtension, + FLMUINT uiIoFlags); + + RCODE Open( + const char * pIoPath, + FLMUINT uiIoFlags); + + FINLINE RCODE Flush( void) + { + return( FERR_OK); + } + + RCODE Read( + FLMUINT uiOffset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE Seek( + FLMUINT uiOffset, + FLMINT iWhence, + FLMUINT * puiNewOffset); + + RCODE Size( + FLMUINT * puiSize); + + RCODE Tell( + FLMUINT * puiOffset); + + RCODE Truncate( + FLMUINT uiSize); + + RCODE Write( + FLMUINT uiOffset, + FLMUINT uiLength, + const void * pvBuffer, + FLMUINT * puiBytesWritten); + + RCODE SectorRead( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV); + + RCODE SectorWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT uiBufferSize, + F_IOBuffer * pBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill = TRUE); + + FINLINE FLMBOOL CanDoAsync( void) + { + return( m_bDoDirectIO); + } + + FINLINE void setExtendSize( + FLMUINT uiExtendSize) + { + m_uiExtendSize = uiExtendSize; + } + + FINLINE void setMaxAutoExtendSize( + FLMUINT uiMaxAutoExtendSize) + { + m_uiMaxAutoExtendSize = uiMaxAutoExtendSize; + } + + FINLINE void setSuballocation( + FLMBOOL bDoSuballocation) + { + m_bDoSuballocation = bDoSuballocation; + } + + FINLINE FLMUINT GetSectorSize( void) + { + return( NLM_SECTOR_SIZE); + } + + FINLINE void SetBlockSize( FLMUINT) + { + } + +private: + + RCODE OpenOrCreate( + const char * pszFileName, + FLMUINT uiAccess, + FLMBOOL bCreateFlag); + + RCODE _Read( + FLMUINT uiOffset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE _DirectIORead( + FLMUINT uiOffset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE _DirectIOSectorRead( + FLMUINT uiReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV); + + RCODE _Write( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT * puiBytesWrittenRV); + + RCODE _DirectIOWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT * puiBytesWrittenRV); + + RCODE Expand( + LONG lStartSector, + LONG lSectorsToAlloc); + + RCODE WriteSectors( + void * pvBuffer, + LONG lStartSector, + LONG lSectorCount, + F_IOBuffer * pBufferObj, + FLMBOOL * pbDidAsync = NULL); + + RCODE _DirectIOSectorWrite( + FLMUINT uiWriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + F_IOBuffer * pBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill); + + LONG m_lFileHandle; + LONG m_lOpenAttr; + LONG m_lVolumeID; + LONG m_lLNamePathCount; + FLMBOOL m_bDoSuballocation; + FLMUINT m_uiExtendSize; + FLMUINT m_uiMaxAutoExtendSize; + FLMBOOL m_bDoDirectIO; + LONG m_lSectorsPerBlock; + LONG m_lMaxBlocks; + FLMUINT m_uiCurrentPos; + FLMBOOL m_bNSS; + FLMINT64 m_NssKey; + FLMBOOL m_bNSSFileOpen; + + friend class F_FileHdlPage; +}; + +#include "fpackoff.h" + +#endif diff --git a/flaim/src/ftk.h b/flaim/src/ftk.h index 71681d9..8f71778 100644 --- a/flaim/src/ftk.h +++ b/flaim/src/ftk.h @@ -25,1235 +25,337 @@ #ifndef FTK_H #define FTK_H -#if defined( FLM_DEBUG) && !defined( FLM_HPUX) - #define f_new new( __FILE__, __LINE__) -#else - #define f_new new -#endif - -#ifdef FLM_DEBUG - #define RC_SET( rc) \ - flmMakeErr(rc, __FILE__, __LINE__) - - RCODE flmMakeErr( - RCODE rc, - const char * pszFile, - int iLine); -#else - #define RC_SET(rc) (rc) -#endif - -#ifdef FLM_NLM - - #ifndef LONG - #define LONG unsigned long + #if defined( FLM_DEBUG) && !defined( FLM_HPUX) + #define f_new new( __FILE__, __LINE__) + #else + #define f_new new #endif - #ifndef WORD - #define WORD unsigned short + #ifdef FLM_DEBUG + #define RC_SET( rc) \ + flmMakeErr(rc, __FILE__, __LINE__) + + RCODE flmMakeErr( + RCODE rc, + const char * pszFile, + int iLine); + #else + #define RC_SET(rc) (rc) #endif - #ifndef BYTE - #define BYTE unsigned char - #endif + #define F_SEM_WAITFOREVER 0xFFFFFFFF - #ifndef wsnchar - typedef unsigned char wsnchar; - #endif + #ifdef FLM_NLM + #include "ftknlm.h" + #elif defined( FLM_WIN) - #ifndef BOOL - typedef unsigned int BOOL; - #endif - - #ifndef DWORD - typedef unsigned int DWORD; - #endif - - #ifndef LPDWORD - typedef unsigned int *LPDWORD; - #endif - - #ifndef ULONG - typedef unsigned long ULONG; - #endif - - #ifndef UCHAR - #define UCHAR unsigned char - #endif - - #ifndef WPARAM - typedef DWORD WPARAM; - #endif - - #ifndef LPARAM - typedef DWORD LPARAM; - #endif - - #ifndef UINT - #define UINT unsigned int - #endif - - #ifndef _SIZE_T - #define _SIZE_T - typedef unsigned int size_t; - #endif - - #ifndef TimerSignature - #define TimerSignature 0x524D4954 // RMIT - #endif - - #ifndef SemaphoreSignature - #define SemaphoreSignature 0x504D4553 // PMES - #endif - - #ifndef AllocSignature - #define AllocSignature 0x54524C41 // TRLA - #endif - - typedef void * MUTEX; - typedef void * SEMAPHORE; - typedef unsigned long ERROR; - - typedef void (* FLM_EXIT_FUNC)( void); - - #define DOSNameSpace 0 - #define MACNameSpace 1 - #define MacNameSpace MACNameSpace - #define NFSNameSpace 2 - #define FTAMNameSpace 3 - #define OS2NameSpace 4 - #define LONGNameSpace 4 - #define NTNameSpace 5 - #define MAX_NAMESPACES 6 - - #define NO_RIGHTS_CHECK_ON_OPEN_BIT 0x00010000 - #define ALLOW_SECURE_DIRECTORY_ACCESS_BIT 0x00020000 - #define READ_ACCESS_BIT 0x00000001 - #define WRITE_ACCESS_BIT 0x00000002 - #define DENY_READ_BIT 0x00000004 - #define DENY_WRITE_BIT 0x00000008 - #define COMPATABILITY_MODE_BIT 0x00000010 - #define FILE_WRITE_THROUGH_BIT 0x00000040 - #define FILE_READ_THROUGH_BIT 0x00000080 - #define ALWAYS_READ_AHEAD_BIT 0x00001000 - #define NEVER_READ_AHEAD_BIT 0x00002000 - - #define READ_ONLY_BIT 0x00000001 - #define HIDDEN_BIT 0x00000002 - #define SYSTEM_BIT 0x00000004 - #define EXECUTE_BIT 0x00000008 - #define SUBDIRECTORY_BIT 0x00000010 - #define ARCHIVE_BIT 0x00000020 - // EXECUTE_CONFIRM_BIT 0x00000040 - #define SHAREABLE_BIT 0x00000080 // Valid only on files - #define OLD_PRIVATE_BIT 0x00000080 // Valid only on directories - // LOW_SEARCH_BIT 0x00000100 - // MID_SEARCH_BIT 0x00000200 - // HI_SEARCH_BIT 0x00000400 - #define NO_SUBALLOC_BIT 0x00000800 - #define SMODE_BITS 0x00000700 // search bits - #define TRANSACTION_BIT 0x00001000 - // OLD_INDEXED_BIT 0x00002000 - #define READ_AUDIT_BIT 0x00004000 - #define WRITE_AUDIT_BIT 0x00008000 - #define IMMEDIATE_PURGE_BIT 0x00010000 - #define RENAME_INHIBIT_BIT 0x00020000 - #define DELETE_INHIBIT_BIT 0x00040000 - #define COPY_INHIBIT_BIT 0x00080000 - #define FILE_AUDITING_BIT 0x00100000 // system auditing - #define REMOTE_DATA_ACCESS_BIT 0x00400000 // ie. Data Migration (file only) - #define REMOTE_DATA_INHIBIT_BIT 0x00800000 // ie. Data Migration (file only) - #define REMOTE_DATA_SAVE_KEY_BIT 0x01000000 // ie. Data Migration (file only) - #define COMPRESS_FILE_IMMEDIATELY_BIT 0x02000000 // immediately try to compress this file (or all files within this subdirectory) - #define DATA_STREAM_IS_COMPRESSED_BIT 0x04000000 // per data stream directory entry - #define DO_NOT_COMPRESS_FILE_BIT 0x08000000 // don't compress this file ever (or default files within this subdirectory) - #define CANT_COMPRESS_DATA_STREAM_BIT 0x20000000 // can't save any space by compressiong this data stream - #define ATTR_ARCHIVE_BIT 0x40000000 // Object Archive Bit (EAs, OwnerID, Trustees - #define ZFS_VOLATILE_BIT 0x80000000 // USED BY NSS (Jim A. Nicolet 11-6-2000) - - #define VOLUME_AUDITING_BIT 0x01 // system auditing - #define SUB_ALLOCATION_ENABLED_BIT 0x02 // sub allocation units valid on this volume - #define FILE_COMPRESSION_ENABLED_BIT 0x04 // file compression enabled on this volume - #define DATA_MIGRATION_ENABLED_BIT 0x08 // data migration is allowed on this volume - #define NEW_TRUSTEE_COUNT_BIT 0x10 // .2 Volumes have only 4 trustee entries per volume instead of 6 - #define DIR_SVCS_OBJ_UPGRADED_BIT 0x20 // Modify 3.2 volume DirObjId to new position - #define VOLUME_IMMEDIATE_PURGE_ENABLED_BIT 0x40 // Volume is marked as immediate purge - - // define the data stream values - - #define PrimaryDataStream 0 - #define MACResourceForkDataStream 1 - #define FTAMDataStream 2 - - #define DefinedAccessRightsBits 0x01FB // all the bits currently used - #define MaximumDirectoryAccessBits 0x01FF // all the defined bits for access privileges - #define AllValidAccessBits 0x100001FF // all the bits that are valid in CreateDirectory - - struct LoadDefinitionStructure - { - struct LoadDefinitionStructure *LDLink; - struct LoadDefinitionStructure *LDKillLink; - struct LoadDefinitionStructure *LDScanLink; - struct ResourceTagStructure *LDResourceList; - LONG LDIdentificationNumber; - LONG LDCodeImageOffset; - LONG LDCodeImageLength; - LONG LDDataImageOffset; - LONG LDDataImageLength; - LONG LDUninitializedDataLength; - LONG LDCustomDataOffset; - LONG LDCustomDataSize; - LONG LDFlags; - LONG LDType; - LONG (*LDInitializationProcedure)( - struct LoadDefinitionStructure *LoadRecord, - struct ScreenStruct *screenID, - BYTE *CommandLine, - BYTE *loadDirectoryPath, - LONG uninitializedDataLength, - LONG fileHandle, - LONG (*ReadRoutine)( - LONG fileHandle, - LONG offset, - void *buffer, - LONG numberOfBytes), - LONG customDataOffset, - LONG customDataSize); - void (*LDExitProcedure)(void); - LONG (*LDCheckUnloadProcedure)( - struct ScreenStruct *screenID); - void *LDPublics; - BYTE LDFileName[36]; - BYTE LDName[128]; - LONG *LDCLIBLoadStructure; - LONG *LDNLMDebugger; - LONG LDParentID; - LONG LDReservedForCLIB; - void *AllocMemory; - LONG LDTimeStamp; - void *LDModuleObjectHandle; - LONG LDMajorVersion; - LONG LDMinorVersion; - LONG LDRevision; - LONG LDYear; - LONG LDMonth; - LONG LDDay; - BYTE *LDCopyright; - LONG LDSuppressUnloadAllocMsg; - LONG Reserved2; - LONG Reserved3; - LONG Reserved4[64]; - LONG Reserved5[12]; - LONG Reserved6; - void *LDDomainID; - struct LoadDefinitionStructure *LDEnvLink; - void *LDAllocPagesListHead; - void *LDTempPublicList; - LONG LDMessageLanguage; - BYTE **LDMessages; - LONG LDMessageCount; - BYTE *LDHelpFile; - LONG LDMessageBufferSize; - LONG LDHelpBufferSize; - LONG LDSharedCodeOffset; - LONG LDSharedCodeLength; - LONG LDSharedDataOffset; - LONG LDSharedDataLength; - LONG (*LDSharedInitProcedure)( - struct LoadDefinitionStructure *LoadRecord, - struct ScreenStruct *screenID, - BYTE *CommandLine); - void (*LDSharedExitProcedure)(void); - LONG LDRPCDataTable; - LONG LDRealRPCDataTable; - LONG LDRPCDataTableSize; - LONG LDNumberOfReferencedPublics; - void **LDReferencedPublics; - LONG LDNumberOfReferencedExports; - LONG LDNICIObject; - LONG LDAllocPagesListLocked; - void *LDAddressSpace; - LONG Reserved7; - - void *MPKStubAddress; - LONG MPKStubSize; - LONG LDBuildNumber; - void *LDExtensionData; - }; - - typedef struct LoadDefinitionStructure LoadDefStruct; - - // defines for the LoadDefinitonStructure's LDFlags member - - #define LDModuleIsReEntrantBit 0x00000001 - #define LDModuleCanBeMultiplyLoadedBit 0x00000002 - #define LDSynchronizeStart 0x00000004 - #define LDPseudoPreemptionBit 0x00000008 - #define LDLoadInKernel 0x00000010 - #define Available_0 0x00000020 - #define LDAutoUnload 0x00000040 - #define LDHiddenModule 0x00000080 - #define LDDigitallySignedFile 0x00000100 - #define LDLoadProtected 0x00000200 - #define LDSharedLibraryModule 0x00000400 - #define LDRestartable 0x00000800 - #define LDUnsafeToUnloadNow 0x00001000 - #define LDModuleIsUniprocessor 0x00002000 - #define LDPreemptable 0x00004000 - #define LDHasSystemCalls 0x00008000 - #define LDVirtualMemory 0x00010000 - #define LDAllExportsMTSafe 0x00020000 - - typedef struct ARG_DATA_Tag - { - char ** ppszArgV; - char * pszArgs; - char * pszThreadName; - int iArgC; - struct LoadDefinitionStructure * moduleHandle; - } ARG_DATA; - - // NOTE: It is ok for these header files to be included in the fpackon.h - // because they should be one-byte packing. - - extern "C" - { - typedef void * SPINLOCK; - - #include "fileio.h" - #include "lfsproto.h" - - #ifndef __DSTRUCT_H__ - #include + #define FSTATIC static + + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN #endif - - #define needssyncclockprototypes - #include "synclock.h" - } - - #define MAX_NETWARE_VOLUME_NAME 16 - #define F_NW_DEFAULT_VOLUME_NUMBER 0 - extern FLMBYTE F_NW_Default_Volume_Name[]; - - extern RCODE MapNWtoFlaimError( - LONG lResult, - RCODE defaultRc); - - extern LONG FlaimToNWOpenFlags( - FLMUINT uiAccess, - FLMBOOL bDoDirectIo); - - extern "C" - { - void kYieldThread( void); - - int kGetThreadName( - FLMUINT32 ui32ThreadId, - char * szName, - int iBufSize); - - void * kCreateThread( - BYTE * name, - void * (*StartAddress)(void *, void *), - void * StackAddressHigh, - LONG StackSize, - void * Argument); - - int kSetThreadName( - void * ThreadHandle, - BYTE * buffer); - - LONG kScheduleThread( - void * ThreadHandle); - - ERROR kDelayThread( - UINT uiMilliseconds); - - void * kCurrentThread(void); - - int kDestroyThread( - void * ThreadHandle); - - void kExitThread( - void * ExitStatus); - - LONG kSetThreadLoadHandle( - void * ThreadHandle, - LONG nlmHandle); - - LONG GetRunningProcess( void); - - void KillMe( - struct LoadDefinitionStructure *LoadRecord); - - void NWYieldIfTime( void); - - void CSetD( - LONG value, - void *address, - LONG numberOfDWords); - - void CMovB( - void *src, - void *dst, - LONG numberOfBytes); - - void * Alloc( - LONG numberOfBytes, - LONG lRTag); - void Free( - void * address); - - LONG AllocateResourceTag( - LONG pvLoadRecord, - BYTE *pvResourceDescriptionString, - LONG ResourceSignature); - - LONG ReturnResourceTag( - LONG RTag, - BYTE displayErrorsFlag); - - extern LONG ConvertPathString( - LONG stationNumber, - BYTE base, - BYTE *modifierString, - LONG *volumeNumber, - LONG *pathBase, - BYTE *pathString, - LONG *pathCount); - - extern LONG GetEntryFromPathStringBase( - LONG Station, - LONG Volume, - LONG PathBase, - BYTE *PathString, - LONG PathCount, - LONG SourceNameSpace, - LONG DesiredNameSpace, - struct DirectoryStructure **Dir, - LONG *DirectoryNumber); - - extern LONG NDSCreateStreamFile( - LONG Station, - LONG Task, - BYTE *fileName, - LONG CreateAttributes, - LONG *fileHandle, - LONG *DOSDirectoryBase); - - extern LONG NDSOpenStreamFile( - LONG Station, - LONG Task, - BYTE *fileName, - LONG RequestedRights, - LONG *fileHandle, - LONG *DOSDirectoryBase); - - extern LONG NDSDeleteStreamFile( - LONG Station, - LONG Task, - BYTE *fileName, - LONG *DOSDirectoryBase); - - extern LONG ReadFile( - LONG stationNumber, - LONG handle, - LONG startingOffset, - LONG bytesToRead, - LONG *actualBytesRead, - void *buffer); - - extern LONG WriteFile( - LONG stationNumber, - LONG handle, - LONG startingOffset, - LONG bytesToWrite, - void *buffer); - - extern LONG SetFileSize( - LONG station, - LONG handle, - LONG filesize, - LONG truncateflag); - - extern LONG GetFileSize( - LONG stationNumber, - LONG handle, - LONG *fileSize); - - extern LONG DirectReadFile( - LONG station, - LONG handle, - LONG startingsector, - LONG sectorcount, - BYTE *buffer); - - extern LONG SwitchToDirectFileMode( - LONG station, - LONG handle); - - extern LONG ReturnVolumeMappingInformation( - LONG volumenumber, - struct VolumeInformationStructure *volumeInformation); - - extern LONG ExpandFileInContiguousBlocks( - LONG station, - LONG handle, - LONG fileblocknumber, - LONG numberofblocks, - LONG vblocknumber, - LONG segnumber); - - extern LONG FreeLimboVolumeSpace( - LONG volumenumber, - LONG numberofblocks); - - extern LONG DirectWriteFileNoWait( - LONG station, - LONG handle, - LONG startingsector, - LONG sectorcount, - BYTE *buffer, - void (*callbackroutine)(LONG, LONG, LONG), - LONG callbackparameter); - - extern LONG DirectWriteFile( - LONG station, - LONG handle, - LONG startingsector, - LONG sectorcount, - BYTE *buffer); - - extern LONG RevokeFileHandleRights( - LONG Station, - LONG Task, - LONG FileHandle, - LONG QueryFlag, // 0 = revoke, 1 = query, 2 = revoke and close if last - LONG removeRights, - LONG *newRights); - - #define DFSFailedCompletion -1 - #define DFSNormalCompletion 0 - #define DFSInsufficientSpace 1 - #define DFSVolumeSegmentDeactivated 4 - #define DFSTruncationFailure 16 - #define DFSHoleInFileError 17 - #define DFSParameterError 18 - #define DFSOverlapError 19 - #define DFSSegmentError 20 - #define DFSBoundryError 21 - #define DFSInsufficientLimboFileSpace 22 - #define DFSNotInDirectFileMode 23 - #define DFSOperationBeyondEndOfFile 24 - #define DFSOutOfHandles 129 - #define DFSHardIOError 131 - #define DFSInvalidFileHandle 136 - #define DFSNoReadPrivilege 147 - #define DFSNoWritePrivilege 148 - #define DFSFileDetached 149 - #define DFSInsufficientMemory 150 - #define DFSInvalidVolume 152 - #define DFSIOLockError 162 - - struct VolumeInformationStructure - { - LONG VolumeAllocationUnitSizeInBytes; - LONG VolumeSizeInAllocationUnits; - LONG VolumeSectorSize; - LONG AllocationUnitsUsed; - LONG AllocationUnitsFreelyAvailable; - LONG AllocationUnitsInDeletedFilesNotAvailable; - LONG AllocationUnitsInAvailableDeletedFiles; - LONG NumberOfPhysicalSegmentsInVolume; - LONG PhysicalSegmentSizeInAllocationUnits[64]; - }; - - #define MModifyNameBit 0x0001 - #define MFileAttributesBit 0x0002 - #define MCreateDateBit 0x0004 - #define MCreateTimeBit 0x0008 - #define MOwnerIDBit 0x0010 - #define MLastArchivedDateBit 0x0020 - #define MLastArchivedTimeBit 0x0040 - #define MLastArchivedIDBit 0x0080 - #define MLastUpdatedDateBit 0x0100 - #define MLastUpdatedTimeBit 0x0200 - #define MLastUpdatedIDBit 0x0400 - #define MLastAccessedDateBit 0x0800 - #define MInheritanceRestrictionMaskBit 0x1000 - #define MMaximumSpaceBit 0x2000 - #define MLastUpdatedInSecondsBit 0x4000 - - struct ModifyStructure - { - BYTE *MModifyName; - LONG MFileAttributes; - LONG MFileAttributesMask; - WORD MCreateDate; - WORD MCreateTime; - LONG MOwnerID; - WORD MLastArchivedDate; - WORD MLastArchivedTime; - LONG MLastArchivedID; - WORD MLastUpdatedDate; - WORD MLastUpdatedTime; - LONG MLastUpdatedID; - WORD MLastAccessedDate; - WORD MInheritanceGrantMask; - WORD MInheritanceRevokeMask; - int MMaximumSpace; - LONG MLastUpdatedInSeconds; - }; - - LONG ImportPublicSymbol( - LONG moduleHandle, - BYTE * symbolName); - - LONG UnImportPublicSymbol( - LONG moduleHandle, - BYTE * symbolName); - - LONG ExportPublicSymbol( - LONG moduleHandle, - BYTE * symbolName, - LONG address); - - void SynchronizeStart( void); - - LONG CFindLoadModuleHandle( void *); - - int atexit( - FLM_EXIT_FUNC fnExit); - - #define LO_RETURN_HANDLE 0x00000040 - - LONG LoadModule( - void * screenID, - BYTE * fileName, - LONG loadOptions); - - LONG UnloadModule( - void ** pScreenID, - const char * commandline); - - typedef struct - { - FLMUINT32 time_low; - FLMUINT16 time_mid; - FLMUINT16 time_hi_and_version; - FLMBYTE clk_seq_hi_res; - FLMBYTE clk_seq_low; - FLMBYTE node[6]; - } NWGUID; - - int SGUIDCreate( NWGUID *guidBfr); - - void * GetSystemConsoleScreen( void); - - LONG SizeOfAllocBlock( - void * AllocAddress); - - SEMAPHORE kSemaphoreAlloc( - BYTE * pSemaName, - UINT SemaCount); - - ERROR kSemaphoreFree( - SEMAPHORE SemaHandle); - - ERROR kSemaphoreWait( - SEMAPHORE SemaHandle); - - ERROR kSemaphoreTimedWait( - SEMAPHORE SemaHandle, - UINT MilliSecondTimeOut); - - ERROR kSemaphoreSignal( - SEMAPHORE SemaHandle); - - UINT kSemaphoreExamineCount( - SEMAPHORE SemaHandle); - - MUTEX kMutexAlloc( - BYTE * MutexName); - - ERROR kMutexFree( - MUTEX MutexHandle); - - ERROR kMutexLock( - MUTEX MutexHandle); - - ERROR kMutexUnlock( - MUTEX MutexHandle); - - void CMoveFast( - void * src, - void * dst, - LONG numberOfBytes); - - void EnterDebugger( void); - - void GetClosestSymbol( - BYTE * szBuffer, - LONG udAddress); - - LONG GetCurrentTime( void); - - void ConvertTicksToSeconds( - LONG ticks, - LONG * seconds, - LONG * tenthsOfSeconds); - - void ConvertSecondsToTicks( - LONG seconds, - LONG tenthsOfSeconds, - LONG * ticks); - - LONG GetCacheBufferSize(void); - - LONG GetOriginalNumberOfCacheBuffers(void); - - LONG GetCurrentNumberOfCacheBuffers(void); - - LONG GetNLMAllocMemoryCounts( - FLMUINT moduleHandle, - FLMUINT * freeBytes, - FLMUINT * freeNodes, - FLMUINT * allocatedBytes, - FLMUINT * allocatedNodes, - FLMUINT * totalMemory); - - LONG atomic_xchg( volatile LONG * address, LONG value); - - #define nlm_AtomicExchange( piTarget, iValue) \ - ((FLMINT32)atomic_xchg( (volatile LONG *)(piTarget), (LONG)(iValue))) - - FLMINT32 nlm_AtomicIncrement( - volatile LONG * piTarget); - - FLMINT32 nlm_AtomicDecrement( - volatile LONG * piTarget); - - #if !defined( __MWERKS__) - #pragma aux nlm_AtomicIncrement parm [ecx]; - #pragma aux nlm_AtomicIncrement = \ - 0xB8 0x01 0x00 0x00 0x00 /* mov eax, 1 */ \ - 0xF0 0x0F 0xC1 0x01 /* lock xadd [ecx], eax */ \ - 0x40 /* inc eax */ \ - parm [ecx] \ - modify exact [eax]; - - #pragma aux nlm_AtomicDecrement parm [ecx]; - #pragma aux nlm_AtomicDecrement = \ - 0xB8 0xFF 0xFF 0xFF 0xFF /* mov eax, 0ffffffffh */ \ - 0xF0 0x0F 0xC1 0x01 /* lock xadd [ecx], eax */ \ - 0x48 /* dec eax */ \ - parm [ecx] \ - modify exact [eax]; - #else - - FINLINE FLMINT32 nlm_AtomicIncrement( - volatile LONG * piTarget) - { - FLMINT32 i32Result; - - __asm - { - mov eax, 1 - mov ecx, piTarget - lock xadd [ecx], eax - inc eax - mov i32Result, eax - } - - return( i32Result); - } - - FINLINE FLMINT32 nlm_AtomicDecrement( - volatile LONG * piTarget) - { - FLMINT32 i32Result; - - __asm - { - mov eax, 0ffffffffh - mov ecx, piTarget - lock xadd [ecx], eax - dec eax - mov i32Result, eax - } - - return( i32Result); - } - + #ifndef WIN32_EXTRA_LEAN + #define WIN32_EXTRA_LEAN #endif + + // This pragma is needed because FLAIM may be built with a + // packing other than 8-bytes on Win (such as 1-byte packing). + // Code in FLAIM that uses windows structures and system calls + // MUST use 8-byte packing (the packing used by the O/S). + // See Microsoft technical article Q117388. - } // extern "C" - - #define FSTATIC - - // The typedef for va_list in stdarg.h do not function properly when - // a va_list is passed down multiple layers as a pointer (va_list *). - // Therefore, the following definitions/typedefs were taken from a - // "fixed" version of stdarg.h implemented by DS. - - typedef unsigned long f_va_list; - - #define f_argsize(x) \ - ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int)-1)) - - #define f_va_start(ap, parmN) \ - ((void)((ap) = (unsigned long)&(parmN) + f_argsize(parmN))) - - #define f_va_arg(ap, type) \ - (*(type *)(((ap) += f_argsize(type)) - (f_argsize(type)))) - - #define f_va_end(ap) \ - ((void)0) - - FINLINE char * f_strcpy( - char * d, - const char * s) - { - while ((*d++ = *s++) != 0); - return( d); - } - - FINLINE unsigned f_strlen( - const char * s) - { - const char * b = s; - - while (*s) - { - s++; - } - - return( s - b); - } - - FINLINE int f_strcmp( - const char * s1, - const char * s2) - { - while( *s1 == *s2 && *s1) - { - s1++; - s2++; - } - return( (int)(*s1 - *s2)); - } - - FINLINE char * f_strncpy( - char * dest, - const char * src, - unsigned n) - { - while( n) - { - *dest++ = *src; - if( *src) - { - src++; - } - n--; - } - - *dest = 0; - return( dest); - } - - FINLINE int f_strncmp( - const char * s1, - const char * s2, - unsigned n) - { - while( *s1 == *s2 && *s1 && n) - { - s1++; - s2++; - n--; - } - - if( n) - { - return( (*s1 - *s2)); - } - - return( (int)0); - } - - char * f_strstr( - const char * pszStr1, - const char * pszStr2); - - FLMINT f_stricmp( - const char * pszStr1, - const char * pszStr2); - - FLMINT f_strnicmp( - const char * pszStr1, - const char * pszStr2, - FLMINT iLen); - - FINLINE char * f_strcat( - char * dst, - const char * src) - { - const char * p = src; - char * q = dst; - - while (*q++); - q--; - while( (*q++ = *p++) != 0); - - return(dst); - } - - FINLINE char * f_strncat( - char * dst , - const char * src, - unsigned n) - { - const char * p = src; - char * q = dst; - - while (*q++); - - q--; n++; - - while( --n) - { - if( (*q++ = *p++) == 0) - { - q--; - break; - } - } - - *q = 0; - return( dst); - } - - char * f_strupr( - char * pszStr); - - FLMINT f_memcmp( - const void * pvMem1, - const void * pvMem2, - FLMUINT uiSize); - - #define f_memcpy( dest, src, size) \ - CMoveFast( (void *)(src), (void *)(dest), size) - - void * f_memset( - void * pvMem, - FLMBYTE ucByte, - FLMUINT uiSize); - - #define f_memset( m, c, size) \ - f_memset( (void *)(m), c, size) - - void * f_memmove( - void * pvDest, - const void * pvSrc, - FLMUINT uiSize); - -#elif defined( FLM_WIN) - - #define FSTATIC static + #pragma pack( push, enter_windows, 8) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #pragma pack( pop, enter_windows) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif + // Conversion from XXX to YYY, possible loss of data - #ifndef WIN32_EXTRA_LEAN - #define WIN32_EXTRA_LEAN - #endif + #pragma warning( disable : 4244) - // This pragma is needed because FLAIM may be built with a - // packing other than 8-bytes on Win (such as 1-byte packing). - // Code in FLAIM that uses windows structures and system calls - // MUST use 8-byte packing (the packing used by the O/S). - // See Microsoft technical article Q117388. - - #pragma pack( push, enter_windows, 8) - #include + // Local variable XXX may be used without having been initialized + + #pragma warning( disable : 4701) + + // Function XXX not inlined + + #pragma warning( disable : 4710) + + #define f_stricmp( str1, str2) \ + _stricmp( (str1), (str2)) + + #define f_strnicmp( str1, str2, size) \ + _strnicmp( (str1), (str2),(size_t)(size)) + + #define f_memcpy( dest, src, size) \ + memcpy((void *)(dest), (void *)(src),(size_t)(size)) + + #define f_memmove( dest, src, length) \ + memmove((void *)(dest), (void *)(src),(size_t)(length)) + + #define f_memset( src, chr, size) \ + memset((void *)(src),(chr),(size_t)(size)) + + #define f_memcmp( str1, str2, length) \ + memcmp((void *)(str1), (void *)(str2),(size_t)(length)) + + #define f_strcat( dest, src) \ + strcat( (char*)(dest), (char*)(src)) + + #define f_strcmp( str1, str2) \ + strcmp( (char*)(str1), (char*)(str2)) + + #define f_strcpy( dest, src) \ + strcpy( (char*)(dest), (char*)(src)) + + #define f_strncpy( dest, src, length) \ + strncpy( (char*)(dest), (char*)(src), (size_t)(length)) + + #define f_strlen( str) \ + ((FLMUINT)strlen( (char*)(str))) + + #define f_strncmp( str1, str2, size) \ + strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) + + #define f_strrchr( str, value ) \ + strrchr( (char*)(str), (int)value) + + #define f_strstr( str1, str2) \ + strstr( (char*)(str1), (char*)(str2)) + + #define f_strncat( str1, str2, n) \ + strncat( (str1), (str2), n) + + #define f_strupr( str) \ + _strupr( (str)) + + #define f_va_list va_list + #define f_va_start va_start + #define f_va_arg va_arg + #define f_va_end va_end + + #elif defined( FLM_UNIX) + + #include + #include + #include + #include + #include + #include + #include + #include + #include #include - #include - #include #include #include - #include - #include - #include - #include - #include - #include - #include - #pragma pack( pop, enter_windows) - - // Conversion from XXX to YYY, possible loss of data - - #pragma warning( disable : 4244) - - // Local variable XXX may be used without having been initialized - - #pragma warning( disable : 4701) - - // Function XXX not inlined - - #pragma warning( disable : 4710) - - #define f_stricmp( str1, str2) \ - _stricmp( (str1), (str2)) - - #define f_strnicmp( str1, str2, size) \ - _strnicmp( (str1), (str2),(size_t)(size)) - - #define f_memcpy( dest, src, size) \ - memcpy((void *)(dest), (void *)(src),(size_t)(size)) - - #define f_memmove( dest, src, length) \ - memmove((void *)(dest), (void *)(src),(size_t)(length)) - - #define f_memset( src, chr, size) \ - memset((void *)(src),(chr),(size_t)(size)) - - #define f_memcmp( str1, str2, length) \ - memcmp((void *)(str1), (void *)(str2),(size_t)(length)) - - #define f_strcat( dest, src) \ - strcat( (char*)(dest), (char*)(src)) - - #define f_strcmp( str1, str2) \ - strcmp( (char*)(str1), (char*)(str2)) - - #define f_strcpy( dest, src) \ - strcpy( (char*)(dest), (char*)(src)) - - #define f_strncpy( dest, src, length) \ - strncpy( (char*)(dest), (char*)(src), (size_t)(length)) - - #define f_strlen( str) \ - ((FLMUINT)strlen( (char*)(str))) - - #define f_strncmp( str1, str2, size) \ - strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) - - #define f_strrchr( str, value ) \ - strrchr( (char*)(str), (int)value) - - #define f_strstr( str1, str2) \ - strstr( (char*)(str1), (char*)(str2)) - - #define f_strncat( str1, str2, n) \ - strncat( (str1), (str2), n) - - #define f_strupr( str) \ - _strupr( (str)) - - #define f_va_list va_list - #define f_va_start va_start - #define f_va_arg va_arg - #define f_va_end va_end - -#elif defined( FLM_UNIX) - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #ifndef _POSIX_THREADS - #define _POSIX_THREADS - #endif - - #include - - #ifndef FLM_OSX - #include - #endif - - #ifdef FLM_AIX - #include - #endif - - #define FSTATIC static - - #define f_stricmp(str1,str2) \ - strcasecmp( (str1), (str2)) - - #define f_strnicmp(str1,str2,size_t) \ - strncasecmp( (str1), (str2),size_t) - - #define f_memcpy( dest, src, size) \ - memcpy( (void*)(dest), (void*)(src), size) - - #define f_memmove( dest, src, len) \ - memmove( (void*)(dest), (void*)(src), len) - - #define f_memset( src, chr, size) \ - memset((void *)(src),(chr),(size_t)(size)) - - #define f_memcmp( str1, str2, length) \ - memcmp((void *)(str1), (void *)(str2),(size_t)(length)) - - #define f_strcat( dest, src) \ - strcat( (char*)(dest), (char*)(src)) - - #define f_strcmp( str1, str2) \ - strcmp( (char*)(str1), (char*)(str2)) - - #define f_strcpy( dest, src) \ - strcpy( (char*)(dest), (char*)(src)) - - #define f_strncpy( dest, src, length) \ - strncpy( (char*)(dest), (char*)(src), (size_t)(length)) - - #define f_strlen( str) \ - strlen( (char*)(str)) - - #define f_strncmp( str1, str2, size) \ - strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) - - #define f_strrchr( str, value ) \ - strrchr( (char*)(str), (int)value) - - #define f_strstr( str1, str2) \ - strstr( (char*)(str1), (char*)(str2)) - - #define f_strncat( str1, str2, n) \ - strncat( (str1), (str2), n) - - char * f_strupr( - char * pszStr); - - #define f_strupr( str) \ - f_strupr( (str)) - - #define f_va_list va_list - #define f_va_start va_start - #define f_va_arg va_arg - #define f_va_end va_end - -#endif - -/**************************************************************************** - CROSS PLATFORM DEFINITIONS -****************************************************************************/ - -#define F_UNREFERENCED_PARM( parm) \ - (void)parm - -#if defined( __va_copy) - #define f_va_copy(to, from) \ - __va_copy(to, from) -#else - #define f_va_copy(to, from) \ - ((to) = (from)) -#endif - -#define shiftN(data,size,distance) \ - f_memmove((FLMBYTE *)(data) + (FLMINT)(distance), \ - (FLMBYTE *)(data), (unsigned)(size)) - -/**************************************************************************** - FLAIM's Assert Layer -****************************************************************************/ - -#ifndef FLM_DEBUG - #define flmAssert( exp) -#else - #ifdef FLM_DBG_LOG - void flmDbgLogFlush( void); - #endif - - #if defined( FLM_WIN) - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), DebugBreak(), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || (DebugBreak(), 0)) - #endif - - #elif defined( FLM_NLM) - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), EnterDebugger(), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || ( EnterDebugger(), 0)) - #endif - - #elif defined( FLM_UNIX) - #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), assert(0), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || (assert(0), 0)) + #ifndef _POSIX_THREADS + #define _POSIX_THREADS #endif - - #else - #define flmAssert( exp) + + #include + + #ifndef FLM_OSX + #include + #endif + + #ifdef FLM_AIX + #include + #endif + + #define FSTATIC static + + #define f_stricmp(str1,str2) \ + strcasecmp( (str1), (str2)) + + #define f_strnicmp(str1,str2,size_t) \ + strncasecmp( (str1), (str2),size_t) + + #define f_memcpy( dest, src, size) \ + memcpy( (void*)(dest), (void*)(src), size) + + #define f_memmove( dest, src, len) \ + memmove( (void*)(dest), (void*)(src), len) + + #define f_memset( src, chr, size) \ + memset((void *)(src),(chr),(size_t)(size)) + + #define f_memcmp( str1, str2, length) \ + memcmp((void *)(str1), (void *)(str2),(size_t)(length)) + + #define f_strcat( dest, src) \ + strcat( (char*)(dest), (char*)(src)) + + #define f_strcmp( str1, str2) \ + strcmp( (char*)(str1), (char*)(str2)) + + #define f_strcpy( dest, src) \ + strcpy( (char*)(dest), (char*)(src)) + + #define f_strncpy( dest, src, length) \ + strncpy( (char*)(dest), (char*)(src), (size_t)(length)) + + #define f_strlen( str) \ + strlen( (char*)(str)) + + #define f_strncmp( str1, str2, size) \ + strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) + + #define f_strrchr( str, value ) \ + strrchr( (char*)(str), (int)value) + + #define f_strstr( str1, str2) \ + strstr( (char*)(str1), (char*)(str2)) + + #define f_strncat( str1, str2, n) \ + strncat( (str1), (str2), n) + + char * f_strupr( + char * pszStr); + + #define f_strupr( str) \ + f_strupr( (str)) + + #define f_va_list va_list + #define f_va_start va_start + #define f_va_arg va_arg + #define f_va_end va_end + + #ifndef INVALID_SOCKET + #define INVALID_SOCKET (-1) + #endif + + #ifndef INADDR_NONE + #define INADDR_NONE (-1) + #endif + + #ifndef SOCKET + #define SOCKET int + #endif + #endif - -#endif - -#ifdef FLM_DEBUG - #define flmReleaseAssert( exp) flmAssert( exp) -#else - #if defined( FLM_WIN) - #define flmReleaseAssert( exp) \ - (void)( (exp) || (DebugBreak(), 0)) - - #elif defined( FLM_NLM) - #define flmReleaseAssert( exp) \ - (void)( (exp) || ( EnterDebugger(), 0)) - - #elif defined( FLM_UNIX) - #include - #define flmReleaseAssert( exp) \ - (void)( (exp) || (abort(), 0)) + + /**************************************************************************** + CROSS PLATFORM DEFINITIONS + ****************************************************************************/ + + #define F_UNREFERENCED_PARM( parm) \ + (void)parm + + #if defined( __va_copy) + #define f_va_copy(to, from) \ + __va_copy(to, from) #else - #define flmReleaseAssert( exp) + #define f_va_copy(to, from) \ + ((to) = (from)) #endif -#endif - - -#include "fpackon.h" -// IMPORTANT NOTE: No other include files should follow this one except -// for fpackoff.h - -FLMUINT f_breakpoint( - FLMUINT uiBreakFlag); - -/**************************************************************************** - ASCII Constants -****************************************************************************/ + + #define shiftN(data,size,distance) \ + f_memmove((FLMBYTE *)(data) + (FLMINT)(distance), \ + (FLMBYTE *)(data), (unsigned)(size)) + + /**************************************************************************** + FLAIM's Assert Layer + ****************************************************************************/ + + #ifndef FLM_DEBUG + #define flmAssert( exp) + #else + #ifdef FLM_DBG_LOG + void flmDbgLogFlush( void); + #endif + + #if defined( FLM_WIN) + #ifdef FLM_DBG_LOG + #define flmAssert( exp) \ + (void)( (exp) || (flmDbgLogFlush(), DebugBreak(), 0)) + #else + #define flmAssert( exp) \ + (void)( (exp) || (DebugBreak(), 0)) + #endif + + #elif defined( FLM_NLM) + #ifdef FLM_DBG_LOG + #define flmAssert( exp) \ + (void)( (exp) || (flmDbgLogFlush(), EnterDebugger(), 0)) + #else + #define flmAssert( exp) \ + (void)( (exp) || ( EnterDebugger(), 0)) + #endif + + #elif defined( FLM_UNIX) + #include + + #ifdef FLM_DBG_LOG + #define flmAssert( exp) \ + (void)( (exp) || (flmDbgLogFlush(), assert(0), 0)) + #else + #define flmAssert( exp) \ + (void)( (exp) || (assert(0), 0)) + #endif + + #else + #define flmAssert( exp) + #endif + + #endif + + #ifdef FLM_DEBUG + #define flmReleaseAssert( exp) flmAssert( exp) + #else + #if defined( FLM_WIN) + #define flmReleaseAssert( exp) \ + (void)( (exp) || (DebugBreak(), 0)) + + #elif defined( FLM_NLM) + #define flmReleaseAssert( exp) \ + (void)( (exp) || ( EnterDebugger(), 0)) + + #elif defined( FLM_UNIX) + #include + #define flmReleaseAssert( exp) \ + (void)( (exp) || (abort(), 0)) + #else + #define flmReleaseAssert( exp) + #endif + #endif + + + #include "fpackon.h" + + // IMPORTANT NOTE: No other include files should follow this one except + // for fpackoff.h + + FLMUINT f_breakpoint( + FLMUINT uiBreakFlag); + + /**************************************************************************** + Desc: ASCII Constants + ****************************************************************************/ + #define ASCII_TAB 0x09 #define ASCII_NEWLINE 0x0A #define ASCII_CR 0x0D @@ -1345,1402 +447,1287 @@ FLMUINT f_breakpoint( #define ASCII_SEVEN 0x37 #define ASCII_EIGHT 0x38 #define ASCII_NINE 0x39 - -#define NATIVE_SPACE ' ' -#define NATIVE_DOT '.' -#define NATIVE_PLUS '+' -#define NATIVE_MINUS '-' -#define NATIVE_WILDCARD '*' -#define NATIVE_QUESTIONMARK '?' - -#define NATIVE_UPPER_A 'A' -#define NATIVE_UPPER_F 'F' -#define NATIVE_UPPER_X 'X' -#define NATIVE_UPPER_Z 'Z' -#define NATIVE_LOWER_A 'a' -#define NATIVE_LOWER_F 'f' -#define NATIVE_LOWER_X 'x' -#define NATIVE_LOWER_Z 'z' -#define NATIVE_ZERO '0' -#define NATIVE_NINE '9' - -#define f_stringToAscii(str) - -#define f_toascii(native) (native) - -#define f_tonative(ascii) (ascii) - -#define f_toupper(native) (((native) >= 'a' && (native) <= 'z') \ - ? (native) - 'a' + 'A' : (native)) - -#define f_tolower(native) (((native) >= 'A' && (native) <= 'Z') \ - ? (native) - 'A' + 'a' : (native)) - -#define f_islower(native) ((native) >= 'a' && (native) <= 'z') - -// Unicode character constants - -#define FLM_UNICODE_LINEFEED ((FLMUNICODE)10) -#define FLM_UNICODE_SPACE ((FLMUNICODE)32) -#define FLM_UNICODE_BANG ((FLMUNICODE)33) -#define FLM_UNICODE_QUOTE ((FLMUNICODE)34) -#define FLM_UNICODE_POUND ((FLMUNICODE)35) -#define FLM_UNICODE_DOLLAR ((FLMUNICODE)36) -#define FLM_UNICODE_PERCENT ((FLMUNICODE)37) -#define FLM_UNICODE_AMP ((FLMUNICODE)38) -#define FLM_UNICODE_APOS ((FLMUNICODE)39) -#define FLM_UNICODE_LPAREN ((FLMUNICODE)40) -#define FLM_UNICODE_RPAREN ((FLMUNICODE)41) -#define FLM_UNICODE_ASTERISK ((FLMUNICODE)42) -#define FLM_UNICODE_PLUS ((FLMUNICODE)43) -#define FLM_UNICODE_COMMA ((FLMUNICODE)44) -#define FLM_UNICODE_HYPHEN ((FLMUNICODE)45) -#define FLM_UNICODE_PERIOD ((FLMUNICODE)46) -#define FLM_UNICODE_FSLASH ((FLMUNICODE)47) - -#define FLM_UNICODE_0 ((FLMUNICODE)48) -#define FLM_UNICODE_1 ((FLMUNICODE)49) -#define FLM_UNICODE_2 ((FLMUNICODE)50) -#define FLM_UNICODE_3 ((FLMUNICODE)51) -#define FLM_UNICODE_4 ((FLMUNICODE)52) -#define FLM_UNICODE_5 ((FLMUNICODE)53) -#define FLM_UNICODE_6 ((FLMUNICODE)54) -#define FLM_UNICODE_7 ((FLMUNICODE)55) -#define FLM_UNICODE_8 ((FLMUNICODE)56) -#define FLM_UNICODE_9 ((FLMUNICODE)57) - -#define FLM_UNICODE_COLON ((FLMUNICODE)58) -#define FLM_UNICODE_SEMI ((FLMUNICODE)59) -#define FLM_UNICODE_LT ((FLMUNICODE)60) -#define FLM_UNICODE_EQ ((FLMUNICODE)61) -#define FLM_UNICODE_GT ((FLMUNICODE)62) -#define FLM_UNICODE_QUEST ((FLMUNICODE)63) -#define FLM_UNICODE_ATSIGN ((FLMUNICODE)64) - -#define FLM_UNICODE_A ((FLMUNICODE)65) -#define FLM_UNICODE_B ((FLMUNICODE)66) -#define FLM_UNICODE_C ((FLMUNICODE)67) -#define FLM_UNICODE_D ((FLMUNICODE)68) -#define FLM_UNICODE_E ((FLMUNICODE)69) -#define FLM_UNICODE_F ((FLMUNICODE)70) -#define FLM_UNICODE_G ((FLMUNICODE)71) -#define FLM_UNICODE_H ((FLMUNICODE)72) -#define FLM_UNICODE_I ((FLMUNICODE)73) -#define FLM_UNICODE_J ((FLMUNICODE)74) -#define FLM_UNICODE_K ((FLMUNICODE)75) -#define FLM_UNICODE_L ((FLMUNICODE)76) -#define FLM_UNICODE_M ((FLMUNICODE)77) -#define FLM_UNICODE_N ((FLMUNICODE)78) -#define FLM_UNICODE_O ((FLMUNICODE)79) -#define FLM_UNICODE_P ((FLMUNICODE)80) -#define FLM_UNICODE_Q ((FLMUNICODE)81) -#define FLM_UNICODE_R ((FLMUNICODE)82) -#define FLM_UNICODE_S ((FLMUNICODE)83) -#define FLM_UNICODE_T ((FLMUNICODE)84) -#define FLM_UNICODE_U ((FLMUNICODE)85) -#define FLM_UNICODE_V ((FLMUNICODE)86) -#define FLM_UNICODE_W ((FLMUNICODE)87) -#define FLM_UNICODE_X ((FLMUNICODE)88) -#define FLM_UNICODE_Y ((FLMUNICODE)89) -#define FLM_UNICODE_Z ((FLMUNICODE)90) - -#define FLM_UNICODE_LBRACKET ((FLMUNICODE)91) -#define FLM_UNICODE_BACKSLASH ((FLMUNICODE)92) -#define FLM_UNICODE_RBRACKET ((FLMUNICODE)93) -#define FLM_UNICODE_UNDERSCORE ((FLMUNICODE)95) - -#define FLM_UNICODE_a ((FLMUNICODE)97) -#define FLM_UNICODE_b ((FLMUNICODE)98) -#define FLM_UNICODE_c ((FLMUNICODE)99) -#define FLM_UNICODE_d ((FLMUNICODE)100) -#define FLM_UNICODE_e ((FLMUNICODE)101) -#define FLM_UNICODE_f ((FLMUNICODE)102) -#define FLM_UNICODE_g ((FLMUNICODE)103) -#define FLM_UNICODE_h ((FLMUNICODE)104) -#define FLM_UNICODE_i ((FLMUNICODE)105) -#define FLM_UNICODE_j ((FLMUNICODE)106) -#define FLM_UNICODE_k ((FLMUNICODE)107) -#define FLM_UNICODE_l ((FLMUNICODE)108) -#define FLM_UNICODE_m ((FLMUNICODE)109) -#define FLM_UNICODE_n ((FLMUNICODE)110) -#define FLM_UNICODE_o ((FLMUNICODE)111) -#define FLM_UNICODE_p ((FLMUNICODE)112) -#define FLM_UNICODE_q ((FLMUNICODE)113) -#define FLM_UNICODE_r ((FLMUNICODE)114) -#define FLM_UNICODE_s ((FLMUNICODE)115) -#define FLM_UNICODE_t ((FLMUNICODE)116) -#define FLM_UNICODE_u ((FLMUNICODE)117) -#define FLM_UNICODE_v ((FLMUNICODE)118) -#define FLM_UNICODE_w ((FLMUNICODE)119) -#define FLM_UNICODE_x ((FLMUNICODE)120) -#define FLM_UNICODE_y ((FLMUNICODE)121) -#define FLM_UNICODE_z ((FLMUNICODE)122) - -#define FLM_UNICODE_LBRACE ((FLMUNICODE)123) -#define FLM_UNICODE_PIPE ((FLMUNICODE)124) -#define FLM_UNICODE_RBRACE ((FLMUNICODE)125) -#define FLM_UNICODE_TILDE ((FLMUNICODE)126) -#define FLM_UNICODE_C_CEDILLA ((FLMUNICODE)199) -#define FLM_UNICODE_N_TILDE ((FLMUNICODE)209) -#define FLM_UNICODE_c_CEDILLA ((FLMUNICODE)231) -#define FLM_UNICODE_n_TILDE ((FLMUNICODE)241) - -/**************************************************************************** - WORD/BYTE ORDERING MACROS -****************************************************************************/ - -FLMUINT32 byteToLong( - FLMBYTE * ptr); - -#define byteToLong(p) ( \ - ((FLMUINT32) ( ((((FLMBYTE *)(p))[ 0]) << 8) | (((FLMBYTE *)(p))[ 1]) ) << 16 ) | \ - (FLMUINT16) ( ((((FLMBYTE *)(p))[ 2]) << 8) | (((FLMBYTE *)(p))[ 3]) ) ) - -FINLINE FLMUINT64 byteToLong64( - FLMBYTE * pucBuf) -{ - FLMUINT64 ui64Val = 0; - - ui64Val |= ((FLMUINT64)pucBuf[ 0]) << 56; - ui64Val |= ((FLMUINT64)pucBuf[ 1]) << 48; - ui64Val |= ((FLMUINT64)pucBuf[ 2]) << 40; - ui64Val |= ((FLMUINT64)pucBuf[ 3]) << 32; - ui64Val |= ((FLMUINT64)pucBuf[ 4]) << 24; - ui64Val |= ((FLMUINT64)pucBuf[ 5]) << 16; - ui64Val |= ((FLMUINT64)pucBuf[ 6]) << 8; - ui64Val |= ((FLMUINT64)pucBuf[ 7]); - - return( ui64Val); -} - -FLMUINT32 byteToInt( - FLMBYTE * ptr); - -#define byteToInt(p) ( \ - (FLMUINT16) ( ((((FLMBYTE *)(p))[ 0]) << 8) | (((FLMBYTE *)(p))[ 1]) ) ) - -void longToByte( - FLMINT32 uiNum, - FLMBYTE * ptr); - -#define longToByte( n, p) { \ - FLMUINT32 ui32Temp = (FLMUINT32) (n); FLMBYTE * pTemp = (FLMBYTE *)(p); \ - pTemp[0] = (FLMBYTE) (ui32Temp >> 24); \ - pTemp[1] = (FLMBYTE) (ui32Temp >> 16); \ - pTemp[2] = (FLMBYTE) (ui32Temp >> 8); \ - pTemp[3] = (FLMBYTE) (ui32Temp ); \ - } - -void long64ToByte( - FLMINT64 uiNum, - FLMBYTE * ptr); - -#define long64ToByte( n, p) { \ - FLMUINT64 ui64Temp = (FLMUINT64) (n); FLMBYTE * pTemp = (FLMBYTE *)(p); \ - pTemp[0] = (FLMBYTE) (ui64Temp >> 56); \ - pTemp[1] = (FLMBYTE) (ui64Temp >> 48); \ - pTemp[2] = (FLMBYTE) (ui64Temp >> 40); \ - pTemp[3] = (FLMBYTE) (ui64Temp >> 32); \ - pTemp[4] = (FLMBYTE) (ui64Temp >> 24); \ - pTemp[5] = (FLMBYTE) (ui64Temp >> 16); \ - pTemp[6] = (FLMBYTE) (ui64Temp >> 8); \ - pTemp[7] = (FLMBYTE) (ui64Temp ); \ - } - -void intToByte( - FLMINT16 uiNum, - FLMBYTE * ptr); - -#define intToByte( n, p) { \ - FLMUINT16 ui16Temp = (FLMUINT16) (n); FLMBYTE * pTemp = (FLMBYTE *) (p); \ - pTemp[0] = (FLMBYTE) (ui16Temp >> 8); \ - pTemp[1] = (FLMBYTE) (ui16Temp ); \ - } - -#ifndef FLM_BIG_ENDIAN - - // Sanity check - - #if defined( FLM_SPARC) - #error Wrong endian order selected - #endif - - #define LO(wrd) (*(FLMUINT8 *)&wrd) - #define HI(wrd) (*((FLMUINT8 *)&wrd + 1)) - - #if( defined( FLM_UNIX) && defined( FLM_STRICT_ALIGNMENT)) - - /**************************************************************************** - LITTLE ENDIAN BYTE ORDER - NOT SINGLE-BYTE ALIGNED - ****************************************************************************/ - - #define FB2UW( bp) ((FLMUINT16)((((FLMUINT16)(((FLMUINT8 *)(bp))[1]))<<8) | \ - (((FLMUINT16)(((FLMUINT8 *)(bp))[0]))))) - - #define FB2UD( bp) ((FLMUINT32)( (((FLMUINT32)(((FLMUINT8 *)(bp))[3]))<<24) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[2]))<<16) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[1]))<< 8) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[0]))))) - - #define UW2FBA( uw, bp) (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00)>>8)))) - - #define UD2FBA( udw, bp) (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00)>>8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000)>>16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000)>>24))) - - #else - - /**************************************************************************** - LITTLE ENDIAN BYTE ORDER - SINGLE-BYTE ALIGNED - ****************************************************************************/ - - #define FB2UW( fbp) (*((FLMUINT16 *)(fbp))) - #define FB2UD( fbp) (*((FLMUINT32 *)(fbp))) - #define UW2FBA( uw, fbp) (*((FLMUINT16 *)(fbp)) = ((FLMUINT16) (uw))) - #define UD2FBA( uw, fbp) (*((FLMUINT32 *)(fbp)) = ((FLMUINT32) (uw))) - - #endif - -#else - + /**************************************************************************** - BIG ENDIAN BYTE ORDER (UNIX) - NOT SINGLE-BYTE ALIGNED + Desc: Native constants ****************************************************************************/ - - #if defined( __i386__) - #error Wrong endian order selected - #endif - - #define LO(wrd) (*((FLMUINT8 *)&wrd + 1)) - #define HI(wrd) (*(FLMUINT8 *)&wrd) - - #define FB2UW( bp ) ( (FLMUINT16)( (((FLMUINT16)(((FLMUINT8 *)(bp))[1]))<<8) | \ - (((FLMUINT16)(((FLMUINT8 *)(bp))[0])) ) )) - - #define FB2UD( bp ) ( (FLMUINT32)( (((FLMUINT32)(((FLMUINT8 *)(bp))[3]))<<24) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[2]))<<16) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[1]))<< 8) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[0])) ) )) - - #define UW2FBA( uw, bp ) (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00)>>8)))) - - #define UD2FBA( udw, bp) (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00)>>8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000)>>16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000)>>24))) - -#endif - -/**************************************************************************** - File Path Functions & Macros -****************************************************************************/ - -#if defined( FLM_WIN) || defined( FLM_NLM) - #define FWSLASH '/' - #define SLASH '\\' - #define SSLASH "\\" - #define COLON ':' - #define PERIOD '.' - #define PARENT_DIR ".." - #define CURRENT_DIR "." -#else - #ifndef FWSLASH - #define FWSLASH '/' - #endif - - #ifndef SLASH - #define SLASH '/' - #endif - - #ifndef SSLASH - #define SSLASH "/" - #endif - - #ifndef COLON - #define COLON ':' - #endif - - #ifndef PERIOD - #define PERIOD '.' - #endif - - #ifndef PARENT_DIR - #define PARENT_DIR ".." - #endif - - #ifndef CURRENT_DIR - #define CURRENT_DIR "." - #endif -#endif - -/**************************************************************************** - CPU Release Functions -****************************************************************************/ - -#ifdef FLM_NLM - #define f_yieldCPU() \ - NWYieldIfTime() -#else - #define f_yieldCPU() -#endif - -void f_sleep( - FLMUINT uiMilliseconds); - -#ifdef FLM_WIN - #define f_sleep( uiMilliseconds) \ - Sleep( (DWORD)uiMilliseconds) -#endif - -/***************************************************************************** - Mutexes -*****************************************************************************/ - -#ifndef FLM_NLM - RCODE f_mutexCreate( - F_MUTEX * phMutex); - - void f_mutexDestroy( - F_MUTEX * phMutex); -#endif - -#if defined( FLM_NLM) - - FINLINE RCODE f_mutexCreate( - F_MUTEX * phMutex) + + #define NATIVE_SPACE ' ' + #define NATIVE_DOT '.' + #define NATIVE_PLUS '+' + #define NATIVE_MINUS '-' + #define NATIVE_WILDCARD '*' + #define NATIVE_QUESTIONMARK '?' + + #define NATIVE_UPPER_A 'A' + #define NATIVE_UPPER_F 'F' + #define NATIVE_UPPER_X 'X' + #define NATIVE_UPPER_Z 'Z' + #define NATIVE_LOWER_A 'a' + #define NATIVE_LOWER_F 'f' + #define NATIVE_LOWER_X 'x' + #define NATIVE_LOWER_Z 'z' + #define NATIVE_ZERO '0' + #define NATIVE_NINE '9' + + #define f_stringToAscii(str) + + #define f_toascii(native) \ + (native) + + #define f_tonative(ascii) \ + (ascii) + + #define f_toupper(native) \ + (((native) >= 'a' && (native) <= 'z') \ + ? (native) - 'a' + 'A' : (native)) + + #define f_tolower(native) \ + (((native) >= 'A' && (native) <= 'Z') \ + ? (native) - 'A' + 'a' : (native)) + + #define f_islower(native) \ + ((native) >= 'a' && (native) <= 'z') + + /**************************************************************************** + Desc: Unicode constants + ****************************************************************************/ + + #define FLM_UNICODE_LINEFEED ((FLMUNICODE)10) + #define FLM_UNICODE_SPACE ((FLMUNICODE)32) + #define FLM_UNICODE_BANG ((FLMUNICODE)33) + #define FLM_UNICODE_QUOTE ((FLMUNICODE)34) + #define FLM_UNICODE_POUND ((FLMUNICODE)35) + #define FLM_UNICODE_DOLLAR ((FLMUNICODE)36) + #define FLM_UNICODE_PERCENT ((FLMUNICODE)37) + #define FLM_UNICODE_AMP ((FLMUNICODE)38) + #define FLM_UNICODE_APOS ((FLMUNICODE)39) + #define FLM_UNICODE_LPAREN ((FLMUNICODE)40) + #define FLM_UNICODE_RPAREN ((FLMUNICODE)41) + #define FLM_UNICODE_ASTERISK ((FLMUNICODE)42) + #define FLM_UNICODE_PLUS ((FLMUNICODE)43) + #define FLM_UNICODE_COMMA ((FLMUNICODE)44) + #define FLM_UNICODE_HYPHEN ((FLMUNICODE)45) + #define FLM_UNICODE_PERIOD ((FLMUNICODE)46) + #define FLM_UNICODE_FSLASH ((FLMUNICODE)47) + + #define FLM_UNICODE_0 ((FLMUNICODE)48) + #define FLM_UNICODE_1 ((FLMUNICODE)49) + #define FLM_UNICODE_2 ((FLMUNICODE)50) + #define FLM_UNICODE_3 ((FLMUNICODE)51) + #define FLM_UNICODE_4 ((FLMUNICODE)52) + #define FLM_UNICODE_5 ((FLMUNICODE)53) + #define FLM_UNICODE_6 ((FLMUNICODE)54) + #define FLM_UNICODE_7 ((FLMUNICODE)55) + #define FLM_UNICODE_8 ((FLMUNICODE)56) + #define FLM_UNICODE_9 ((FLMUNICODE)57) + + #define FLM_UNICODE_COLON ((FLMUNICODE)58) + #define FLM_UNICODE_SEMI ((FLMUNICODE)59) + #define FLM_UNICODE_LT ((FLMUNICODE)60) + #define FLM_UNICODE_EQ ((FLMUNICODE)61) + #define FLM_UNICODE_GT ((FLMUNICODE)62) + #define FLM_UNICODE_QUEST ((FLMUNICODE)63) + #define FLM_UNICODE_ATSIGN ((FLMUNICODE)64) + + #define FLM_UNICODE_A ((FLMUNICODE)65) + #define FLM_UNICODE_B ((FLMUNICODE)66) + #define FLM_UNICODE_C ((FLMUNICODE)67) + #define FLM_UNICODE_D ((FLMUNICODE)68) + #define FLM_UNICODE_E ((FLMUNICODE)69) + #define FLM_UNICODE_F ((FLMUNICODE)70) + #define FLM_UNICODE_G ((FLMUNICODE)71) + #define FLM_UNICODE_H ((FLMUNICODE)72) + #define FLM_UNICODE_I ((FLMUNICODE)73) + #define FLM_UNICODE_J ((FLMUNICODE)74) + #define FLM_UNICODE_K ((FLMUNICODE)75) + #define FLM_UNICODE_L ((FLMUNICODE)76) + #define FLM_UNICODE_M ((FLMUNICODE)77) + #define FLM_UNICODE_N ((FLMUNICODE)78) + #define FLM_UNICODE_O ((FLMUNICODE)79) + #define FLM_UNICODE_P ((FLMUNICODE)80) + #define FLM_UNICODE_Q ((FLMUNICODE)81) + #define FLM_UNICODE_R ((FLMUNICODE)82) + #define FLM_UNICODE_S ((FLMUNICODE)83) + #define FLM_UNICODE_T ((FLMUNICODE)84) + #define FLM_UNICODE_U ((FLMUNICODE)85) + #define FLM_UNICODE_V ((FLMUNICODE)86) + #define FLM_UNICODE_W ((FLMUNICODE)87) + #define FLM_UNICODE_X ((FLMUNICODE)88) + #define FLM_UNICODE_Y ((FLMUNICODE)89) + #define FLM_UNICODE_Z ((FLMUNICODE)90) + + #define FLM_UNICODE_LBRACKET ((FLMUNICODE)91) + #define FLM_UNICODE_BACKSLASH ((FLMUNICODE)92) + #define FLM_UNICODE_RBRACKET ((FLMUNICODE)93) + #define FLM_UNICODE_UNDERSCORE ((FLMUNICODE)95) + + #define FLM_UNICODE_a ((FLMUNICODE)97) + #define FLM_UNICODE_b ((FLMUNICODE)98) + #define FLM_UNICODE_c ((FLMUNICODE)99) + #define FLM_UNICODE_d ((FLMUNICODE)100) + #define FLM_UNICODE_e ((FLMUNICODE)101) + #define FLM_UNICODE_f ((FLMUNICODE)102) + #define FLM_UNICODE_g ((FLMUNICODE)103) + #define FLM_UNICODE_h ((FLMUNICODE)104) + #define FLM_UNICODE_i ((FLMUNICODE)105) + #define FLM_UNICODE_j ((FLMUNICODE)106) + #define FLM_UNICODE_k ((FLMUNICODE)107) + #define FLM_UNICODE_l ((FLMUNICODE)108) + #define FLM_UNICODE_m ((FLMUNICODE)109) + #define FLM_UNICODE_n ((FLMUNICODE)110) + #define FLM_UNICODE_o ((FLMUNICODE)111) + #define FLM_UNICODE_p ((FLMUNICODE)112) + #define FLM_UNICODE_q ((FLMUNICODE)113) + #define FLM_UNICODE_r ((FLMUNICODE)114) + #define FLM_UNICODE_s ((FLMUNICODE)115) + #define FLM_UNICODE_t ((FLMUNICODE)116) + #define FLM_UNICODE_u ((FLMUNICODE)117) + #define FLM_UNICODE_v ((FLMUNICODE)118) + #define FLM_UNICODE_w ((FLMUNICODE)119) + #define FLM_UNICODE_x ((FLMUNICODE)120) + #define FLM_UNICODE_y ((FLMUNICODE)121) + #define FLM_UNICODE_z ((FLMUNICODE)122) + + #define FLM_UNICODE_LBRACE ((FLMUNICODE)123) + #define FLM_UNICODE_PIPE ((FLMUNICODE)124) + #define FLM_UNICODE_RBRACE ((FLMUNICODE)125) + #define FLM_UNICODE_TILDE ((FLMUNICODE)126) + #define FLM_UNICODE_C_CEDILLA ((FLMUNICODE)199) + #define FLM_UNICODE_N_TILDE ((FLMUNICODE)209) + #define FLM_UNICODE_c_CEDILLA ((FLMUNICODE)231) + #define FLM_UNICODE_n_TILDE ((FLMUNICODE)241) + + /**************************************************************************** + Desc: Byte order macros + ****************************************************************************/ + + FINLINE FLMUINT32 byteToLong( + FLMBYTE * pucBuf) { - if( (*phMutex = (F_MUTEX)kMutexAlloc( (BYTE *)"NOVDB")) == F_MUTEX_NULL) - { - return( RC_SET( FERR_MEM)); - } - - return( FERR_OK); - } - - FINLINE void f_mutexDestroy( - F_MUTEX * phMutex) - { - if (*phMutex != F_MUTEX_NULL) - { - (void)kMutexFree( (MUTEX)(*phMutex)); - *phMutex = F_MUTEX_NULL; - } - } - - FINLINE void f_mutexLock( - F_MUTEX hMutex) - { - (void)kMutexLock( (MUTEX)hMutex); - } - - FINLINE void f_mutexUnlock( - F_MUTEX hMutex) - { - (void)kMutexUnlock( (MUTEX)hMutex); - } - -#elif defined( FLM_WIN) - - FINLINE void f_mutexLock( - F_MUTEX hMutex) - { - (void)EnterCriticalSection( (CRITICAL_SECTION *)hMutex); - } - - FINLINE void f_mutexUnlock( - F_MUTEX hMutex) - { - (void)LeaveCriticalSection( (CRITICAL_SECTION *)hMutex); + FLMUINT32 ui32Val = 0; + + ui32Val |= ((FLMUINT32)pucBuf[ 0]) << 24; + ui32Val |= ((FLMUINT32)pucBuf[ 1]) << 16; + ui32Val |= ((FLMUINT32)pucBuf[ 2]) << 8; + ui32Val |= ((FLMUINT32)pucBuf[ 3]); + + return( ui32Val); } -#elif defined( FLM_UNIX) - - void f_mutexLock( - F_MUTEX hMutex); + FINLINE FLMUINT64 byteToLong64( + FLMBYTE * pucBuf) + { + FLMUINT64 ui64Val = 0; - void f_mutexUnlock( - F_MUTEX hMutex); - -#endif - - -/***************************************************************************** - Semaphores -*****************************************************************************/ - -/* pass this define to semwait if you want to wait forever. may cause hung */ -/* machines or proccesses */ -#define F_SEM_WAITFOREVER (0xFFFFFFFF) - -#if defined( FLM_WIN) - typedef HANDLE F_SEM; - typedef HANDLE * F_SEM_p; - #define F_SEM_NULL NULL - -#elif defined( FLM_NLM) - typedef SEMAPHORE F_SEM; - typedef SEMAPHORE * F_SEM_p; - #define F_SEM_NULL 0 - -#elif defined( FLM_UNIX) - - /* Added by R. Ganesan because Event Semaphores are not the same as - Mutex Semaphores. Event Semaphores can be signalled without being - locked. Event Semaphores need to have a genuine wait till they are - signalled. - - Note: If semaphore.h is not available; this can be implemented in - terms of condition variables. Condition variables can also be used - if it is desired that multiple signals == one signal. - */ + ui64Val |= ((FLMUINT64)pucBuf[ 0]) << 56; + ui64Val |= ((FLMUINT64)pucBuf[ 1]) << 48; + ui64Val |= ((FLMUINT64)pucBuf[ 2]) << 40; + ui64Val |= ((FLMUINT64)pucBuf[ 3]) << 32; + ui64Val |= ((FLMUINT64)pucBuf[ 4]) << 24; + ui64Val |= ((FLMUINT64)pucBuf[ 5]) << 16; + ui64Val |= ((FLMUINT64)pucBuf[ 6]) << 8; + ui64Val |= ((FLMUINT64)pucBuf[ 7]); + + return( ui64Val); + } + + FINLINE FLMUINT16 byteToInt( + FLMBYTE * pucBuf) + { + FLMUINT16 ui16Val = 0; + + ui16Val |= ((FLMUINT16)pucBuf[ 0]) << 8; + ui16Val |= ((FLMUINT16)pucBuf[ 1]); + + return( ui16Val); + } + + FINLINE void longToByte( + FLMINT32 i32Num, + FLMBYTE * pucBuf) + { + FLMUINT32 ui32Temp = (FLMUINT32)(i32Num); + FLMBYTE * pucTemp = pucBuf; + pucTemp[ 0] = (FLMBYTE) (ui32Temp >> 24); + pucTemp[ 1] = (FLMBYTE) (ui32Temp >> 16); + pucTemp[ 2] = (FLMBYTE) (ui32Temp >> 8); + pucTemp[ 3] = (FLMBYTE) (ui32Temp); + } + + FINLINE void long64ToByte( + FLMINT64 i64Num, + FLMBYTE * pucBuf) + { + FLMUINT64 ui64Temp = (FLMUINT64)i64Num; + FLMBYTE * pucTemp = pucBuf; + + pucTemp[ 0] = (FLMBYTE) (ui64Temp >> 56); + pucTemp[ 1] = (FLMBYTE) (ui64Temp >> 48); + pucTemp[ 2] = (FLMBYTE) (ui64Temp >> 40); + pucTemp[ 3] = (FLMBYTE) (ui64Temp >> 32); + pucTemp[ 4] = (FLMBYTE) (ui64Temp >> 24); + pucTemp[ 5] = (FLMBYTE) (ui64Temp >> 16); + pucTemp[ 6] = (FLMBYTE) (ui64Temp >> 8); + pucTemp[ 7] = (FLMBYTE) (ui64Temp); + } + + FINLINE void intToByte( + FLMINT16 i16Num, + FLMBYTE * pucBuf) + { + FLMUINT16 ui16Temp = (FLMUINT16)i16Num; + FLMBYTE * pucTemp = pucBuf; + + pucTemp[ 0] = (FLMBYTE) (ui16Temp >> 8); + pucTemp[ 1] = (FLMBYTE) (ui16Temp); + } + + #ifndef FLM_BIG_ENDIAN + + #if defined( FLM_SPARC) || defined( FLM_POWER_PC) + #error Wrong endian order selected + #endif + + #define LO(wrd) \ + (*(FLMUINT8 *)&wrd) + + #define HI(wrd) \ + (*((FLMUINT8 *)&wrd + 1)) + + #if( defined( FLM_UNIX) && defined( FLM_STRICT_ALIGNMENT)) + + #define FB2UW( bp) \ + ((FLMUINT16)((((FLMUINT16)(((FLMUINT8 *)(bp))[1]))<<8) | \ + (((FLMUINT16)(((FLMUINT8 *)(bp))[0]))))) + + #define FB2UD( bp) \ + ((FLMUINT32)( (((FLMUINT32)(((FLMUINT8 *)(bp))[3]))<<24) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[2]))<<16) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[1]))<< 8) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[0]))))) + + #define UW2FBA( uw, bp) \ + (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ + ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00)>>8)))) + + #define UD2FBA( udw, bp) \ + (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ + ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00)>>8)), \ + ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000)>>16)), \ + ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000)>>24))) + + #else + + #define FB2UW( fbp) \ + (*((FLMUINT16 *)(fbp))) + + #define FB2UD( fbp) \ + (*((FLMUINT32 *)(fbp))) + + #define UW2FBA( uw, fbp) \ + (*((FLMUINT16 *)(fbp)) = ((FLMUINT16) (uw))) + + #define UD2FBA( uw, fbp) \ + (*((FLMUINT32 *)(fbp)) = ((FLMUINT32) (uw))) + + #endif + + #else + + #if defined( __i386__) + #error Wrong endian order selected + #endif + + #define LO(wrd) \ + (*((FLMUINT8 *)&wrd + 1)) + + #define HI(wrd) \ + (*(FLMUINT8 *)&wrd) + + #define FB2UW( bp) \ + ((FLMUINT16)((((FLMUINT16)(((FLMUINT8 *)(bp))[1])) << 8) | \ + (((FLMUINT16)(((FLMUINT8 *)(bp))[0])) ) )) + + #define FB2UD( bp) \ + ((FLMUINT32)((((FLMUINT32)(((FLMUINT8 *)(bp))[3])) << 24) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[2])) << 16) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[1])) << 8) | \ + (((FLMUINT32)(((FLMUINT8 *)(bp))[0])) ) )) + + #define UW2FBA( uw, bp) + (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ + ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00)>>8)))) + + #define UD2FBA( udw, bp) \ + (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ + ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00)>>8)), \ + ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000)>>16)), \ + ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000)>>24))) + #endif + + /**************************************************************************** + Desc: File Path Functions & Macros + ****************************************************************************/ + + #if defined( FLM_WIN) || defined( FLM_NLM) + #define FWSLASH '/' + #define SLASH '\\' + #define SSLASH "\\" + #define COLON ':' + #define PERIOD '.' + #define PARENT_DIR ".." + #define CURRENT_DIR "." + #else + #ifndef FWSLASH + #define FWSLASH '/' + #endif + + #ifndef SLASH + #define SLASH '/' + #endif + + #ifndef SSLASH + #define SSLASH "/" + #endif + + #ifndef COLON + #define COLON ':' + #endif + + #ifndef PERIOD + #define PERIOD '.' + #endif + + #ifndef PARENT_DIR + #define PARENT_DIR ".." + #endif + + #ifndef CURRENT_DIR + #define CURRENT_DIR "." + #endif + #endif + + /**************************************************************************** + Desc: CPU Release Functions + ****************************************************************************/ + + #ifdef FLM_NLM + #define f_yieldCPU() \ + NWYieldIfTime() + #else + #define f_yieldCPU() + #endif + + void f_sleep( + FLMUINT uiMilliseconds); + + #ifdef FLM_WIN + #define f_sleep( uiMilliseconds) \ + Sleep( (DWORD)uiMilliseconds) + #endif + + /**************************************************************************** + Desc: Mutexes + ****************************************************************************/ + + #if defined( FLM_WIN) + + RCODE f_mutexCreate( + F_MUTEX * phMutex); + + void f_mutexDestroy( + F_MUTEX * phMutex); + + FINLINE void f_mutexLock( + F_MUTEX hMutex) + { + (void)EnterCriticalSection( (CRITICAL_SECTION *)hMutex); + } + + FINLINE void f_mutexUnlock( + F_MUTEX hMutex) + { + (void)LeaveCriticalSection( (CRITICAL_SECTION *)hMutex); + } + + #elif defined( FLM_UNIX) + + RCODE f_mutexCreate( + F_MUTEX * phMutex); + + void f_mutexDestroy( + F_MUTEX * phMutex); + + void f_mutexLock( + F_MUTEX hMutex); + + void f_mutexUnlock( + F_MUTEX hMutex); + + #endif + + + /**************************************************************************** + Desc: Semaphores + ****************************************************************************/ + + #if defined( FLM_WIN) + + typedef HANDLE F_SEM; + typedef HANDLE * F_SEM_p; + #define F_SEM_NULL NULL + + #elif defined( FLM_UNIX) + + #if defined( FLM_AIX) || defined( FLM_OSX) + + typedef struct + { + pthread_mutex_t lock; + pthread_cond_t cond; + int count; + } sema_t; + + int sema_init( sema_t * sem); + + void sema_destroy( sema_t * sem); + + void p_operation_cleanup( void * arg); + + int sema_wait( sema_t * sem); + + int sema_timedwait( sema_t * sem, unsigned int uiTimeout); + + int sema_signal( sema_t * sem); + + #else + + #include + + #endif + + typedef F_SEM * F_SEM_p; + #define F_SEM_NULL NULL + + #elif !defined( FLM_NLM) + #error Unsupported platform + #endif + + #if defined( FLM_WIN) + + FINLINE RCODE f_semCreate( + F_SEM * phSem) + { + if( (*phSem = CreateSemaphore( (LPSECURITY_ATTRIBUTES)NULL, + 0, 10000, NULL )) == NULL) + { + return( RC_SET( FERR_MUTEX_OPERATION_FAILED)); + } + + return FERR_OK; + } + + FINLINE void f_semDestroy( + F_SEM * phSem) + { + if (*phSem != F_SEM_NULL) + { + CloseHandle( *phSem); + *phSem = F_SEM_NULL; + } + } + + FINLINE RCODE f_semWait( + F_SEM hSem, + FLMUINT uiTimeout) + { + if( WaitForSingleObject( hSem, uiTimeout ) == WAIT_OBJECT_0) + { + return( FERR_OK); + } + else + { + return( RC_SET( FERR_MUTEX_UNABLE_TO_LOCK)); + } + } + + FINLINE void f_semSignal( + F_SEM hSem) + { + (void)ReleaseSemaphore( hSem, 1, NULL); + } + + #elif defined( FLM_UNIX) + + void f_semDestroy( + F_SEM * phSem); + + RCODE f_semCreate( + F_SEM * phSem); + + RCODE f_semWait( + F_SEM hSem, + FLMUINT uiTimeout); + + FINLINE void f_semSignal( + F_SEM hSem) + { #if defined( FLM_AIX) || defined( FLM_OSX) - - // OS X only has named semaphores, not unamed ones. If does, however - // have condition variables and mutexes, so we'll just use the AIX - // code (and get timed waits as a bonus...) - - typedef struct - { - pthread_mutex_t lock; - pthread_cond_t cond; - int count; - } sema_t; - - int sema_init( sema_t * sem); - void sema_destroy( sema_t * sem); - void p_operation_cleanup( void * arg); - int sema_wait( sema_t * sem); - int sema_timedwait( sema_t * sem, unsigned int uiTimeout); - int sema_signal( sema_t * sem); - + (void)sema_signal( (sema_t *)hSem); #else - #include - - // Note for future reference: We had problems in the AIX build for - // eDir 8.8 with open being redefined to open64 in some places - // because we needed support for large files and this was causing - // problems with FlmBlobImp::open(). The redefinition happens in - // fcntl.h, and only fposix.cpp needs to include it. Unfortunately, - // semaphore.h also includes fcntl.h, and most flaim files end up - // including this ftksem.h. This means that if we ever enable - // large file support on other unix's, we might bump into these - // problems again. - + (void)sem_post( (sem_t *)hSem); + #endif + } #endif - typedef F_SEM * F_SEM_p; - #define F_SEM_NULL NULL - -#else - #error Unsupported platform -#endif - -#if defined( FLM_NLM) - - FINLINE RCODE f_semCreate( - F_SEM * phSem) - { - if( (*phSem = (F_SEM)kSemaphoreAlloc( (BYTE *)"NOVDB", 0)) == F_SEM_NULL) - { - return( RC_SET( FERR_MEM)); - } - - return( FERR_OK); - } - - FINLINE void f_semDestroy( - F_SEM * phSem) - { - if (*phSem != F_SEM_NULL) - { - (void)kSemaphoreFree( (SEMAPHORE)(*phSem)); - *phSem = F_SEM_NULL; - } - } - - FINLINE RCODE f_semWait( - F_SEM hSem, - FLMUINT uiTimeout) - { - RCODE rc = FERR_OK; - - if( uiTimeout == F_SEM_WAITFOREVER) - { - if( kSemaphoreWait( (SEMAPHORE)hSem) != 0) - { - rc = RC_SET( FERR_MUTEX_UNABLE_TO_LOCK); - } - } - else - { - if( kSemaphoreTimedWait( (SEMAPHORE)hSem, (UINT)uiTimeout) != 0) - { - rc = RC_SET( FERR_MUTEX_UNABLE_TO_LOCK); - } - } - - return( rc); - } - - FINLINE void f_semSignal( - F_SEM hSem) - { - (void)kSemaphoreSignal( (SEMAPHORE)hSem); - } - -#elif defined( FLM_WIN) - - FINLINE RCODE f_semCreate( - F_SEM * phSem) - { - if( (*phSem = CreateSemaphore( (LPSECURITY_ATTRIBUTES)NULL, - 0, 10000, NULL )) == NULL) - { - return( RC_SET( FERR_MUTEX_OPERATION_FAILED)); - } - - return FERR_OK; - } - - FINLINE void f_semDestroy( - F_SEM * phSem) - { - if (*phSem != F_SEM_NULL) - { - CloseHandle( *phSem); - *phSem = F_SEM_NULL; - } - } - - FINLINE RCODE f_semWait( - F_SEM hSem, - FLMUINT uiTimeout) - { - if( WaitForSingleObject( hSem, uiTimeout ) == WAIT_OBJECT_0) - { - return( FERR_OK); - } - else - { - return( RC_SET( FERR_MUTEX_UNABLE_TO_LOCK)); - } - } - - FINLINE void f_semSignal( - F_SEM hSem) - { - (void)ReleaseSemaphore( hSem, 1, NULL); - } - -#elif defined( FLM_UNIX) - - void f_semDestroy( - F_SEM * phSem); - - RCODE f_semCreate( - F_SEM * phSem); - - RCODE f_semWait( - F_SEM hSem, - FLMUINT uiTimeout); - - FINLINE void f_semSignal( - F_SEM hSem) - { -#if defined( FLM_AIX) || defined( FLM_OSX) - (void)sema_signal( (sema_t *)hSem); -#else - (void)sem_post( (sem_t *)hSem); -#endif - } - -#else - #error Platform undefined -#endif - -/**************************************************************************** - Random Generation Functions -****************************************************************************/ - -#define MAX_RANDOM 2147483646L - -typedef struct -{ - FLMINT32 i32Seed; -} f_randomGenerator; - -/* - Call f_randomSetSeed to initialize your random-number generator. Then -call f_randomLong, f_randomChoice, or f_randomTruth to access the series of -random values. - - Initialize your generator with f_randomSetSeed( &r, SOME_CONSTANT) to get a -reproducible sequence of pseudo-random numbers. Using different constant -seeds will give you independent sequences. The constant can be any number -between 1 and MAX_RANDOM, inclusive. - - Call f_randomLong to get a number randomly distributed between 1 and -MAX_RANDOM. This is the basic call, but is usually not as convenient as -the subsequent functions, all of which call f_randomLong and process the -result into a more useable form. - - 1 <= f_randomLong(&r) <= MAX_RANDOM - - Call f_randomChoice to get a number uniformly distributed across a -specified range of integer values. - - lo <= f_randomChoice(&r, lo, hi) <= hi - - Call f_randomTruth(&r, n) to get a boolean value which is true n percent -of the time (0 <= n <= 100). - - 0 <= f_randomTrue(&r, n) <= 1 -*/ - -void f_randomize( - f_randomGenerator * pRand); - -void f_randomSetSeed( - f_randomGenerator * pRand, - FLMINT32 i32seed); - -FLMINT32 f_randomLong( - f_randomGenerator * pRand); - -FLMINT32 f_randomChoice( - f_randomGenerator * pRand, - FLMINT32 lo, - FLMINT32 hi); - -FLMINT f_randomTruth( - f_randomGenerator * pRand, - FLMINT iPercentageTrue); - -/**************************************************************************** - Time, date, timestamp functions -****************************************************************************/ -typedef struct -{ - FLMUINT16 year; - FLMBYTE month; - FLMBYTE day; -} F_DATE, * F_DATE_p; - -typedef struct -{ - FLMBYTE hour; - FLMBYTE minute; - FLMBYTE second; - FLMBYTE hundredth; -} F_TIME, * F_TIME_p; - -typedef struct -{ - FLMUINT16 year; - FLMBYTE month; - FLMBYTE day; - FLMBYTE hour; - FLMBYTE minute; - FLMBYTE second; - FLMBYTE hundredth; -} F_TMSTAMP, * F_TMSTAMP_p; - -void f_timeGetSeconds( - FLMUINT * puiSeconds); - -void f_timeGetTimeStamp( - F_TMSTAMP * pTimeStamp); - -FLMINT f_timeGetLocalOffset( void); - -void f_timeSecondsToDate( - FLMUINT uiSeconds, - F_TMSTAMP * pTimeStamp); - -void f_timeDateToSeconds( - F_TMSTAMP * pTimeStamp, - FLMUINT * puiSeconds); - -FLMINT f_timeCompareTimeStamps( - F_TMSTAMP * pTimeStamp1, - F_TMSTAMP * pTimeStamp2, - FLMUINT uiFlag); - -#if defined( FLM_UNIX) - unsigned f_timeGetMilliTime(); -#endif - -/********************************************************************** -Desc: Atomic Increment, Decrement, Exchange -Note: Some of this code is derived from the Ximian source code contained - in that Mono project's atomic.h file. -**********************************************************************/ -#ifndef FLM_HAVE_ATOMICS - #define FLM_HAVE_ATOMICS -#endif - -/******************************************************************* -Desc: -*******************************************************************/ -#if defined( FLM_GNUC) && defined( __ia64__) -FINLINE FLMINT32 ia64_compare_and_swap( - volatile int * piTarget, - FLMINT32 i32NewVal, - FLMINT32 i32CompVal) -{ - FLMINT32 i32Old; - - asm volatile ("mov ar.ccv = %2 ;;\n\t" - "cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t" - : "=r" (i32Old) : "r" (piTarget), - "r" (i32CompVal), - "r" (i32NewVal)); - - return( i32Old); -} -#endif - -/********************************************************************** -Desc: -**********************************************************************/ -#if defined( FLM_SPARC) && defined( FLM_SOLARIS) && !defined( FLM_GNUC) -extern "C" FLMINT32 sparc_atomic_add_32( - volatile FLMINT32 * piTarget, - FLMINT32 iDelta); -#endif - -/********************************************************************** -Desc: -**********************************************************************/ -#if defined( FLM_SPARC) && defined( FLM_SOLARIS) && !defined( FLM_GNUC) -extern "C" FLMINT32 sparc_atomic_xchg_32( - volatile FLMINT32 * piTarget, - FLMINT32 iNewValue); -#endif - -/********************************************************************** -Desc: -**********************************************************************/ -#if defined( FLM_AIX) -FINLINE int aix_atomic_add( - volatile int * piTarget, - int iDelta) -{ - return( fetch_and_add( (int *)piTarget, iDelta) + iDelta); -} -#endif - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 _flmAtomicInc( - FLMATOMIC * piTarget) -{ - #if defined( FLM_NLM) - { - return( (FLMINT32)nlm_AtomicIncrement( (volatile LONG *)piTarget)); - } - #elif defined( FLM_WIN) - { - return( (FLMINT32)InterlockedIncrement( (volatile LONG *)piTarget)); - } - #elif defined( FLM_AIX) - { - return( (FLMINT32)aix_atomic_add( piTarget, 1)); - } - #elif defined( FLM_GNUC) - { - #if defined( __i386__) || defined( __x86_64__) - { - FLMINT32 i32Tmp; - - __asm__ __volatile__ ("lock; xaddl %0, %1" - : "=r" (i32Tmp), "=m" (*piTarget) - : "0" (1), "m" (*piTarget)); - - return( i32Tmp + 1); - } - #elif defined( __ppc__) || defined ( __powerpc__) - { - FLMINT32 i32Result = 0; - FLMINT32 i32Tmp; - - __asm__ __volatile__ ("\n1:\n\t" - "lwarx %0, 0, %2\n\t" - "addi %1, %0, 1\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 1b" - : "=&b" (i32Result), "=&b" (i32Tmp) - : "r" (piTarget) : "cc", "memory"); + /**************************************************************************** + Desc: Random numbers + ****************************************************************************/ - return( i32Result + 1); - } - #elif defined( __ia64__) + #define MAX_RANDOM 2147483646L + + typedef struct + { + FLMINT32 i32Seed; + } f_randomGenerator; + + void f_randomize( + f_randomGenerator * pRand); + + void f_randomSetSeed( + f_randomGenerator * pRand, + FLMINT32 i32seed); + + FLMINT32 f_randomLong( + f_randomGenerator * pRand); + + FLMINT32 f_randomChoice( + f_randomGenerator * pRand, + FLMINT32 lo, + FLMINT32 hi); + + FLMINT f_randomTruth( + f_randomGenerator * pRand, + FLMINT iPercentageTrue); + + /**************************************************************************** + Desc: Time, date, timestamp functions + ****************************************************************************/ + typedef struct + { + FLMUINT16 year; + FLMBYTE month; + FLMBYTE day; + } F_DATE, * F_DATE_p; + + typedef struct + { + FLMBYTE hour; + FLMBYTE minute; + FLMBYTE second; + FLMBYTE hundredth; + } F_TIME, * F_TIME_p; + + typedef struct + { + FLMUINT16 year; + FLMBYTE month; + FLMBYTE day; + FLMBYTE hour; + FLMBYTE minute; + FLMBYTE second; + FLMBYTE hundredth; + } F_TMSTAMP, * F_TMSTAMP_p; + + void f_timeGetSeconds( + FLMUINT * puiSeconds); + + void f_timeGetTimeStamp( + F_TMSTAMP * pTimeStamp); + + FLMINT f_timeGetLocalOffset( void); + + void f_timeSecondsToDate( + FLMUINT uiSeconds, + F_TMSTAMP * pTimeStamp); + + void f_timeDateToSeconds( + F_TMSTAMP * pTimeStamp, + FLMUINT * puiSeconds); + + FLMINT f_timeCompareTimeStamps( + F_TMSTAMP * pTimeStamp1, + F_TMSTAMP * pTimeStamp2, + FLMUINT uiFlag); + + #if defined( FLM_UNIX) + unsigned f_timeGetMilliTime(); + #endif + + /********************************************************************** + Desc: Atomic Increment, Decrement, Exchange + Note: Some of this code is derived from the Ximian source code contained + in that Mono project's atomic.h file. + **********************************************************************/ + #ifndef FLM_HAVE_ATOMICS + #define FLM_HAVE_ATOMICS + #endif + + /******************************************************************* + Desc: + *******************************************************************/ + #if defined( FLM_GNUC) && defined( __ia64__) + FINLINE FLMINT32 ia64_compare_and_swap( + volatile int * piTarget, + FLMINT32 i32NewVal, + FLMINT32 i32CompVal) + { + FLMINT32 i32Old; + + asm volatile ("mov ar.ccv = %2 ;;\n\t" + "cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t" + : "=r" (i32Old) : "r" (piTarget), + "r" (i32CompVal), + "r" (i32NewVal)); + + return( i32Old); + } + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_SPARC) && defined( FLM_SOLARIS) && !defined( FLM_GNUC) + extern "C" FLMINT32 sparc_atomic_add_32( + volatile FLMINT32 * piTarget, + FLMINT32 iDelta); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_SPARC) && defined( FLM_SOLARIS) && !defined( FLM_GNUC) + extern "C" FLMINT32 sparc_atomic_xchg_32( + volatile FLMINT32 * piTarget, + FLMINT32 iNewValue); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_AIX) + FINLINE int aix_atomic_add( + volatile int * piTarget, + int iDelta) + { + return( fetch_and_add( (int *)piTarget, iDelta) + iDelta); + } + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 _flmAtomicInc( + FLMATOMIC * piTarget) + { + #if defined( FLM_NLM) { - FLMINT32 i32Old; - - for( ;;) + return( (FLMINT32)nlm_AtomicIncrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedIncrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_AIX) + { + return( (FLMINT32)aix_atomic_add( piTarget, 1)); + } + #elif defined( FLM_GNUC) + { + #if defined( __i386__) || defined( __x86_64__) { - i32Old = (FLMINT32)*piTarget; + FLMINT32 i32Tmp; - if( ia64_compare_and_swap( piTarget, - i32Old + 1, i32Old) == i32Old) - { - break; - } - } - - return( i32Old + 1); - } - #elif defined( __s390__) - { - FLMINT32 i32Tmp; + __asm__ __volatile__ ("lock; xaddl %0, %1" + : "=r" (i32Tmp), "=m" (*piTarget) + : "0" (1), "m" (*piTarget)); - __asm__ __volatile__ ("\tLA\t2,%1\n" - "0:\tL\t%0,%1\n" - "\tLR\t1,%0\n" - "\tAHI\t1,1\n" - "\tCS\t%0,1,0(2)\n" - "\tJNZ\t0b\n" - "\tLR\t%0,1" - : "=r" (i32Tmp), "+m" (*piTarget) - : : "1", "2", "cc"); + return( i32Tmp + 1); + } + #elif defined( __ppc__) || defined ( __powerpc__) + { + FLMINT32 i32Result = 0; + FLMINT32 i32Tmp; + + __asm__ __volatile__ ("\n1:\n\t" + "lwarx %0, 0, %2\n\t" + "addi %1, %0, 1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 1b" + : "=&b" (i32Result), "=&b" (i32Tmp) + : "r" (piTarget) : "cc", "memory"); - return( i32Tmp); + return( i32Result + 1); + } + #elif defined( __ia64__) + { + FLMINT32 i32Old; + + for( ;;) + { + i32Old = (FLMINT32)*piTarget; + + if( ia64_compare_and_swap( piTarget, + i32Old + 1, i32Old) == i32Old) + { + break; + } + } + + return( i32Old + 1); + } + #elif defined( __s390__) + { + FLMINT32 i32Tmp; + + __asm__ __volatile__ ("\tLA\t2,%1\n" + "0:\tL\t%0,%1\n" + "\tLR\t1,%0\n" + "\tAHI\t1,1\n" + "\tCS\t%0,1,0(2)\n" + "\tJNZ\t0b\n" + "\tLR\t%0,1" + : "=r" (i32Tmp), "+m" (*piTarget) + : : "1", "2", "cc"); + + return( i32Tmp); + } + #else + #ifdef FLM_HAVE_ATOMICS + #undef FLM_HAVE_ATOMICS + #endif + + F_UNREFERENCED_PARM( piTarget); + + flmAssert( 0); + return( 0); + #endif } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) + return( sparc_atomic_add_32( piTarget, 1)); #else #ifdef FLM_HAVE_ATOMICS #undef FLM_HAVE_ATOMICS #endif - + F_UNREFERENCED_PARM( piTarget); - - flmAssert( 0); - return( 0); - #endif - } - #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) - return( sparc_atomic_add_32( piTarget, 1)); - #else - #ifdef FLM_HAVE_ATOMICS - #undef FLM_HAVE_ATOMICS - #endif - - F_UNREFERENCED_PARM( piTarget); - - flmAssert( 0); - return( 0); - #endif -} - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 _flmAtomicDec( - FLMATOMIC * piTarget) -{ - #if defined( FLM_NLM) - { - return( (FLMINT32)nlm_AtomicDecrement( (volatile LONG *)piTarget)); - } - #elif defined( FLM_WIN) - { - return( (FLMINT32)InterlockedDecrement( (volatile LONG *)piTarget)); - } - #elif defined( FLM_AIX) - { - return( (FLMINT32)aix_atomic_add( piTarget, -1)); - } - #elif defined( FLM_GNUC) - { - #if defined( __i386__) || defined( __x86_64__) - { - FLMINT32 i32Tmp; - - __asm__ __volatile__ ("lock; xaddl %0, %1" - : "=r" (i32Tmp), "=m" (*piTarget) - : "0" (-1), "m" (*piTarget)); - - return( i32Tmp - 1); - } - #elif defined( __ppc__) || defined ( __powerpc__) - { - FLMINT32 i32Result = 0; - FLMINT32 i32Tmp; - - __asm__ __volatile__ ("\n1:\n\t" - "lwarx %0, 0, %2\n\t" - "addi %1, %0, -1\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 1b" - : "=&b" (i32Result), "=&b" (i32Tmp) - : "r" (piTarget) : "cc", "memory"); - - return( i32Result - 1); - } - #elif defined( __ia64__) - { - FLMINT32 i32Old; - - for( ;;) - { - i32Old = (FLMINT32)*piTarget; - - if( ia64_compare_and_swap( piTarget, i32Old - 1, - i32Old) == i32Old) - { - break; - } - } - - return( i32Old - 1); - } - #elif defined( __s390__) - { - FLMINT32 i32Tmp; - __asm__ __volatile__ ("\tLA\t2,%1\n" - "0:\tL\t%0,%1\n" - "\tLR\t1,%0\n" - "\tAHI\t1,-1\n" - "\tCS\t%0,1,0(2)\n" - "\tJNZ\t0b\n" - "\tLR\t%0,1" - : "=r" (i32Tmp), "+m" (*piTarget) - : : "1", "2", "cc"); - - return( i32Tmp); - } - #else - #ifdef FLM_HAVE_ATOMICS - #undef FLM_HAVE_ATOMICS - #endif - - F_UNREFERENCED_PARM( piTarget); - flmAssert( 0); return( 0); #endif } - #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) - return( sparc_atomic_add_32( piTarget, -1)); - #else - #ifdef FLM_HAVE_ATOMICS - #undef FLM_HAVE_ATOMICS - #endif - - F_UNREFERENCED_PARM( piTarget); - - flmAssert( 0); - return( 0); - #endif -} - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 _flmAtomicExchange( - FLMATOMIC * piTarget, - FLMINT32 i32NewVal) -{ - #if defined( FLM_NLM) + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 _flmAtomicDec( + FLMATOMIC * piTarget) { - return( (FLMINT32)nlm_AtomicExchange( - (volatile LONG *)piTarget, i32NewVal)); - } - #elif defined( FLM_WIN) - { - return( (FLMINT32)InterlockedExchange( (volatile LONG *)piTarget, - i32NewVal)); - } - #elif defined( FLM_AIX) - { - int iOldVal; - - for( ;;) - { - iOldVal = (int)*piTarget; - - if( compare_and_swap( (int *)piTarget, &iOldVal, i32NewVal)) + #if defined( FLM_NLM) + { + return( (FLMINT32)nlm_AtomicDecrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedDecrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_AIX) + { + return( (FLMINT32)aix_atomic_add( piTarget, -1)); + } + #elif defined( FLM_GNUC) + { + #if defined( __i386__) || defined( __x86_64__) { - break; - } - } - - return( (FLMINT32)iOldVal); - } - #elif defined( FLM_GNUC) - { - #if defined( __i386__) || defined( __x86_64__) - { - FLMINT32 i32Ret; - - __asm__ __volatile__ ("1:; lock; cmpxchgl %2, %0; jne 1b" - : "=m" (*piTarget), "=a" (i32Ret) - : "r" (i32NewVal), "m" (*piTarget), - "a" (*piTarget)); - - return( i32Ret); - } - #elif defined( __ppc__) || defined ( __powerpc__) - { - FLMINT32 i32Tmp = 0; - - __asm__ __volatile__ ("\n1:\n\t" - "lwarx %0, 0, %2\n\t" - "stwcx. %3, 0, %2\n\t" - "bne 1b" - : "=r" (i32Tmp) : "0" (i32Tmp), - "b" (piTarget), - "r" (i32NewVal) : "cc", "memory"); - - return( i32Tmp); - } - #elif defined( __ia64__) - { - FLMINT32 i32Result; - - for( ;;) - { - i32Result = (FLMINT32)*piTarget; + FLMINT32 i32Tmp; - if( ia64_compare_and_swap( piTarget, - i32NewVal, i32Result) == i32Result) - { - break; - } - } - - return( i32Result); - } - #elif defined( __s390__) - { - FLMINT32 i32Ret; + __asm__ __volatile__ ("lock; xaddl %0, %1" + : "=r" (i32Tmp), "=m" (*piTarget) + : "0" (-1), "m" (*piTarget)); - __asm__ __volatile__ ("\tLA\t1,%0\n" - "0:\tL\t%1,%0\n" - "\tCS\t%1,%2,0(1)\n" - "\tJNZ\t0b" - : "+m" (*piTarget), "=r" (i32Ret) - : "r" (i32NewVal) - : "1", "cc"); + return( i32Tmp - 1); + } + #elif defined( __ppc__) || defined ( __powerpc__) + { + FLMINT32 i32Result = 0; + FLMINT32 i32Tmp; + + __asm__ __volatile__ ("\n1:\n\t" + "lwarx %0, 0, %2\n\t" + "addi %1, %0, -1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 1b" + : "=&b" (i32Result), "=&b" (i32Tmp) + : "r" (piTarget) : "cc", "memory"); + + return( i32Result - 1); + } + #elif defined( __ia64__) + { + FLMINT32 i32Old; + + for( ;;) + { + i32Old = (FLMINT32)*piTarget; + + if( ia64_compare_and_swap( piTarget, i32Old - 1, + i32Old) == i32Old) + { + break; + } + } + + return( i32Old - 1); + } + #elif defined( __s390__) + { + FLMINT32 i32Tmp; - return( i32Ret); + __asm__ __volatile__ ("\tLA\t2,%1\n" + "0:\tL\t%0,%1\n" + "\tLR\t1,%0\n" + "\tAHI\t1,-1\n" + "\tCS\t%0,1,0(2)\n" + "\tJNZ\t0b\n" + "\tLR\t%0,1" + : "=r" (i32Tmp), "+m" (*piTarget) + : : "1", "2", "cc"); + + return( i32Tmp); + } + #else + #ifdef FLM_HAVE_ATOMICS + #undef FLM_HAVE_ATOMICS + #endif + + F_UNREFERENCED_PARM( piTarget); + + flmAssert( 0); + return( 0); + #endif } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) + return( sparc_atomic_add_32( piTarget, -1)); #else #ifdef FLM_HAVE_ATOMICS #undef FLM_HAVE_ATOMICS #endif - + + F_UNREFERENCED_PARM( piTarget); + + flmAssert( 0); + return( 0); + #endif + } + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 _flmAtomicExchange( + FLMATOMIC * piTarget, + FLMINT32 i32NewVal) + { + #if defined( FLM_NLM) + { + return( (FLMINT32)nlm_AtomicExchange( + (volatile LONG *)piTarget, i32NewVal)); + } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedExchange( (volatile LONG *)piTarget, + i32NewVal)); + } + #elif defined( FLM_AIX) + { + int iOldVal; + + for( ;;) + { + iOldVal = (int)*piTarget; + + if( compare_and_swap( (int *)piTarget, &iOldVal, i32NewVal)) + { + break; + } + } + + return( (FLMINT32)iOldVal); + } + #elif defined( FLM_GNUC) + { + #if defined( __i386__) || defined( __x86_64__) + { + FLMINT32 i32Ret; + + __asm__ __volatile__ ("1:; lock; cmpxchgl %2, %0; jne 1b" + : "=m" (*piTarget), "=a" (i32Ret) + : "r" (i32NewVal), "m" (*piTarget), + "a" (*piTarget)); + + return( i32Ret); + } + #elif defined( __ppc__) || defined ( __powerpc__) + { + FLMINT32 i32Tmp = 0; + + __asm__ __volatile__ ("\n1:\n\t" + "lwarx %0, 0, %2\n\t" + "stwcx. %3, 0, %2\n\t" + "bne 1b" + : "=r" (i32Tmp) : "0" (i32Tmp), + "b" (piTarget), + "r" (i32NewVal) : "cc", "memory"); + + return( i32Tmp); + } + #elif defined( __ia64__) + { + FLMINT32 i32Result; + + for( ;;) + { + i32Result = (FLMINT32)*piTarget; + + if( ia64_compare_and_swap( piTarget, + i32NewVal, i32Result) == i32Result) + { + break; + } + } + + return( i32Result); + } + #elif defined( __s390__) + { + FLMINT32 i32Ret; + + __asm__ __volatile__ ("\tLA\t1,%0\n" + "0:\tL\t%1,%0\n" + "\tCS\t%1,%2,0(1)\n" + "\tJNZ\t0b" + : "+m" (*piTarget), "=r" (i32Ret) + : "r" (i32NewVal) + : "1", "cc"); + + return( i32Ret); + } + #else + #ifdef FLM_HAVE_ATOMICS + #undef FLM_HAVE_ATOMICS + #endif + + F_UNREFERENCED_PARM( piTarget); + F_UNREFERENCED_PARM( i32NewVal); + + flmAssert( 0); + return( 0); + #endif + } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) + return( sparc_atomic_xchg_32( piTarget, i32NewVal)); + #else + #ifdef FLM_HAVE_ATOMICS + #undef FLM_HAVE_ATOMICS + #endif + F_UNREFERENCED_PARM( piTarget); F_UNREFERENCED_PARM( i32NewVal); - + flmAssert( 0); return( 0); #endif } - #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) - return( sparc_atomic_xchg_32( piTarget, i32NewVal)); - #else - #ifdef FLM_HAVE_ATOMICS - #undef FLM_HAVE_ATOMICS - #endif - - F_UNREFERENCED_PARM( piTarget); - F_UNREFERENCED_PARM( i32NewVal); - - flmAssert( 0); - return( 0); - #endif -} - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 flmAtomicInc( - FLMATOMIC * piTarget, - F_MUTEX hMutex = F_MUTEX_NULL, - FLMBOOL bMutexAlreadyLocked = FALSE) -{ - #ifdef FLM_HAVE_ATOMICS - F_UNREFERENCED_PARM( bMutexAlreadyLocked); - F_UNREFERENCED_PARM( hMutex); - - return( _flmAtomicInc( piTarget)); - #else - { - FLMINT32 i32NewVal; - - flmAssert( hMutex != F_MUTEX_NULL); - - if( !bMutexAlreadyLocked) - { - f_mutexLock( hMutex); - } - - i32NewVal = (FLMINT32)(++(*piTarget)); - - if( !bMutexAlreadyLocked) - { - f_mutexUnlock( hMutex); - } - - return( i32NewVal); - } - #endif -} - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 flmAtomicDec( - FLMATOMIC * piTarget, - F_MUTEX hMutex = F_MUTEX_NULL, - FLMBOOL bMutexAlreadyLocked = FALSE) -{ - #ifdef FLM_HAVE_ATOMICS - F_UNREFERENCED_PARM( bMutexAlreadyLocked); - F_UNREFERENCED_PARM( hMutex); - - return( _flmAtomicDec( piTarget)); - #else - { - FLMINT32 i32NewVal; - - flmAssert( hMutex != F_MUTEX_NULL); - - if( !bMutexAlreadyLocked) - { - f_mutexLock( hMutex); - } - - i32NewVal = (FLMINT32)(--(*piTarget)); - - if( !bMutexAlreadyLocked) - { - f_mutexUnlock( hMutex); - } - - return( i32NewVal); - } - #endif -} - -/********************************************************************** -Desc: -**********************************************************************/ -FINLINE FLMINT32 flmAtomicExchange( - FLMATOMIC * piTarget, - FLMINT32 i32NewVal, - F_MUTEX hMutex = F_MUTEX_NULL, - FLMBOOL bMutexAlreadyLocked = FALSE) -{ - #ifdef FLM_HAVE_ATOMICS - F_UNREFERENCED_PARM( bMutexAlreadyLocked); - F_UNREFERENCED_PARM( hMutex); - - return( _flmAtomicExchange( piTarget, i32NewVal)); - #else - { - FLMINT32 i32OldVal; - - flmAssert( hMutex != F_MUTEX_NULL); - - if( !bMutexAlreadyLocked) - { - f_mutexLock( hMutex); - } - - i32OldVal = (FLMINT32)*piTarget; - *piTarget = i32NewVal; - - if( !bMutexAlreadyLocked) - { - f_mutexUnlock( hMutex); - } - - return( i32OldVal); - } - #endif -} - -/**************************************************************************** - Pseudo Serial Numbers -****************************************************************************/ - -RCODE f_initSerialNumberGenerator( void); - -RCODE f_createSerialNumber( - FLMBYTE * pszGuid); - -void f_freeSerialNumberGenerator( void); - -/**************************************************************************** - CRC -****************************************************************************/ - -RCODE f_initCRCTable( - FLMUINT32 ** ppui32CRCTbl); - -void f_updateCRC( - FLMUINT32 * pui32CRCTbl, - FLMBYTE * pucBlk, - FLMUINT uiBlkSize, - FLMUINT32 * pui32CRC); - -#define f_freeCRCTable( ppui32CRCTbl) \ - f_free( ppui32CRCTbl) - -/**************************************************************************** -Desc: Returns TRUE if the passed-in character is 0-9, a-f, or A-F -****************************************************************************/ -FINLINE FLMBOOL f_isHexChar( - FLMBYTE ucChar) -{ - if( (ucChar >= '0' && ucChar <= '9') || - (ucChar >= 'A' && ucChar <= 'F') || - (ucChar >= 'a' && ucChar <= 'f')) - { - return( TRUE); - } - - return( FALSE); -} - -/**************************************************************************** -Desc: Returns the base-10 equivalent of a hex character -****************************************************************************/ -FINLINE FLMBYTE f_getHexVal( - FLMBYTE ucChar) -{ - if( ucChar >= '0' && ucChar <= '9') - { - return( (FLMBYTE)(ucChar - '0')); - } - else if( ucChar >= 'A' && ucChar <= 'F') - { - return( (FLMBYTE)((ucChar - 'A') + 10)); - } - else if( ucChar >= 'a' && ucChar <= 'f') - { - return( (FLMBYTE)((ucChar - 'a') + 10)); - } - - return( 0); -} - -/**************************************************************************** - Process ID Functions - ****************************************************************************/ - -#if defined( FLM_WIN) - - FINLINE FLMUINT f_getpid() - { - return _getpid(); - } - -#elif defined( FLM_UNIX) - - pid_t getpid( void); - - FINLINE FLMUINT f_getpid() - { - return getpid(); - } - -#elif defined( FLM_NLM) - - FLMUINT f_getNLMHandle( void); - - FINLINE FLMUINT f_getpid() - { - return( f_getNLMHandle()); - } - -#endif - -typedef struct -{ - char * pszDestStr; -} F_SPRINTF_INFO; - -void flmSprintfStringFormatter( - char ucFormatChar, - FLMUINT uiWidth, - FLMUINT uiPrecision, - FLMUINT uiFlags, - F_SPRINTF_INFO * pInfo, - f_va_list * args); - -FLMINT f_vsprintf( - char * pszDestStr, - const char * pszFormat, - f_va_list * args); - -typedef FLMINT (* F_SORT_COMPARE_FUNC)( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); - -typedef void (* F_SORT_SWAP_FUNC)( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); - -void f_qsort( - void * pvBuffer, - FLMUINT uiLowerBounds, - FLMUINT uiUpperBounds, - F_SORT_COMPARE_FUNC fnCompare, - F_SORT_SWAP_FUNC fnSwap); - -FLMINT flmQSortUINTCompare( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); - -void flmQSortUINTSwap( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); -/**************************************************************************** - Module Load/Unload Functions + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 flmAtomicInc( + FLMATOMIC * piTarget, + F_MUTEX hMutex = F_MUTEX_NULL, + FLMBOOL bMutexAlreadyLocked = FALSE) + { + #ifdef FLM_HAVE_ATOMICS + F_UNREFERENCED_PARM( bMutexAlreadyLocked); + F_UNREFERENCED_PARM( hMutex); + + return( _flmAtomicInc( piTarget)); + #else + { + FLMINT32 i32NewVal; + + flmAssert( hMutex != F_MUTEX_NULL); + + if( !bMutexAlreadyLocked) + { + f_mutexLock( hMutex); + } + + i32NewVal = (FLMINT32)(++(*piTarget)); + + if( !bMutexAlreadyLocked) + { + f_mutexUnlock( hMutex); + } + + return( i32NewVal); + } + #endif + } + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 flmAtomicDec( + FLMATOMIC * piTarget, + F_MUTEX hMutex = F_MUTEX_NULL, + FLMBOOL bMutexAlreadyLocked = FALSE) + { + #ifdef FLM_HAVE_ATOMICS + F_UNREFERENCED_PARM( bMutexAlreadyLocked); + F_UNREFERENCED_PARM( hMutex); + + return( _flmAtomicDec( piTarget)); + #else + { + FLMINT32 i32NewVal; + + flmAssert( hMutex != F_MUTEX_NULL); + + if( !bMutexAlreadyLocked) + { + f_mutexLock( hMutex); + } + + i32NewVal = (FLMINT32)(--(*piTarget)); + + if( !bMutexAlreadyLocked) + { + f_mutexUnlock( hMutex); + } + + return( i32NewVal); + } + #endif + } + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 flmAtomicExchange( + FLMATOMIC * piTarget, + FLMINT32 i32NewVal, + F_MUTEX hMutex = F_MUTEX_NULL, + FLMBOOL bMutexAlreadyLocked = FALSE) + { + #ifdef FLM_HAVE_ATOMICS + F_UNREFERENCED_PARM( bMutexAlreadyLocked); + F_UNREFERENCED_PARM( hMutex); + + return( _flmAtomicExchange( piTarget, i32NewVal)); + #else + { + FLMINT32 i32OldVal; + + flmAssert( hMutex != F_MUTEX_NULL); + + if( !bMutexAlreadyLocked) + { + f_mutexLock( hMutex); + } + + i32OldVal = (FLMINT32)*piTarget; + *piTarget = i32NewVal; + + if( !bMutexAlreadyLocked) + { + f_mutexUnlock( hMutex); + } + + return( i32OldVal); + } + #endif + } + + /**************************************************************************** + Pseudo Serial Numbers ****************************************************************************/ - -typedef void * FlmModHandle; - -RCODE FlmModLoad( - const char * pszName, - FlmModHandle * phMod); - -#ifndef FLM_NLM - RCODE FlmModUnload( - FlmModHandle * phMod); -#else - RCODE FlmModUnload( - const char * pszModPath); -#endif - -RCODE FlmSymLoad( - const char * pszName, - FlmModHandle hMod, - void ** ppvSym); - -RCODE FlmSymUnload( - const char * pszName); - -char * f_strchr( - const char * pszStr, - char c); + + RCODE f_initSerialNumberGenerator( void); + + RCODE f_createSerialNumber( + FLMBYTE * pszGuid); + + void f_freeSerialNumberGenerator( void); + + /**************************************************************************** + CRC + ****************************************************************************/ + + RCODE f_initCRCTable( + FLMUINT32 ** ppui32CRCTbl); + + void f_updateCRC( + FLMUINT32 * pui32CRCTbl, + FLMBYTE * pucBlk, + FLMUINT uiBlkSize, + FLMUINT32 * pui32CRC); + + #define f_freeCRCTable( ppui32CRCTbl) \ + f_free( ppui32CRCTbl) + + /**************************************************************************** + Desc: Returns TRUE if the passed-in character is 0-9, a-f, or A-F + ****************************************************************************/ + FINLINE FLMBOOL f_isHexChar( + FLMBYTE ucChar) + { + if( (ucChar >= '0' && ucChar <= '9') || + (ucChar >= 'A' && ucChar <= 'F') || + (ucChar >= 'a' && ucChar <= 'f')) + { + return( TRUE); + } + + return( FALSE); + } + + /**************************************************************************** + Desc: Returns the base-10 equivalent of a hex character + ****************************************************************************/ + FINLINE FLMBYTE f_getHexVal( + FLMBYTE ucChar) + { + if( ucChar >= '0' && ucChar <= '9') + { + return( (FLMBYTE)(ucChar - '0')); + } + else if( ucChar >= 'A' && ucChar <= 'F') + { + return( (FLMBYTE)((ucChar - 'A') + 10)); + } + else if( ucChar >= 'a' && ucChar <= 'f') + { + return( (FLMBYTE)((ucChar - 'a') + 10)); + } + + return( 0); + } + + /**************************************************************************** + Desc: Process ID Functions + ****************************************************************************/ + + #if defined( FLM_WIN) + + FINLINE FLMUINT f_getpid() + { + return _getpid(); + } + + #elif defined( FLM_UNIX) + + pid_t getpid( void); + + FINLINE FLMUINT f_getpid() + { + return getpid(); + } + + #elif defined( FLM_NLM) + + FINLINE FLMUINT f_getpid() + { + return( f_getNLMHandle()); + } + + #endif + + typedef struct + { + char * pszDestStr; + } F_SPRINTF_INFO; + + void flmSprintfStringFormatter( + char ucFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + F_SPRINTF_INFO * pInfo, + f_va_list * args); + + FLMINT f_vsprintf( + char * pszDestStr, + const char * pszFormat, + f_va_list * args); + + typedef FLMINT (* F_SORT_COMPARE_FUNC)( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + typedef void (* F_SORT_SWAP_FUNC)( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + void f_qsort( + void * pvBuffer, + FLMUINT uiLowerBounds, + FLMUINT uiUpperBounds, + F_SORT_COMPARE_FUNC fnCompare, + F_SORT_SWAP_FUNC fnSwap); + + FLMINT flmQSortUINTCompare( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + void flmQSortUINTSwap( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + /**************************************************************************** + Desc: Module Load/Unload Functions + ****************************************************************************/ + + typedef void * FlmModHandle; + + RCODE FlmModLoad( + const char * pszName, + FlmModHandle * phMod); + + #ifndef FLM_NLM + RCODE FlmModUnload( + FlmModHandle * phMod); + #else + RCODE FlmModUnload( + const char * pszModPath); + #endif + + RCODE FlmSymLoad( + const char * pszName, + FlmModHandle hMod, + void ** ppvSym); + + RCODE FlmSymUnload( + const char * pszName); + + char * f_strchr( + const char * pszStr, + char c); #include "fpackoff.h" #endif diff --git a/flaim/src/ftknlm.h b/flaim/src/ftknlm.h new file mode 100644 index 0000000..49c5d54 --- /dev/null +++ b/flaim/src/ftknlm.h @@ -0,0 +1,1714 @@ +//------------------------------------------------------------------------- +// Desc: Toolkit - cross platform APIs for system functionality. +// Tabs: 3 +// +// Copyright (c) 1991-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: $ +//------------------------------------------------------------------------- + +#ifndef FTKNLM_H +#define FTKNLM_H + +#pragma pack(push,1) + + typedef unsigned long LONG; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned short wchar_t; + typedef unsigned char wsnchar; + typedef unsigned int BOOL; + typedef unsigned int DWORD; + typedef unsigned int * LPDWORD; + typedef unsigned long ULONG; + typedef unsigned char UCHAR; + typedef DWORD WPARAM; + typedef DWORD LPARAM; + typedef unsigned int UINT; + typedef unsigned int size_t; + typedef void * MUTEX; + typedef void * SEMAPHORE; + typedef unsigned long ERROR; + typedef void * SPINLOCK; + typedef LONG clockAndStatus[3]; + typedef unsigned int SOCKET; + typedef unsigned long f_va_list; + typedef SEMAPHORE F_SEM; + + typedef void (* FLM_EXIT_FUNC)( void); + + #define FSTATIC + + #define F_SEM_NULL 0 + + #define TimerSignature 0x524D4954 + #define SemaphoreSignature 0x504D4553 + #define AllocSignature 0x54524C41 + + #define DOSNameSpace 0 + #define MACNameSpace 1 + #define MacNameSpace MACNameSpace + #define NFSNameSpace 2 + #define FTAMNameSpace 3 + #define OS2NameSpace 4 + #define LONGNameSpace 4 + #define NTNameSpace 5 + #define MAX_NAMESPACES 6 + + #define NO_RIGHTS_CHECK_ON_OPEN_BIT 0x00010000 + #define ALLOW_SECURE_DIRECTORY_ACCESS_BIT 0x00020000 + #define READ_ACCESS_BIT 0x00000001 + #define WRITE_ACCESS_BIT 0x00000002 + #define DENY_READ_BIT 0x00000004 + #define DENY_WRITE_BIT 0x00000008 + #define COMPATABILITY_MODE_BIT 0x00000010 + #define FILE_WRITE_THROUGH_BIT 0x00000040 + #define FILE_READ_THROUGH_BIT 0x00000080 + #define ALWAYS_READ_AHEAD_BIT 0x00001000 + #define NEVER_READ_AHEAD_BIT 0x00002000 + + #define READ_ONLY_BIT 0x00000001 + #define HIDDEN_BIT 0x00000002 + #define SYSTEM_BIT 0x00000004 + #define EXECUTE_BIT 0x00000008 + #define SUBDIRECTORY_BIT 0x00000010 + #define ARCHIVE_BIT 0x00000020 + #define SHAREABLE_BIT 0x00000080 + #define OLD_PRIVATE_BIT 0x00000080 + #define NO_SUBALLOC_BIT 0x00000800 + #define SMODE_BITS 0x00000700 + #define TRANSACTION_BIT 0x00001000 + #define READ_AUDIT_BIT 0x00004000 + #define WRITE_AUDIT_BIT 0x00008000 + #define IMMEDIATE_PURGE_BIT 0x00010000 + #define RENAME_INHIBIT_BIT 0x00020000 + #define DELETE_INHIBIT_BIT 0x00040000 + #define COPY_INHIBIT_BIT 0x00080000 + #define FILE_AUDITING_BIT 0x00100000 + #define REMOTE_DATA_ACCESS_BIT 0x00400000 + #define REMOTE_DATA_INHIBIT_BIT 0x00800000 + #define REMOTE_DATA_SAVE_KEY_BIT 0x01000000 + #define COMPRESS_FILE_IMMEDIATELY_BIT 0x02000000 + #define DATA_STREAM_IS_COMPRESSED_BIT 0x04000000 + #define DO_NOT_COMPRESS_FILE_BIT 0x08000000 + #define CANT_COMPRESS_DATA_STREAM_BIT 0x20000000 + #define ATTR_ARCHIVE_BIT 0x40000000 + #define ZFS_VOLATILE_BIT 0x80000000 + + #define VOLUME_AUDITING_BIT 0x01 + #define SUB_ALLOCATION_ENABLED_BIT 0x02 + #define FILE_COMPRESSION_ENABLED_BIT 0x04 + #define DATA_MIGRATION_ENABLED_BIT 0x08 + #define NEW_TRUSTEE_COUNT_BIT 0x10 + #define DIR_SVCS_OBJ_UPGRADED_BIT 0x20 + #define VOLUME_IMMEDIATE_PURGE_ENABLED_BIT 0x40 + + #define PrimaryDataStream 0 + #define MACResourceForkDataStream 1 + #define FTAMDataStream 2 + + #define DefinedAccessRightsBits 0x01FB + #define MaximumDirectoryAccessBits 0x01FF + #define AllValidAccessBits 0x100001FF + + #define SYNCCLOCK_CLOCK_BIT 0x00000001L + #define SYNCCLOCK_TICK_INCREMENT_BIT 0x00000002L + #define SYNCCLOCK_ADJUSTMENT_BIT 0x00000004L + #define SYNCCLOCK_GROSS_CORRECTION_BIT 0x00000008L + #define SYNCCLOCK_ADJUSTMENT_COUNT_BIT 0x00000010L + #define SYNCCLOCK_STATUS_BIT 0x00000020L + #define SYNCCLOCK_STD_TICK_BIT 0x00000040L + #define SYNCCLOCK_EVENT_TIME_BIT 0x00000080L + #define SYNCCLOCK_EVENT_OFFSET_BIT 0x00000100L + #define SYNCCLOCK_HARDWARE_CLOCK_BIT 0x00000200L + #define SYNCCLOCK_RESERVED1_BIT 0x00000400L + #define SYNCCLOCK_DAYLIGHT_BIT 0x00000800L + #define SYNCCLOCK_TIMEZONE_OFFSET_BIT 0x00001000L + #define SYNCCLOCK_TZNAME_BIT 0x00002000L + #define SYNCCLOCK_TIMEZONE_STR_BIT 0x00004000L + #define SYNCCLOCK_DAYLIGHT_OFFSET_BIT 0x00008000L + #define SYNCCLOCK_DAYLIGHT_ON_OFF_BIT 0x00010000L + #define SYNCCLOCK_START_DST_BIT 0x00020000L + #define SYNCCLOCK_STOP_DST_BIT 0x00040000L + #define SYNCCLOCK_ALL_DEFINED_BITS (0x0007FFFFL & ~SYNCCLOCK_HARDWARE_CLOCK_BIT) + + #define LDModuleIsReEntrantBit 0x00000001 + #define LDModuleCanBeMultiplyLoadedBit 0x00000002 + #define LDSynchronizeStart 0x00000004 + #define LDPseudoPreemptionBit 0x00000008 + #define LDLoadInKernel 0x00000010 + #define Available_0 0x00000020 + #define LDAutoUnload 0x00000040 + #define LDHiddenModule 0x00000080 + #define LDDigitallySignedFile 0x00000100 + #define LDLoadProtected 0x00000200 + #define LDSharedLibraryModule 0x00000400 + #define LDRestartable 0x00000800 + #define LDUnsafeToUnloadNow 0x00001000 + #define LDModuleIsUniprocessor 0x00002000 + #define LDPreemptable 0x00004000 + #define LDHasSystemCalls 0x00008000 + #define LDVirtualMemory 0x00010000 + #define LDAllExportsMTSafe 0x00020000 + + #define DFSFailedCompletion -1 + #define DFSNormalCompletion 0 + #define DFSInsufficientSpace 1 + #define DFSVolumeSegmentDeactivated 4 + #define DFSTruncationFailure 16 + #define DFSHoleInFileError 17 + #define DFSParameterError 18 + #define DFSOverlapError 19 + #define DFSSegmentError 20 + #define DFSBoundryError 21 + #define DFSInsufficientLimboFileSpace 22 + #define DFSNotInDirectFileMode 23 + #define DFSOperationBeyondEndOfFile 24 + #define DFSOutOfHandles 129 + #define DFSHardIOError 131 + #define DFSInvalidFileHandle 136 + #define DFSNoReadPrivilege 147 + #define DFSNoWritePrivilege 148 + #define DFSFileDetached 149 + #define DFSInsufficientMemory 150 + #define DFSInvalidVolume 152 + #define DFSIOLockError 162 + + #define MModifyNameBit 0x0001 + #define MFileAttributesBit 0x0002 + #define MCreateDateBit 0x0004 + #define MCreateTimeBit 0x0008 + #define MOwnerIDBit 0x0010 + #define MLastArchivedDateBit 0x0020 + #define MLastArchivedTimeBit 0x0040 + #define MLastArchivedIDBit 0x0080 + #define MLastUpdatedDateBit 0x0100 + #define MLastUpdatedTimeBit 0x0200 + #define MLastUpdatedIDBit 0x0400 + #define MLastAccessedDateBit 0x0800 + #define MInheritanceRestrictionMaskBit 0x1000 + #define MMaximumSpaceBit 0x2000 + #define MLastUpdatedInSecondsBit 0x4000 + + #define MAX_NETWARE_VOLUME_NAME 16 + #define F_NW_DEFAULT_VOLUME_NUMBER 0 + + #define LO_RETURN_HANDLE 0x00000040 + + #define htonl WS2_32_htonl + #define ntohl WS2_32_ntohl + #define htons WS2_32_htons + #define ioctlsocket WS2_32_ioctlsocket + #define ntohs WS2_32_ntohs + #define send WS2_32_send + #define recv WS2_32_recv + #define bind WS2_32_bind + #define listen WS2_32_listen + #define closesocket WS2_32_closesocket + #define getpeername WS2_32_getpeername + #define getsockname WS2_32_getsockname + #define getsockopt WS2_32_getsockopt + #define select WS2_32_select + #define setsockopt WS2_32_setsockopt + #define socket WS2_32_socket + #define inet_addr WS2_32_inet_addr + #define inet_ntoa WS2_32_inet_ntoa + #define gethostbyaddr WS2_32_gethostbyaddr + #define gethostbyname WS2_32_gethostbyname + #define gethostname WS2_32_gethostname + + #define connect(s,name,namelen) \ + WSAConnect(s,name,namelen, 0,0,0,0) + + #define accept(s,addr,addrlen) \ + WSAAccept(s,addr,addrlen,0,0) + + #define IPPROTO_IP 0 // dummy for IP + #define IPPROTO_ICMP 1 // control message protocol + #define IPPROTO_IGMP 2 // internet group management protocol + #define IPPROTO_GGP 3 // gateway (deprecated) + #define IPPROTO_TCP 6 // tcp + #define IPPROTO_PUP 12 // pup + #define IPPROTO_UDP 17 // user datagram protocol + #define IPPROTO_IDP 22 // xns idp + #define IPPROTO_ND 77 // UNOFFICIAL net disk proto + + #define TCP_NODELAY 0x0001 + + #define SOCK_STREAM 1 // stream socket + #define SOCK_DGRAM 2 // datagram socket + #define SOCK_RAW 3 // raw-protocol interface + #define SOCK_RDM 4 // reliably-delivered message + #define SOCK_SEQPACKET 5 // sequenced packet stream + + #define WSADESCRIPTION_LEN 256 + #define WSASYS_STATUS_LEN 128 + + #define s_addr S_un.S_addr + #define s_host S_un.S_un_b.s_b2 + #define s_net S_un.S_un_b.s_b1 + #define s_imp S_un.S_un_w.s_w2 + #define s_impno S_un.S_un_b.s_b4 + #define s_lh S_un.S_un_b.s_b3 + + #define h_addr h_addr_list[0] + + #define FD_SETSIZE 64 + + #define WINSOCK_VERSION MAKEWORD(2,2) + + #define INVALID_SOCKET (SOCKET)(~0) + #define SOCKET_ERROR (-1) + + #define AF_INET 2 + + #define WSABASEERR 10000 + #define WSAEINTR (WSABASEERR+4) + #define WSAEBADF (WSABASEERR+9) + #define WSAEACCES (WSABASEERR+13) + #define WSAEFAULT (WSABASEERR+14) + #define WSAEINVAL (WSABASEERR+22) + #define WSAEMFILE (WSABASEERR+24) + #define WSAEWOULDBLOCK (WSABASEERR+35) + #define WSAEINPROGRESS (WSABASEERR+36) + #define WSAEALREADY (WSABASEERR+37) + #define WSAENOTSOCK (WSABASEERR+38) + #define WSAEDESTADDRREQ (WSABASEERR+39) + #define WSAEMSGSIZE (WSABASEERR+40) + #define WSAEPROTOTYPE (WSABASEERR+41) + #define WSAENOPROTOOPT (WSABASEERR+42) + #define WSAEPROTONOSUPPORT (WSABASEERR+43) + #define WSAESOCKTNOSUPPORT (WSABASEERR+44) + #define WSAEOPNOTSUPP (WSABASEERR+45) + #define WSAEPFNOSUPPORT (WSABASEERR+46) + #define WSAEAFNOSUPPORT (WSABASEERR+47) + #define WSAEADDRINUSE (WSABASEERR+48) + #define WSAEADDRNOTAVAIL (WSABASEERR+49) + #define WSAENETDOWN (WSABASEERR+50) + #define WSAENETUNREACH (WSABASEERR+51) + #define WSAENETRESET (WSABASEERR+52) + #define WSAECONNABORTED (WSABASEERR+53) + #define WSAECONNRESET (WSABASEERR+54) + #define WSAENOBUFS (WSABASEERR+55) + #define WSAEISCONN (WSABASEERR+56) + #define WSAENOTCONN (WSABASEERR+57) + #define WSAESHUTDOWN (WSABASEERR+58) + #define WSAETOOMANYREFS (WSABASEERR+59) + #define WSAETIMEDOUT (WSABASEERR+60) + #define WSAECONNREFUSED (WSABASEERR+61) + #define WSAELOOP (WSABASEERR+62) + #define WSAENAMETOOLONG (WSABASEERR+63) + #define WSAEHOSTDOWN (WSABASEERR+64) + #define WSAEHOSTUNREACH (WSABASEERR+65) + #define WSAENOTEMPTY (WSABASEERR+66) + #define WSAEPROCLIM (WSABASEERR+67) + #define WSAEUSERS (WSABASEERR+68) + #define WSAEDQUOT (WSABASEERR+69) + #define WSAESTALE (WSABASEERR+70) + #define WSAEREMOTE (WSABASEERR+71) + #define WSASYSNOTREADY (WSABASEERR+91) + #define WSAVERNOTSUPPORTED (WSABASEERR+92) + #define WSANOTINITIALISED (WSABASEERR+93) + #define WSAEDISCON (WSABASEERR+101) + #define WSAENOMORE (WSABASEERR+102) + #define WSAECANCELLED (WSABASEERR+103) + #define WSAEINVALIDPROCTABLE (WSABASEERR+104) + #define WSAEINVALIDPROVIDER (WSABASEERR+105) + #define WSAEPROVIDERFAILEDINIT (WSABASEERR+106) + #define WSASYSCALLFAILURE (WSABASEERR+107) + #define WSASERVICE_NOT_FOUND (WSABASEERR+108) + #define WSATYPE_NOT_FOUND (WSABASEERR+109) + #define WSA_E_NO_MORE (WSABASEERR+110) + #define WSA_E_CANCELLED (WSABASEERR+111) + #define WSAEREFUSED (WSABASEERR+112) + #define WSAHOST_NOT_FOUND (WSABASEERR+1001) + #define WSATRY_AGAIN (WSABASEERR+1002) + #define WSANO_RECOVERY (WSABASEERR+1003) + #define WSANO_DATA (WSABASEERR+1004) + + #define INADDR_ANY 0x00000000 + #define INADDR_LOOPBACK 0x7f000001 + #define INADDR_BROADCAST 0xffffffff + #define INADDR_NONE 0xffffffff + #define ADDR_ANY INADDR_ANY + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct LoadDefStruct + { + struct LoadDefStruct * LDLink; + struct LoadDefStruct * LDKillLink; + struct LoadDefStruct * LDScanLink; + struct ResourceTagStructure * LDResourceList; + LONG LDIdentificationNumber; + LONG LDCodeImageOffset; + LONG LDCodeImageLength; + LONG LDDataImageOffset; + LONG LDDataImageLength; + LONG LDUninitializedDataLength; + LONG LDCustomDataOffset; + LONG LDCustomDataSize; + LONG LDFlags; + LONG LDType; + LONG (*LDInitializationProcedure)( + struct LoadDefinitionStructure * LoadRecord, + struct ScreenStruct * screenID, + BYTE * CommandLine, + BYTE * loadDirectoryPath, + LONG uninitializedDataLength, + LONG fileHandle, + LONG (*ReadRoutine)( + LONG fileHandle, + LONG offset, + void * buffer, + LONG numberOfBytes), + LONG customDataOffset, + LONG customDataSize); + + void (*LDExitProcedure)(void); + + LONG (*LDCheckUnloadProcedure)( + struct ScreenStruct *screenID); + + void * LDPublics; + BYTE LDFileName[36]; + BYTE LDName[128]; + LONG * LDCLIBLoadStructure; + LONG * LDNLMDebugger; + LONG LDParentID; + LONG LDReservedForCLIB; + void * AllocMemory; + LONG LDTimeStamp; + void * LDModuleObjectHandle; + LONG LDMajorVersion; + LONG LDMinorVersion; + LONG LDRevision; + LONG LDYear; + LONG LDMonth; + LONG LDDay; + BYTE * LDCopyright; + LONG LDSuppressUnloadAllocMsg; + LONG Reserved2; + LONG Reserved3; + LONG Reserved4[64]; + LONG Reserved5[12]; + LONG Reserved6; + void * LDDomainID; + struct LoadDefinitionStructure * LDEnvLink; + void * LDAllocPagesListHead; + void * LDTempPublicList; + LONG LDMessageLanguage; + BYTE ** LDMessages; + LONG LDMessageCount; + BYTE * LDHelpFile; + LONG LDMessageBufferSize; + LONG LDHelpBufferSize; + LONG LDSharedCodeOffset; + LONG LDSharedCodeLength; + LONG LDSharedDataOffset; + LONG LDSharedDataLength; + LONG (*LDSharedInitProcedure)( + struct LoadDefinitionStructure * LoadRecord, + struct ScreenStruct * screenID, + BYTE * CommandLine); + + void (*LDSharedExitProcedure)(void); + + LONG LDRPCDataTable; + LONG LDRealRPCDataTable; + LONG LDRPCDataTableSize; + LONG LDNumberOfReferencedPublics; + void ** LDReferencedPublics; + LONG LDNumberOfReferencedExports; + LONG LDNICIObject; + LONG LDAllocPagesListLocked; + void * LDAddressSpace; + LONG Reserved7; + void * MPKStubAddress; + LONG MPKStubSize; + LONG LDBuildNumber; + void * LDExtensionData; + } LoadDefStruct; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct FCBType + { + LONG OpenFileLink; + LONG StationLink; + struct FCBType * ShareLinkNext; + struct FCBType * ShareLinkLast; + struct OwnerRestrictionNodeStructure * OwnerRestrictionNode; + struct SpaceRestrictionNodeStructure * SubdirectoryRestrictionNode; + LONG OpenCount; + LONG DirectoryEntry; + LONG DirectoryNumber; + LONG ActualDirectoryEntry; + LONG FileSize; + LONG FirstCluster; + LONG CurrentBlock; + LONG CurrentCluster; + struct FATStruct * FATTable; + LONG TNodePointer; + LONG DateValueStamp; + void * TurboFAT; + LONG OldFileSize; + LONG TransactionPointer; + LONG Station; + LONG Task; + BYTE HandleCount[4]; + BYTE Flags; + BYTE TTSFlags; + BYTE ByteToBlockShiftFactor; + BYTE BlockToSectorShiftFactor; + BYTE SectorToBlockMask; + BYTE VolumeNumber; + BYTE ExtraFlags; + BYTE DataStream; + LONG CommitSemaphore; + LONG ActualOldLastCluster; + LONG FCBInUseCount; + BYTE ExtraExtraFlags; + BYTE SubAllocFlags; + BYTE RemoveSkipUpdateFlags; + BYTE DeCompressFlags; + LONG VolumeManagerID; + LONG SubAllocSemaphore; + LONG SAStartingSector[2]; + LONG SANumberOfSectors[2]; + LONG SAFATCount; + LONG TempCacheListHead; + LONG TempCacheListTail; + struct CompressControlNodeStructure * CompressControlNode; + struct FCBType * DeCompressFCB; + LONG DeCompressPosition; + LONG DeCompressHandle; + LONG RALastReadStartOffset; + LONG RALastReadEndOffset; + LONG RANextReadAheadOffset; + LONG RAHalfSize; + LONG MoreFlags; + LONG StationBackLink; + SPINLOCK DFSSpinLock; + LONG DFSUseCount; + LONG DFSCurrentCluster; + LONG DFSCurrentBlock; + LONG unused; + LONG unused1; + LONG unused2; + LONG unused3; + } FCBType; + + /************************************************************************* + Desc: + *************************************************************************/ + struct DirectoryStructure + { + #define NumberOfDirectoryTrustees 4 + int DSubdirectory; + LONG DFileAttributes; + BYTE DUniqueID; + BYTE DFlags; + BYTE DNameSpace; + BYTE DFileNameLength; + BYTE DFileName[12]; + LONG DCreateDateAndTime; + LONG DOwnerID; + LONG DLastArchivedDateAndTime; + LONG DLastArchivedID; + LONG DLastUpdatedDateAndTime; + LONG DLastUpdatedID; + LONG DFileSize; + LONG DFirstBlock; + LONG DNextTrusteeEntry; + LONG DTrustees[NumberOfDirectoryTrustees]; + LONG DLookUpEntryNumber; + int DLastUpdatedInSeconds; + WORD DTrusteeMask[NumberOfDirectoryTrustees]; + WORD DChangeReferenceID; + WORD DLastAccessedTime; + WORD DMaximumAccessMask; + WORD DLastAccessedDate; + LONG DDeletedFileTime; + LONG DDeletedDateAndTime; + LONG DDeletedID; + LONG DExtendedAttributes; + LONG DDeletedBlockSequenceNumber; + LONG DPrimaryEntry; + LONG DNameList; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct Synchronized_Clock_T + { + #define MAX_TIME_ZONE_STRING_LENGTH 80 + LONG clock[2]; + LONG statusFlags; + LONG adjustmentCount; + LONG adjustment[2]; + LONG grossCorrection[2]; + LONG tickIncrement[2]; + LONG stdTickIncrement[2]; + LONG eventOffset[2]; + LONG eventTime; + LONG daylight; + long timezoneOffset; + long tzname[2]; + char timeZoneString[MAX_TIME_ZONE_STRING_LENGTH]; + long daylightOffset; + long daylightOnOff; + LONG startDSTime; + LONG stopDSTime; + } Synchronized_Clock_T; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct + { + char ** ppszArgV; + char * pszArgs; + char * pszThreadName; + int iArgC; + LoadDefStruct * moduleHandle; + } ARG_DATA; + + /************************************************************************* + Desc: + *************************************************************************/ + struct VolumeInformationStructure + { + LONG VolumeAllocationUnitSizeInBytes; + LONG VolumeSizeInAllocationUnits; + LONG VolumeSectorSize; + LONG AllocationUnitsUsed; + LONG AllocationUnitsFreelyAvailable; + LONG AllocationUnitsInDeletedFilesNotAvailable; + LONG AllocationUnitsInAvailableDeletedFiles; + LONG NumberOfPhysicalSegmentsInVolume; + LONG PhysicalSegmentSizeInAllocationUnits[64]; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + struct ModifyStructure + { + BYTE *MModifyName; + LONG MFileAttributes; + LONG MFileAttributesMask; + WORD MCreateDate; + WORD MCreateTime; + LONG MOwnerID; + WORD MLastArchivedDate; + WORD MLastArchivedTime; + LONG MLastArchivedID; + WORD MLastUpdatedDate; + WORD MLastUpdatedTime; + LONG MLastUpdatedID; + WORD MLastAccessedDate; + WORD MInheritanceGrantMask; + WORD MInheritanceRevokeMask; + int MMaximumSpace; + LONG MLastUpdatedInSeconds; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct + { + FLMUINT32 time_low; + FLMUINT16 time_mid; + FLMUINT16 time_hi_and_version; + FLMBYTE clk_seq_hi_res; + FLMBYTE clk_seq_low; + FLMBYTE node[6]; + } NWGUID; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct WSAData + { + WORD wVersion; + WORD wHighVersion; + char szDescription[ WSADESCRIPTION_LEN + 1]; + char szSystemStatus[ WSASYS_STATUS_LEN + 1]; + unsigned short iMaxSockets; + unsigned short iMaxUdpDg; + char * lpVendorInfo; + } WSADATA, * LPWSADATA; + + /************************************************************************* + Desc: + *************************************************************************/ + struct in_addr + { + union + { + struct + { + unsigned char s_b1; + unsigned char s_b2; + unsigned char s_b3; + unsigned char s_b4; + } S_un_b; + + struct + { + unsigned short s_w1; + unsigned short s_w2; + } S_un_w; + + unsigned long S_addr; + } S_un; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + struct sockaddr_in + { + short sin_family; + unsigned short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + struct sockaddr + { + unsigned short sa_family; + char sa_data[14]; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + struct hostent + { + char * h_name; + char ** h_aliases; + short h_addrtype; + short h_length; + char ** h_addr_list; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + struct timeval + { + long tv_sec; + long tv_usec; + }; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct fd_set + { + unsigned int fd_count; + SOCKET fd_array[ FD_SETSIZE]; + } fd_set; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct _WSABUF + { + unsigned long len; + char * buf; + } WSABUF, * LPWSABUF; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct + { + ULONG TokenRate; + ULONG TokenBucketSize; + ULONG PeakBandwidth; + ULONG Latency; + ULONG DelayVariation; + ULONG ServiceType; + ULONG MaxSduSize; + ULONG MinimumPolicedSize; + } FLOWSPEC, *PFLOWSPEC, * LPFLOWSPEC; + + /************************************************************************* + Desc: + *************************************************************************/ + typedef struct + { + FLOWSPEC SendingFlowspec; + FLOWSPEC ReceivingFlowspec; + WSABUF ProviderSpecific; + } QOS, * LPQOS; + + extern "C" FLMBYTE F_NW_Default_Volume_Name[]; + + extern "C" RCODE MapNWtoFlaimError( + LONG lResult, + RCODE defaultRc); + + extern "C" LONG FlaimToNWOpenFlags( + FLMUINT uiAccess, + FLMBOOL bDoDirectIo); + + extern "C" LONG GetCurrentClock( + clockAndStatus * dataPtr); + + extern "C" void GetSyncClockFields( + LONG bitMap, + Synchronized_Clock_T * aClock); + + extern "C" void kYieldThread( void); + + extern "C" int kGetThreadName( + FLMUINT32 ui32ThreadId, + char * szName, + int iBufSize); + + extern "C" void * kCreateThread( + BYTE * name, + void * (*StartAddress)(void *, void *), + void * StackAddressHigh, + LONG StackSize, + void * Argument); + + extern "C" int kSetThreadName( + void * ThreadHandle, + BYTE * buffer); + + extern "C" LONG kScheduleThread( + void * ThreadHandle); + + extern "C" ERROR kDelayThread( + UINT uiMilliseconds); + + extern "C" void * kCurrentThread( void); + + extern "C" int kDestroyThread( + void * ThreadHandle); + + extern "C" void kExitThread( + void * ExitStatus); + + extern "C" LONG kSetThreadLoadHandle( + void * ThreadHandle, + LONG nlmHandle); + + extern "C" LONG GetRunningProcess( void); + + extern "C" void KillMe( + LoadDefStruct * LoadRecord); + + extern "C" void NWYieldIfTime( void); + + extern "C" void CSetD( + LONG value, + void * address, + LONG numberOfDWords); + + extern "C" void CMovB( + void * src, + void * dst, + LONG numberOfBytes); + + extern "C" void * Alloc( + LONG numberOfBytes, + LONG lRTag); + + extern "C" void Free( + void * address); + + extern "C" LONG AllocateResourceTag( + LONG pvLoadRecord, + BYTE * pvResourceDescriptionString, + LONG ResourceSignature); + + extern "C" LONG ReturnResourceTag( + LONG RTag, + BYTE displayErrorsFlag); + + extern "C" LONG ConvertPathString( + LONG stationNumber, + BYTE base, + BYTE * modifierString, + LONG * volumeNumber, + LONG * pathBase, + BYTE * pathString, + LONG * pathCount); + + extern "C" LONG GetEntryFromPathStringBase( + LONG Station, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG SourceNameSpace, + LONG DesiredNameSpace, + struct DirectoryStructure ** Dir, + LONG * DirectoryNumber); + + extern "C" LONG NDSCreateStreamFile( + LONG Station, + LONG Task, + BYTE * fileName, + LONG CreateAttributes, + LONG * fileHandle, + LONG * DOSDirectoryBase); + + extern "C" LONG NDSOpenStreamFile( + LONG Station, + LONG Task, + BYTE * fileName, + LONG RequestedRights, + LONG * fileHandle, + LONG * DOSDirectoryBase); + + extern "C" LONG NDSDeleteStreamFile( + LONG Station, + LONG Task, + BYTE * fileName, + LONG * DOSDirectoryBase); + + extern "C" LONG EraseFile( + LONG Station, + LONG Task, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG MatchBits); + + extern "C" LONG RenameEntry( + LONG Station, + LONG Task, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG MatchBits, + BYTE SubdirectoryFlag, + LONG NewBase, + BYTE * NewString, + LONG NewCount, + LONG CompatabilityFlag, + BYTE AllowRenamesToMyselfFlag); + + extern "C" LONG OpenFile( + LONG Station, + LONG Task, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG MatchBits, + LONG RequestedRights, + BYTE DataStreamNumber, + LONG * Handle, + LONG * DirectoryNumber, + void ** DirectoryEntry); + + extern "C" LONG CreateFile( + LONG Station, + LONG Task, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG CreatedAttributes, + LONG FlagBits, + BYTE DataStreamNumber, + LONG * Handle, + LONG * DirectoryNumber, + void ** DirectoryEntry); + + extern "C" LONG CloseFile( + LONG station, + LONG task, + LONG handle); + + extern "C" LONG ReadFile( + LONG stationNumber, + LONG handle, + LONG startingOffset, + LONG bytesToRead, + LONG * actualBytesRead, + void * buffer); + + extern "C" LONG WriteFile( + LONG stationNumber, + LONG handle, + LONG startingOffset, + LONG bytesToWrite, + void * buffer); + + extern "C" LONG SetFileSize( + LONG station, + LONG handle, + LONG filesize, + LONG truncateflag); + + extern "C" LONG GetFileSize( + LONG stationNumber, + LONG handle, + LONG * fileSize); + + extern "C" LONG DirectReadFile( + LONG station, + LONG handle, + LONG startingsector, + LONG sectorcount, + BYTE * buffer); + + extern "C" LONG SwitchToDirectFileMode( + LONG station, + LONG handle); + + extern "C" LONG ReturnVolumeMappingInformation( + LONG volumenumber, + struct VolumeInformationStructure * volumeInformation); + + extern "C" LONG ExpandFileInContiguousBlocks( + LONG station, + LONG handle, + LONG fileblocknumber, + LONG numberofblocks, + LONG vblocknumber, + LONG segnumber); + + extern "C" LONG FreeLimboVolumeSpace( + LONG volumenumber, + LONG numberofblocks); + + extern "C" LONG DirectWriteFileNoWait( + LONG station, + LONG handle, + LONG startingsector, + LONG sectorcount, + BYTE * buffer, + void (*callbackroutine)(LONG, LONG, LONG), + LONG callbackparameter); + + extern "C" LONG DirectWriteFile( + LONG station, + LONG handle, + LONG startingsector, + LONG sectorcount, + BYTE * buffer); + + extern "C" LONG RevokeFileHandleRights( + LONG Station, + LONG Task, + LONG FileHandle, + LONG QueryFlag, + LONG removeRights, + LONG * newRights); + + extern "C" LONG ModifyDirectoryEntry( + LONG Station, + LONG Task, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG MatchBits, + LONG TargetNameSpace, + struct ModifyStructure * ModifyVector, + LONG ModifyBits, + LONG AllowWildCardsFlag); + + extern "C" LONG MapFileHandleToFCB( + LONG handle, + FCBType ** fcb); + + extern "C" LONG MapPathToDirectoryNumber( + LONG Station, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG * DirectoryNumber, + LONG * FileFlag); + + extern "C" LONG CreateDirectory( + LONG Station, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace, + LONG DirectoryAccessMask, + LONG * ReturnedDirectoryNumber, + void ** ReturnedSubDir); + + extern "C" LONG DeleteDirectory( + LONG Station, + LONG Volume, + LONG PathBase, + BYTE * PathString, + LONG PathCount, + LONG NameSpace); + + extern "C" LONG DirectorySearch( + LONG Station, + LONG Volume, + LONG DirectoryNumber, + LONG NameSpace, + LONG StartEntryNumber, + BYTE * Pattern, + LONG MatchBits, + struct DirectoryStructure ** DirectoryEntry, + LONG * ReturnedDirectoryNumber); + + extern "C" LONG VMGetDirectoryEntry( + LONG volumeNumber, + LONG directoryEntry, + void * directoryEntryPointer); + + extern "C" LONG ImportPublicSymbol( + LONG moduleHandle, + BYTE * symbolName); + + extern "C" LONG UnImportPublicSymbol( + LONG moduleHandle, + BYTE * symbolName); + + extern "C" LONG ExportPublicSymbol( + LONG moduleHandle, + BYTE * symbolName, + LONG address); + + extern "C" void SynchronizeStart( void); + + extern "C" LONG CFindLoadModuleHandle( void *); + + extern "C" int atexit( + FLM_EXIT_FUNC fnExit); + + extern "C" LONG LoadModule( + void * screenID, + BYTE * fileName, + LONG loadOptions); + + extern "C" LONG UnloadModule( + void ** pScreenID, + const char * commandline); + + extern "C" int SGUIDCreate( + NWGUID * guidBfr); + + extern "C" void * GetSystemConsoleScreen( void); + + extern "C" LONG SizeOfAllocBlock( + void * AllocAddress); + + extern "C" SEMAPHORE kSemaphoreAlloc( + BYTE * pSemaName, + UINT SemaCount); + + extern "C" ERROR kSemaphoreFree( + SEMAPHORE SemaHandle); + + extern "C" ERROR kSemaphoreWait( + SEMAPHORE SemaHandle); + + extern "C" ERROR kSemaphoreTimedWait( + SEMAPHORE SemaHandle, + UINT MilliSecondTimeOut); + + extern "C" ERROR kSemaphoreSignal( + SEMAPHORE SemaHandle); + + extern "C" UINT kSemaphoreExamineCount( + SEMAPHORE SemaHandle); + + extern "C" MUTEX kMutexAlloc( + BYTE * MutexName); + + extern "C" ERROR kMutexFree( + MUTEX MutexHandle); + + extern "C" ERROR kMutexLock( + MUTEX MutexHandle); + + extern "C" ERROR kMutexUnlock( + MUTEX MutexHandle); + + extern "C" void CMoveFast( + void * src, + void * dst, + LONG numberOfBytes); + + extern "C" void EnterDebugger( void); + + extern "C" void GetClosestSymbol( + BYTE * szBuffer, + LONG udAddress); + + extern "C" LONG GetCurrentTime( void); + + extern "C" void ConvertTicksToSeconds( + LONG ticks, + LONG * seconds, + LONG * tenthsOfSeconds); + + extern "C" void ConvertSecondsToTicks( + LONG seconds, + LONG tenthsOfSeconds, + LONG * ticks); + + extern "C" LONG GetCacheBufferSize(void); + + extern "C" LONG GetOriginalNumberOfCacheBuffers(void); + + extern "C" LONG GetCurrentNumberOfCacheBuffers(void); + + extern "C" LONG GetNLMAllocMemoryCounts( + FLMUINT moduleHandle, + FLMUINT * freeBytes, + FLMUINT * freeNodes, + FLMUINT * allocatedBytes, + FLMUINT * allocatedNodes, + FLMUINT * totalMemory); + + FLMUINT f_getNLMHandle( void); + + extern "C" LONG atomic_xchg( + volatile LONG * address, + LONG value); + + extern "C" FLMINT32 nlm_AtomicIncrement( + volatile LONG * piTarget); + + extern "C" FLMINT32 nlm_AtomicDecrement( + volatile LONG * piTarget); + + #define nlm_AtomicExchange( piTarget, iValue) \ + ((FLMINT32)atomic_xchg( (volatile LONG *)(piTarget), (LONG)(iValue))) + + /************************************************************************* + Desc: + *************************************************************************/ + #if !defined( __MWERKS__) + #pragma aux nlm_AtomicIncrement parm [ecx]; + #pragma aux nlm_AtomicIncrement = \ + 0xB8 0x01 0x00 0x00 0x00 /* mov eax, 1 */ \ + 0xF0 0x0F 0xC1 0x01 /* lock xadd [ecx], eax */ \ + 0x40 /* inc eax */ \ + parm [ecx] \ + modify exact [eax]; + + #pragma aux nlm_AtomicDecrement parm [ecx]; + #pragma aux nlm_AtomicDecrement = \ + 0xB8 0xFF 0xFF 0xFF 0xFF /* mov eax, 0ffffffffh */ \ + 0xF0 0x0F 0xC1 0x01 /* lock xadd [ecx], eax */ \ + 0x48 /* dec eax */ \ + parm [ecx] \ + modify exact [eax]; + #endif + + /************************************************************************* + Desc: + *************************************************************************/ + #if defined( __MWERKS__) + FINLINE FLMINT32 nlm_AtomicIncrement( + volatile LONG * piTarget) + { + FLMINT32 i32Result; + + __asm + { + mov eax, 1 + mov ecx, piTarget + lock xadd [ecx], eax + inc eax + mov i32Result, eax + } + + return( i32Result); + } + #endif + + /************************************************************************* + Desc: + *************************************************************************/ + #if defined( __MWERKS__) + FINLINE FLMINT32 nlm_AtomicDecrement( + volatile LONG * piTarget) + { + FLMINT32 i32Result; + + __asm + { + mov eax, 0ffffffffh + mov ecx, piTarget + lock xadd [ecx], eax + dec eax + mov i32Result, eax + } + + return( i32Result); + } + #endif + + /************************************************************************* + Desc: + *************************************************************************/ + #define FD_CLR(fd, set) do { \ + unsigned int __i; \ + for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) { \ + if (((fd_set *)(set))->fd_array[__i] == fd) { \ + while (__i < ((fd_set *)(set))->fd_count-1) { \ + ((fd_set *)(set))->fd_array[__i] = \ + ((fd_set *)(set))->fd_array[__i+1]; \ + __i++; \ + } \ + ((fd_set *)(set))->fd_count--; \ + break; \ + } \ + } \ + } while(0) + + /************************************************************************* + Desc: + *************************************************************************/ + #define FD_SET(fd, set) do { \ + unsigned int __i; \ + for (__i = 0; __i < ((fd_set *)(set))->fd_count; __i++) { \ + if (((fd_set *)(set))->fd_array[__i] == (fd)) { \ + break; \ + } \ + } \ + if (__i == ((fd_set *)(set))->fd_count) { \ + if (((fd_set *)(set))->fd_count < FD_SETSIZE) { \ + ((fd_set *)(set))->fd_array[__i] = (fd); \ + ((fd_set *)(set))->fd_count++; \ + } \ + } \ + } while(0) + + #define FD_ZERO(set) \ + (((fd_set *)(set))->fd_count=0) + + #define FD_ISSET(fd, set) \ + __WSAFDIsSet((SOCKET)(fd), (fd_set *)(set)) + + #define MAKEWORD(low,high) \ + ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8)) + + extern "C" int WSAStartup( + unsigned short wVersionRequested, + LPWSADATA lpWSAData); + + extern "C" int WSACleanup( void); + + extern "C" int gethostname( + char * name, + int namelen); + + extern "C" struct hostent * gethostbyname( + const char * name); + + extern "C" struct hostent * gethostbyaddr( + const char * addr, + int len, + int type); + + extern "C" char * inet_ntoa( + struct in_addr in); + + extern "C" int select( + int nfds, + fd_set * readfds, + fd_set * writefds, + fd_set * exceptfds, + const struct timeval * timeout); + + extern "C" int __WSAFDIsSet( SOCKET, fd_set *); + + extern "C" int recv( + SOCKET s, + char * buf, + int len, + int flags); + + extern "C" int send( + SOCKET s, + const char * buf, + int len, + int flags); + + extern "C" int setsockopt( + SOCKET s, + int level, + int optname, + const char * optval, + int optlen); + + extern "C" int closesocket( + SOCKET s); + + extern "C" SOCKET socket( + int af, + int type, + int protocol); + + extern "C" int bind( + SOCKET s, + const struct sockaddr * name, + int namelen); + + extern "C" int listen( + SOCKET s, + int backlog); + + extern "C" unsigned long inet_addr( + const char * cp); + + extern "C" unsigned short htons( + unsigned short hostshort); + + extern "C" unsigned long htonl( + unsigned long hostlong); + + extern "C" int WSAGetLastError( void); + + extern "C" int WSAConnect( + SOCKET s, + const struct sockaddr * name, + int namelen, + LPWSABUF lpCallerData, + LPWSABUF lpCalleeData, + LPQOS lpSQOS, + LPQOS lpGQOS); + + extern "C" SOCKET WSAAccept( + SOCKET s, + struct sockaddr * addr, + int * addrlen, + void * lpfnCondition, + DWORD dwCallbackData); + + #define f_argsize(x) \ + ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int)-1)) + + #define f_va_start(ap, parmN) \ + ((void)((ap) = (unsigned long)&(parmN) + f_argsize(parmN))) + + #define f_va_arg(ap, type) \ + (*(type *)(((ap) += f_argsize(type)) - (f_argsize(type)))) + + #define f_va_end(ap) \ + ((void)0) + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE char * f_strcpy( + char * d, + const char * s) + { + while ((*d++ = *s++) != 0); + return( d); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE unsigned f_strlen( + const char * s) + { + const char * b = s; + + while (*s) + { + s++; + } + + return( s - b); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE int f_strcmp( + const char * s1, + const char * s2) + { + while( *s1 == *s2 && *s1) + { + s1++; + s2++; + } + return( (int)(*s1 - *s2)); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE char * f_strncpy( + char * dest, + const char * src, + unsigned n) + { + while( n) + { + *dest++ = *src; + if( *src) + { + src++; + } + n--; + } + + *dest = 0; + return( dest); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE int f_strncmp( + const char * s1, + const char * s2, + unsigned n) + { + while( *s1 == *s2 && *s1 && n) + { + s1++; + s2++; + n--; + } + + if( n) + { + return( (*s1 - *s2)); + } + + return( (int)0); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE char * f_strcat( + char * dst, + const char * src) + { + const char * p = src; + char * q = dst; + + while (*q++); + q--; + while( (*q++ = *p++) != 0); + + return(dst); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE char * f_strncat( + char * dst , + const char * src, + unsigned n) + { + const char * p = src; + char * q = dst; + + while (*q++); + + q--; n++; + + while( --n) + { + if( (*q++ = *p++) == 0) + { + q--; + break; + } + } + + *q = 0; + return( dst); + } + + char * f_strstr( + const char * pszStr1, + const char * pszStr2); + + FLMINT f_stricmp( + const char * pszStr1, + const char * pszStr2); + + FLMINT f_strnicmp( + const char * pszStr1, + const char * pszStr2, + FLMINT iLen); + + char * f_strupr( + char * pszStr); + + FLMINT f_memcmp( + const void * pvMem1, + const void * pvMem2, + FLMUINT uiSize); + + #define f_memcpy( dest, src, size) \ + CMoveFast( (void *)(src), (void *)(dest), size) + + void * f_memset( + void * pvMem, + FLMBYTE ucByte, + FLMUINT uiSize); + + #define f_memset( m, c, size) \ + f_memset( (void *)(m), c, size) + + void * f_memmove( + void * pvDest, + const void * pvSrc, + FLMUINT uiSize); + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE RCODE f_mutexCreate( + F_MUTEX * phMutex) + { + if( (*phMutex = (F_MUTEX)kMutexAlloc( (BYTE *)"NOVDB")) == F_MUTEX_NULL) + { + return( RC_SET( FERR_MEM)); + } + + return( FERR_OK); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE void f_mutexDestroy( + F_MUTEX * phMutex) + { + if (*phMutex != F_MUTEX_NULL) + { + (void)kMutexFree( (MUTEX)(*phMutex)); + *phMutex = F_MUTEX_NULL; + } + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE void f_mutexLock( + F_MUTEX hMutex) + { + (void)kMutexLock( (MUTEX)hMutex); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE void f_mutexUnlock( + F_MUTEX hMutex) + { + (void)kMutexUnlock( (MUTEX)hMutex); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE RCODE f_semCreate( + F_SEM * phSem) + { + if( (*phSem = (F_SEM)kSemaphoreAlloc( (BYTE *)"NOVDB", 0)) == F_SEM_NULL) + { + return( RC_SET( FERR_MEM)); + } + + return( FERR_OK); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE void f_semDestroy( + F_SEM * phSem) + { + if (*phSem != F_SEM_NULL) + { + (void)kSemaphoreFree( (SEMAPHORE)(*phSem)); + *phSem = F_SEM_NULL; + } + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE RCODE f_semWait( + F_SEM hSem, + FLMUINT uiTimeout) + { + RCODE rc = FERR_OK; + + if( uiTimeout == F_SEM_WAITFOREVER) + { + if( kSemaphoreWait( (SEMAPHORE)hSem) != 0) + { + rc = RC_SET( FERR_MUTEX_UNABLE_TO_LOCK); + } + } + else + { + if( kSemaphoreTimedWait( (SEMAPHORE)hSem, (UINT)uiTimeout) != 0) + { + rc = RC_SET( FERR_MUTEX_UNABLE_TO_LOCK); + } + } + + return( rc); + } + + /************************************************************************* + Desc: + *************************************************************************/ + FINLINE void f_semSignal( + F_SEM hSem) + { + (void)kSemaphoreSignal( (SEMAPHORE)hSem); + } + +#pragma pack(pop) +#endif diff --git a/flaim/src/nlmload.cpp b/flaim/src/nlmload.cpp new file mode 100644 index 0000000..ed57ae4 --- /dev/null +++ b/flaim/src/nlmload.cpp @@ -0,0 +1,433 @@ +//------------------------------------------------------------------------- +// Desc: Startup/Exit module for FLAIM utilities on Netware. +// Tabs: 3 +// +// Copyright (c) 1999-2000,2002-2003,2005-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: nlmload.cpp 12334 2006-01-23 12:45:35 -0700 (Mon, 23 Jan 2006) dsanders $ +//------------------------------------------------------------------------- + +#include "flaim.h" +#include "ftk.h" + +#ifdef FLM_WATCOM_NLM + +extern "C" void * nlmStart( + void * hThread, + void * pData); + +extern "C" void exit( + int exitCode); + +extern "C" int nlm_main( + int iArgC, + char ** ppszArgV); + +extern "C" LONG FlmLoad( + LoadDefStruct * moduleHandle, + struct ScreenStruct * initScreen, + char * commandLine, + char * loadDirectoryPath, + LONG uninitializedDataLength, + LONG fileHandle, + LONG (*ReadRoutine) + (LONG handle, + LONG offset, + char * buffer, + LONG length), + LONG customDataOffset, + LONG customDataSize); + +extern "C" void FlmUnload( void); + +static SEMAPHORE gv_lFlmSyncSem = 0; +static FLMBOOL gv_bUnloadCalled = FALSE; +static FLMBOOL gv_bMainRunning = FALSE; +static LONG gv_lAllocRTag = 0; +static LONG gv_lMyModuleHandle = 0; +static FLM_EXIT_FUNC gv_fnExit; + +extern "C" void __wcpp_4_fatal_runtime_error_( + char * msg, + unsigned retcode) +{ + (void)msg; + (void)retcode; +} + +/******************************************************************** +Desc: Signals the FlmLoad thread to release the console. +*********************************************************************/ +void SynchronizeStart( void) +{ + if (gv_lFlmSyncSem) + { + (void)kSemaphoreSignal( gv_lFlmSyncSem); + } +} + +/******************************************************************** +Desc: Startup routine for the NLM - that gets the main going in + its own thread. +*********************************************************************/ +void * nlmStart( + void * hThread, + void * pData) +{ + ARG_DATA * pArgData = (ARG_DATA *)pData; + LoadDefStruct * moduleHandle = pArgData->moduleHandle; + + (void)hThread; + + (void)kSetThreadName( (void *)kCurrentThread(), + (BYTE *)pArgData->pszThreadName); + + (void)nlm_main( pArgData->iArgC, pArgData->ppszArgV); + + Free( pArgData->ppszArgV); + Free( pArgData->pszArgs); + Free( pArgData->pszThreadName); + Free( pArgData); + + gv_bMainRunning = FALSE; + + if (!gv_bUnloadCalled) + { + KillMe( moduleHandle); + } + + kExitThread( NULL); + return( NULL); +} + +/******************************************************************** +Desc: Startup routine for the NLM. +*********************************************************************/ +LONG FlmLoad( + LoadDefStruct * moduleHandle, + struct ScreenStruct * initScreen, + char * commandLine, + char * loadDirectoryPath, + LONG uninitializedDataLength, + LONG fileHandle, + LONG (*ReadRoutine) + (LONG handle, + LONG offset, + char * buffer, + LONG length), + LONG customDataOffset, + LONG customDataSize) +{ + char * pszTmp; + char * pszArgStart; + int iArgC; + int iTotalArgChars; + int iArgSize; + char ** ppszArgV = NULL; + char * pszArgs = NULL; + char * pszDestArg; + bool bFirstPass = true; + char cEnd; + ARG_DATA * pArgData = NULL; + LONG sdRet = 0; + char * pszThreadName; + int iTmpLen; + void * hThread = NULL; + + gv_bUnloadCalled = FALSE; + + (void)initScreen; + (void)uninitializedDataLength; + (void)fileHandle; + (void)ReadRoutine; + (void)customDataOffset; + (void)customDataSize; + + // Allocate the needed resource tags + + gv_lMyModuleHandle = (LONG)moduleHandle; + + if( (gv_lAllocRTag = AllocateResourceTag( + (LONG)moduleHandle, + (BYTE *)"FLAIM Memory", AllocSignature)) == NULL) + { + sdRet = 1; + goto Exit; + } + + if (moduleHandle->LDFlags & 4) // Synchronized start + { + gv_lFlmSyncSem = kSemaphoreAlloc( (BYTE *)"FLAIM", 0); + } + + // First pass: Count the arguments in the command line + // and determine how big of a buffer we will need. + // Second pass: Put argments into allocated buffer. + +Parse_Args: + + iTotalArgChars = 0; + iArgC = 0; + + iArgSize = f_strlen( loadDirectoryPath); + + if (!bFirstPass) + { + ppszArgV [iArgC] = pszDestArg; + f_memcpy( pszDestArg, loadDirectoryPath, iArgSize); + pszDestArg [iArgSize] = 0; + pszDestArg += (iArgSize + 1); + } + + iArgC++; + iTotalArgChars += iArgSize; + pszTmp = commandLine; + + for (;;) + { + + // Skip leading blanks. + + while ((*pszTmp) && (*pszTmp == ' ')) + { + pszTmp++; + } + + if (!(*pszTmp)) + { + break; + } + + if ((*pszTmp == '"') || (*pszTmp == '\'')) + { + cEnd = *pszTmp; + pszTmp++; + } + else + { + cEnd = ' '; + } + + pszArgStart = pszTmp; + iArgSize = 0; + + // Count the characters in the parameter. + + while ((*pszTmp) && (*pszTmp != cEnd)) + { + iArgSize++; + pszTmp++; + } + + if ((!iArgSize) && (cEnd == ' ')) + { + break; + } + + // If 2nd pass, save the argument. + + if (!bFirstPass) + { + ppszArgV [iArgC] = pszDestArg; + if (iArgSize) + { + f_memcpy( pszDestArg, pszArgStart, iArgSize); + } + pszDestArg [iArgSize] = 0; + pszDestArg += (iArgSize + 1); + } + + iArgC++; + iTotalArgChars += iArgSize; + + // Skip trailing quote or blank. + + if (*pszTmp) + { + pszTmp++; + } + } + + if (bFirstPass) + { + if ((ppszArgV = (char **)Alloc( + sizeof( char *) * iArgC, gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + if ((pszArgs = (char *)Alloc( + iTotalArgChars + iArgC, gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + pszDestArg = pszArgs; + bFirstPass = false; + goto Parse_Args; + } + + pszTmp = (char *)(&moduleHandle->LDName [1]); + iTmpLen = (int)(moduleHandle->LDName [0]); + + if ((pszThreadName = (char *)Alloc( + iTmpLen + 1, gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + f_memcpy( pszThreadName, pszTmp, iTmpLen); + pszThreadName [iTmpLen] = 0; + + if ((pArgData = (ARG_DATA *)Alloc( + sizeof( ARG_DATA), gv_lAllocRTag)) == NULL) + { + sdRet = 1; + goto Exit; + } + + pArgData->ppszArgV = ppszArgV; + pArgData->pszArgs = pszArgs; + pArgData->iArgC = iArgC; + pArgData->moduleHandle = moduleHandle; + pArgData->pszThreadName = pszThreadName; + + gv_bMainRunning = TRUE; + + if ((hThread = kCreateThread( (BYTE *)"FLAIM", nlmStart, NULL, 32768, + (void *)pArgData)) == NULL) + { + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + if (kSetThreadLoadHandle( hThread, (LONG)moduleHandle) != 0) + { + (void)kDestroyThread( hThread); + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + if (kScheduleThread( hThread) != 0) + { + (void)kDestroyThread( hThread); + gv_bMainRunning = FALSE; + sdRet = 2; + goto Exit; + } + + if (moduleHandle->LDFlags & 4) + { + // Synchronized start + + (void)kSemaphoreWait( gv_lFlmSyncSem); + } + +Exit: + + if (sdRet != 0) + { + if (ppszArgV) + { + Free( ppszArgV); + } + + if (pszArgs) + { + Free( pszArgs); + } + + if (pszThreadName) + { + Free( pszThreadName); + } + + if (pArgData) + { + Free( pArgData); + } + + if (gv_lFlmSyncSem) + { + kSemaphoreFree( gv_lFlmSyncSem); + gv_lFlmSyncSem = 0; + } + if (!gv_bUnloadCalled) + { + KillMe( moduleHandle); + } + } + + return( sdRet); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FlmUnload(void) +{ + gv_bUnloadCalled = TRUE; + + if( gv_fnExit) + { + (*gv_fnExit)(); + gv_fnExit = NULL; + } + + while (gv_bMainRunning) + { + kYieldThread(); + } + + if (gv_lFlmSyncSem) + { + kSemaphoreFree( gv_lFlmSyncSem); + gv_lFlmSyncSem = 0; + } + + if( gv_lAllocRTag) + { + ReturnResourceTag( gv_lAllocRTag, 1); + gv_lAllocRTag = 0; + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void exit( + int exitCode) +{ + (void)exitCode; +} + +/**************************************************************************** +Desc: +****************************************************************************/ +int atexit( + FLM_EXIT_FUNC fnExit) +{ + gv_fnExit = fnExit; + return( 0); +} + +#endif // FLM_WATCOM_NLM diff --git a/flaim/src/nwyield.cpp b/flaim/src/nwyield.cpp new file mode 100644 index 0000000..827cf31 --- /dev/null +++ b/flaim/src/nwyield.cpp @@ -0,0 +1,249 @@ +//------------------------------------------------------------------------- +// Desc: Special CPU yielding routines for Netware +// Tabs: 3 +// +// Copyright (c) 2000-2003,2005-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// 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, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: nwyield.cpp 12315 2006-01-19 15:16:37 -0700 (Thu, 19 Jan 2006) dsanders $ +//------------------------------------------------------------------------- + +#include "flaimsys.h" + +#ifdef FLM_NLM + +/****************************************************************************/ +/* Procedures imported from the Kernel */ +/****************************************************************************/ + +extern "C" +{ + +void StopBell(void); + +unsigned long kQueCount( + unsigned long uiQueHandle); + +unsigned long CEvaluateExpression( + unsigned char ** commandLine, + unsigned long * stackFrame, + unsigned long * number); + +/**************************************************************************** + Data items imported from the kernel +****************************************************************************/ + +extern unsigned long CpuCurrentProcessor; +extern unsigned long WorkToDoListHead; + +/****************************************************************************/ + +struct OldPerCpuStruct +{ + unsigned long reserved0[24]; + + /* offset 0x60 */ + unsigned long reserved1[3]; + unsigned long PSD_ThreadStartClocks; + unsigned long reserved2[4]; + + unsigned long reserved3[40]; + + /* offset 0x120 */ + unsigned long PSD_LocalWTDHead; +}; + +/****************************************************************************/ +#if !defined( __MWERKS__) +extern unsigned long ReadInternalClock(void); +#else +unsigned long ReadInternalClock(void); +#endif + +// Local function prototypes + +FSTATIC int LocalYieldInit( void); + +FSTATIC void OldOSCompatibleYield(void); + + +} // extern "C" + +#if !defined( __MWERKS__) +#pragma aux ReadInternalClock = \ +0x0F 0x31 /* RDTSC */\ +modify exact [EAX EDX]; +#else +unsigned long ReadInternalClock(void) +{ + __asm + { + rdtsc + ret + } +} +#endif + +/****************************************************************************/ + +static unsigned long yieldTimeSlice = 0; +static unsigned long stackFrame[0x100] = {0}; +static unsigned long * ThreadFeederQue = 0; +static struct OldPerCpuStruct * pPerCpuDataArea = 0; + +/**************************************************************************** +Desc: This API is called once the first time NWYieldIfTime() is called if + kYieldIfTimeSliceUp isn't supported by the host OS. +****************************************************************************/ +FSTATIC int LocalYieldInit(void) +{ + unsigned char * buffer; + unsigned char * pointer; + unsigned long ccode; + unsigned long address; + unsigned long (*ConvertMicroSecondsToClocks)(unsigned long data); + + // Fixup ThreadFeededQue + + buffer = (unsigned char *)"SERVER.NLM|ThreadFeederQue"; + + // Get the address from the debugger + + ccode = CEvaluateExpression( &buffer, &stackFrame[0], &address); + if (ccode != 0) + { + return( -1); + } + + ThreadFeederQue = (unsigned long *)address; + + // Setup yieldTimeSlice + // First get a pointer to ConvertMicroSecondsToClocks and then verify it + + pointer = (unsigned char *)(&StopBell); + pointer = pointer + 0x1ea; + if (pointer[0] != 0x8b || + pointer[1] != 0x44 || + pointer[2] != 0x24 || + pointer[3] != 0x04 || + pointer[4] != 0x33 || + pointer[5] != 0xd2 || + pointer[6] != 0xf7) + { + return( -1); + } + + *(unsigned long *)(&ConvertMicroSecondsToClocks) = (unsigned long)pointer; + + // Now calculate our desired time slice in clocks + + yieldTimeSlice = (*ConvertMicroSecondsToClocks)(200); + + // Get a pointer to the per-CPU data area + + buffer = (unsigned char *)"LOADER.NLM|PerCpuDataArea"; + ccode = CEvaluateExpression( &buffer, &stackFrame[0], &address); + if (ccode != 0) + { + return( -1); + } + + pPerCpuDataArea = (struct OldPerCpuStruct *)address; + return( 0); +} + +/**************************************************************************** +Desc: This routine does everything that kYieldIfTimeSliceUp() does, and it is + compatible with 5.0 SP4 and 5.1 release. It shouldn't be used on host + OSs that support kYieldIfTimeSliceUp(). +****************************************************************************/ +FSTATIC void OldOSCompatibleYield(void) +{ + unsigned long timeStamp; + unsigned long threadStartTime; + + if ((CpuCurrentProcessor == 0) && (WorkToDoListHead != 0)) + { + + // If we are P0 and there is legacy WTD waiting, then yield + + kYieldThread(); + return; + } + + if ((pPerCpuDataArea->PSD_LocalWTDHead != 0) || + (kQueCount( ThreadFeederQue[CpuCurrentProcessor]) != 0)) + { + + // If there is MPK WTD or a feederQ thread waiting, then yield + + kYieldThread(); + return; + } + + timeStamp = ReadInternalClock(); + threadStartTime = pPerCpuDataArea->PSD_ThreadStartClocks; + + // Note 32 bit arithmetic is sufficient and less overhead + + if ((timeStamp - threadStartTime) > yieldTimeSlice) + { + kYieldThread(); + } +} + +/**************************************************************************** +Desc: This is the routine to call for time sensitive yielding. The first + time it is called, it will change itself to a JMP to the appropriate + yield procedure. If it is on 5.1 SP1 or greater, it will jump to + kYieldIfTimeSliceUp(). If it is on 5.0 SP4 or 5.1 release, it will + jump to OldOSCompatibleYield(). Otherwise it will jump to + kYieldThread(). +****************************************************************************/ +void NWYieldIfTime(void) +{ + unsigned char * fixup; + unsigned long address; + + *(unsigned long *)(&address) = ImportPublicSymbol( + (unsigned long)f_getNLMHandle(), + (unsigned char *)"\x13" "kYieldIfTimeSliceUp"); + + fixup = (unsigned char *)(&NWYieldIfTime); + + if (address == 0) + { + // We couldn't import the procedure, so see if our local routine + // is compatible. + + if (LocalYieldInit() == 0) + { + address = (unsigned long)(&OldOSCompatibleYield); + } + else + { + address = (unsigned long)(&kYieldThread); + } + } + + fixup[0] = 0xE9; + ++fixup; + address = address - (4 + (unsigned long)fixup); + *(unsigned long *)fixup = address; +} + +#endif // FLM_NLM diff --git a/flaim/util/dbshell.cpp b/flaim/util/dbshell.cpp index 100de60..a3086e0 100644 --- a/flaim/util/dbshell.cpp +++ b/flaim/util/dbshell.cpp @@ -3859,10 +3859,7 @@ FLMINT FlmFileSysCommand::execute( pShell->con_printf( "Error changing directory\n"); } #elif defined( FLM_NLM) - if (chdir( (char *)ppszArgV [1]) != 0) - { - pShell->con_printf( "Error changing directory\n"); - } + pShell->con_printf( "Unable to change directory\n"); #else #error "This platform is not supported" @@ -5072,11 +5069,16 @@ FSTATIC void extractBaseDirAndWildcard( /*************************************************************************** Desc: Program entry point (main) ****************************************************************************/ -#if defined( FLM_UNIX) || defined( FLM_NLM) -extern "C" int main( +#if defined( FLM_UNIX) +int main( int, // iArgC, char ** // ppszArgV ) +#elif defined( FLM_NLM) +extern "C" int nlm_main( + int, // iArgC, + char ** // ppucArgV + ) #else int __cdecl main( int, // iArgC, @@ -5091,11 +5093,6 @@ int __cdecl main( gv_bRunning = TRUE; - // Setup the routines to be called when the NLM exits - - atexit( xshellCleanup); -// SynchronizeStart(); - #endif if( RC_BAD( rc = FlmStartup())) @@ -5141,4 +5138,3 @@ Exit: gv_bRunning = FALSE; return( 0); } - diff --git a/flaim/util/sample.cpp b/flaim/util/sample.cpp index cc1b59c..e1afb89 100644 --- a/flaim/util/sample.cpp +++ b/flaim/util/sample.cpp @@ -22,8 +22,8 @@ // $Id: sample.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $ //------------------------------------------------------------------------- -#include #include "flaim.h" +#include const char * gv_pszSampleDictionary = "0 @1@ field Person\n"