[med-svn] [ncbi-vdb] 02/05: Imported Upstream version 2.7.0+dfsg
Andreas Tille
tille at debian.org
Fri Jul 22 13:22:35 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository ncbi-vdb.
commit 9fcac712e70795323b981ee8e82d6c14aafe63f7
Author: Andreas Tille <tille at debian.org>
Date: Fri Jul 22 14:20:37 2016 +0200
Imported Upstream version 2.7.0+dfsg
---
interfaces/os/mac/byteswap.h | 39 -
interfaces/os/mac/endian.h | 39 -
interfaces/os/mac/os-native.h | 114 --
interfaces/os/sun/arch-impl.h | 287 ---
interfaces/os/sun/atomic.h | 152 --
interfaces/os/sun/atomic32.h | 218 ---
interfaces/os/sun/bitstr.h | 47 -
interfaces/os/sun/byteswap.h | 40 -
interfaces/os/sun/endian.h | 44 -
interfaces/os/sun/fmtdef.h | 42 -
interfaces/os/sun/noarch/bitstr.h | 417 -----
interfaces/os/sun/os-native.h | 181 --
interfaces/os/sun/strtol.h | 67 -
interfaces/os/sun/va_copy.h | 49 -
interfaces/os/win/atomic.h | 149 --
interfaces/os/win/atomic32.h | 194 --
interfaces/os/win/atomic64.h | 194 --
interfaces/os/win/byteswap.h | 44 -
interfaces/os/win/endian.h | 42 -
interfaces/os/win/os-native.h | 238 ---
interfaces/os/win/oserror.h | 41 -
interfaces/os/win/strtol.h | 158 --
interfaces/os/win/sysalloc.h | 69 -
libs/ascp/mac/ascp-path.c | 74 -
libs/ascp/win/ascp-path.c | 75 -
libs/ascp/win/connect.c | 525 ------
libs/kapp/mac/ram.c | 63 -
libs/kapp/sun/sysmain.c | 243 ---
libs/kapp/win/args-conv-os.c | 48 -
libs/kapp/win/main-priv-win.h | 51 -
libs/kapp/win/ram.c | 62 -
libs/kapp/win/sysmain.c | 300 ---
libs/kfc/win/sysctx.c | 342 ----
libs/kfc/win/sysrsrc.c | 186 --
libs/kfs/win/directory-path.c | 83 -
libs/kfs/win/lnk_tools.c | 518 ------
libs/kfs/win/sysdir-priv.h | 92 -
libs/kfs/win/sysdir.c | 3135 --------------------------------
libs/kfs/win/sysdll.c | 1417 ---------------
libs/kfs/win/sysfile-priv.h | 82 -
libs/kfs/win/sysfile-v2.c | 1028 -----------
libs/kfs/win/sysfile.c | 1059 -----------
libs/kfs/win/syslockfile.c | 67 -
libs/kfs/win/sysmmap-priv.h | 71 -
libs/kfs/win/sysmmap.c | 138 --
libs/klib/sun/syslog.c | 208 ---
libs/klib/sun/systime.c | 110 --
libs/klib/win/misc.c | 33 -
libs/klib/win/sysalloc.c | 68 -
libs/klib/win/syserrcode.c | 85 -
libs/klib/win/syslog.c | 121 --
libs/klib/win/systime.c | 355 ----
libs/klib/win/syswriter.c | 185 --
libs/kns/mac/sysendpoint.c | 140 --
libs/kns/mac/syspoll.c | 96 -
libs/kns/win/sysendpoint.c | 147 --
libs/kns/win/sysmgr.c | 65 -
libs/kns/win/syssock.c | 1855 -------------------
libs/kns/win/sysstream.c | 232 ---
libs/kproc/sun/sysbarrier.c | 170 --
libs/kproc/sun/syslock-priv.h | 62 -
libs/kproc/sun/syslock.c | 501 -----
libs/kproc/win/syscond-priv.h | 79 -
libs/kproc/win/syscond.c | 500 -----
libs/kproc/win/syslock-priv.h | 67 -
libs/kproc/win/syslock.c | 725 --------
libs/kproc/win/sysmgr.c | 37 -
libs/kproc/win/systhread.c | 291 ---
libs/kproc/win/systimeout.c | 70 -
libs/krypto/win/sysrng.c | 132 --
libs/ktst/win/systestenv.cpp | 167 --
libs/tui/win/systui.c | 590 ------
libs/vfs/win/syskeyring.c | 58 -
libs/vfs/win/syspath.c | 471 -----
libs/xfs/win/operations.c | 2666 ---------------------------
libs/xfs/win/operations.h | 50 -
libs/xfs/win/platform.c | 541 ------
libs/xfs/win/security.c | 1935 --------------------
test/vdb/kfg/mac/test-dependencies.kfg | 3 -
test/vdb/kfg/win/test-dependencies.kfg | 3 -
80 files changed, 25342 deletions(-)
diff --git a/interfaces/os/mac/byteswap.h b/interfaces/os/mac/byteswap.h
deleted file mode 100644
index 172fd8b..0000000
--- a/interfaces/os/mac/byteswap.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_mac_byteswap_
-#define _h_mac_byteswap_
-
-#include <architecture/byte_order.h>
-
-/* make these look the same as on Linux
- use the lower-level Mac routines, as
- they are specific in their data types */
-#define bswap_16(x) OSSwapInt16 (x)
-#define bswap_32(x) OSSwapInt32 (x)
-#define bswap_64(x) OSSwapInt64 (x)
-
-#endif /* _h_mac_byteswap_ */
diff --git a/interfaces/os/mac/endian.h b/interfaces/os/mac/endian.h
deleted file mode 100644
index 367e1f0..0000000
--- a/interfaces/os/mac/endian.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_mac_endian_
-#define _h_mac_endian_
-
-#include <machine/endian.h>
-
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#define __PDP_ENDIAN PDP_ENDIAN
-
-#define __BYTE_ORDER BYTE_ORDER
-
-
-#endif /* _h_mac_endian_ */
diff --git a/interfaces/os/mac/os-native.h b/interfaces/os/mac/os-native.h
deleted file mode 100644
index 3e26ff5..0000000
--- a/interfaces/os/mac/os-native.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_os_native_
-#define _h_os_native_
-
-#ifndef _h_unix_native_
-#include "../unix/unix-native.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*--------------------------------------------------------------------------
- * strdup - declared unless _ANSI_SOURCE is defined - redeclare anyway
- * strndup - implemented inline here
- */
-char *strdup ( const char *str );
-
-#if !defined(__MAC_10_6) || (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6)
-static __inline__
-char *strndup ( const char *str, size_t n )
-{
- char *dupstr;
-
- const char *end = ( const char* ) memchr ( str, 0, n );
- if ( end != NULL )
- n = end - str;
-
- dupstr = (char*)malloc ( n + 1 );
- if ( dupstr != NULL )
- {
- memcpy ( dupstr, str, n );
- dupstr [ n ] = 0;
- }
-
- return dupstr;
-}
-#endif
-
-/*--------------------------------------------------------------------------
- * strchrnul - implemented inline here
- */
-static __inline__
-char *strchrnul ( const char *str, int c )
-{
- int i;
- for ( i = 0; str [ i ] != 0 && str [ i ] != c; ++i )
- ( void ) 0;
- return & ( ( char* ) str ) [ i ];
-}
-
-/*--------------------------------------------------------------------------
- * memchr - implemented inline here
- */
-static __inline__
-void *memrchr ( const void *s, int c, size_t n )
-{
- size_t i;
- const char *cp = (const char*)s;
- for ( i = n; i > 0; )
- {
- if ( ( int ) cp [ -- i ] == c )
- return ( void* ) & cp [ i ];
- }
- return NULL;
-}
-
-
-/*--------------------------------------------------------------------------
- * strtoll - declared unless _ANSI_SOURCE is defined - redeclare anyway
- * strtoul - older includes were not ready for c99
- *
- * NB - the define __DARWIN_NO_LONG_LONG will be true for
- * cases when long long would be int64_t.
- */
-#if __DARWIN_NO_LONG_LONG
-int64_t strtoll ( const char *s, char **end, int base );
-uint64_t strtoull ( const char *s, char **end, int base );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_os_native_ */
diff --git a/interfaces/os/sun/arch-impl.h b/interfaces/os/sun/arch-impl.h
deleted file mode 100644
index c8fffd6..0000000
--- a/interfaces/os/sun/arch-impl.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_arch_impl_
-#define _h_arch_impl_
-
-#include <stdint.h>
-#include <byteswap.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __inline__
-#define __inline__ inline
-#endif
-
-static __inline__
-int16_t uint16_lsbit ( uint16_t self )
-{
- int rtn;
- for ( rtn = 0; rtn < 16; ++ rtn )
- {
- if ( ( self & ( 1 << rtn) ) != 0 )
- return ( int16_t ) rtn;
- }
- return -1;
-}
-
-static __inline__
-int32_t uint32_lsbit ( uint32_t self )
-{
- int rtn;
- for ( rtn = 0; rtn < 32; ++ rtn )
- {
- if ( ( self & ( 1 << rtn) ) != 0 )
- return ( int32_t ) rtn;
- }
- return -1;
-}
-
-typedef struct int128_t int128_t;
-struct int128_t
-{
- uint64_t lo;
- int64_t hi;
-};
-
-static __inline__
-int64_t int128_hi ( const int128_t *self )
-{
- return self -> hi;
-}
-
-static __inline__
-uint64_t int128_lo ( const int128_t *self )
-{
- return self -> lo;
-}
-
-static __inline__
-void int128_sethi ( int128_t *self, int64_t i )
-{
- self -> hi = i;
-}
-
-static __inline__
-void int128_setlo ( int128_t *self, uint64_t i )
-{
- self -> lo = i;
-}
-
-typedef struct uint128_t uint128_t;
-struct uint128_t
-{
- uint64_t lo;
- uint64_t hi;
-};
-
-static __inline__
-uint64_t uint128_hi ( const uint128_t *self )
-{
- return self -> hi;
-}
-
-static __inline__
-uint64_t uint128_lo ( const uint128_t *self )
-{
- return self -> lo;
-}
-
-static __inline__
-void uint128_sethi ( uint128_t *self, uint64_t i )
-{
- self -> hi = i;
-}
-
-static __inline__
-void uint128_setlo ( uint128_t *self, uint64_t i )
-{
- self -> lo = i;
-}
-
-static __inline__
-void int128_add ( int128_t *self, const int128_t *i )
-{
- int carry = ( ( int64_t ) self -> lo < 0 ) && ( ( int64_t ) i -> lo < 0 );
- self -> hi += i -> hi;
- self -> lo += i -> lo;
- self -> hi += carry;
-}
-
-static __inline__
-void int128_sub ( int128_t *self, const int128_t *i )
-{
- int carry = self -> lo < i -> lo;
- self -> hi -= i -> hi;
- self -> lo -= i -> lo;
- self -> hi -= carry;
-}
-
-static __inline__
-void int128_sar ( int128_t *self, uint32_t i )
-{
- if ( ( i &= 0x7F ) != 0 )
- {
- int64_t shifted = self -> hi;
-
- if ( i >= 64 )
- {
- self -> hi >>= 63;
- self -> lo = shifted >> ( i - 64 );
- }
- else
- {
- self -> lo >>= i;
- shifted <<= 64 - i;
- self -> hi >>= i;
- self -> lo |= shifted;
- }
- }
-}
-
-static __inline__
-void int128_shl ( int128_t *self, uint32_t i )
-{
- if ( ( i &= 0x7F ) != 0 )
- {
- uint64_t shifted = self -> lo;
-
- if ( i >= 64 )
- {
- self -> lo = 0;
- self -> hi = ( int64_t ) ( shifted << ( i - 64 ) );
- }
- else
- {
- self -> hi <<= i;
- shifted >>= 64 - i;
- self -> lo <<= i;
- self -> hi |= ( int64_t ) shifted;
- }
- }
-}
-
-static __inline__
-void uint128_and ( uint128_t *self, const uint128_t *i )
-{
- self -> hi &= i -> hi;
- self -> lo &= i -> lo;
-}
-
-static __inline__
-void uint128_or ( uint128_t *self, const uint128_t *i )
-{
- self -> hi |= i -> hi;
- self -> lo |= i -> lo;
-}
-
-static __inline__
-void uint128_orlo ( uint128_t *self, uint64_t i )
-{
- self -> lo |= i;
-}
-
-static __inline__
-void uint128_xor ( uint128_t *self, const uint128_t *i )
-{
- self -> hi ^= i -> hi;
- self -> lo ^= i -> lo;
-}
-
-static __inline__
-void uint128_not ( uint128_t *self )
-{
- self -> hi = ~ self -> hi;
- self -> lo = ~ self -> lo;
-}
-
-static __inline__
-void uint128_shr ( uint128_t *self, uint32_t i )
-{
- if ( ( i &= 0x7F ) != 0 )
- {
- uint64_t shifted = self -> hi;
-
- if ( i >= 64 )
- {
- self -> hi >>= 63;
- self -> lo = shifted >> ( i - 64 );
- }
- else
- {
- self -> lo >>= i;
- shifted <<= 64 - i;
- self -> hi >>= i;
- self -> lo |= shifted;
- }
- }
-}
-
-static __inline__
-void uint128_shl ( uint128_t *self, uint32_t i )
-{
- if ( ( i &= 0x7F ) != 0 )
- {
- uint64_t shifted = self -> lo;
-
- if ( i >= 64 )
- {
- self -> lo = 0;
- self -> hi = shifted << ( i - 64 );
- }
- else
- {
- self -> hi <<= i;
- shifted >>= 64 - i;
- self -> lo <<= i;
- self -> hi |= shifted;
- }
- }
-}
-
-static __inline__
-void uint128_bswap ( uint128_t *self )
-{
- uint64_t tmp = bswap_64 ( self -> lo );
- self -> lo = bswap_64 ( self -> hi );
- self -> hi = tmp;
-}
-
-static __inline__
-void uint128_bswap_copy ( uint128_t *to, const uint128_t *from )
-{
- uint64_t tmp = bswap_64 ( from -> lo );
- to -> lo = bswap_64 ( from -> hi );
- to -> hi = tmp;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_arch_impl_ */
diff --git a/interfaces/os/sun/atomic.h b/interfaces/os/sun/atomic.h
deleted file mode 100644
index c1ee0f4..0000000
--- a/interfaces/os/sun/atomic.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_atomic_
-#define _h_atomic_
-
-#ifndef _h_atomic32_
-#include "atomic32.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int atomic_int;
-typedef struct atomic32_t atomic_t;
-
-/* ( * v ) */
-#define atomic_read( v ) \
- atomic32_read ( v )
-
-/* ( * v ) = i */
-#define atomic_set( v, i ) \
- atomic32_set ( v, i )
-
-/* prior = ( * v ), ( * v ) += i, prior */
-#define atomic_read_and_add( v, i ) \
- atomic32_read_and_add ( v, i )
-
-/* ( * v ) += i */
-#define atomic_add( v, i ) \
- atomic32_add ( v, i )
-
-/* ( * v ) += i */
-#define atomic_add_and_read( v, i ) \
- atomic32_add_and_read ( v, i )
-
-/* ( void ) ++ ( * v ) */
-#define atomic_inc( v ) \
- atomic32_inc ( v )
-
-/* ( void ) -- ( * v ) */
-#define atomic_dec( v ) \
- atomic32_dec ( v )
-
-/* -- ( * v ) == 0 */
-#define atomic_dec_and_test( v ) \
- atomic32_dec_and_test ( v )
-
-/* ++ ( * v ) == 0
- when atomic_dec_and_test uses predecrement, you want
- postincrement to this function. so it isn't very useful */
-#define atomic_inc_and_test( v ) \
- atomic32_inc_and_test ( v )
-
-/* ( * v ) -- == 0
- HERE's useful */
-#define atomic_test_and_inc( v ) \
- atomic32_test_and_inc ( v )
-
-/* prior = ( * v ), ( * v ) = ( prior == t ? s : prior ), prior */
-#define atomic_test_and_set( v, s, t ) \
- atomic32_test_and_set ( v, s, t )
-
-/* void *atomic_test_and_set_ptr ( void *volatile *v, void *s, void *t ) */
-#define atomic_test_and_set_ptr( v, s, t ) \
- atomic_cas_ptr ( ( volatile void* ) ( v ), ( t ), ( s ) )
-
-/* val = ( * v ), ( ( * v ) = ( val < t ) ? val + i : val ), val */
-#define atomic_read_and_add_lt( v, i, t ) \
- atomic32_read_and_add_lt ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val <= t ) ? val + i : val ), val */
-#define atomic_read_and_add_le( v, i, t ) \
- atomic32_read_and_add_le ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val == t ) ? val + i : val ), val */
-#define atomic_read_and_add_eq( v, i, t ) \
- atomic32_read_and_add_eq ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val != t ) ? val + i : val ), val */
-#define atomic_read_and_add_ne( v, i, t ) \
- atomic32_read_and_add_ne ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val >= t ) ? val + i : val ), val */
-#define atomic_read_and_add_ge( v, i, t ) \
- atomic32_read_and_add_ge ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val > t ) ? val + i : val ), val */
-#define atomic_read_and_add_gt( v, i, t ) \
- atomic32_read_and_add_gt ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( ( val & 1 ) == 1 ) ? val + i : val ), val */
-#define atomic_read_and_add_odd( v, i ) \
- atomic32_read_and_add_odd ( v, i )
-
-/* val = ( * v ), ( ( * v ) = ( ( val & 1 ) == 0 ) ? val + i : val ), val */
-#define atomic_read_and_add_even( v, i ) \
- atomic32_read_and_add_even ( v, i )
-
-/* DEPRECATED */
-
-/* val = ( * v ), ( * v ) = ( val < t ? val + i : val ), ( val < t ? 1 : 0 ) */
-#define atomic_add_if_lt( v, i, t ) \
- atomic32_add_if_lt ( v, i, t )
-
-/* val = ( * v ), ( * v ) = ( val <= t ? val + i : val ), ( val <= t ? 1 : 0 ) */
-#define atomic_add_if_le( v, i, t ) \
- atomic32_add_if_le ( v, i, t )
-
-/* val = ( * v ), ( * v ) = ( val == t ? val + i : val ), ( val == t ? 1 : 0 ) */
-#define atomic_add_if_eq( v, i, t ) \
- atomic32_add_if_eq ( v, i, t )
-
-/* val = ( * v ), ( * v ) = ( val >= t ? val + i : val ), ( val >= t ? 1 : 0 ) */
-#define atomic_add_if_ge( v, i, t ) \
- atomic32_add_if_ge ( v, i, t )
-
-/* val = ( * v ), ( * v ) = ( val > t ? val + i : val ), ( val > t ? 1 : 0 ) */
-#define atomic_add_if_gt( v, i, t ) \
- atomic32_add_if_gt ( v, i, t )
-
-#undef LOCK
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_atomic_ */
diff --git a/interfaces/os/sun/atomic32.h b/interfaces/os/sun/atomic32.h
deleted file mode 100644
index adf6d40..0000000
--- a/interfaces/os/sun/atomic32.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_atomic32_
-#define _h_atomic32_
-
-#include <sys/atomic.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __inline__
-#define __inline__ inline
-#endif
-
-/*
- * mimic common structure
- */
-typedef struct atomic32_t atomic32_t;
-struct atomic32_t
-{
- volatile uint32_t counter;
-};
-
-/* int atomic32_read ( const atomic32_t *v ); */
-#define atomic32_read( v ) \
- ( ( v ) -> counter )
-
-/* void atomic32_set ( atomic32_t *v, int i ); */
-#define atomic32_set( v, i ) \
- ( ( void ) ( ( ( v ) -> counter ) = ( i ) ) )
-
-/* add to v -> counter and return the prior value
- int atomic32_read_and_add ( atomic32_t *v, int i ) */
-#define atomic32_read_and_add( v, i ) \
- ( atomic_add_32_nv ( & ( v ) -> counter, ( int32_t ) ( i ) ) - ( i ) )
-
-/* if no read is needed, define the least expensive atomic add */
-#define atomic32_add( v, i ) \
- atomic_add_32 ( & ( v ) -> counter, ( int32_t ) ( i ) )
-
-/* add to v -> counter and return the result
- int atomic32_add_and_read ( atomic32_t *v, int i ) */
-#define atomic32_add_and_read( v, i ) \
- atomic_add_32_nv ( & ( v ) -> counter, ( int32_t ) ( i ) )
-
-/* void atomic32_inc ( atomic32_t *v ) */
-#define atomic32_inc( v ) \
- atomic_inc_32 ( & ( v ) -> counter )
-
-/* void atomic32_dec ( atomic32_t *v ) */
-#define atomic32_dec( v ) \
- atomic_dec_32 ( & ( v ) -> counter )
-
-/* decrement by one and test result for 0
- int atomic32_dec_and_test ( atomic32_t *v ) */
-#define atomic32_dec_and_test( v ) \
- ( atomic_dec_32_nv ( & ( v ) -> counter ) == 0 )
-
-/* when atomic32_dec_and_test uses predecrement, you want
- postincrement to this function. so it isn't very useful
- int atomic32_inc_and_test ( atomic32_t *v ) */
-#define atomic32_inc_and_test( v ) \
- ( atomic_inc_32_nv ( & ( v ) -> counter ) == 0 )
-
-/* HERE's useful */
-#define atomic32_test_and_inc( v ) \
- ( atomic_inc_32_nv ( & ( v ) -> counter ) == 1 )
-
-/* int atomic32_test_and_set ( atomic32_t *v, int s, int t ) */
-#define atomic32_test_and_set( v, s, t ) \
- atomic_cas_32 ( & ( v ) -> counter, ( t ), ( s ) )
-
-/* conditional modifications */
-static __inline__
-int atomic32_read_and_add_lt ( atomic32_t *v, int i, int t )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); rtn < t; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#define atomic32_add_if_lt( v, i, t ) \
- ( atomic32_read_and_add_lt ( v, i, t ) < ( t ) )
-
-static __inline__
-int atomic32_read_and_add_le ( atomic32_t *v, int i, int t )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); rtn <= t; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#define atomic32_add_if_le( v, i, t ) \
- ( atomic32_read_and_add_le ( v, i, t ) <= ( t ) )
-
-static __inline__
-int atomic32_read_and_add_eq ( atomic32_t *v, int i, int t )
-{
- return atomic32_test_and_set ( v, t + i, t );
-}
-
-#define atomic32_add_if_eq( v, i, t ) \
- ( atomic32_read_and_add_eq ( v, i, t ) == ( t ) )
-
-static __inline__
-int atomic32_read_and_add_ne ( atomic32_t *v, int i, int t )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); rtn != t; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#define atomic32_add_if_ne( v, i, t ) \
- ( atomic32_read_and_add_ne ( v, i, t ) != ( t ) )
-
-static __inline__
-int atomic32_read_and_add_ge ( atomic32_t *v, int i, int t )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); rtn >= t; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#define atomic32_add_if_ge( v, i, t ) \
- ( atomic32_read_and_add_ge ( v, i, t ) >= ( t ) )
-
-static __inline__
-int atomic32_read_and_add_gt ( atomic32_t *v, int i, int t )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); rtn > t; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#define atomic32_add_if_gt( v, i, t ) \
- ( atomic32_read_and_add_gt ( v, i, t ) > ( t ) )
-
-static __inline__
-int atomic32_read_and_add_odd ( atomic32_t *v, int i )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); ( rtn & 1 ) != 0; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-static __inline__
-int atomic32_read_and_add_even ( atomic32_t *v, int i )
-{
- int val, rtn;
- for ( rtn = atomic32_read ( v ); ( rtn & 1 ) == 0; rtn = val )
- {
- val = atomic32_test_and_set ( v, rtn + i, rtn );
- if ( val == rtn )
- break;
- }
- return rtn;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_atomic32_ */
diff --git a/interfaces/os/sun/bitstr.h b/interfaces/os/sun/bitstr.h
deleted file mode 100644
index 338e78b..0000000
--- a/interfaces/os/sun/bitstr.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_bitstr_
-#define _h_bitstr_
-
-#include "endian.h"
-
-/* use 64-bit accumulator, 32-bit word size */
-#define WRDSIZE 32
-#define WRDSHIFT 5
-#define WRD uint32_t
-#define ACC uint64_t
-
-/* swap only on little-endian platforms */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define BSWAP( x ) bswap_32 ( x )
-#else
-#define BSWAP( x ) ( x )
-#endif
-
-#include "./noarch/bitstr.h"
-
-#endif /* _h_bitstr_ */
diff --git a/interfaces/os/sun/byteswap.h b/interfaces/os/sun/byteswap.h
deleted file mode 100644
index d420058..0000000
--- a/interfaces/os/sun/byteswap.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_byteswap_
-#define _h_byteswap_
-
-#include <stdint.h>
-#include <sys/byteorder.h>
-
-/* N.B. Sun's BSWAP seems to be macro-based,
- meaning that (x) will be evaluated multiple times */
-
-#define bswap_16(x) BSWAP_16 (x)
-#define bswap_32(x) BSWAP_32 (x)
-#define bswap_64(x) BSWAP_64 (x)
-
-#endif /* _h_byteswap_ */
diff --git a/interfaces/os/sun/endian.h b/interfaces/os/sun/endian.h
deleted file mode 100644
index e6132c8..0000000
--- a/interfaces/os/sun/endian.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_endian_
-#define _h_endian_
-
-#include <sys/isa_defs.h>
-
-#define __LITTLE_ENDIAN 1234
-#define __BIG_ENDIAN 4321
-#define __PDP_ENDIAN 3412
-
-#if defined _BIG_ENDIAN
-#define __BYTE_ORDER __BIG_ENDIAN
-#elif defined _LITTLE_ENDIAN
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#else
-#error "did not determine byte order"
-#endif
-
-#endif /* _h_endian_ */
diff --git a/interfaces/os/sun/fmtdef.h b/interfaces/os/sun/fmtdef.h
deleted file mode 100644
index d51c88f..0000000
--- a/interfaces/os/sun/fmtdef.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_fmtdef_
-#define _h_fmtdef_
-
-/* int64_t is "long long int" in 32 bit */
-#define LD64 "lld"
-#define LU64 "llu"
-#define LX64 "llX"
-#define Lx64 "llx"
-
-/* size_t is traditionally "unsigned int"
- although it should have been "long unsigned int" */
-#define LUSZ "u"
-#define LXSZ "X"
-#define LxSZ "x"
-
-#endif /* _h_fmtdef_ */
diff --git a/interfaces/os/sun/noarch/bitstr.h b/interfaces/os/sun/noarch/bitstr.h
deleted file mode 100644
index 9bfcdba..0000000
--- a/interfaces/os/sun/noarch/bitstr.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_noarch_bitstr_
-#define _h_noarch_bitstr_
-
-#ifndef _h_bitstr_
-#error "don't include <noarch/bitstr.h> directly - use <bitstr.h>"
-#endif
-
-#ifndef _h_klib_defs_
-#include <klib/defs.h>
-#endif
-
-#include <byteswap.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __inline__
-#define __inline__ inline
-#endif
-
-/* bitcpy
- * copy a string of bits from source to dest
- *
- * both source and dest may have non-byte aligned pointers
- * the number of bits to copy need not be byte aligned
- *
- * depending upon architecture and OS conventions, the word
- * size may be adjusted to 1, 2, or 4 bytes, where the base
- * pointers are always word aligned.
- *
- * bits in memory are always treated as big-endian, meaning
- * that on multi-byte fetches and stores, we perform byte-swapping
- * if there are shifts or masks
- */
-static __inline__
-void bitcpy ( void *dbase, bitsz_t doff, const void *sbase, bitsz_t soff, bitsz_t sz )
-{
- /* noop if sz == 0 */
- if ( sz != 0 )
- {
- /* loop counter and destination word count */
- size_t i, dcountz;
-
- /* left & right masks and working register */
- WRD lmask, rmask, reg;
-
- /* produce word-aligned pointers */
-#if WRDSIZE == 8
- /* 1-4. all at once */
- WRD *dst = ( WRD* ) dbase + ( doff >> WRDSHIFT );
- const WRD *src = ( const WRD* ) sbase + ( soff >> WRDSHIFT );
-#else
- /* 1. capture word alignment adjustment */
- size_t dadjust = ( size_t ) dbase & ( WRDSIZE / 8 - 1 );
- size_t sadjust = ( size_t ) sbase & ( WRDSIZE / 8 - 1 );
-
- /* 2. create word-aligned pointers */
- WRD *dst = ( WRD* ) ( ( size_t ) dbase - dadjust );
- const WRD *src = ( const WRD* ) ( ( size_t ) sbase - sadjust );
-
- /* 3. incorporate alignment adjustment into offset bits */
- doff += dadjust << 3;
- soff += sadjust << 3;
-
- /* 4. readjust pointers based upon offset */
- dst += doff >> WRDSHIFT;
- src += soff >> WRDSHIFT;
-#endif
- /* 5. restate offsets */
- doff &= ( WRDSIZE - 1 );
- soff &= ( WRDSIZE - 1 );
-
- /* calculate number of words - 1 in dst */
- dcountz = ( doff + sz + ( WRDSIZE - 1 ) - WRDSIZE ) >> WRDSHIFT;
-
- /* calculate masks */
- lmask = rmask = ~ 0;
- lmask >>= doff;
- rmask >>= ( doff + sz ) & ( WRDSIZE - 1 );
- if ( ( WRD ) ( rmask + 1 ) == 0 )
- rmask = 0;
-
- /* prime register with masked dst [ 0 ] */
- reg = BSWAP ( dst [ 0 ] ) & ~ lmask;
-
- /* if source and destination are aligned */
- if ( doff == soff )
- {
- /* merge src [ 0 ] into reg through mask */
- reg |= BSWAP ( src [ 0 ] ) & lmask;
-
-#if WRDSIZE > 8
- /* straight copies don't need byteswap
- other than on first and last words
- put first word back into little-endian
- for remainder of loop */
- if ( dcountz > 0 )
- {
- reg = BSWAP ( reg );
-#endif
- /* aligned buffers have n:n word ratio */
- for ( i = 0; i < dcountz; )
- {
- dst [ i ] = reg;
- reg = src [ ++ i ];
- }
-
-#if WRDSIZE > 8
- /* revert to big-endian */
- reg = BSWAP ( reg );
- }
-#endif
- }
-
- /* shifting alignment */
- else
- {
- /* source count may differ from dest count */
- size_t scountz = ( soff + sz + ( WRDSIZE - 1 ) - WRDSIZE ) >> WRDSHIFT;
-
- /* use double-word accumulator */
- ACC acc = BSWAP ( src [ 0 ] );
-
- /* shift amount */
- int shift = ( int ) doff - ( int ) soff;
- if ( shift > 0 )
- {
- /* take only valid bits in shifted initial src */
- reg |= ( WRD ) ( acc >> shift ) & lmask;
-
- /* because "shift" > 0, we know "dcountz" >= "scountz" */
- for ( acc <<= WRDSIZE, i = 0; i < scountz; acc <<= WRDSIZE )
- {
- dst [ i ] = BSWAP ( reg );
- ++ i;
- acc |= BSWAP ( src [ i ] );
- reg = ( WRD ) ( acc >> shift );
- }
-
- /* if "dcountz" > "scountz" */
- if ( i < dcountz )
- {
- dst [ i ] = BSWAP ( reg );
- reg = ( WRD ) ( acc >> shift );
- }
- }
-
- else
- {
- /* need single word read-ahead and right-shift */
- shift += WRDSIZE;
-
- /* because "shift" was < 0, we know "dcountz" <= "scountz" */
- for ( acc <<= WRDSIZE, i = 0; i < dcountz; acc <<= WRDSIZE )
- {
- acc |= BSWAP ( src [ i + 1 ] );
- reg |= ( WRD ) ( acc >> shift ) & lmask;
- dst [ i ++ ] = BSWAP ( reg );
- lmask = ~ 0;
- reg = 0;
- }
-
- /* if "dcountz" < "scountz" */
- if ( i < scountz )
- acc |= BSWAP ( src [ scountz ] );
-
- reg |= ( WRD ) ( acc >> shift ) & lmask;
- }
- }
-
- /* mask off unused bytes from src */
- reg &= ~ rmask;
-
- /* bring in saved bits from dst */
- reg |= BSWAP ( dst [ dcountz ] ) & rmask;
-
- /* write out last word */
- dst [ dcountz ] = BSWAP ( reg );
- }
-}
-
-/* bitcmp
- * performs bitwise a - b, returning result as int
- * result value has no meaning, only sign
- * where < 0 means a < b, > 0 means a > b, and 0 means a == b
- *
- * since the comparison produces a tri-state indicator of
- * relative magnitude, the order of "a" and "b" is important.
- * furthermore, the difference operator must be evaluated
- * left to right, because the result indicates more than
- * equality.
- *
- * see bitcpy for general word alignment information
- */
-static __inline__
-int bitcmp ( const void *abase, bitsz_t aoff, const void *bbase, bitsz_t boff, bitsz_t sz )
-{
- int diff = 0;
-
- if ( sz != 0 )
- {
- /* loop counter and left word count */
- size_t i, lcountz;
-
- /* left & right masks and working registers */
- WRD lmask, rmask, lreg, rreg;
-
- /* produce word-aligned pointers */
-#if WRDSIZE == 8
- /* 1-4. all at once */
- const WRD *left = ( const WRD* ) abase + ( aoff >> WRDSHIFT );
- const WRD *right = ( const WRD* ) bbase + ( boff >> WRDSHIFT );
-#else
- /* 1. capture word alignment adjustment */
- size_t aadjust = ( size_t ) abase & ( WRDSIZE / 8 - 1 );
- size_t badjust = ( size_t ) bbase & ( WRDSIZE / 8 - 1 );
-
- /* 2. create word-aligned pointers */
- const WRD *left = ( const WRD* ) ( ( size_t ) abase - aadjust );
- const WRD *right = ( const WRD* ) ( ( size_t ) bbase - badjust );
-
- /* 3. incorporate alignment adjustment into offset bits */
- aoff += aadjust << 3;
- boff += badjust << 3;
-
- /* 4. readjust pointers based upon offset */
- left += aoff >> WRDSHIFT;
- right += boff >> WRDSHIFT;
-#endif
- /* 5. restate offsets */
- aoff &= ( WRDSIZE - 1 );
- boff &= ( WRDSIZE - 1 );
-
- /* calculate number of words - 1 in left
- since we know a-priori that "sz" > 0, we
- know that the left and right counts must be
- at least 1. our loops treat the last word
- specially, so calculate a loop counter that
- excludes the last word */
- lcountz = ( aoff + sz + ( WRDSIZE - 1 ) - WRDSIZE ) >> WRDSHIFT;
-
- /* calculate masks */
- lmask = rmask = ~ 0;
- lmask >>= aoff;
- rmask >>= ( aoff + sz ) & ( WRDSIZE - 1 );
- if ( ( WRD ) ( rmask + 1 ) == 0 )
- rmask = 0;
-
- /* significant bits from left [ 0 ] */
- lreg = BSWAP ( left [ 0 ] ) & lmask;
-
- /* if source and destination are aligned */
- if ( aoff == boff )
- {
- /* test against right bits through mask */
- rreg = BSWAP ( right [ 0 ] ) & lmask;
-
- /* produce a difference of all but the last
- aligned word, where initial word has been
- left-masked. the last word is tested below. */
- for ( i = 1; i <= lcountz; ++ i )
- {
- diff = ( int ) lreg - ( int ) rreg;
- if ( diff != 0 )
- return diff;
-
- /* byte-swapping occurs on little-endian architectures */
- lreg = BSWAP ( left [ i ] );
- rreg = BSWAP ( right [ i ] );
- }
-
- /* fall out to end for masked comparison of last word */
- }
-
- /* shifting alignment */
- else
- {
- /* right count may differ from left count
- since alignments differ, the span of "sz"
- bits may hit a different number of words in
- the left array than in the right. */
- size_t rcountz = ( boff + sz + ( WRDSIZE - 1 ) - WRDSIZE ) >> WRDSHIFT;
-
- /* use double-word accumulator
- note that the extra bits get ignored */
- ACC acc = BSWAP ( right [ 0 ] );
-
- /* shift amount: positive if "b" needs to be right shifted.
- NOTE - since the comparison must be successively performed
- from left to right ( see above ), shifting is ALWAYS toward
- right, making for special handling when "shift" < 0 ( see below ) */
- int shift = ( int ) aoff - ( int ) boff;
- if ( shift > 0 )
- {
- /* initial word from right operand, aligned with left */
- rreg = ( WRD ) ( acc >> shift ) & lmask;
-
- /* "shift" > 0 means "lcountz" >= "rcountz" */
- for ( acc <<= WRDSIZE, i = 1; i <= rcountz; acc <<= WRDSIZE, ++ i )
- {
- /* compare words at i-1 */
- diff = ( int ) lreg - ( int ) rreg;
- if ( diff != 0 )
- return diff;
-
- /* accumulate next word from right operand */
- acc |= BSWAP ( right [ i ] );
-
- /* bring in next word from left operand */
- lreg = BSWAP ( left [ i ] );
-
- /* produce aligned word from right operand */
- rreg = ( WRD ) ( acc >> shift );
- }
-
- /* if there is one more word in left */
- if ( lcountz > rcountz )
- {
- /* compare penultimate */
- diff = ( int ) lreg - ( int ) rreg;
- if ( diff != 0 )
- return diff;
-
- /* get last word in left */
- lreg = BSWAP ( left [ lcountz ] );
-
- /* last word from right is already in "acc" */
- rreg = ( WRD ) ( acc >> shift );
- }
-
- /* fall out to end for masked comparison of last word */
- }
-
- else
- {
- /* since all shifts must be toward right ( due to left to right
- comparison ), this alignment will require a pre-fetch from
- right operand into accumulator, and adjusting the negative
- shift amount to a positive right-shift. */
- shift += WRDSIZE;
-
- /* since "shift" was negative, we know "lcountz" <= "rcountz",
- so use "lcountz" as loop limit. pre-shift "acc" as loop init */
- for ( acc <<= WRDSIZE, i = 1; i <= lcountz; acc <<= WRDSIZE, ++ i )
- {
- /* accumulate next word from right operand */
- acc |= BSWAP ( right [ i ] );
-
- /* produce aligned word from right operand */
- rreg = ( WRD ) ( acc >> shift ) & lmask;
-
- /* now test against left */
- diff = ( int ) lreg - ( int ) rreg;
- if ( diff != 0 )
- return diff;
-
- /* bring in next word from left operand */
- lreg = BSWAP ( left [ i ] );
-
- /* no more left mask */
- lmask = ~ 0;
- }
-
- /* if there is one more word in right */
- if ( lcountz < rcountz )
- acc |= BSWAP ( right [ rcountz ] );
-
- /* produce "rreg" from "acc" */
- rreg = ( WRD ) ( acc >> shift ) & lmask;
-
- /* fall out to end for masked comparison of last word */
- }
- }
-
- /* mask off unused bytes from right */
- lreg &= ~ rmask;
- rreg &= ~ rmask;
-
- /* perform final comparison */
- diff = ( int ) lreg - ( int ) rreg;
- }
-
- return diff;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_noarch_bitstr_ */
diff --git a/interfaces/os/sun/os-native.h b/interfaces/os/sun/os-native.h
deleted file mode 100644
index bcb83e8..0000000
--- a/interfaces/os/sun/os-native.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_os_native_
-#define _h_os_native_
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <time.h>
-
-#ifndef _h_unix_native_
-#include "../unix/unix-native.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __inline__
-#define __inline__ inline
-#endif
-
-/*--------------------------------------------------------------------------
- * index
- * we should get rid of this entirely
- */
-#define index strchr
-
-
-#ifndef strndupa /* Solaris 11 adds some of these */
-/*--------------------------------------------------------------------------
- * strndup - implemented inline here
- */
-static __inline__
-char *strndup ( const char *str, size_t n )
-{
- char *dupstr;
-
- const char *end = ( const char* ) memchr ( str, 0, n );
- if ( end != NULL )
- n = end - str;
-
- dupstr = ( char* ) malloc ( n + 1 );
- if ( dupstr != NULL )
- {
- memcpy ( dupstr, str, n );
- dupstr [ n ] = 0;
- }
-
- return dupstr;
-}
-
-/*--------------------------------------------------------------------------
- * strchrnul - implemented inline here
- */
-static __inline__
-char *strchrnul ( const char *str, int c )
-{
- int i;
- for ( i = 0; str [ i ] != 0 && str [ i ] != c; ++i )
- ( void ) 0;
- return & ( ( char* ) str ) [ i ];
-}
-#endif
-
-/*--------------------------------------------------------------------------
- * memchr - implemented inline here
- */
-static __inline__
-void *memrchr ( const void *s, int c, size_t n )
-{
- size_t i;
- const char *cp = ( const char* ) s;
- for ( i = n; i > 0; )
- {
- if ( ( int ) cp [ -- i ] == c )
- return ( void* ) & cp [ i ];
- }
- return NULL;
-}
-
-#ifndef strndupa
-static __inline__
-char *strsep ( char **stringp, const char *delim )
-{
- char *s, *tok, c, delim_char;
- const char *p_delim;
-
- if ( ( s = *stringp ) == NULL )
- return NULL;
-
- for ( tok = s; ; )
- {
- c = *s++;
- p_delim = delim;
- do
- {
- if ( ( delim_char = *p_delim++ ) == c )
- {
- if ( c == 0 )
- s = NULL;
- else
- s[-1] = 0;
- *stringp = s;
- return ( tok );
- }
- } while ( delim_char != 0 );
- }
-}
-
-static __inline__
-const char *strcasestr (const char *s1, const char *s2)
-{
- unsigned char c2 = tolower((unsigned char) *s2);
- size_t l1 = strlen(s1), l2 = strlen(s2);
-
- if (l2 == 0) {
- return s1;
- }
-
- while (l1 >= l2) {
- if (tolower((unsigned char) *s1) == c2
- && (l2 == 1 || strncasecmp(s1 + 1, s2 + 1, l2 - 1) == 0)) {
- return s1;
- }
- ++s1;
- --l1;
- }
-
- return NULL;
-}
-#endif
-
-static __inline__
-time_t timegm ( struct tm *gmt )
-{
- /* XXX - extend past 2099. (2100 isn't a leap year.) */
- static const int days_so_far [ 12 ] =
- {
- 0, 31, 59, 90, 120, 151,
- 181, 212, 243, 273, 304, 334
- };
- int days = ( ( gmt -> tm_year - 70 ) * 365 +
- ( ( gmt -> tm_year - 68 ) >> 2 ) +
- days_so_far [ gmt -> tm_mon ] + gmt -> tm_mday
- );
- if ( gmt -> tm_year % 4 == 0 && gmt -> tm_mon < 2 )
- -- days;
-
- return ( ( days * 24 + gmt -> tm_hour ) * 60 + gmt -> tm_min ) * 60 + gmt -> tm_sec;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_os_native_ */
diff --git a/interfaces/os/sun/strtol.h b/interfaces/os/sun/strtol.h
deleted file mode 100644
index 79f462f..0000000
--- a/interfaces/os/sun/strtol.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_strtol_
-#define _h_strtol_
-
-#ifndef _h_os_native_
-#include <os-native.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*--------------------------------------------------------------------------
- * strtoi32
- * strtoi32
- * based upon actual usage
- */
-#define strtoi32( str, endp, base ) \
- strtol ( str, endp, base )
-
-#define strtou32( str, endp, base ) \
- strtoul ( str, endp, base )
-
-
-/*--------------------------------------------------------------------------
- * strtoi64
- * strtoi64
- * based upon actual usage
- */
-#define strtoi64( str, endp, base ) \
- strtoll ( str, endp, base )
-
-#define strtou64( str, endp, base ) \
- strtoull ( str, endp, base )
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_strtol_ */
diff --git a/interfaces/os/sun/va_copy.h b/interfaces/os/sun/va_copy.h
deleted file mode 100644
index 34fb64f..0000000
--- a/interfaces/os/sun/va_copy.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_va_copy_
-#define _h_va_copy_
-
-/* GCC may internally undef 'va_copy' upon include of stdarg.h
- force it to be included before defining va_copy */
-#include <stdarg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* kludge - GCC stdarg has this line:
- #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
- fix build for c99 */
-#if ! defined va_copy && defined __va_copy
-#define va_copy __va_copy
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_va_copy_ */
diff --git a/interfaces/os/win/atomic.h b/interfaces/os/win/atomic.h
deleted file mode 100644
index 993d642..0000000
--- a/interfaces/os/win/atomic.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_atomic_
-#define _h_atomic_
-
-#define DFLT_ATOMIC_BITS 32
-
-#ifndef _h_atomic32_
-#include "atomic32.h"
-#endif
-
-#if ! defined _h_atomic64_ && _ARCH_BITS == 64
-#include "atomic64.h"
-#endif
-
-typedef struct atomic_ptr_t atomic_ptr_t;
-struct atomic_ptr_t
-{
- void * volatile ptr;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if DFLT_ATOMIC_BITS == 32
-#define ATOMIC_NAME( suffix ) \
- atomic32_ ## suffix
-typedef LONG atomic_int;
-#else
-#define ATOMIC_NAME( suffix ) \
- atomic64_ ## suffix
-typedef LONGLONG atomic_int;
-#endif
-
-typedef struct ATOMIC_NAME ( t ) atomic_t;
-
-/* ( * v ) */
-#define atomic_read( v ) \
- ATOMIC_NAME ( read ) ( v )
-
-/* ( * v ) = i */
-#define atomic_set( v, i ) \
- ATOMIC_NAME ( set ) ( v, i )
-
-/* prior = ( * v ), ( * v ) += i, prior */
-#define atomic_read_and_add( v, i ) \
- ATOMIC_NAME ( read_and_add ) ( v, i )
-
-/* ( * v ) += i */
-#define atomic_add( v, i ) \
- ATOMIC_NAME ( add ) ( v, i )
-
-/* ( * v ) += i */
-#define atomic_add_and_read( v, i ) \
- ATOMIC_NAME ( add_and_read ) ( v, i )
-
-/* ( void ) ++ ( * v ) */
-#define atomic_inc( v ) \
- ATOMIC_NAME ( inc ) ( v )
-
-/* ( void ) -- ( * v ) */
-#define atomic_dec( v ) \
- ATOMIC_NAME ( dec ) ( v )
-
-/* -- ( * v ) == 0 */
-#define atomic_dec_and_test( v ) \
- ATOMIC_NAME ( dec_and_test ) ( v )
-
-/* ++ ( * v ) == 0
- when atomic_dec_and_test uses predecrement, you want
- postincrement to this function. so it isn't very useful */
-#define atomic_inc_and_test( v ) \
- ATOMIC_NAME ( inc_and_test ) ( v )
-
-/* ( * v ) -- == 0
- HERE's useful */
-#define atomic_test_and_inc( v ) \
- ATOMIC_NAME ( test_and_inc ) ( v )
-
-/* prior = ( * v ), ( * v ) = ( prior == t ? s : prior ), prior */
-#define atomic_test_and_set( v, s, t ) \
- ATOMIC_NAME ( test_and_set ) ( v, s, t )
-
-/* THIS FUNCTION IS universal in the case of Windows, it uses the sizeof(ptr) */
-#define atomic_test_and_set_ptr( v, s, t ) \
- InterlockedCompareExchangePointer( & ( v ) -> ptr, ( s ), ( t ) )
-
-/* val = ( * v ), ( ( * v ) = ( val < t ) ? val + i : val ), val */
-#define atomic_read_and_add_lt( v, i, t ) \
- ATOMIC_NAME ( read_and_add_lt ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val <= t ) ? val + i : val ), val */
-#define atomic_read_and_add_le( v, i, t ) \
- ATOMIC_NAME ( read_and_add_le ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val == t ) ? val + i : val ), val */
-#define atomic_read_and_add_eq( v, i, t ) \
- ATOMIC_NAME ( read_and_add_eq ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val != t ) ? val + i : val ), val */
-#define atomic_read_and_add_ne( v, i, t ) \
- ATOMIC_NAME ( read_and_add_ne ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val >= t ) ? val + i : val ), val */
-#define atomic_read_and_add_ge( v, i, t ) \
- ATOMIC_NAME ( read_and_add_ge ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( val > t ) ? val + i : val ), val */
-#define atomic_read_and_add_gt( v, i, t ) \
- ATOMIC_NAME ( read_and_add_gt ) ( v, i, t )
-
-/* val = ( * v ), ( ( * v ) = ( ( val & 1 ) == 1 ) ? val + i : val ), val */
-#define atomic_read_and_add_odd( v, i ) \
- ATOMIC_NAME ( read_and_add_odd ) ( v, i )
-
-/* val = ( * v ), ( ( * v ) = ( ( val & 1 ) == 0 ) ? val + i : val ), val */
-#define atomic_read_and_add_even( v, i ) \
- ATOMIC_NAME ( read_and_add_even ) ( v, i )
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_atomic_ */
diff --git a/interfaces/os/win/atomic32.h b/interfaces/os/win/atomic32.h
deleted file mode 100644
index ecb46a4..0000000
--- a/interfaces/os/win/atomic32.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_atomic32_
-#define _h_atomic32_
-
-#define WIN32_LEAN_AND_MEAN
-#include <WINDOWS.H>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct atomic32_t atomic32_t;
-struct atomic32_t
-{
- volatile LONG counter;
-};
-
-/* int atomic32_read ( const atomic32_t *v ); */
-#define atomic32_read( v ) \
- ( ( v ) -> counter )
-
-/* void atomic32_set ( atomic32_t *v, int i ); */
-#define atomic32_set( v, i ) \
- ( ( void ) ( ( ( v ) -> counter ) = ( i ) ) )
-
-/* add to v -> counter and return the prior value */
-/* int atomic32_read_and_add ( atomic32_t *v, int i ) */
-#define atomic32_read_and_add( v, i ) \
- InterlockedExchangeAdd ( & ( v ) -> counter, ( i ) )
-
-/* if no read is needed, define the least expensive atomic add */
-#define atomic32_add( v, i ) \
- atomic32_read_and_add ( v, i )
-
-/* add to v -> counter and return the result */
-static __inline int atomic32_add_and_read ( atomic32_t *v, int i )
-{
- return atomic32_read_and_add ( v, i ) + i;
-}
-
-/* void atomic32_inc ( atomic32_t *v ) */
-#define atomic32_inc( v ) \
- InterlockedIncrement ( & ( v ) -> counter )
-
-/* void atomic32_dec ( atomic32_t *v ) */
-#define atomic32_dec( v ) \
- InterlockedDecrement ( & ( v ) -> counter )
-
-/* decrement by one and test result for 0 */
-/* int atomic32_dec_and_test ( atomic32_t *v ) */
-#define atomic32_dec_and_test( v ) \
- ( InterlockedDecrement ( & ( v ) -> counter ) == 0 )
-
-/* when atomic32_dec_and_test uses predecrement, you want
- postincrement to this function. so it isn't very useful */
-/* int atomic32_inc_and_test ( atomic32_t *v ) */
-#define atomic32_inc_and_test( v ) \
- ( InterlockedIncrement ( & ( v ) -> counter ) == 0 )
-
-/* HERE's useful */
-#define atomic32_test_and_inc( v ) \
- ( atomic32_read_and_add ( v, 1 ) == 0 )
-
-/* int atomic32_test_and_set ( atomic32_t *v, int s, int t ) */
-#define atomic32_test_and_set( v, s, t ) \
- InterlockedCompareExchange ( & ( v ) -> counter, ( s ), ( t ) )
-
-/* conditional modifications */
-static __inline int atomic32_read_and_add_lt ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val < t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_le ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val <= t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_eq ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val == t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_ne ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val != t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_ge ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val >= t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_gt ( atomic32_t *v, int i, int t )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); val > t; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_odd ( atomic32_t *v, int i )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); ( val & 1 ) != 0; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline int atomic32_read_and_add_even ( atomic32_t *v, int i )
-{
- LONG val, val_intern;
- for ( val = atomic32_read ( v ); ( val & 1 ) == 0; val = val_intern )
- {
- val_intern = atomic32_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_atomic32_ */
diff --git a/interfaces/os/win/atomic64.h b/interfaces/os/win/atomic64.h
deleted file mode 100644
index de57561..0000000
--- a/interfaces/os/win/atomic64.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_atomic64_
-#define _h_atomic64_
-
-#define WIN32_LEAN_AND_MEAN
-#include <WINDOWS.H>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct atomic64_t atomic64_t;
-struct atomic64_t
-{
- volatile LONGLONG counter;
-};
-
-/* int atomic64_read ( const atomic64_t *v ); */
-#define atomic64_read( v ) \
- ( ( v ) -> counter )
-
-/* void atomic64_set ( atomic64_t *v, long int i ); */
-#define atomic64_set( v, i ) \
- ( ( void ) ( ( ( v ) -> counter ) = ( i ) ) )
-
-/* add to v -> counter and return the prior value */
-/* int atomic32_read_and_add ( atomic32_t *v, int i ) */
-#define atomic64_read_and_add( v, i ) \
- InterlockedExchangeAdd64 ( & ( v ) -> counter, ( i ) )
-
-/* if no read is needed, define the least expensive atomic add */
-#define atomic64_add( v, i ) \
- atomic64_read_and_add ( v, i )
-
-/* add to v -> counter and return the result */
-static __inline LONG64 atomic64_add_and_read ( atomic64_t *v, int i )
-{
- return atomic64_read_and_add ( v, i ) + i;
-}
-
-/* void atomic64_inc ( atomic64_t *v ) */
-#define atomic64_inc( v ) \
- InterlockedIncrement64 ( & ( v ) -> counter )
-
-/* void atomic64_dec ( atomic64_t *v ) */
-#define atomic64_dec( v ) \
- InterlockedDecrement64 ( & ( v ) -> counter )
-
-/* decrement by one and test result for 0 */
-/* int atomic64_dec_and_test ( atomic64_t *v ) */
-#define atomic64_dec_and_test( v ) \
- ( InterlockedDecrement64 ( & ( v ) -> counter ) == 0 )
-
-/* when atomic64_dec_and_test uses predecrement, you want
- postincrement to this function. so it isn't very useful */
-/* int atomic64_inc_and_test ( atomic64_t *v ) */
-#define atomic64_inc_and_test( v ) \
- ( InterlockedIncrement64 ( & ( v ) -> counter ) == 0 )
-
-/* HERE's useful */
-#define atomic64_test_and_inc( v ) \
- ( atomic64_read_and_add ( v, 1 ) == 0 )
-
-/* int atomic64_test_and_set ( atomic64_t *v, int s, int t ) */
-#define atomic64_test_and_set( v, s, t ) \
- InterlockedCompareExchange64 ( & ( v ) -> counter, ( s ), ( t ) )
-
-/* conditional modifications */
-static __inline LONG64 atomic64_read_and_add_lt ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); val < t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_le ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); val <= t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_eq ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read( v ); val == t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_ne ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); val != t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_ge ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); val >= t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_gt ( atomic64_t *v, int i, int t )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); val > t; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_odd ( atomic64_t *v, int i )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); ( val & 1 ) != 0; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-static __inline LONG64 atomic64_read_and_add_even ( atomic64_t *v, int i )
-{
- LONG64 val, val_intern;
- for ( val = atomic64_read ( v ); ( val & 1 ) == 0; val = val_intern )
- {
- val_intern = atomic64_test_and_set ( v, val + i, val );
- if ( val_intern == val )
- break;
- }
- return val;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_atomic64_ */
diff --git a/interfaces/os/win/byteswap.h b/interfaces/os/win/byteswap.h
deleted file mode 100644
index 4b92f51..0000000
--- a/interfaces/os/win/byteswap.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_win_byteswap_
-#define _h_win_byteswap_
-
-#ifndef _INC_STDLIB
-#include <stdlib.h>
-#endif
-
-/* make these look the same as on Linux
- use the lower-level Windows routines, as
- they are specific in their data types */
-#undef bswap_16
-#define bswap_16(x) _byteswap_ushort(x)
-#undef bswap_32
-#define bswap_32(x) _byteswap_ulong(x)
-#undef bswap_64
-#define bswap_64(x) _byteswap_uint64(x)
-
-#endif /* _h_win_byteswap_ */
diff --git a/interfaces/os/win/endian.h b/interfaces/os/win/endian.h
deleted file mode 100644
index 61d9c7d..0000000
--- a/interfaces/os/win/endian.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_win_endian_
-#define _h_win_endian_
-
-/* magic values pulled from RPCNDR.H */
-
-#define __LITTLE_ENDIAN (0X00000010L)
-#define __BIG_ENDIAN (0X00000000L)
-
-#if defined(__RPC_MAC__)
-#define __BYTE_ORDER __BIG_ENDIAN
-#else
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif
-
-
-#endif /* _h_win_endian_ */
diff --git a/interfaces/os/win/os-native.h b/interfaces/os/win/os-native.h
deleted file mode 100644
index 4093703..0000000
--- a/interfaces/os/win/os-native.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_os_native_
-#define _h_os_native_
-
-/* get this guy included so that off_t is 64 bit */
-#ifndef _STDINT_H
-#include "stdint.h"
-#endif
-
-#ifndef _h_klib_defs_
-#include <klib/defs.h>
-#endif
-
-#ifndef _h_klib_text_
-#include <klib/text.h>
-#endif
-
-/* specify at least NT 4.0 */
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
-#endif
-
-/* we should never include this directly */
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include <limits.h>
-
-#include <ctype.h>
-#include <direct.h>
-#include <math.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-/* to make code work that depends on POSIX-bits (octal!) under Windows */
-#define S_IWGRP 0020
-#define S_IWOTH 0002
-
-#define mode_t uint32_t
-
-/*--------------------------------------------------------------------------
- * timeout_t
- * a structure for communicating a timeout
- * which under Windows is a relative time
- */
-struct timeout_t
-{
- uint32_t mS;
- uint32_t prepared;
-};
-
-#ifndef putenv
-#define putenv( s ) _putenv ( s )
-#endif
-
-#define mkdir( d, m ) _mkdir( d )
-#define strcasecmp _stricmp
-#define strtoll _strtoi64
-#define strtok_r strtok_s
-
-#undef strdup
-#define strdup( str ) \
- string_dup_measure ( ( str ), NULL )
-
-#undef strndup
-#define strndup( str, n ) \
- string_dup ( ( str ), ( n ) )
-
-int __cdecl isalnum ( int ch );
-int __cdecl isalpha ( int ch );
-int __cdecl iscntrl ( int ch );
-int __cdecl isdigit ( int ch );
-int __cdecl isgraph ( int ch );
-int __cdecl islower ( int ch );
-int __cdecl isupper ( int ch );
-int __cdecl isprint ( int ch );
-int __cdecl ispunct ( int ch );
-int __cdecl isspace ( int ch );
-int __cdecl isxdigit ( int ch );
-int __cdecl tolower ( int ch );
-int __cdecl toupper ( int ch );
-
-#undef isascii
-int __cdecl isascii ( int ch );
-
-static __inline int isblank(int x)
-{
- return (((x) == ' ') || ((x) == '\t'));
-}
-
-KLIB_EXTERN int CC snprintf ( char * buffer, size_t bufsize, const char * format, ... );
-
-static __inline
-void *memrchr ( const void *s, int c, size_t n )
-{
- size_t i;
- const char *cp = (const char*)s;
- for ( i = n; i > 0; )
- {
- if ( ( int ) cp [ -- i ] == c )
- return (void *)(cp + i);
- }
- return NULL;
-}
-
-static __inline
-char *strchrnul ( const char *s, int c_in )
-{
- uint32_t i;
- for ( i=0; s[i] != 0; ++i )
- {
- if ( s[i] == c_in )
- break;
- }
- return ( char * )&s[ i ];
-}
-
-static __inline
-char *strsep ( char **stringp, const char *delim )
-{
- char *s, *tok, c, delim_char;
- const char *p_delim;
-
- if ( ( s = *stringp ) == NULL )
- return NULL;
-
- for ( tok = s; ; )
- {
- c = *s++;
- p_delim = delim;
- do {
- if ( ( delim_char = *p_delim++ ) == c )
- {
- if ( c == 0 )
- s = NULL;
- else
- s[-1] = 0;
- *stringp = s;
- return ( tok );
- }
- } while ( delim_char != 0 );
- }
- return NULL;
-}
-
-#define gmtime_r(t, tm) gmtime_s(tm, t)
-#define timegm _mkgmtime
-
-static __inline
-int strncasecmp( const char *s1, const char *s2, size_t n )
-{
- return _strnicmp( s1, s2, n );
-}
-
-static __inline
-const char *strcasestr (const char *s1, const char *s2)
-{
- unsigned char c2 = tolower((unsigned char) *s2);
- size_t l1 = strlen(s1), l2 = strlen(s2);
-
- if (l2 == 0) {
- return s1;
- }
-
- while (l1 >= l2) {
- if (tolower((unsigned char) *s1) == c2
- && (l2 == 1 || _strnicmp(s1 + 1, s2 + 1, l2 - 1) == 0)) {
- return s1;
- }
- ++s1;
- --l1;
- }
-
- return NULL;
-}
-
-static __inline
-long int lround ( double x )
-{
- double val = ( x < 0.0 ) ? ceil ( x - 0.5 ) : floor ( x + 0.5 );
- if ( val > ( double ) LONG_MAX )
- return LONG_MAX;
- if ( val < ( double ) LONG_MIN )
- return LONG_MIN;
- return ( long int ) val;
-}
-
-#define isalnum( ch ) isalnum ( ( unsigned char ) ( ch ) )
-#define isalpha( ch ) isalpha ( ( unsigned char ) ( ch ) )
-#define isascii( ch ) isascii ( ( unsigned char ) ( ch ) )
-#define iscntrl( ch ) iscntrl ( ( unsigned char ) ( ch ) )
-#define isdigit( ch ) isdigit ( ( unsigned char ) ( ch ) )
-#define isgraph( ch ) isgraph ( ( unsigned char ) ( ch ) )
-#define islower( ch ) islower ( ( unsigned char ) ( ch ) )
-#define isupper( ch ) isupper ( ( unsigned char ) ( ch ) )
-#define isprint( ch ) isprint ( ( unsigned char ) ( ch ) )
-#define ispunct( ch ) ispunct ( ( unsigned char ) ( ch ) )
-#define isspace( ch ) isspace ( ( unsigned char ) ( ch ) )
-#define isxdigit( ch ) isxdigit ( ( unsigned char ) ( ch ) )
-#define tolower( ch ) tolower ( ( unsigned char ) ( ch ) )
-#define toupper( ch ) toupper ( ( unsigned char ) ( ch ) )
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_os_native_ */
diff --git a/interfaces/os/win/oserror.h b/interfaces/os/win/oserror.h
deleted file mode 100644
index 32fe03c..0000000
--- a/interfaces/os/win/oserror.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_oserror_
-#define _h_oserror_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <winerror.h>
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_oserror_ */
diff --git a/interfaces/os/win/strtol.h b/interfaces/os/win/strtol.h
deleted file mode 100644
index 524991c..0000000
--- a/interfaces/os/win/strtol.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_strtol_
-#define _h_strtol_
-
-#ifndef _h_klib_defs_
-#include <klib/defs.h>
-#endif
-
-#include <ctype.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*--------------------------------------------------------------------------
- * strtoi32
- * strtoi32
- * based upon actual usage
- */
-#define strtoi32( str, endp, base ) \
- ( int32_t ) strtol ( str, endp, base )
-
-#define strtou32( str, endp, base ) \
- ( uint32_t ) strtoul ( str, endp, base )
-
-
-/*--------------------------------------------------------------------------
- * strtoi64
- * strtoi64
- * based upon actual usage
- */
-#define strtoi64( str, endp, base ) \
- _strtoi64 ( str, endp, base )
-
-#define strtou64( str, endp, base ) \
- _strtoui64 ( str, endp, base )
-
-#if 0
-/*this implementation does not report overflow... */
-static __inline
-__int64 strtoi64( const char* str, char** endp, uint32_t base )
-{
- int i = 0;
- __int64 ret_value = 0;
-
- if ( str != NULL && base != 1 && base <= 36 )
- {
- bool negate = false;
-
- for ( ; isspace( str [ i ] ); ++ i )
- ( void ) 0;
-
- switch ( str [ i ] )
- {
- case '-':
- negate = true;
- case '+':
- ++ i;
- break;
- }
-
- if ( base == 0 )
- {
- if ( str [ i ] != '0' )
- base = 10;
- else if ( tolower ( str [ i + 1 ] == 'x' ) )
- {
- base = 16;
- i += 2;
- }
- else
- {
- base = 8;
- i += 1;
- }
- }
-
- if ( base <= 10 )
- {
- for ( ; isdigit ( str [ i ] ); ++ i )
- {
- uint32_t digit = str [ i ] - '0';
- if ( digit >= base )
- break;
- ret_value *= base;
- ret_value += digit;
- }
- }
- else
- {
- for ( ; ; ++ i )
- {
- if ( isdigit ( str [ i ] ) )
- {
- ret_value *= base;
- ret_value += str [ i ] - '0';
- }
- else if ( ! isalpha ( str [ i ] ) )
- break;
- else
- {
- uint32_t digit = toupper ( str [ i ] ) - 'A' + 10;
- if ( digit >= base )
- break;
- ret_value *= base;
- ret_value += digit;
- }
- }
- }
-
- if ( negate )
- ret_value = - ret_value;
- }
-
- if ( endp != NULL )
- * endp = (char *)str + i;
-
- return ret_value;
-}
-
-static __inline
-unsigned __int64 strtou64( const char* str, char** endp, uint32_t base )
-{
- return strtoi64( str, endp, base );
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_strtol_ */
diff --git a/interfaces/os/win/sysalloc.h b/interfaces/os/win/sysalloc.h
deleted file mode 100644
index 16c530e..0000000
--- a/interfaces/os/win/sysalloc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_sysalloc_
-#define _h_sysalloc_
-
-#ifndef _h_klib_extern_
-#include <klib/extern.h>
-#endif
-
-#include <malloc.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* malloc, calloc, realloc
- */
-KLIB_EXTERN void * CC klib_malloc ( size_t bytes );
-KLIB_EXTERN void * CC klib_calloc ( size_t count, size_t size );
-KLIB_EXTERN void * CC klib_realloc ( void *obj, size_t bytes );
-
-/* free
- */
-KLIB_EXTERN void CC klib_free ( void *obj );
-
-#ifndef _c_sysalloc_
-
-#undef malloc
-#undef calloc
-#undef realloc
-#undef free
-
-#define malloc klib_malloc
-#define calloc klib_calloc
-#define realloc klib_realloc
-#define free klib_free
-
-#endif /* _c_sysalloc_ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_sysalloc_ */
diff --git a/libs/ascp/mac/ascp-path.c b/libs/ascp/mac/ascp-path.c
deleted file mode 100644
index 6b3747a..0000000
--- a/libs/ascp/mac/ascp-path.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include "ascp-priv.h" /* ascp_path */
-#include <klib/printf.h> /* string_printf */
-#include <assert.h>
-#include <limits.h> /* PATH_MAX */
-#include <stdlib.h> /* getenv */
-
-bool ascp_path(const char **cmd, const char **key) {
- static int idx = 0;
- static const char *k[] = {
- "/Applications/Aspera Connect.app/Contents/Resources/asperaweb_id_dsa.openssh",
- "/Applications/Aspera Connect.app/Contents/Resources/asperaweb_id_dsa.putty",
- };
- static const char c[] = "/Applications/Aspera Connect.app/Contents/"
- "Resources/ascp";
- assert(cmd != NULL && key != NULL);
- if (idx == 0 || idx == 1) {
- ++idx;
- *cmd = c;
- *key = k[idx];
- return true;
- }
- else if (idx == 2 || idx == 3) {
- rc_t rc = 0;
- static char k[PATH_MAX] = "";
- static char c[PATH_MAX] = "";
- {
- size_t num_writ = 0;
- const char* home = getenv("HOME");
- if (home == NULL) {
- home = "";
- }
- if (idx == 2) {
- rc = string_printf(k, sizeof k, &num_writ,
-"%s/Applications/Aspera Connect.app/Contents/Resources/asperaweb_id_dsa.openssh"
- , home);
- }
- else {
- rc = string_printf(k, sizeof k, &num_writ,
-"%s/Applications/Aspera Connect.app/Contents/Resources/asperaweb_id_dsa.putty"
- , home);
- }
- if (rc != 0 || num_writ >= PATH_MAX) {
- assert(0);
- k[0] = '\0';
- }
- else {
- rc = string_printf(c, sizeof c, &num_writ,
- "%s/Applications/Aspera Connect.app/Contents/Resources/ascp"
- , home);
- if (rc != 0 || num_writ >= PATH_MAX) {
- assert(0);
- c[0] = '\0';
- }
- }
- }
- if (rc != 0) {
- *cmd = *key = NULL;
- idx = 0;
- return false;
- }
- else {
- *cmd = c;
- *key = k;
- ++idx;
- return true;
- }
- return true;
- }
- else {
- idx = 0;
- *cmd = *key = NULL;
- return false;
- }
-}
diff --git a/libs/ascp/win/ascp-path.c b/libs/ascp/win/ascp-path.c
deleted file mode 100644
index 2aafb36..0000000
--- a/libs/ascp/win/ascp-path.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include "ascp-priv.h" /* ascp_path */
-#include <assert.h>
-
-static int size_of(const char **array) {
- int i = 0;
- while (*(array++) != NULL) {
- ++i;
- }
- return i;
-}
-
-bool ascp_path(const char **cmd, const char **key) {
- static int idx = 0;
-
- static const char *c[] = {
- "C:\\Program Files (x86)\\Aspera\\Aspera Connect\\bin\\ascp.exe",
- "C:\\Program Files (x86)\\Aspera\\Aspera Connect\\bin\\ascp.exe",
-
- "C:\\Program Files\\Aspera\\Aspera Connect\\bin\\ascp.exe",
- "C:\\Program Files\\Aspera\\Aspera Connect\\bin\\ascp.exe",
- };
-
- static const char *k[] = {
-"C:\\Program Files (x86)\\Aspera\\Aspera Connect\\etc\\asperaweb_id_dsa.openssh"
- ,
-"C:\\Program Files (x86)\\Aspera\\Aspera Connect\\etc\\asperaweb_id_dsa.putty",
-
- "C:\\Program Files\\Aspera\\Aspera Connect\\etc\\asperaweb_id_dsa.openssh"
- ,
- "C:\\Program Files\\Aspera\\Aspera Connect\\etc\\asperaweb_id_dsa.putty",
- };
-
- int size = 4;
-
- assert(cmd != NULL && key != NULL);
-// assert(size_of(c) == size_of(k));
-
- if (idx < size) {
- *cmd = c[idx];
- *key = k[idx];
- ++idx;
- return true;
- }
- else {
- *cmd = *key = NULL;
- idx = 0;
- return false;
- }
-}
diff --git a/libs/ascp/win/connect.c b/libs/ascp/win/connect.c
deleted file mode 100644
index 0f44429..0000000
--- a/libs/ascp/win/connect.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include "ascp-priv.h" /* STS_DBG */
-
-#include <kfs/directory.h> /* KDirectory */
-#include <kfs/impl.h> /* KSysDir */
-#include <kfs/kfs-priv.h> /* KDirectoryPosixStringToSystemString */
-
-#include <klib/log.h> /* LOGERR */
-#include <klib/out.h> /* OUTMSG */
-#include <klib/printf.h> /* string_printf */
-#include <klib/rc.h>
-#include <klib/status.h> /* STSMSG */
-
-#include <Windows.h>
-
-#include <assert.h>
-#include <stdio.h> /* stderr */
-
-#define RELEASE(type, obj) do { rc_t rc2 = type##Release(obj); \
- if (rc2 && !rc) { rc = rc2; } obj = NULL; } while (false)
-
-#define STS_FIN 3
-
-static void beat(uint64_t heartbeat, bool flush) {
- static int i = 0;
- static char c = '1';
- return;
- if (heartbeat == 0) {
- return;
- }
- if (flush) {
- fprintf(stderr, "\n");
-/* fflush(stderr); */
- return;
- }
- fprintf(stderr, "%c", c);
- if (++i >= 60) {
- fprintf(stderr,
- "\r \r");
- i = 0;
- ++c;
- switch (c) {
- case ':':
- c = 'A';
- break;
- case '[':
- c = 'a';
- break;
- case 127:
- c = '!';
- break;
- }
- }
-}
-
-static rc_t mkAscpCommand(char *buffer, size_t len,
- const char *path, const char *key,
- const char *src, const char *dest, const AscpOptions *opt)
-{
- KDirectory *dir = NULL;
- const char *maxRate = NULL;
- const char *host = NULL;
- const char *user = NULL;
- size_t num_writ = 0;
-
- size_t pos = 0;
-
- char system[MAX_PATH] = "";
-
- rc_t rc = KDirectoryNativeDir(&dir);
- if (rc != 0) {
- return rc;
- }
-
- rc = KDirectoryPosixStringToSystemString(
- dir, system, sizeof system, "%s", dest);
- if (rc == 0) {
- if (opt != NULL) {
- if (opt->host != NULL && opt->host[0] != '\0') {
- host = opt->host;
- }
- if (opt->target_rate != NULL && opt->target_rate[0] != '\0') {
- maxRate = opt->target_rate;
- }
- if (opt->user != NULL && opt->user[0] != '\0') {
- user = opt->user;
- }
- }
-
- rc = string_printf(buffer, len, &num_writ,
- "\"%s\" -i \"%s\" -pQTk1%s%s%s%s%s%s %s %s",
- path, key,
- maxRate == NULL ? "" : " -l", maxRate == NULL ? "" : maxRate,
- host == NULL ? "" : " --host ", host == NULL ? "" : host,
- user == NULL ? "" : " --user ", user == NULL ? "" : host,
- src, system);
- if (rc != 0) {
- LOGERR(klogInt, rc, "while creating ascp command line");
- }
- else {
- assert(num_writ < len);
- }
- }
-
- RELEASE(KDirectory, dir);
-
- return rc;
-}
-
-static int execute(const char *command, uint64_t heartbeat,
- bool cacheKey, bool *writeFailed, bool *canceled,
- const char *name, TQuitting *quitting)
-{
- DWORD exitCode = STILL_ACTIVE;
- HANDLE g_hChildStd_IN_Rd = NULL;
- HANDLE g_hChildStd_IN_Wr = NULL;
- HANDLE g_hChildStd_OUT_Rd = NULL;
- HANDLE g_hChildStd_OUT_Wr = NULL;
- SECURITY_ATTRIBUTES saAttr;
- BOOL bSuccess = FALSE;
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
-
- wchar_t wcommand[5000];
-
- assert(writeFailed && canceled);
- *writeFailed = false;
-
- STSMSG(STS_INFO, ("Starting %s ", command));
-
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- // Create a pipe for the child process's STDOUT.
- if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr,
- 0))
- {
- rc_t rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
- LOGERR(klogErr, rc, "Stdout CreatePipe");
- return 1;
- }
-
- // Ensure the read handle to the pipe for STDOUT is not inherited.
- if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT,
- 0))
- {
- rc_t rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
- LOGERR(klogErr, rc, "Stdout SetHandleInformation");
- return 1;
- }
-
- // Create a pipe for the child process's STDIN.
- if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr,
- 0))
- {
- puts("Stdin CreatePipe");
- return 1;
- }
-
- // Ensure the write handle to the pipe for STDIN is not inherited.
- if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT,
- 0))
- {
- puts("Stdin SetHandleInformation");
- return 1;
- }
-
- // Set up members of the PROCESS_INFORMATION structure.
- ZeroMemory(&pi, sizeof(pi));
-
- // Set up members of the STARTUPINFO structure.
- // This structure specifies the STDIN and STDOUT handles for redirection.
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- si.hStdError = g_hChildStd_OUT_Wr;
- si.hStdOutput = g_hChildStd_OUT_Wr;
- si.hStdInput = g_hChildStd_IN_Rd;
- si.dwFlags |= STARTF_USESTDHANDLES;
-
- mbstowcs(wcommand, command, strlen(command) + 1);
-
- bSuccess = CreateProcess(
- NULL,//_In_opt_ LPCTSTR lpApplicationName,
- wcommand,//_Inout_opt_ LPTSTR lpCommandLine, command line
- NULL,//_In_opt_ LPSECURITY_ATTRIBUTES process security attributes
- NULL,//_In_opt_ LPSECURITY_ATTRIBUTES primary thread security attributes
- TRUE,//_In_ BOOL handles are inherited
- 0, //_In_ DWORD creation flags
- NULL,//_In_opt_ LPVOID use parent's environment
- NULL,//_In_opt_ LPCTSTR use parent's current directory
- &si, //_In_ LPSTARTUPINFO STARTUPINFO pointer
- &pi //_Out_ LPPROCESS_INFORMATION receives PROCESS_INFORMATION
- );
- if (bSuccess) {
- bool progressing = false;
- EAscpState state = eStart;
- const char y[] = "y\r\n";
- const char n[] = "n\r\n";
- const char *answer = cacheKey ? y : n;
- bool first = true;
- CHAR chBuf[4096];
- DWORD dwRead = 0;
- DWORD dwWritten = 0;
- DWORD dwFileSize = 0;
- HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD dwMilliseconds = 1000;
- DWORD dwMillisecondsRemains = 1000;
- String line;
- StringInit(&line, NULL, 0, 0);
- if (heartbeat > 0) {
- dwMillisecondsRemains = (DWORD)heartbeat;
- }
- // Write to the pipe that is the standard input for a child process.
- // Data is written to the pipe's buffers, so it is not necessary to wait
- // until the child process is running before writing data.
- assert(sizeof y == sizeof n);
- bSuccess = WriteFile(g_hChildStd_IN_Wr, answer, sizeof y - 1,
- &dwWritten, NULL);
- if (!bSuccess) {
- puts("failed to write to child's Stdin");
- return 1;
- }
- if (!CloseHandle(g_hChildStd_IN_Wr)) {
- puts("StdInWr CloseHandle");
- return 1;
- }
- CloseHandle(pi.hThread);
-
- // Successfully created the process. Wait for it to finish.
- while (true) {
- char noprogress[] = "\r "
- " \r";
- if (exitCode != STILL_ACTIVE) {
-/* printf(">>GetExitCodeProcess = %d\n", exitCode); */
- }
- bSuccess = GetExitCodeProcess(pi.hProcess, &exitCode);
- if (exitCode != STILL_ACTIVE) {
-/* printf(">>GetExitCodeProcess = %d\n", exitCode); */
- }
- if (!bSuccess) {
- rc_t rc = RC(rcExe,
- rcProcess, rcExecuting, rcProcess, rcFailed);
- if (progressing) {
- WriteFile(hParentStdOut, noprogress, sizeof noprogress - 1,
- &dwWritten, NULL);
- }
- LOGERR(klogErr, rc,
- "Executed command, couldn't get exit code");
- return 1;
- }
- if (exitCode == STILL_ACTIVE) {
- if (first) {
- first = false;
- }
- else {
- if (STS_DBG > KStsLevelGet()) {
- beat(heartbeat, false);
- }
- }
- WaitForSingleObject(pi.hProcess, dwMilliseconds);
- dwFileSize = GetFileSize(g_hChildStd_OUT_Rd, NULL);
- if (dwFileSize > 0) {
- STSMSG(STS_FIN + 1,
- ("GetFileSize(ChildStdOut) = %d", dwFileSize));
- }
- while (dwFileSize > 0) {
- bSuccess = ReadFile(g_hChildStd_OUT_Rd,
- chBuf, sizeof chBuf, &dwRead, NULL);
- if (!bSuccess) {
- if (progressing) {
- WriteFile(hParentStdOut, noprogress,
- sizeof noprogress - 1, &dwWritten, NULL);
- }
- break;
- }
- ascpParse(chBuf, dwRead, name, &state, &line);
- if (state == eWriteFailed) {
- *writeFailed = true;
- }
- else if (state == eProgress) {
- if (heartbeat > 0) {
- if (dwMillisecondsRemains > dwMilliseconds) {
- dwMillisecondsRemains -= dwMilliseconds;
- }
- else {
- const char *p = chBuf;
- size_t l = dwRead;
- if (line.addr != NULL && line.len != 0) {
- p = line.addr;
- l = line.len;
- WriteFile(hParentStdOut, "\r", 1,
- &dwWritten, NULL);
- bSuccess = WriteFile(hParentStdOut, p,
- (DWORD)l, &dwWritten, NULL);
- dwMillisecondsRemains = (DWORD)heartbeat;
- progressing = true;
- }
- }
- }
- }
-/* OUTMSG(("%.*s", dwRead, chBuf)); */
- if (STS_DBG <= KStsLevelGet()) {
- if (KStsMsg("%.*s", dwRead, chBuf) != 0) {
- bSuccess = WriteFile(hParentStdOut, chBuf,
- dwRead, &dwWritten, NULL);
- }
- }
- dwFileSize = GetFileSize(g_hChildStd_OUT_Rd, NULL);
- if (dwFileSize > 0) {
- STSMSG(STS_FIN + 1,
- ("GetFileSize(ChildStdOut) = %d", dwFileSize));
- }
- }
- }
- else {
- if (STS_DBG > KStsLevelGet()) {
-// beat(heartbeat, true);
- }
- if (progressing) {
- WriteFile(hParentStdOut, noprogress,
- sizeof noprogress - 1, &dwWritten, NULL);
- }
- break;
- }
- if (quitting != NULL) {
- rc_t rc = quitting();
- if (rc != 0) {
- if (progressing) {
- WriteFile(hParentStdOut, noprogress,
- sizeof noprogress - 1, &dwWritten, NULL);
- }
- *canceled = true;
- break;
- }
- }
- }
- if (!*canceled) {
- WaitForSingleObject(pi.hProcess, INFINITE);
-
- // Get the exit code.
-/* printf(">GetExitCodeProcess = %d\n", exitCode); */
- bSuccess = GetExitCodeProcess(pi.hProcess, &exitCode);
- if (!bSuccess) {
- rc_t rc = RC(rcExe,
- rcProcess, rcExecuting, rcProcess, rcFailed);
- LOGERR(klogErr,
- rc, "Executed command but couldn't get exit code");
- return 1;
- }
- }
-/* printf("<GetExitCodeProcess = %d\n", exitCode); */
-
- CloseHandle(pi.hProcess);
-
- if (exitCode != 0 && STS_DBG > KStsLevelGet()) {
- if (KStsMsg("%.*s", dwRead, chBuf) != 0) {
- bSuccess = WriteFile(hParentStdOut, chBuf,
- dwRead, &dwWritten, NULL);
- }
- }
- if (dwFileSize > 0) {
- STSMSG(STS_FIN, ("GetFileSize(ChildStdOut) = %d", dwFileSize));
- }
- while (dwFileSize > 0) {
- bSuccess = ReadFile(g_hChildStd_OUT_Rd,
- chBuf, sizeof chBuf, &dwRead, NULL);
- if (!bSuccess || dwRead == 0) {
- break;
- }
- ascpParse(chBuf, dwRead, name, &state, &line);
- if (state == eWriteFailed) {
- *writeFailed = true;
- }
- dwFileSize = GetFileSize(g_hChildStd_OUT_Rd, NULL);
- if (dwFileSize > 0) {
- STSMSG(STS_FIN, ("GetFileSize(ChildStdOut) = %d", dwFileSize));
- }
- }
-
- return exitCode;
- }
- else {
- return GetLastError();
- }
-}
-
-rc_t run_ascp(const char *path, const char *key,
- const char *src, const char *dest, const AscpOptions *opt)
-{
- rc_t rc = 0;
- uint64_t heartbeat = 0;
- char buffer[MAX_PATH * 3] = "";
- bool writeFailed = false;
- TQuitting *quitting = NULL;
-
- if (opt != NULL) {
- heartbeat = opt->heartbeat;
- quitting = opt->quitting;
- }
-
- rc = mkAscpCommand(buffer, sizeof buffer, path, key, src, dest, opt);
- if (rc == 0) {
- bool cacheKey = false;
- if (opt != NULL && opt->cache_key) {
- cacheKey = true;
- }
- {
- int value = 0;
- bool canceled = false;
- const char *name = strrchr(dest, '/');
- if (name == NULL) {
- name = dest;
- }
- else {
- if (*(name + 1) != '\0') {
- ++name;
- }
- else {
- name = dest;
- }
- }
- value = execute(buffer, heartbeat, cacheKey,
- &writeFailed, &canceled, name, quitting);
- if (value != 0) {
- if (writeFailed) {
- rc = RC(rcExe, rcProcess, rcExecuting,
- rcMemory, rcExhausted);
- }
- else {
- rc = RC(rcExe, rcProcess, rcExecuting, rcProcess, rcFailed);
- }
- }
- if (value == 0 && rc == 0 && canceled && quitting != NULL) {
- rc = quitting();
- }
- }
- }
-
- return rc;
-}
-
-int silent_system(const char *command) {
- HANDLE g_hChildStd_OUT_Rd = NULL;
- HANDLE g_hChildStd_OUT_Wr = NULL;
- BOOL bSuccess = FALSE;
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- SECURITY_ATTRIBUTES saAttr;
-
- wchar_t wcommand[5000];
-
- // Set the bInheritHandle flag so pipe handles are inherited.
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- // Create a pipe for the child process's STDOUT.
- if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) {
- rc_t rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
- LOGERR(klogErr, rc, "Stdout CreatePipe");
- return 1;
- }
-
- // Ensure the read handle to the pipe for STDOUT is not inherited.
- if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
- rc_t rc = RC(rcExe, rcFileDesc, rcCreating, rcFileDesc, rcFailed);
- LOGERR(klogErr, rc, "Stdout SetHandleInformation");
- return 1;
- }
-
- ZeroMemory(&pi, sizeof(pi));
-
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- si.hStdError = g_hChildStd_OUT_Wr;
- si.hStdOutput = g_hChildStd_OUT_Wr;
- si.dwFlags |= STARTF_USESTDHANDLES;
-
- mbstowcs(wcommand, command, strlen(command) + 1);
-
- bSuccess = CreateProcess(
- NULL, //_In_opt_ LPCTSTR lpApplicationName,
- wcommand, //_Inout_opt_ LPTSTR lpCommandLine,
- NULL, //_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
- NULL, //_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
- TRUE, //_In_ BOOL bInheritHandles,
- 0, //_In_ DWORD dwCreationFlags,
- NULL, //_In_opt_ LPVOID lpEnvironment,
- NULL, //_In_opt_ LPCTSTR lpCurrentDirectory,
- &si, //_In_ LPSTARTUPINFO lpStartupInfo,
- &pi //_Out_ LPPROCESS_INFORMATION lpProcessInformation
- );
- if (bSuccess) {
- return 0;
- }
- else {
- return GetLastError();
- }
-}
diff --git a/libs/kapp/mac/ram.c b/libs/kapp/mac/ram.c
deleted file mode 100644
index 7c21f6f..0000000
--- a/libs/kapp/mac/ram.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include "../main-priv.h"
-#include <kapp/main.h>
-#include <klib/log.h>
-#include <klib/rc.h>
-
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/sysctl.h>
-
-/* KAppGetTotalRam
- * Mac specific function of getting amount of RAM
- */
-rc_t KAppGetTotalRam ( uint64_t * totalRam )
-{
- rc_t rc;
-
- size_t len = sizeof *totalRam;
- int ret;
-
- assert ( totalRam != 0 );
-
- ret = sysctlbyname("hw.memsize", totalRam, &len, NULL, 0 );
- if ( ret < 0 )
- {
- int status = errno;
- rc = RC ( rcApp, rcNoTarg, rcInitializing, rcMemory, rcFailed );
- PLOGERR ( klogFatal, ( klogFatal, rc,
- "failed to retrieve number of RAM pages. error code: $(status) - $(msg)"
- , "status=%d,msg=%!"
- , status, status
- ));
- return rc;
- }
-
- return 0;
-}
diff --git a/libs/kapp/sun/sysmain.c b/libs/kapp/sun/sysmain.c
deleted file mode 100644
index d0c53e3..0000000
--- a/libs/kapp/sun/sysmain.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include "../main-priv.h"
-#include <sysalloc.h>
-#include <kapp/main.h>
-#include <klib/log.h>
-#include <klib/report.h>
-#include <klib/rc.h>
-#include <atomic32.h>
-
-#undef __XOPEN_OR_POSIX
-#define __XOPEN_OR_POSIX 1
-
-#undef __EXTENSIONS__
-#define __EXTENSIONS__ 1
-
-#include <unistd.h>
-#include <signal.h>
-#include <sys/signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <assert.h>
-
-#if ! _DEBUGGING && ! defined CATCH_SIGSEGV
-#define CATCH_SIGSEGV 1
-#endif
-
-/*--------------------------------------------------------------------------
- * Main
- */
-
-static bool no_hup;
-static atomic32_t hangup;
-static atomic32_t quitting;
-
-/* Quitting
- * is the program supposed to exit
- */
-rc_t Quitting ( void )
-{
- if ( atomic32_read ( & quitting ) == 0 )
- return 0;
- LOGMSG ( klogInfo, "EXITING..." );
- return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcCanceled );
-}
-
-/* SignalQuit
- * tell the program to quit
- */
-rc_t SignalQuit ( void )
-{
- ReportSilence ();
-
- if ( kill ( 0, SIGTERM ) != 0 ) switch ( errno )
- {
- case EINVAL:
- return RC ( rcExe, rcProcess, rcSignaling, rcMessage, rcInvalid );
- case EPERM:
- return RC ( rcExe, rcProcess, rcSignaling, rcMessage, rcUnauthorized );
- default:
- return RC ( rcExe, rcProcess, rcSignaling, rcNoObj, rcUnknown );
- }
- return 0;
-}
-
-/* Hangup
- * has the program received a SIGHUP
- */
-rc_t Hangup ( void )
-{
- if ( atomic32_read ( & hangup ) == 0 )
- return 0;
- LOGMSG ( klogInfo, "HANGUP...\n" );
- return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcIncomplete );
-}
-
-/* SignalHup
- * send the program a SIGHUP
- */
-rc_t SignalHup ( void )
-{
- if ( kill ( 0, SIGHUP ) != 0 ) switch ( errno )
- {
- case EINVAL:
- return RC ( rcExe, rcProcess, rcSignaling, rcMessage, rcInvalid );
- case EPERM:
- return RC ( rcExe, rcProcess, rcSignaling, rcMessage, rcUnauthorized );
- default:
- return RC ( rcExe, rcProcess, rcSignaling, rcNoObj, rcUnknown );
- }
- return 0;
-}
-
-/* SignalNoHup
- * tell the program to stay alive even after SIGHUP
- */
-rc_t SignalNoHup ( void )
-{
- no_hup = true;
- return 0;
-}
-
-/* SigHupHandler
- */
-static
-void SigHupHandler ( int sig )
-{
- ( ( void ) sig );
- atomic32_inc ( & hangup );
- if ( ! no_hup )
- atomic32_inc ( & quitting );
- PLOGMSG ( klogInfo, ( klogInfo, "SIGNAL - $(sig)\n", "sig=HUP" ));
-}
-
-/* SigQuitHandler
- */
-static
-void SigQuitHandler ( int sig )
-{
- const char *msg;
-
- ReportSilence ();
-
- atomic32_inc ( & quitting );
- switch ( sig )
- {
- case SIGINT:
- msg = "^C";
- break;
- case SIGQUIT:
- msg = "QUIT";
- break;
- case SIGTERM:
- msg = "TERM";
- break;
- default:
- PLOGMSG ( klogWarn, ( klogWarn, "SIGNAL - $(sig)\n", "sig=%d", sig ));
- return;
- }
-
- PLOGMSG ( klogInfo, ( klogInfo, "SIGNAL - $(sig)", "sig=%s", msg ) );
-}
-
-/* SigSegvHandler
- */
-#if CATCH_SIGSEGV
-static
-void SigSegvHandler ( int sig )
-{
- ( ( void ) sig );
- PLOGMSG ( klogFatal, ( klogFatal, "SIGNAL - $(sig)\n", "sig=Segmentation fault" ));
- abort ();
- exit ( 1 );
-}
-#endif
-
-/* main
- * Unix specific main entrypoint
- */
-int main ( int argc, char *argv [] )
-{
- static struct
- {
- void ( * handler ) ( int );
- int sig;
- } sigs [] =
- {
- { SigHupHandler, SIGHUP },
- { SigQuitHandler, SIGINT },
- { SigQuitHandler, SIGQUIT },
-#if CATCH_SIGSEGV
- { SigSegvHandler, SIGSEGV },
-#endif
- { SigQuitHandler, SIGTERM }
- };
-
- rc_t rc;
- int i, status;
- struct sigaction sig_saves [ sizeof sigs / sizeof sigs [ 0 ] ];
-
- /* get application version */
- uint32_t vers = KAppVersion ();
-
- /* initialize logging to default values */
- KLogInit ();
-
- /* install signal handlers */
- for ( i = 0; i < sizeof sigs / sizeof sigs [ 0 ]; ++ i )
- {
- struct sigaction act;
- memset ( & act, 0, sizeof act );
- act . sa_handler = sigs [ i ] . handler;
- act . sa_flags = SA_RESETHAND;
-
- status = sigaction ( sigs [ i ] . sig, & act, & sig_saves [ i ] );
- if ( status < 0 )
- {
- PLOGMSG ( klogFatal, ( klogFatal,
- "failed to install handler for signal $(sig) - $(msg)"
- , "sig=%d,msg='%s'"
- , sigs [ i ] . sig
- , strerror ( errno )
- ));
- return 2;
- }
- }
-
- /* run this guy */
- rc = KMane ( argc, argv );
-
- /* remove handlers, for what it's worth */
- for ( i = 0; i < sizeof sigs / sizeof sigs [ 0 ]; ++ i )
- sigaction ( sigs [ i ] . sig, & sig_saves [ i ], NULL );
-
- return ( rc == 0 ) ? 0 : 3;
-}
diff --git a/libs/kapp/win/args-conv-os.c b/libs/kapp/win/args-conv-os.c
deleted file mode 100644
index 87596de..0000000
--- a/libs/kapp/win/args-conv-os.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#include <klib/rc.h>
-#include <kapp/args-conv.h>
-
-#include <os-native.h>
-
-#include "main-priv-win.h"
-
-rc_t ArgsConvFilepath(const Args * args, uint32_t arg_index, const char * arg, size_t arg_len, void ** result, WhackParamFnP * whack)
-{
- wchar_t arg_wide[MAX_PATH];
- char * res;
-
- string_cvt_wchar_copy(arg_wide, MAX_PATH, arg, arg_len);
-
- res = rewrite_arg_as_path(arg_wide, false);
- if (!res)
- return RC (rcRuntime, rcArgv, rcConstructing, rcMemory, rcExhausted);
-
- *result = res;
-
- return 0;
-}
diff --git a/libs/kapp/win/main-priv-win.h b/libs/kapp/win/main-priv-win.h
deleted file mode 100644
index b5484f9..0000000
--- a/libs/kapp/win/main-priv-win.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#ifndef _h_main_priv_win_
-#define _h_main_priv_win_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Windows function to convert arguments from wchar_t string to utf-8 string
- * Also checks and converts path from Windows to POSIX format
- *
- * "arg" windows command line argument
- *
- * "known_as_path" indicates whether we need a path conversion path.
- * If it set to false, then rewrite_arg will only convert argument to utf-8.
- *
- * "after_main" indicates whether rewrite happens before or inside calling KMane
- */
-char * CC rewrite_arg_as_path ( const wchar_t *arg, bool before_kmane );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_main_priv_ */
diff --git a/libs/kapp/win/ram.c b/libs/kapp/win/ram.c
deleted file mode 100644
index 27743c5..0000000
--- a/libs/kapp/win/ram.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#define UNICODE 1
-#define _UNICODE 1
-
-#include "../main-priv.h"
-#include <klib/log.h>
-#include <klib/rc.h>
-
-#include <WINDOWS.H>
-#include <assert.h>
-
-/* KAppGetTotalRam
- * Windows specific function of getting amount of RAM
- */
-rc_t KAppGetTotalRam ( uint64_t * totalRam )
-{
- rc_t rc;
- BOOL ret;
-
- assert ( totalRam != 0 );
-
- ret = GetPhysicallyInstalledSystemMemory ( totalRam );
- if ( ! ret )
- {
- DWORD error = GetLastError();
- rc = RC ( rcApp, rcNoTarg, rcInitializing, rcMemory, rcFailed );
- PLOGERR ( klogFatal, ( klogFatal, rc,
- "failed to retrieve size of RAM. error code: $(ERR_CODE) - $(ERR_MESSAGE)"
- , "ERR_CODE=%u,ERR_MESSAGE=%!"
- , (uint32_t)error, (uint32_t)error ));
- return rc;
- }
-
- *totalRam *= 1024;
-
- return 0;
-}
diff --git a/libs/kapp/win/sysmain.c b/libs/kapp/win/sysmain.c
deleted file mode 100644
index 90a56ec..0000000
--- a/libs/kapp/win/sysmain.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#define UNICODE 1
-#define _UNICODE 1
-
-#include "../main-priv.h"
-#include <sysalloc.h>
-#include <kapp/main.h>
-#include <klib/log.h>
-#include <klib/status.h>
-#include <klib/debug.h>
-#include <klib/rc.h>
-#include <klib/text.h>
-#include <klib/report.h>
-#include <atomic32.h>
-
-/* #define _WIN32_WINNT 0x0500 */
-/* commented out: 10/21/2010 by wolfgang
- reason: Kurt introduced in sysdll.c a new functionality
- which requires a newer windows-version
- (i realized it as compiler parameter in build/Makefile.vc++) */
-
-#include <WINDOWS.H>
-#include <OBJBASE.H>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <ctype.h>
-#include <os-native.h>
-
-/*--------------------------------------------------------------------------
- * Main
- */
-
-static bool no_hup;
-static atomic32_t hangup;
-static atomic32_t quitting;
-
-static bool convert_args_paths = true;
-
-/* Quitting
- * is the program supposed to exit
- */
-rc_t CC Quitting ( void )
-{
- if ( atomic32_read ( & quitting ) == 0 )
- return 0;
- LOGMSG ( klogInfo, "EXITING..." );
- return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcCanceled );
-}
-
-/* SignalQuit
- * tell the program to quit
- */
-rc_t CC SignalQuit ( void )
-{
- return RC ( rcExe, rcProcess, rcSignaling, rcNoObj, rcUnknown );
-}
-
-/* Hangup
- * has the program received a SIGHUP
- */
-rc_t CC Hangup ( void )
-{
- if ( atomic32_read ( & hangup ) == 0 )
- return 0;
- LOGMSG ( klogInfo, "HANGUP...\n" );
- return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcIncomplete );
-}
-
-/* SignalHup
- * send the program a SIGHUP
- */
-rc_t CC SignalHup ( void )
-{
- return RC ( rcExe, rcProcess, rcSignaling, rcNoObj, rcUnknown );
-}
-
-/* SignalNoHup
- * tell the program to stay alive even after SIGHUP
- */
-rc_t CC SignalNoHup ( void )
-{
- no_hup = true;
- return 0;
-}
-
-
-BOOL CC Our_HandlerRoutine( DWORD dwCtrlType )
-{
- BOOL res = FALSE;
- switch( dwCtrlType )
- {
- case CTRL_C_EVENT : ReportSilence ();
- atomic32_inc ( & quitting );
- res = TRUE;
- break;
- }
- return res;
-}
-
-
-/* main
- * Windows specific main entrypoint
- */
-static
-int main2 ( int argc, char *argv [] )
-{
- rc_t rc;
-
- SetConsoleCtrlHandler( ( PHANDLER_ROUTINE ) Our_HandlerRoutine, TRUE );
-
- /* run this guy */
- rc = KMane ( argc, argv );
-
- return ( rc == 0 ) ? 0 : 3;
-}
-
-static
-char * convert_arg_utf8( const wchar_t *arg )
-{
- size_t src_size, dst_size;
- char * utf8;
- /* measure the string */
- wchar_cvt_string_measure ( arg, & src_size, & dst_size );
-
- /* allocate a UTF-8 buffer */
- utf8 = malloc ( dst_size + 1 );
- if ( utf8 != NULL )
- {
- /* copy the wide argument to utf8 */
- wchar_cvt_string_copy ( utf8, dst_size + 1,
- arg, src_size );
-
- /* terminate the string */
- utf8 [ dst_size ] = 0;
- }
-
- return utf8;
-}
-
-char * CC rewrite_arg_as_path ( const wchar_t *arg, bool before_kmane )
-{
- char *utf8;
- bool has_drive = false;
- size_t i, src_size, dst_size;
- DWORD len;
-
- /* detect drive or full path */
- wchar_t rewrit [ MAX_PATH ];
- /*
- we don't want to rewrite twice,
- so if we rewrote first time
- from wmain (before_kmane = true, convert_args_paths = true),
- then we skip second rewrite by checking convert_args_paths to be true
- */
- if ( arg [ 0 ] < 128 && (before_kmane || !convert_args_paths))
- {
- bool rewrite = false;
-
- /* look for non-drive path */
- if ( arg [ 0 ] == '\\' || arg [ 0 ] == '/' )
- {
- /* full path - not network */
- if ( arg [ 1 ] != '\\' && arg [ 1 ] != '/' )
- {
- /* check for cygdrive */
- if ( memcmp( arg, L"/cygdrive/", sizeof L"/cygdrive/" - sizeof L"" ) == 0 )
- arg += sizeof "/cygdrive" - 1;
- else
- rewrite = true;
-
- }
-
- }
- /* look for drive path */
- else if ( isalpha ( arg [ 0 ] ) && arg [ 1 ] == ':' )
- {
- has_drive = true;
-
- /* look for drive relative */
- if ( arg [ 2 ] != '\\' && arg [ 2 ] != '/' )
- rewrite = true;
- }
- if ( rewrite )
- {
- /* incomplete path */
- len = GetFullPathNameW ( arg, sizeof rewrit / sizeof rewrit [ 0 ], rewrit, NULL );
- if ( len == 0 || len >= MAX_PATH )
- {
- /* complain */
- return NULL;
- }
- arg = rewrit;
-
- has_drive = ( isalpha ( arg [ 0 ] ) && arg [ 1 ] == ':' );
- }
- }
-
- /* allocate a UTF-8 buffer */
- utf8 = convert_arg_utf8 ( arg );
- if ( utf8 != NULL )
- {
- dst_size = string_size(utf8);
- if (has_drive)
- {
- utf8 [ 1 ] = utf8 [ 0 ];
- utf8 [ 0 ] = '/';
- }
-
- /* map all backslashes to fwdslashes */
- for ( i = 0; i < dst_size; ++ i )
- {
- if ( utf8 [ i ] == '\\' )
- utf8 [ i ] = '/';
- }
- }
-
- return utf8;
-}
-
-int __cdecl wmain ( int argc, wchar_t *wargv [], wchar_t *envp [] )
-{
- char **argv;
- int i, status;
-
- /* must initialize COM... must initialize COM... */
- /* CoInitializeEx ( NULL, COINIT_MULTITHREADED ); */
- CoInitialize(NULL);
-
- /* create a copy of args */
- argv = calloc ( argc + 1, sizeof * argv );
- if ( argv == NULL )
- status = 5;
- else
- {
- /* convert wchar_t arguments to UTF-8
- rewriting anything that looks like a path */
- for ( i = 0; i < argc; ++ i )
- {
- if ( convert_args_paths )
- {
- argv [ i ] = rewrite_arg_as_path ( wargv [ i ], true );
- }
- else
- {
- argv [ i ] = convert_arg_utf8 ( wargv [ i ] );
- }
-
- if ( argv [ i ] == NULL )
- break;
- }
-
- /* perform normal main operations on UTF-8 with POSIX-style paths */
- if ( i == argc )
- status = main2 ( argc, argv );
-
- /* tear down argv */
- while ( -- i >= 0 )
- free ( argv [ i ] );
- free ( argv );
- }
-
- /* balance the COM initialization */
- CoUninitialize ();
-
- return status;
-}
-
-void __declspec( dllexport ) __stdcall wmainCRTStartupNoPathConversion()
-{
- convert_args_paths = false;
- wmainCRTStartup();
-}
diff --git a/libs/kfc/win/sysctx.c b/libs/kfc/win/sysctx.c
deleted file mode 100644
index 4c3a299..0000000
--- a/libs/kfc/win/sysctx.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfc/ctx.h>
-#include <kfc/rsrc.h>
-#include <kfc/rsrc-global.h>
-#include <kfc/except.h>
-#include <kfc/rc.h>
-#include <kfc/xc.h>
-#include <kproc/procmgr.h>
-#include <kproc/task.h>
-#include <kproc/impl.h>
-#include <klib/container.h>
-
-#include <sysalloc.h>
-
-#include <atomic32.h>
-
-#include "rsrc-priv.h"
-#include "sysctx-priv.h"
-
-#include <WINDOWS.H>
-#include <string.h>
-#include <assert.h>
-
-/* thread-local storage */
-typedef struct TLS TLS;
-struct TLS
-{
- DLNode n;
- KRsrc rsrc;
- KCtx ctx;
- DWORD threadId;
-};
-
-static DWORD key;
-static DLList s_tls;
-static uint32_t s_tls_count;
-static CRITICAL_SECTION crit;
-static atomic32_t key_once, crit_once;
-
-
-/* whack
- * whack thread-local storage
- */
-static
-void CC whack_tls ( DLNode * n, void * ignore )
-{
- TLS * tls = ( TLS * ) n;
-
- /* the "parent" ctx */
- ctx_t ctx = & tls -> ctx;
- FUNC_ENTRY ( ctx, rcRuntime, rcThread, rcDestroying );
-
- /* whack the resource managers */
- KRsrcWhack ( & tls -> rsrc, ctx );
-
- /* free the memory */
- free ( tls );
-
- /* reduce the count */
- -- s_tls_count;
-}
-
-static
-void win_thread_once ( atomic32_t * once, void ( * trigger ) ( void ) )
-{
- switch ( atomic32_test_and_set ( once, 1, 0 ) )
- {
- case 0:
- ( * trigger ) ();
- atomic32_set ( once, 2 );
- break;
- case 1:
- while ( atomic32_read ( once ) == 1 )
- Sleep ( 1 );
- break;
- case 2:
- break;
- }
-}
-
-static
-void init_crit ( void )
-{
- InitializeCriticalSection ( & crit );
-}
-
-static
-void enter_critical_section ( void )
-{
- /* Windows didn't come up with the concept of
- multi-thread-safe critical sections until Vista */
- win_thread_once ( & crit_once, init_crit );
-
- EnterCriticalSection ( & crit );
-}
-
-static
-void leave_critical_section ( void )
-{
- LeaveCriticalSection ( & crit );
-}
-
-static
-TLS * win_thread_getspecific ( DWORD tlsKey )
-{
- return TlsGetValue ( tlsKey );
-}
-
-static
-bool CC eliminate_dups ( DLNode * n, void * data )
-{
- const TLS * tls = ( const void * ) data;
- if ( ( ( const TLS * ) n ) -> threadId != tls -> threadId )
- return false;
-
- DLListUnlink ( & s_tls, n );
- whack_tls ( n, NULL );
- return true;
-}
-
-static
-void CC garbage_collect_tls ( DLNode * n, void * ignore )
-{
- TLS * tls = ( TLS* ) n;
- HANDLE t = OpenThread ( THREAD_QUERY_INFORMATION, FALSE, tls -> threadId );
- if ( t != NULL )
- CloseHandle ( t );
- else
- {
- DLListUnlink ( & s_tls, & tls -> n );
- whack_tls ( & tls -> n, NULL );
- }
-}
-
-static
-void win_thread_setspecific ( DWORD tlsKey, TLS * tls )
-{
- /* record the thread id */
- tls -> threadId = GetCurrentThreadId ();
-
- /* need to record these for cleanup function */
- enter_critical_section ();
-
- /* quickly scan for reused thread id */
- DLListDoUntil ( & s_tls, false, eliminate_dups, tls );
-
- /* push the entry */
- DLListPushTail ( & s_tls, & tls -> n );
-
- /* try to garbage collect for threads
- that have already exited */
- if ( ++ s_tls_count >= 64 )
- DLListForEach ( & s_tls, false, garbage_collect_tls, NULL );
-
- /* done with the list */
- leave_critical_section ();
-
- /* store it on the thread */
- TlsSetValue ( tlsKey, tls );
-}
-
-
-/* make_tls
- * create thread-local storage
- */
-static
-TLS * make_tls ( const KFuncLoc * func_loc )
-{
- ctx_t ctx;
-
- /* create the storage */
- TLS * tls = calloc ( 1, sizeof * tls );
- if ( tls == NULL )
- exit ( -1 );
-
- /* grab its context */
- ctx = & tls -> ctx;
-
- /* recover process-global resources */
- TRY ( KRsrcGlobalInit ( & tls -> ctx, func_loc, true ) )
- {
- /* attach references */
- TRY ( KRsrcInit ( & tls -> rsrc, ctx ) )
- {
- /* reset context */
- tls -> ctx . rsrc = & tls -> rsrc;
-
- /* set on thread */
- win_thread_setspecific ( key, tls );
- assert ( ! FAILED () );
- }
- }
-
- if ( FAILED () )
- {
- free ( tls );
- exit ( -1 );
- }
-
- return tls;
-}
-
-static
-rc_t CC TLSCleanupTaskWhack ( KTask * self )
-{
- KTaskDestroy ( self, "TLSCleanupTask" );
- free ( self );
- return 0;
-}
-
-static
-rc_t CC TLSCleanupTaskExecute ( KTask * self )
-{
- DLListWhack ( & s_tls, whack_tls, NULL );
- return 0;
-}
-
-static KTask_vt_v1 TLSCleanupTask_vt =
-{
- 1, 0,
- TLSCleanupTaskWhack,
- TLSCleanupTaskExecute
-};
-
-static
-void install_cleanup_task ( void )
-{
- rc_t rc = KProcMgrInit ();
- if ( rc == 0 )
- {
- KProcMgr * mgr;
- rc = KProcMgrMakeSingleton ( & mgr );
- if ( rc == 0 )
- {
- /* create task to install into procmgr */
- KTask * task = malloc ( sizeof * task );
- if ( task != NULL )
- {
- rc = KTaskInit ( task,
- ( const KTask_vt * ) & TLSCleanupTask_vt,
- "TLSCleanupTask", "" );
- if ( rc != 0 )
- free ( task );
- else
- {
- KTaskTicket ticket;
- rc = KProcMgrAddCleanupTask ( mgr, & ticket, task );
- if ( rc != 0 )
- KTaskRelease ( task );
- }
- }
-
- KProcMgrRelease ( mgr );
- }
- }
-}
-
-/* make_key
- * initialize the thread-local storage key
- */
-static
-void make_key ( void )
-{
- /* install cleanup task -
- Windows doesn't appear to support
- libraries that create TLS but
- don't own the thread main */
- install_cleanup_task ();
-
- /* create key into thread-local storage */
- key = TlsAlloc ();
-}
-
-
-/* get_tls_ctx
- * reads thread-local storage
- */
-static
-const KCtx * get_tls_ctx ( const KFuncLoc * func_loc )
-{
- TLS * tls;
-
- /* ensure the key is there */
- win_thread_once ( & key_once, make_key );
-
- /* retrieve the existing tls */
- tls = win_thread_getspecific ( key );
-
- /* create a new one if missing */
- if ( tls == NULL )
- {
- tls = make_tls ( func_loc );
- assert ( tls != NULL );
- }
-
- return & tls -> ctx;
-}
-
-
-/* ctx_recover
- * queries thread for previously stored KRsrc block
- * creates a new one if necessary
- */
-ctx_t ctx_recover ( KCtx * new_ctx, const KFuncLoc * func_loc )
-{
- DECLARE_FUNC_LOC ( rcRuntime, rcMgr, rcOpening );
-
- if ( new_ctx != NULL )
- {
- const KCtx * ctx = get_tls_ctx ( & s_func_loc );
-
- /* clear new_ctx and initialize special members */
- RESET_CTX(new_ctx, ctx, func_loc);
- }
-
- return new_ctx;
-}
diff --git a/libs/kfc/win/sysrsrc.c b/libs/kfc/win/sysrsrc.c
deleted file mode 100644
index 01a287d..0000000
--- a/libs/kfc/win/sysrsrc.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfc/extern.h>
-#include <kfc/rsrc.h>
-#include <kfc/rsrc-global.h>
-#include <kfc/ctx.h>
-#include <kfc/except.h>
-#include <kfc/rc.h>
-#include <kfc/xc.h>
-#include <kproc/procmgr.h>
-#include <atomic32.h>
-
-#include "rsrc-priv.h"
-
-#include <WINDOWS.H>
-#include <string.h>
-#include <assert.h>
-
-
-static KRsrc s_rsrc;
-static CRITICAL_SECTION crit;
-static atomic32_t s_initialized, crit_once;
-
-static
-void win_thread_once ( atomic32_t * once, void ( * trigger ) ( void ) )
-{
- switch ( atomic32_test_and_set ( once, 1, 0 ) )
- {
- case 0:
- ( * trigger ) ();
- atomic32_set ( once, 2 );
- break;
- case 1:
- while ( atomic32_read ( once ) == 1 )
- Sleep ( 1 );
- break;
- case 2:
- break;
- }
-}
-
-static
-void init_crit ( void )
-{
- InitializeCriticalSection ( & crit );
-}
-
-static
-void enter_critical_section ( void )
-{
- /* Windows didn't come up with the concept of
- multi-thread-safe critical sections until Vista */
- win_thread_once ( & crit_once, init_crit );
-
- EnterCriticalSection ( & crit );
-}
-
-static
-void leave_critical_section ( void )
-{
- LeaveCriticalSection ( & crit );
-}
-
-static
-void atexit_task ( void )
-{
- if ( atomic32_read ( & s_initialized ) == 2 )
- {
- KCtx local_ctx;
- DECLARE_FUNC_LOC ( rcRuntime, rcMgr, rcDestroying );
- memset ( & local_ctx, 0, sizeof local_ctx );
- local_ctx . rsrc = & s_rsrc;
- local_ctx . loc = & s_func_loc;
-
- KRsrcGlobalWhack ( & local_ctx );
- }
-}
-
-/* Global
- * retrieve process-global singleton KRsrc block
- * creates and initializes block on initial request
- * caches pointer for subsequent requests
- */
-void KRsrcGlobalInit ( KCtx * ctx, const KFuncLoc * loc, bool full )
-{
- int initialized;
-
- assert ( ctx != NULL );
- assert ( loc != NULL );
-
- /* initialize caller's top-level ctx */
- memset ( ctx, 0, sizeof * ctx );
- ctx -> rsrc = & s_rsrc;
- ctx -> loc = loc;
-
- /* singleton initialization */
- initialized = atomic32_read ( & s_initialized );
- if ( 0 <= initialized && initialized < 2 )
- {
- /* acquire lock */
- enter_critical_section ();
-
- initialized = atomic32_read ( & s_initialized );
- if ( 0 <= initialized && initialized < 2 )
- {
- KCtx local_ctx;
- DECLARE_FUNC_LOC ( rcRuntime, rcMgr, rcConstructing );
-
- /* link a new local context */
- ctx_init ( & local_ctx, ( ctx_t* ) & ctx, & s_func_loc );
-
- /* common initializer- errors are
- propagated to and handled by caller */
- rsrc_init ( & s_rsrc, ctx, full );
-
- /* mark the level of initialization */
- atomic32_set ( & s_initialized, full ? 2 : 1 );
-
- if ( full )
- {
- /* register global cleanup */
- int status = atexit ( atexit_task );
- if ( status != 0 )
- SYSTEM_ERROR ( xcUnexpected, "atexit failed: %!", status );
- }
- }
-
- /* release lock */
- leave_critical_section ();
- }
-}
-
-
-/* Whack
- * the global KRsrc may be referenced by local KRsrc
- */
-void KRsrcGlobalWhack ( ctx_t ctx )
-{
- if ( atomic32_read ( & s_initialized ) > 0 )
- {
- /* acquire lock, but ignore status */
- enter_critical_section ();
- if ( atomic32_read ( & s_initialized ) > 0 )
- {
- /* early whack of KProcMgr */
- KProcMgrRelease ( s_rsrc . proc );
- s_rsrc . proc = NULL;
-
- /* run destructor tasks while we still have other mgrs */
- KProcMgrWhack ();
-
- /* tear it down */
- KRsrcWhack ( & s_rsrc, ctx );
-
- /* mark as torn down */
- atomic32_set ( & s_initialized, -1 );
- }
-
- /* release lock */
- leave_critical_section ();
- }
-}
diff --git a/libs/kfs/win/directory-path.c b/libs/kfs/win/directory-path.c
deleted file mode 100644
index fefb193..0000000
--- a/libs/kfs/win/directory-path.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-
-#include "sysdir-priv.h"
-
-#include <kfs/impl.h> /* KSysDir */
-#include <kfs/directory.h>
-#include <kfs/kfs-priv.h> /* KSysDirOSPath */
-
-#include <klib/rc.h>
-
-#include <wchar.h>
-
-/* PosixStringToSystemString
- * converts posix path string to system path
- * "buffer" [ OUT ] - NUL terminated system path string
- * "bsize" [ IN ] - buffer length
- * "path" [ IN ] - NUL terminated posix path string
- */
-LIB_EXPORT rc_t CC KDirectoryPosixStringToSystemString(const KDirectory *self,
- char *buffer,
- size_t bsize,
- const char *path,
- ...)
-{
- rc_t rc = 0;
-
- if (self == NULL) {
- return RC(rcFS, rcDirectory, rcAccessing, rcSelf, rcNull);
- }
-
- if (buffer == NULL) {
- return RC(rcFS, rcDirectory, rcAccessing, rcBuffer, rcNull);
- }
-
- if (bsize == 0) {
- return RC(rcFS, rcDirectory, rcAccessing, rcBuffer, rcInsufficient);
- }
-
- {
- struct KSysDir *sysDir = KDirectoryGetSysDir(self);
- wchar_t wd_path[MAX_PATH];
-
- va_list args;
- va_start(args, path);
- rc = KSysDirOSPath(sysDir, wd_path, MAX_PATH, path, args);
- va_end(args);
-
- if (rc == 0) {
- size_t ret = wcstombs(buffer, wd_path, bsize);
- if (ret >= MAX_PATH) {
- return RC(rcExe, rcPath, rcConverting, rcPath, rcExcessive);
- }
- }
- }
-
- return rc;
-}
diff --git a/libs/kfs/win/lnk_tools.c b/libs/kfs/win/lnk_tools.c
deleted file mode 100644
index 82a565f..0000000
--- a/libs/kfs/win/lnk_tools.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <sysalloc.h>
-
-#include <Shlobj.h>
-
-#define LNK_RES_ERROR 0
-#define LNK_RES_FILE 1
-#define LNK_RES_DIR 2
-
-#define LNK_FLAG_HasLinkTargetIDList 0x1
-#define LNK_FLAG_HasLinkInfo 0x2
-#define LNK_FLAG_HasName 0x4
-#define LNK_FLAG_HasRelativePath 0x8
-#define LNK_FLAG_HasWorkingDir 0x10
-#define LNK_FLAG_HasArguments 0x20
-#define LNK_FLAG_HasIconLocation 0x40
-#define LNK_FLAG_IsUniCode 0x80
-#define LNK_FLAG_ForceNoLinkInfo 0x100
-#define LNK_FLAG_HasExpString 0x200
-#define LNK_FLAG_RunInSeparateProcess 0x400
-#define LNK_FLAG_Unused1 0x800
-#define LNK_FLAG_HasDarwinID 0x1000
-#define LNK_FLAG_RunAsUser 0x2000
-#define LNK_FLAG_HasExpIcon 0x4000
-#define LNK_FLAG_NoPidIAlias 0x8000
-#define LNK_FLAG_Unused2 0x10000
-#define LNK_FLAG_RunWithShimLayer 0x20000
-#define LNK_FLAG_ForceNoLinkTrack 0x40000
-#define LNK_FLAG_EnableTargetMatdata 0x80000
-#define LNK_FLAG_DisableLinkPathTracking 0x100000
-#define LNK_FLAG_DisableKnowFolderTracking 0x200000
-#define LNK_FLAG_DisableKnowFolderAlias 0x400000
-#define LNK_FLAG_AllowLinkToLink 0x800000
-#define LNK_FLAG_UnaliasOnSave 0x1000000
-
-
-#define LNK_ATTR_FILE_ATTRIBUTE_READONLY 0x1
-#define LNK_ATTR_FILE_ATTRIBUTE_HIDDEN 0x2
-#define LNK_ATTR_FILE_ATTRIBUTE_SYSTEM 0x4
-#define LNK_ATTR_Reserved1 0x8
-#define LNK_ATTR_FILE_ATTRIBUTE_DIRECTORY 0x10
-#define LNK_ATTR_FILE_ATTRIBUTE_ARCHIVE 0x20
-#define LNK_ATTR_Reserved2 0x40
-#define LNK_ATTR_FILE_ATTRIBUTE_NORMAL 0x80
-#define LNK_ATTR_FILE_ATTRIBUTE_TEMPORARY 0x100
-#define LNK_ATTR_FILE_ATTRIBUTE_SPARSE_FILE 0x200
-#define LNK_ATTR_FILE_ATTRIBUTE_REPARSE_POINT 0x400
-#define LNK_ATTR_FILE_ATTRIBUTE_COMPRESSED 0x800
-#define LNK_ATTR_FILE_ATTRIBUTE_OFFLINE 0x1000
-#define LNK_ATTR_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
-#define LNK_ATTR_FILE_ATTRIBUTE_ENCRYPTED 0x4000
-
-/* the first 20 "magic" bytes of a MS-lnk-file
- ( 4 bytes header-size and 16 bytes LinkCLSID ) */
-const unsigned char lnk_ref[ 20 ] =
-{
- 0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46
-};
-
-
-static bool has_lnk_extension( const wchar_t *path )
-{
- size_t len = wcslen( path );
-
- if ( len < 5 ) return false;
- if ( path[ len - 4 ] != '.' ) return false;
- if ( path[ len - 3 ] != 'l' && path[ len - 3 ] != 'L' ) return false;
- if ( path[ len - 2 ] != 'n' && path[ len - 2 ] == 'N' ) return false;
- if ( path[ len - 1 ] != 'k' && path[ len - 1 ] == 'K' ) return false;
- return true;
-}
-
-
-static bool add_lnk_extension( wchar_t *path, const size_t path_size )
-{
- size_t len = wcslen( path );
- if ( len + 5 >= path_size )
- return false;
- path[ len + 0 ] = '.';
- path[ len + 1 ] = 'l';
- path[ len + 2 ] = 'n';
- path[ len + 3 ] = 'k';
- path[ len + 5 ] = 0;
- return true;
-}
-
-
-static HANDLE lnk_file_open( const wchar_t *path, DWORD * filesize )
-{
- HANDLE hfile = CreateFileW( path, // file to open
- GENERIC_READ, // open for reading
- FILE_SHARE_READ, // share for reading
- NULL, // default security
- OPEN_EXISTING, // existing file only
- FILE_ATTRIBUTE_NORMAL, // normal file
- NULL ); // no attr. template
- if ( hfile != INVALID_HANDLE_VALUE )
- {
- if ( filesize != NULL )
- *filesize = GetFileSize( hfile, NULL );
- }
- return hfile;
-}
-
-
-static bool lnk_file_exists( const wchar_t *path )
-{
- HANDLE hFile = lnk_file_open( path, NULL );
- if ( hFile != INVALID_HANDLE_VALUE )
- {
- CloseHandle( hFile );
- return true;
- }
- else
- return false;
-}
-
-
-static unsigned char * lnk_file_read( HANDLE hfile, const size_t n_bytes, DWORD * read )
-{
- unsigned char * res;
-
- if ( read != NULL ) *read = 0;
- res = (unsigned char *)malloc( n_bytes );
- if ( res != NULL )
- {
- DWORD dwBytesRead;
- if ( FALSE == ReadFile( hfile, res, ( DWORD ) n_bytes, &dwBytesRead, NULL ) )
- {
- free( res );
- res = NULL;
- }
- else
- {
- if ( read != NULL )
- *read = dwBytesRead;
- }
- }
- return res;
-}
-
-
-static DWORD lnk_file_get_DWORD( const unsigned char * buffer, const int idx )
-{
- DWORD res = 0;
- memcpy( &res, &(buffer[ idx ]), sizeof( res ) );
- return res;
-}
-
-static WORD lnk_file_get_WORD( const unsigned char * buffer, const int idx )
-{
- WORD res = 0;
- memcpy( &res, &(buffer[ idx ]), sizeof( res ) );
- return res;
-}
-
-
-static bool lnk_file_validate_buffer( const unsigned char * buffer, const size_t buffsize )
-{
- bool res = ( buffsize >= sizeof lnk_ref );
- if ( res )
- res = ( 0 == memcmp ( buffer, lnk_ref, sizeof lnk_ref ) );
- return res;
-}
-
-
-/* the path is given in windows-native notation and wide-char */
-static bool lnk_file_validate( const wchar_t *path )
-{
- HANDLE hfile;
- bool res;
-
- hfile = lnk_file_open( path, NULL );
- res = ( hfile != INVALID_HANDLE_VALUE );
- if ( res )
- {
- DWORD dwBytesRead;
- unsigned char * buffer = lnk_file_read( hfile, 32, &dwBytesRead );
- CloseHandle( hfile );
- res = ( buffer != NULL );
- if ( res )
- {
- res = lnk_file_validate_buffer( buffer, dwBytesRead );
- free( buffer );
- }
- }
- return res;
-}
-
-/* resolves a lnk file, after it's content was loaded into a buffer
- buffer ... IN points to the file-content
- buffsize ... IN also the size of the lnk-file
- resolved ... OUT resolved path as wchar_t in windows-native form
-
- return-value 0 ... resolving failed
- 1 ... resolved path is a file
- 2 ... resolved path is a directory
-*/
-static int lnk_file_resolve_buffer( const unsigned char * buffer, const size_t buffsize,
- wchar_t ** resolved )
-{
- char * base_path = NULL;
- int res = LNK_RES_ERROR;
- if ( lnk_file_validate_buffer( buffer, buffsize ) )
- {
- int idx = 0x4C;
- DWORD flags = lnk_file_get_DWORD( buffer, 0x14 );
- DWORD attr = lnk_file_get_DWORD( buffer, 0x18 );
-
- /* we have to handle the TargetIDList even if it is of no relevance
- to resolving the link, just to get the correct index for the next
- section */
- if ( flags & LNK_FLAG_HasLinkTargetIDList )
- idx += ( lnk_file_get_WORD( buffer, idx ) + 2 );
- if ( flags & LNK_FLAG_HasLinkInfo )
- {
- DWORD base_path_ofs = lnk_file_get_DWORD( buffer, idx + 16 );
- if ( base_path_ofs > 0 )
- {
- const char * src = (const char *)&( buffer[ idx + base_path_ofs ]);
- if ( *src != 0 )
- {
- size_t required;
- errno_t e = mbstowcs_s( &required, NULL, 0, src, 0 );
- if ( required > 0 )
- {
- *resolved = (wchar_t *) malloc( ( required + 1 ) * 2 );
- if ( *resolved )
- {
- size_t converted;
- mbstowcs_s( &converted, *resolved, required + 1, src, required + 1 );
- if ( attr & LNK_ATTR_FILE_ATTRIBUTE_DIRECTORY )
- res = LNK_RES_DIR;
- else
- res = LNK_RES_FILE;
- }
- }
- }
- }
- }
- }
- return res;
-}
-
-
-/* translate a given lnk-file (full path) 'c:\somewhere\alink.lnk'
- into the path the lnk-file contains:
- 'c:\somewhere\subpath\file.txt'
- or
- 'c:\anotherpath\sub\sub\file.txt'
- */
-static int lnk_file_resolve( const wchar_t *lnk_file, wchar_t ** resolved )
-{
- HANDLE hfile;
- DWORD dwFileSize;
- int res = LNK_RES_ERROR;
-
- if ( resolved != NULL )
- {
- *resolved = NULL;
- hfile = lnk_file_open( lnk_file, &dwFileSize );
- if ( hfile != INVALID_HANDLE_VALUE )
- {
- unsigned char * buffer = lnk_file_read( hfile, (size_t)dwFileSize, NULL );
- if ( buffer != NULL )
- {
- res = lnk_file_resolve_buffer( buffer, dwFileSize, resolved );
- free( buffer );
- }
- }
- }
- return res;
-}
-
-
-static bool win_path_exists( const wchar_t * path )
-{
- bool res = false;
- if ( path != NULL )
- {
- HANDLE hfile = CreateFileW( path,
- 0, /* do not ask for RD or WR, that prevents access-denied-err */
- FILE_SHARE_READ, /* needed to get a handle to obj's that are shared */
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
- NULL );
- if ( hfile != INVALID_HANDLE_VALUE )
- {
- res = true;
- CloseHandle( hfile );
- }
-#if _DEBUGGING
- else
- {
- DWORD status = GetLastError ();
- switch ( status )
- {
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- break;
- default:
- DBGMSG ( DBG_KFS, DBG_FLAG_ANY, ( "win_path_exists: WARNING - unrecognized error code - %u.", status ) );
- }
- }
-#endif
- }
- return res;
-}
-
-static
-wchar_t * less_brain_dead_wcsdup ( const wchar_t * path )
-{
- if ( path != NULL )
- {
- size_t len = wcslen ( path ) + 3;
- wchar_t *cpy = malloc ( len * sizeof * cpy );
- if ( cpy != NULL )
- return wcscpy ( cpy, path );
- }
- return NULL;
-}
-
-static size_t win_existing_path( const wchar_t *path )
-{
- size_t res = 0;
- wchar_t * temp = less_brain_dead_wcsdup( path );
- if ( temp != NULL )
- {
- wchar_t * part = wcsrchr( temp, L'\\' );
- while ( part != NULL && res == 0 )
- {
- *part = 0;
- if ( win_path_exists( temp ) )
- res = ( part - temp );
- else
- part = wcsrchr( temp, L'\\' );
- }
- free( temp );
- }
- return res;
-}
-
-
-static wchar_t * win_assemble_lnk( const wchar_t *path, const size_t exists, size_t * remaining )
-{
- wchar_t * res = NULL;
- if ( path != NULL && remaining != NULL )
- {
- size_t path_len, buff_len;
-
- *remaining = 0;
- path_len = wcslen( path );
- #define ExtraChars 5
- buff_len = ( path_len + ExtraChars ) * sizeof( * path );
- res = (wchar_t *)malloc( buff_len );
- if ( res != NULL )
- {
- size_t term;
- const wchar_t * from = ( path + exists + 1 );
- const wchar_t * next_bs = wcschr( from, L'\\' );
- if ( next_bs == NULL )
- term = path_len;
- else
- {
- term = ( next_bs - path );
- *remaining = term;
- }
- /* if the string to be copied does not fit into the buffer
- wcsncpy_s will terminate the application instead of returning
- an error !!! */
- wcsncpy_s( res, path_len + ExtraChars, path, term ); /* 2nd argument is in elements, not bytes */
- res[ term + 0 ] = L'.';
- res[ term + 1 ] = L'l';
- res[ term + 2 ] = L'n';
- res[ term + 3 ] = L'k';
- res[ term + 4 ] = 0;
- }
- #undef ExtraChars
- }
- return res;
-}
-
-
-static wchar_t * win_assemble_path( const wchar_t *part1, const wchar_t *part2 )
-{
- wchar_t *res = NULL;
- if ( part1 != NULL && part2 != NULL )
- {
- size_t len1 = wcslen( part1 );
- size_t len2 = wcslen( part2 );
- res = (wchar_t *)malloc( ( len1 + len2 + 1 ) * sizeof( * part1 ) );
- if ( res != NULL )
- {
- /* if the string to be copied does not fit into the buffer
- wcsncpy_s will terminate the application instead of returning
- an error !!! */
- wcsncpy_s( res, len1+1, part1, len1 );
- wcsncpy_s( res+len1, len2+1, part2, len2 );
- res[ len1 + len2 ] = 0;
- }
- }
- return res;
-}
-
-
-static bool win_resolve_path( const wchar_t *path, wchar_t ** resolved, const int depth )
-{
- bool res = false;
-
- if ( depth > 10 )
- return res;
- if ( resolved != NULL )
- {
- *resolved = NULL;
- res = win_path_exists( path );
- if ( res )
- /* the given path exists, no need to resolve links... */
- *resolved = less_brain_dead_wcsdup( path );
- else
- {
- /* detect the part of the path that does exist
- exists points at the backslash behind the existing path */
- size_t exists = win_existing_path( path );
- if ( exists > 0 )
- {
- size_t remaining;
- wchar_t * possible_lnk = win_assemble_lnk( path, exists, &remaining );
- if ( possible_lnk != NULL )
- {
- wchar_t * lnk_resolved = NULL;
- int status = lnk_file_resolve( possible_lnk, &lnk_resolved );
- if ( status != LNK_RES_ERROR )
- {
- if ( remaining > 0 )
- {
- wchar_t * new_path = win_assemble_path( lnk_resolved, path + remaining );
- free( lnk_resolved );
- if ( new_path != NULL )
- {
- res = win_resolve_path( new_path, resolved, depth + 1 );
- free( new_path );
- }
- }
- else
- {
- *resolved = lnk_resolved;
- res = true;
- }
- }
- free( possible_lnk );
- }
- }
- }
- }
- return res;
-}
-
-
-bool win_CreateLink( const wchar_t * target, const wchar_t * lnk_file, const wchar_t * desc )
-{
- bool res = false;
- HRESULT hres;
- IShellLink * psl;
-
- // Get a pointer to the IShellLink interface.
- hres = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- &IID_IShellLink, (LPVOID*)&psl );
- if ( SUCCEEDED( hres ) )
- {
- IPersistFile* ppf;
-
- // Set the path to the shortcut target and add the description.
- psl -> lpVtbl -> SetPath( psl, target );
- if ( desc != NULL )
- psl -> lpVtbl -> SetDescription( psl, desc );
-
- // Query IShellLink for the IPersistFile interface for saving the
- // shortcut in persistent storage.
- hres = psl -> lpVtbl -> QueryInterface( psl, &IID_IPersistFile, (LPVOID*)&ppf );
- if ( SUCCEEDED( hres ) )
- {
- // Save the link by calling IPersistFile::Save.
- hres = ppf -> lpVtbl -> Save( ppf, lnk_file, TRUE );
- res = SUCCEEDED( hres );
- ppf -> lpVtbl -> Release( ppf );
- }
- psl -> lpVtbl -> Release( psl );
- }
- return res;
-}
diff --git a/libs/kfs/win/sysdir-priv.h b/libs/kfs/win/sysdir-priv.h
deleted file mode 100644
index 1ae8cc7..0000000
--- a/libs/kfs/win/sysdir-priv.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_sysdir_priv_
-#define _h_sysdir_priv_
-
-#ifndef _h_kfs_impl_
-#include <kfs/impl.h>
-#endif
-
-#ifndef _h_klib_rc_
-#include <klib/rc.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*--------------------------------------------------------------------------
- * KDirectory
- * a Windows extension
- */
-
-
-/* MakeFromRealPath
- * creates a KDirectory from a Windows path
- */
-rc_t KDirectoryMakeFromRealPath ( KDirectory **dirp,
- const wchar_t *real, bool update, bool chroot );
-
-
-/*--------------------------------------------------------------------------
- * KSysDir
- * a Windows directory
- */
-typedef struct KSysDir KSysDir;
-
-
-#if 0
-/* MakePath
- * create a full path from partial
- *
- * "ctx" [ IN ] - a prepared context for returning non-zero rc_t
- *
- * "canon" [ IN ] - if true, rewrite path in canonical form. usually
- * not required when passing a path to the system, as the OS performs
- * its own processing.
- *
- * "bufer" [ OUT ] and "path_max" [ IN ] - return buffer for processed path
- *
- * "path" [ IN ] and "args" [ IN, NULL OKAY ] - input path to be resolved
- */
-rc_t KSysDirMakePath ( const KSysDir* self, enum RCContext ctx, bool canon,
- wchar_t *buffer, size_t path_max, const char *path, va_list args );
-#endif
-
-
-/* OSPath
- * returns a real OS path
- */
-rc_t KSysDirOSPath ( const KSysDir *self,
- wchar_t *real, size_t bsize, const char *path, va_list args );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_sysdir_priv_ */
diff --git a/libs/kfs/win/sysdir.c b/libs/kfs/win/sysdir.c
deleted file mode 100644
index b503f5f..0000000
--- a/libs/kfs/win/sysdir.c
+++ /dev/null
@@ -1,3135 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-
-/*--------------------------------------------------------------------------
- * forwards
- */
-struct KSysDir;
-
-#define UNICODE 1
-#define _UNICODE 1
-
-#define KDIR_IMPL struct KSysDir
-
-#include "sysfile-priv.h"
-#include <klib/namelist.h>
-#include <klib/text.h>
-#include <klib/rc.h>
-#include <klib/log.h>
-#include <klib/out.h>
-#include <klib/debug.h>
-#include <klib/klib-priv.h>
-
-#include <sysalloc.h>
-
-#include <stdio.h>
-#include <wchar.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <WINDOWS.H>
-#include <WINNT.H>
-
-#include "lnk_tools.c"
-
-#include <os-native.h>
-
-#ifndef IO_REPARSE_TAG_SYMLINK
-#define IO_REPARSE_TAG_SYMLINK 0xA000000C
-#endif
-
-
-/* Missing functions from our text library
- * size is bytes; max_chars is number of elements
- */
-
-/* utf16_utf32
- * converts UTF16 text to a single UTF32 character
- * returns the number of UTF16 words consumed, such that:
- * return > 0 means success
- * return == 0 means insufficient input
- * return < 0 means bad input or bad argument
- */
-static
-int utf16_utf32 ( uint32_t *dst, const wchar_t *begin, const wchar_t *end )
-{
- uint32_t ch;
-
- if ( dst == NULL || begin == NULL || end == NULL )
- return -1;
-
- if ( begin == end )
- return 0;
-
- /* windows utf16 */
-
- ch = (uint32_t)(begin [0]);
-
- if ((ch < 0xD800) || (ch <= 0xE000))
- {
- *dst = ch;
- return 1;
- }
- else
- {
- uint32_t ch;
-
- /* need at least 2 words */
- if (begin >= end)
- return -1;
-
- /* extreme checks */
- if (((begin[0] & 0xFC00) != 0xD8) ||
- ((begin[1] & 0xFC00) != 0xDC))
- return -1;
-
- ch = (begin[0] & 0x03FF) << 10 |
- (begin[1] & 0x03FF);
- return 2;
- }
-}
-
-
-/* utf32_utf16
- * converts a single UTF32 character to UTF16 text
- * returns the number of UTF16 words generated, such that:
- * return > 0 means success
- * return == 0 means insufficient output
- * return < 0 means bad character or bad argument
- */
-static
-int utf32_utf16 ( wchar_t *begin, wchar_t *end, uint32_t ch )
-{
- if (ch < 0x10000)
- {
- if ((ch <= 0xDFFF) && (ch >= 0xD800))
- return -1;
-
- begin[0] = (uint16_t)ch;
- return 1;
- }
- else if ((ch >= 0x10FFFF) || (end <= begin))
- return -1;
- else
- {
- uint32_t cch;
-
- cch = ch - 0x10000;
- /* cch <= 0xFFFFF since ch < 0x10FFFF */
-
- begin[0] = 0xD800 | (cch >> 10); /* upper 10 bits */
- begin[1] = 0xDC00 | (cch & 0x3FF); /* lower 10 bita */
- return 2;
- }
-}
-
-
-static int wstrcase_cmp (const wchar_t * a, size_t asize,
- const wchar_t * b, size_t bsize,
- uint32_t max_chars)
-{
- uint32_t num_chars;
- const wchar_t *aend, *bend;
-
- assert ( a != NULL && b != NULL );
-
- /* set up end limit triggers */
- aend = a + asize;
- bend = b + bsize;
-
- num_chars = 0;
-
- while ( a < aend && b < bend )
- {
- uint32_t ach, bch;
-
- /* read a character from a */
- int len = utf16_utf32 ( & ach, a, aend );
- if ( len <= 0 )
- {
- asize -= ( size_t ) ( aend - a );
- break;
- }
- a += len;
-
- /* read a character from b */
- len = utf16_utf32 ( & bch, b, bend );
- if ( len <= 0 )
- {
- bsize -= ( size_t ) ( bend - b );
- break;
- }
- b += len;
-
- /* compare characters with case */
- if ( ach != bch )
- {
- /* only go lower case if they differ */
- ach = towlower ( ( wint_t ) ach );
- bch = towlower ( ( wint_t ) bch );
-
- if ( ach != bch )
- {
- if ( ach < bch )
- return -1;
- return 1;
- }
- }
-
- /* if char count is sufficient, we're done */
- if ( ++ num_chars == max_chars )
- return 0;
- }
-
- /* one or both reached end < max_chars */
- if (asize < bsize)
- return -1;
- return asize > bsize;
-}
-
-/*--------------------------------------------------------------------------
- * KSysDirEnum
- * a Windows directory enumerator
- */
-typedef struct KSysDirEnum KSysDirEnum;
-struct KSysDirEnum
-{
- HANDLE handle;
- WIN32_FIND_DATAW fd;
- int found;
- bool first;
-};
-
-/* Whack
- */
-static
-void KSysDirEnumWhack ( KSysDirEnum *self )
-{
- FindClose( self->handle );
-}
-
-/* Init
- */
-static
-rc_t KSysDirEnumInit ( KSysDirEnum *self, const wchar_t *path )
-{
- uint32_t err;
- rc_t rc;
-
- self -> first = true;
- self -> handle = FindFirstFileW ( path, & self -> fd );
- if ( self -> handle != INVALID_HANDLE_VALUE )
- {
- self -> found = 1;
- return 0;
- }
-
- self -> found = 0;
- err = GetLastError ();
- switch ( err )
- {
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- rc = RC ( rcFS, rcDirectory, rcListing, rcPath, rcNotFound );
- break;
- default :
- rc = RC ( rcFS, rcDirectory, rcListing, rcNoObj, rcUnknown );
- }
-
- PLOGERR ( klogInfo,
- ( klogInfo, rc, "error FindFirstFileW - $(E) - $(C)",
- "E=%!,C=%u", err, err ) );
-
- return rc;
-}
-
-
-static
-rc_t KSysDirEnumInitAll ( KSysDirEnum *self, wchar_t *path, uint32_t path_length )
-{
- /* prepare the path for KSysDirEnumInit() */
- path [ path_length + 0 ] = '\\';
- path [ path_length + 1 ] = '*';
- path [ path_length + 2 ] = '.';
- path [ path_length + 3 ] = '*';
- path [ path_length + 4 ] = 0;
-
- return KSysDirEnumInit ( self, path );
-}
-
-/* Next
- */
-static
-const wchar_t *KSysDirEnumNext ( const KSysDirEnum *cself )
-{
- KSysDirEnum* self = (KSysDirEnum*)cself;
-
- while( self->found )
- {
- if ( self -> first )
- self -> first = false;
- else
- self->found = FindNextFileW( self->handle, &self->fd );
-
- if ( self->found )
- {
- /* filter out the '.' and '..' entries */
- if ( self ->fd.cFileName[ 0 ] == '.' )
- {
- switch ( self->fd.cFileName[ 1 ] )
- {
- case 0:
- continue;
- case '.':
- if ( self->fd.cFileName[ 2 ] == 0 )
- continue;
- break;
- }
- }
- return self->fd.cFileName;
- }
- }
-
- return NULL;
-}
-
-
-/*--------------------------------------------------------------------------
- * KSysDirListing
- * a Windows directory listing
- */
-typedef VNamelist KSysDirListing;
-
-static
-int KSysDirListingSort ( const void *a, const void *b )
-{
- size_t A,B,M;
- A = wchar_string_size (a);
- B = wchar_string_size (b);
- /* close enough for max chars? */
- M = (A>B) ? A : B;
-
- return wstrcase_cmp (a, A, b, B, ( uint32_t ) M);
-}
-
-static
-rc_t KSysDirListingInit ( KSysDirListing *self, const wchar_t *path, const KDirectory *dir,
- bool ( CC * f ) ( const KDirectory*, const char*, void* ), void *data )
-{
- KSysDirEnum list;
- rc_t rc = KSysDirEnumInit ( & list, path );
- if ( rc == 0 )
- {
- const wchar_t *name;
- char utf8_name[ MAX_PATH ];
- size_t utf8_size, utf16_size;
-
- while ( ( name = KSysDirEnumNext ( & list ) ) != NULL )
- {
- utf16_size = wchar_string_size ( name );
- utf8_size = wchar_cvt_string_copy ( utf8_name, sizeof( utf8_name ), name, utf16_size );
- if ( utf8_size >= sizeof( utf8_name ) )
- {
- rc = RC(rcFS, rcDirectory, rcListing, rcName, rcExcessive );
- break;
- }
-
- if ( f != NULL )
- {
- if ( ! ( * f ) ( dir, utf8_name, data ) )
- continue;
- }
-
- rc = VNamelistAppend( self, utf8_name );
- if ( rc != 0 )
- {
- break;
- }
-
- }
-
- KSysDirEnumWhack ( & list );
- }
- return rc;
-}
-
-/*--------------------------------------------------------------------------
- * KSysDir
- * a Windows directory
- */
-typedef struct KSysDir KSysDir;
-struct KSysDir
-{
- KDirectory dad;
- uint32_t root;
- uint32_t length;
- wchar_t path [ MAX_PATH ];
-};
-
-
-/* helper function to translate a windows-error-code into rc-code */
-static
-rc_t translate_file_error( DWORD error, enum RCContext ctx )
-{
- switch ( error )
- {
- case ERROR_FILE_NOT_FOUND :
- case ERROR_PATH_NOT_FOUND :
- case ERROR_INVALID_DRIVE :
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcNotFound );
-
- case ERROR_ALREADY_EXISTS:
- case ERROR_FILE_EXISTS :
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcExists );
-
-/* case ERROR_PATH_NOT_FOUND : */
- case ERROR_INVALID_NAME :
- case ERROR_BAD_PATHNAME :
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- case ERROR_ACCESS_DENIED :
- case ERROR_INVALID_ACCESS :
- case ERROR_SHARING_VIOLATION :
- case ERROR_LOCK_VIOLATION :
- case ERROR_PATH_BUSY :
- case ERROR_WRITE_PROTECT :
- case ERROR_DELETE_PENDING :
- return RC ( rcFS, rcDirectory, ctx, rcDirectory, rcUnauthorized );
-
- case ERROR_NOT_ENOUGH_MEMORY :
- case ERROR_OUTOFMEMORY :
- return RC ( rcFS, rcDirectory, ctx, rcMemory, rcExhausted );
-
- case ERROR_TOO_MANY_OPEN_FILES :
- return RC ( rcFS, rcDirectory, ctx, rcFileDesc, rcExhausted );
-
- case ERROR_HANDLE_DISK_FULL :
- return RC ( rcFS, rcDirectory, ctx, rcStorage, rcExhausted );
-
- case ERROR_BUFFER_OVERFLOW :
- case ERROR_FILENAME_EXCED_RANGE :
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcExcessive );
- }
- return RC ( rcFS, rcDirectory, ctx, rcNoObj, rcUnknown );
-}
-
-
-/* helper */
-
-static rc_t print_error_for( DWORD error, const wchar_t * path, const char * function, enum RCContext ctx, KLogLevel level )
-{
- rc_t rc = translate_file_error( error, ctx );
-#if _DEBUGGING
- char buffer[ 4096 ];
- size_t src_size, dst_size, len;
- wchar_cvt_string_measure ( path, &src_size, &dst_size );
- len = wchar_cvt_string_copy ( buffer, sizeof buffer, path, src_size );
- buffer[ len ] = 0;
- PLOGERR ( level,
- ( level, rc, "error $(F) - $(E) - $(C) for $(D)",
- "F=%s,E=%!,C=%u,D=%s", function, error, error, buffer ) );
-#endif
- return rc;
-}
-
-
-static void wchar_2_char( const wchar_t * path, char * buffer, size_t buflen )
-{
- size_t src_size, dst_size, len;
- wchar_cvt_string_measure ( path, &src_size, &dst_size );
- len = wchar_cvt_string_copy ( buffer, buflen, path, src_size );
- buffer[ len ] = 0;
-}
-
-
-static
-uint32_t KSysDirPathTypeFromFindData ( WIN32_FIND_DATA *find_data,
- const wchar_t * path,
- const uint32_t type )
-{
- uint32_t res = type;
-
- if( ( find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 )
- {
- res = kptDir;
- }
- else if ( ( find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE ) != 0 )
- {
- res = kptCharDev;
- }
-
- /* add in alias bit */
- if ( ( find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) != 0 )
- {
- if ( ( find_data->dwReserved0 & IO_REPARSE_TAG_SYMLINK ) != 0 )
- res |= kptAlias;
- }
- else
- {
- if ( has_lnk_extension( path ) ) /* lnk_tools.c */
- if ( lnk_file_validate( path ) ) /* lnk_tools.c */
- res |= kptAlias;
- }
- return res;
-}
-
-static
-uint32_t KSysDirResolvePathAndDetectPathType ( const wchar_t *path )
-{
- uint32_t res = kptNotFound;
- wchar_t *resolved;
- if ( win_resolve_path( path, &resolved, 1 ) ) /* lnk_tools.c */
- {
- WIN32_FIND_DATA find_data;
- HANDLE f_findfile = FindFirstFileW( resolved, &find_data );
- if ( f_findfile != INVALID_HANDLE_VALUE )
- {
- FindClose( f_findfile );
- res = KSysDirPathTypeFromFindData ( &find_data, resolved, kptFile );
- }
- else
- {
- uint32_t err = GetLastError();
- switch( err )
- {
- case ERROR_BAD_NETPATH:
- case ERROR_BAD_NET_NAME:
- /* see if the netpath is a server
- NB - our special wcsdup allocated extra space for this */
- wcscat ( resolved, L"\\*" );
- f_findfile = FindFirstFileW( resolved, &find_data );
- if ( f_findfile != INVALID_HANDLE_VALUE )
- {
- FindClose ( f_findfile );
- res = kptDir;
- break;
- }
- /* no break */
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- res = kptNotFound;
- break;
-
- default:
- res = kptBadPath;
- }
- }
- free( resolved );
- }
- return res;
-}
-
-/* KSysDirPathType
- * returns a KPathType
- *
- * "path" [ IN ] - NUL terminated string in directory-native character set
- */
-static
-uint32_t KSysDirFullFSPathType ( const wchar_t * path )
-{
- WIN32_FIND_DATA find_data;
- HANDLE f_findfile = FindFirstFileW( path, &find_data );
- if ( f_findfile == INVALID_HANDLE_VALUE )
- {
- DWORD status = GetLastError ();
- switch( status )
- {
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_BAD_NETPATH:
- case ERROR_BAD_NET_NAME:
- /* try to follow the path, section by section
- if a section cannot be found try to resolve it as
- MS-shell-link ( .lnk file ) */
- return KSysDirResolvePathAndDetectPathType ( path );
- default:
- DBGMSG ( DBG_KFS, DBG_FLAG_ANY, ( "FindFirstFileW: WARNING - unrecognized return code - %u.\n", status ) );
- print_error_for( status, path, "FindFirstFileW", rcResolving, klogErr );
- return kptBadPath;
- }
- }
- FindClose( f_findfile );
- return KSysDirPathTypeFromFindData ( &find_data, path, kptFile );
-}
-
-
-static
-uint32_t KSysDirFullPathType ( const wchar_t *path )
-{
- /* recognize of odd, POSIX'ish patterns and handle them directly */
- if ( path [ 0 ] == '/' || path [ 0 ] == '\\' )
- {
- /* looking exactly for "root" */
- if ( path [ 1 ] == 0 )
- return kptFakeRoot;
- }
-
- /* regognize this 'c:\' as a valid path...*/
- if ( iswalpha( path[ 0 ] ) && path [ 1 ] == ':' && path [ 2 ] == '\\' && path[ 3 ] == 0 )
- {
- uint32_t path_type = kptBadPath;
- uint32_t mask = 0;
- if ( path[ 0 ] >= 'A' && path[ 0 ] <= 'Z' )
- {
- mask = ( 1 << ( path[ 0 ] - 'A' ) );
- }
- else if ( path[ 0 ] >= 'a' && path[ 0 ] <= 'z' )
- {
- mask = ( 1 << ( path[ 0 ] - 'a' ) );
- }
- if ( mask > 0 )
- {
- DWORD drivebitmask = GetLogicalDrives(); /* each logical drive has its own bit set */
- if ( ( drivebitmask & mask ) == mask )
- path_type = kptDir;
- }
- return path_type;
- }
-
- /* let the file system tell us */
- return KSysDirFullFSPathType ( path );
-}
-
-
-/* KSysDirMake
- * allocate an uninialized object
- */
-static
-KSysDir *KSysDirMake ( size_t path_size )
-{
- KSysDir *dir = malloc ( sizeof *dir - sizeof dir->path +
- 4 * sizeof dir -> path [ 0 ] + path_size );
- return dir;
-}
-
-
-/* KSysDirDestroy
- */
-static
-rc_t CC KSysDirDestroy ( KSysDir *self )
-{
- free ( self );
- return 0;
-}
-
-/* KSysDirCanonPath
- */
-static
-rc_t KSysDirCanonPath ( const KSysDir *self, enum RCContext ctx, wchar_t *path, uint32_t path_length )
-{
- wchar_t *low, *dst, *last, *end = path + path_length;
-
- if ( self -> root != 0 )
- low = path + self -> root;
- else if ( path [ 1 ] == ':' )
- low = path + 2;
- else
- low = path;
- dst = last = low;
-
- while( 1 )
- {
- wchar_t *src = wcschr ( last + 1, '\\' );
- if ( src == NULL )
- src = end;
-
- /* detect special sequences */
- switch ( src - last )
- {
- case 1:
- if ( last [ 1 ] == '\\' && last != path ) /* keep leading double slash */
- {
- /* "\\\\" -> "\\" */
- last = src;
- }
- break;
-
- case 2:
- if ( last [ 1 ] == '.' )
- {
- /* skip over */
- last = src;
- if ( src != end )
- continue;
- }
- break;
-
- case 3:
- if ( last [ 1 ] == '.' && last [ 2 ] == '.' )
- {
- /* remove previous leaf in path */
- dst [ 0 ] = 0;
- dst = wcsrchr ( path, '\\' );
- if ( dst == NULL || dst < low )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- last = src;
- if ( src != end )
- continue;
- }
- break;
- }
-
- /* if rewriting, copy leaf */
- assert ( src >= last );
-
- /* if rewriting, copy leaf */
- if ( dst != last )
- memmove ( dst, last, ( src - last ) * sizeof * dst );
-
- /* move destination ahead */
- dst += src - last;
-
- /* if we're done, go */
- if ( src == end )
- break;
-
- /* find next separator */
- last = src;
- }
-
- /* NUL terminate if modified */
- if ( dst != end )
- *dst = 0;
-
- return 0;
-}
-
-/* KSysDirMakePath
- * creates a full path from partial
-
- self ....... has the first (base) part of the path in wchar_t !!!
- canon ...... if true the assembled path will be "canonilized" as last step
- buffer ..... into this buffer the full-path will be assembled ( wchar_t !!! )
- path_max ... the size of the buffer in bytes
- path ....... the partial path in utf8, can contain string-subst-elements !!!
- args ....... arguments to construct the partial path in utf8 ( can be NULL )
- */
-static
-rc_t KSysDirMakeSimulatedFSPath ( const KSysDir* self, enum RCContext ctx, bool canon,
- wchar_t *buffer, size_t path_max, const char *path, va_list args, bool fake_posix )
-{
- int temp_size_in_bytes;
- uint32_t i, temp_length_in_utf8_chars;
- uint32_t buffer_length_in_wchars;
- char temp_utf8_buffer [ MAX_PATH ];
-
- /* check if the given partial path is not NULL and not empty */
- if( path == NULL )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcNull );
- if ( path [ 0 ] == 0 )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- /* We construct in temp_utf8_buffer the relative path the user has given:
- If there are no args we copy with _snprintf else we use vsnprintf,
- !!! the args are always utf8, the given path is in utf8 !!!
- that is the reason for the temporary utf8-buffer */
- temp_size_in_bytes = ( args == NULL ) ?
- _snprintf ( temp_utf8_buffer, sizeof temp_utf8_buffer, "%s", path ):
- vsnprintf( temp_utf8_buffer, sizeof temp_utf8_buffer, path, args );
-
- /* we check if _snprnitf/vsnprintf was sucessful */
- if ( temp_size_in_bytes < 0 || temp_size_in_bytes >= sizeof temp_utf8_buffer )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcExcessive );
-
- /* we measure the number of utf8-chars we have in our temp-buffer
- only for international chars in the temp-buffer there will be
- path_length_in_utf8_chars != path_size_in_bytes */
- temp_length_in_utf8_chars = string_len ( temp_utf8_buffer, temp_size_in_bytes );
-
- /* normally we don't receive native Windows paths here.
- but there is a use below ( when creating native directory )
- that feeds a Windows path, so deal with it here. */
- if ( ( isalpha ( temp_utf8_buffer [ 0 ] ) && temp_utf8_buffer [ 1 ] == ':' ) ||
- ( temp_utf8_buffer [ 0 ] == '\\' && temp_utf8_buffer [ 1 ] == '\\' ) ||
- ( temp_utf8_buffer [ 0 ] == '/' && temp_utf8_buffer [ 1 ] == '/' ) )
- {
- /* in the case the path is a absolute path for windows (starting with "C:" for instance)
- we completely ignore the path in self and use the given path only.
- !!! except we are chrooted, in this case the given path is invalid
- ( no abs. path for chrooted dir's ) */
- if ( self -> root != 0 )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- /* we detected a drive or UNC path - require a further character */
- if ( temp_utf8_buffer [ 2 ] == 0 )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- buffer_length_in_wchars = 0;
- }
-
-
- /**************************************************/
- /* THESE ARE EXPECTED TO BE POSIX-STYLE PATHS NOW */
- /**************************************************/
-
- /* relative path to directory */
- else if ( temp_utf8_buffer [ 0 ] != '/' )
- {
- /* copy base of path from self */
- assert ( self -> length >= 3 );
- buffer_length_in_wchars = self -> length;
- }
- else
- {
- /* POSIX full path, should include drive letter or UNC slashes */
-
- /* get chroot'd path length */
- buffer_length_in_wchars = self -> root;
-
- /* if the full path includes a drive letter */
- if ( isalpha ( temp_utf8_buffer [ 1 ] ) && temp_utf8_buffer [ 2 ] == '/' )
- {
- /* fail if chroot'd */
- if ( self -> root != 0 )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- /* rewrite drive letter */
- temp_utf8_buffer [ 0 ] = tolower ( temp_utf8_buffer [ 1 ] );
- temp_utf8_buffer [ 1 ] = ':';
- }
- /* detect UNC path */
- else if ( temp_utf8_buffer [ 1 ] == '/' )
- {
- /* fail if chroot'd */
- if ( self -> root != 0 )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- /* fail if just '//' */
- if ( temp_utf8_buffer [ 2 ] == 0 )
- {
- if ( ! fake_posix )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- temp_utf8_buffer [ 1 ] = 0;
- temp_length_in_utf8_chars = 1;
- temp_size_in_bytes = 1;
- }
- }
- else if ( self -> root == 0 )
- {
- /* this is a "full" path that does not appear to be convertible
- to a Windows full path, unless we are chroot'd */
- if ( ! fake_posix )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
-
- /* allow path like "/C" */
- if ( isalpha ( temp_utf8_buffer [ 1 ] ) && temp_utf8_buffer [ 2 ] == 0 )
- {
- temp_utf8_buffer [ 0 ] = tolower ( temp_utf8_buffer [ 1 ] );
- temp_utf8_buffer [ 1 ] = ':';
- temp_utf8_buffer [ 2 ] = '/';
- temp_utf8_buffer [ 3 ] = 0;
- temp_length_in_utf8_chars = 3;
- temp_size_in_bytes = 3;
- }
- }
- else
- {
- /* this needs to be a valid UNC or drive path */
- assert ( self -> root >= 3 );
- }
- }
-
- /* check for buffer overrun */
- if ( buffer_length_in_wchars + temp_length_in_utf8_chars >= path_max / sizeof * buffer )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcExcessive );
-
- /* prepend UTF-16 directory path */
- if ( buffer_length_in_wchars != 0 )
- {
- memcpy ( buffer, self -> path, buffer_length_in_wchars * sizeof * buffer );
-
- /* if path is relative, expect trailing '\\'
- if path is full, expect NO trailing '\\' */
- assert ( ( buffer_length_in_wchars == self ->length &&
- buffer [ buffer_length_in_wchars - 1 ] == '\\' ) ||
- ( buffer_length_in_wchars == self ->root &&
- buffer [ buffer_length_in_wchars - 1 ] != '\\' ) );
- }
-
- /* append the temp_utf8_buffer to the user-supplied relative path */
- buffer_length_in_wchars += (uint32_t)string_cvt_wchar_copy ( & buffer [ buffer_length_in_wchars ],
- path_max - buffer_length_in_wchars * sizeof buffer [ 0 ],
- temp_utf8_buffer, temp_size_in_bytes );
- /* the job of the temp_utf8_buffer is done now... */
-
- /* detect exhausted buffer */
- if ( buffer_length_in_wchars >= path_max / sizeof * buffer )
- return RC ( rcFS, rcDirectory, ctx, rcPath, rcExcessive );
-
- /* must be either:
- 1) a full drive-letter path, or
- 2) an UNC path.
- minimum path length is 3 */
- assert ( buffer_length_in_wchars >= 3 || fake_posix );
- assert ( buffer[ buffer_length_in_wchars ] == 0 );
-
- if ( buffer_length_in_wchars > 3 )
- {
- /* remove any trailing slash added by caller */
- while ( buffer_length_in_wchars > 3 && buffer [ buffer_length_in_wchars - 1 ] == '/' )
- buffer [ -- buffer_length_in_wchars ] = 0;
- }
-
- /* convert forward to backward slashes */
- for ( i = 0; i < buffer_length_in_wchars; ++ i )
- {
- if ( buffer [ i ] == '/' )
- buffer [ i ] = '\\';
- }
-
- /* if caller wants canonical representation
- or I'm chrooted, rewrite */
- if ( buffer_length_in_wchars > 2 && ( canon || self -> root > 2 ) )
- {
- return KSysDirCanonPath ( self, ctx, buffer, buffer_length_in_wchars );
- }
-
- return 0;
-}
-
-static
-rc_t KSysDirMakePath ( const KSysDir* self, enum RCContext ctx, bool canon,
- wchar_t *buffer, size_t path_max, const char *path, va_list args )
-{
- return KSysDirMakeSimulatedFSPath ( self, ctx, canon, buffer, path_max, path, args, false );
-}
-
-LIB_EXPORT rc_t KSysDirOSPath ( const KSysDir *self,
- wchar_t *real, size_t real_size, const char *path, va_list args )
-{
- return KSysDirMakePath ( self, rcLoading, true, real, real_size, path, args );
-}
-
-/* KSysDirInit - forward declaration
- */
-static
-rc_t KSysDirInit ( KSysDir *self, enum RCContext ctx, uint32_t dad_root,
- const wchar_t *path, size_t path_size, uint32_t path_length,
- bool update, bool chroot );
-
-/* KSysDirList
- * create a directory listing
- *
- * "list" [ OUT ] - return parameter for list object
- *
- * "path" [ IN, NULL OKAY ] - optional parameter for target
- * directory. if NULL, interpreted to mean "."
- */
-static
-rc_t CC KSysDirList ( const KSysDir *self, KNamelist **listp,
- bool ( CC * f ) ( const KDirectory *dir, const char *name, void *data ), void *data,
- const char *path, va_list args )
-{
- KSysDir full;
- rc_t rc = KSysDirMakePath ( self, rcListing, true, full.path, sizeof full.path, path, args );
- if ( rc == 0 )
- {
- size_t size_in_bytes;
- uint32_t len_in_chars = utf16_string_measure( full.path, &size_in_bytes );
-
- /* require space for a '\\*.*' and NUL */
- if ( len_in_chars + 5 > sizeof full.path / sizeof full . path [ 0 ] )
- rc = RC ( rcFS, rcDirectory, rcListing, rcPath, rcExcessive );
- else
- {
- rc = KSysDirInit( &full, rcListing, self->root, NULL, size_in_bytes, len_in_chars, 0, 0 );
- if ( rc == 0 )
- {
- KSysDirListing *list;
-
- len_in_chars = full.length;
- full . path [ len_in_chars + 0 ] = '*';
- full . path [ len_in_chars + 1 ] = '.';
- full . path [ len_in_chars + 2 ] = '*';
- full . path [ len_in_chars + 3 ] = 0;
-
- rc = VNamelistMake ( &list, 5 );
- if ( rc == 0 )
- {
- rc = KSysDirListingInit( list, full.path, & full.dad, f, data );
- if ( rc != 0 )
- {
- VNamelistRelease ( list );
- }
- else
- {
- rc = VNamelistToNamelist ( list, listp );
- VNamelistRelease ( list );
- }
- }
- }
- }
- }
- return rc;
-}
-
-static
-uint32_t CC KSysDirPathType ( const KSysDir *self, const char *path, va_list args )
-{
- wchar_t full[ MAX_PATH ];
- rc_t rc = KSysDirMakePath( self, rcAccessing, false, full, sizeof full, path, args );
- if ( rc == 0 )
- {
- return KSysDirFullPathType( full );
- }
- return kptBadPath;
-}
-
-/* KSysDirVisit
- * visit each path under designated directory,
- * recursively if so indicated
- *
- * "recurse" [ IN ] - if non-zero, recursively visit sub-directories
- *
- * "f" [ IN ] and "data" [ IN, OPAQUE ] - function to execute
- * on each path. receives a base directory and relative path
- * for each entry, where each path is also given the leaf name
- * for convenience. if "f" returns non-zero, the iteration will
- * terminate and that value will be returned. NB - "dir" will not
- * be the same as "self".
- *
- * "path" [ IN ] - NUL terminated string in directory-native character set
- */
-typedef struct KSysDirVisitData KSysDirVisitData;
-struct KSysDirVisitData
-{
- rc_t ( CC * f ) ( KDirectory*, uint32_t, const char*, void* );
- void *data;
- KSysDir dir;
- bool recurse;
-};
-
-static
-rc_t KSysDirVisitDir ( KSysDirVisitData *pb )
-{
- /* get a directory listing */
- rc_t rc;
- KSysDirEnum listing;
- uint32_t path_length;
- size_t path_size;
-
- /* measure length and size of the given path, we will need both... */
- path_length = wchar_string_measure ( pb->dir.path, &path_size );
-
- /* add a trailing backslash (windows!) if it is not there... */
- if ( pb->dir.path[ path_length - 1 ] != '\\' )
- {
- /* check if there is space for another character */
- if ( ( path_size + sizeof pb->dir.path [ 0 ] ) >= sizeof pb->dir.path )
- {
- return RC( rcFS, rcDirectory, rcVisiting, rcPath, rcExcessive );
- }
- pb->dir.path[ path_length + 0 ] = '\\';
- pb->dir.path[ path_length + 1 ] = 0;
- ++ path_length;
- path_size += sizeof pb->dir.path[ 0 ];
- pb->dir.length = path_length;
- }
-
- /* check if there is space for 6 more bytes ( '*.*' ) */
- if ( ( path_size + 3 * sizeof pb->dir.path[ 0 ] ) >= sizeof pb->dir.path )
- {
- return RC( rcFS, rcDirectory, rcVisiting, rcPath, rcExcessive );
- }
- /* append '*.*' to make KSysDirEnumInit work under Windows! */
- pb -> dir . path [ path_length + 0 ] = '*';
- pb -> dir . path [ path_length + 1 ] = '.';
- pb -> dir . path [ path_length + 2 ] = '*';
- pb -> dir . path [ path_length + 3 ] = 0;
-
- rc = KSysDirEnumInit ( &listing, pb->dir.path );
- if( rc == 0 )
- {
- const wchar_t *name;
-
- /* truncate the appended '*.*' to visit the entries */
- pb -> dir . path [ path_length ] = 0;
-
- for ( name = KSysDirEnumNext( &listing );
- name != NULL;
- name = KSysDirEnumNext( &listing ) )
- {
- uint32_t type, name_length;
- size_t name_size;
- char temp_utf8_buffer [ MAX_PATH ];
-
- /* measure length and size of the element-name, we will need both... */
- name_length = wchar_string_measure ( name, &name_size );
- /* check if we have enought space for path and element-name */
- if ( path_size + name_size >= sizeof pb->dir.path )
- {
- rc = RC( rcFS, rcDirectory, rcVisiting, rcPath, rcExcessive );
- break;
- }
-
- /* append the element-name to the path */
- wcscpy ( &pb->dir.path[ path_length ], name );
- type = KSysDirFullPathType( pb->dir.path );
- if( type == kptBadPath )
- {
- rc = RC( rcFS, rcDirectory, rcVisiting, rcPath, rcInvalid );
- break;
- }
-
- /* the callback-function expects the name as utf8 !!! */
- wchar_cvt_string_copy ( temp_utf8_buffer, sizeof temp_utf8_buffer,
- name, name_size );
- rc = (*pb->f)( &pb->dir.dad, type, temp_utf8_buffer, pb->data );
- if ( rc != 0 )
- break;
-
- /* if recursive visiting is requested and the element is a directory */
- if ( pb->recurse && ( type & ( kptAlias - 1 ) ) == kptDir )
- {
- /* append the element-name-length temporary to the length of the path */
- pb->dir.length += name_length;
- /* call this function recursive */
- rc = KSysDirVisitDir( pb );
- /* restore the original path-length (for the caller function) */
- pb->dir.length = path_length;
- if ( rc != 0 )
- break;
- }
-
- } /* for () */
-
- KSysDirEnumWhack( &listing );
- }
- return rc;
-}
-
-
-static
-rc_t Enumerate_DriveLetters( const KSysDir *self,
- rc_t ( CC * f ) ( KDirectory *dir, uint32_t type, const char *name, void *data ), void *data )
-{
- rc_t rc = 0;
- DWORD drivebitmask = GetLogicalDrives(); /* each logical drive has its own bit set */
- if ( drivebitmask == 0 )
- rc = translate_file_error( GetLastError(), rcListing );
- else
- {
- uint32_t i, n, mask = 1;
- for ( i = 0; i < 26 && rc == 0; ++i, mask <<= 1 )
- {
- if ( ( drivebitmask & mask ) == mask )
- {
- char drive[ 5 ];
- drive[ 0 ] = 'A' + i;
- drive[ 1 ] = 0;
- rc = f( ( KDirectory * ) self, kptDir, ( const char * )drive, data );
- }
- }
- }
- return rc;
-}
-
-
-static
-rc_t CC KSysDirVisit ( const KSysDir *self, bool recurse,
- rc_t ( CC * f ) ( KDirectory *dir, uint32_t type, const char *name, void *data ), void *data,
- const char *path, va_list args )
-{
- KSysDirVisitData pb;
- rc_t rc = KSysDirMakeSimulatedFSPath( self, rcVisiting, true, pb.dir.path, sizeof pb.dir.path, path, args, true );
- if ( rc == 0 )
- {
- size_t path_size;
- uint32_t path_length;
-
- uint32_t path_type = KSysDirFullPathType( pb.dir.path );
- switch( path_type & ( kptAlias - 1 ) )
- {
- case kptNotFound:
- return RC( rcFS, rcDirectory, rcVisiting, rcPath, rcNotFound );
- case kptBadPath:
- return RC( rcFS, rcDirectory, rcVisiting, rcPath, rcInvalid );
- case kptDir:
- break;
- case kptFakeRoot:
- return Enumerate_DriveLetters( self, f, data );
-
- /* call code to enumerate drives */
- default:
- return RC( rcFS, rcDirectory, rcVisiting, rcPath, rcIncorrect );
- }
-
- path_length = utf16_string_measure( pb.dir.path, &path_size );
- rc = KSysDirInit ( & pb . dir, rcVisiting, self -> root,
- NULL, path_size, path_length,
- self -> dad . read_only ? 0 : 1, 0 );
- if ( rc == 0 )
- {
- pb . f = f;
- pb . data = data;
- pb . recurse = recurse;
- rc = KSysDirVisitDir ( & pb );
- }
- }
- return rc;
-}
-
-/* KSysDirRelativePath
- * makes "path" relative to "root"
- * both "root" and "path" MUST be absolute
- * both "root" and "path" MUST be canonical, i.e. have no "./" or "../" sequences
- * both root and path are in windows-native format!
- */
-static
-rc_t KSysDirRelativePath ( const KSysDir *self, enum RCContext ctx,
- const wchar_t *root, wchar_t *path, size_t path_max )
-{
- size_t psize;
- uint32_t backup, blength_in_chars, dst, diff_from_here;
-
- const wchar_t *r = root + self->root;
- const wchar_t *p = path + self->root;
-
- /* stop gap fix.. not actually comparing the utf16 values correctly */
- for ( ; towlower (*r) == towlower (*p); ++ r, ++ p )
- {
- /* disallow identical paths */
- if ( * r == 0 )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcInvalid );
- }
-
- /* paths are identical up to "r","p"
- if "r" is within a leaf name, then no backup is needed
- by counting every '\\' from "r" to end, obtain backup count */
- for ( backup = 0; * r != 0; ++ r )
- {
- if ( * r == '\\' )
- ++ backup;
- }
-
- /* the number of characters to be inserted */
- blength_in_chars = backup * 3;
-
- /* align "p" to last directory separator */
- if ( p > path ) {
- while ( p [ -1 ] != '\\' ) -- p;
- }
-
- /* the size of the remaining relative path */
- psize = wcslen ( p );
- diff_from_here = ( uint32_t )( p - path );
-
- /* open up space if needed */
- if ( diff_from_here < blength_in_chars )
- {
- /* prevent overflow */
- if ( ( blength_in_chars + psize ) * sizeof( *path ) >= path_max )
- return RC( rcFS, rcDirectory, ctx, rcPath, rcExcessive );
- memmove ( & path[ blength_in_chars ], p, psize * ( sizeof *p ) );
- }
-
- /* insert backup sequences */
- for ( dst = 0; backup > 0; -- backup )
- {
- path [ dst++ ] = '.';
- path [ dst++ ] = '.';
- path [ dst++ ] = '\\';
- }
-
- /* close gap */
- if ( diff_from_here > blength_in_chars )
- wcscpy ( & path [ blength_in_chars ], p );
- path[ blength_in_chars + psize ] = 0;
-
- return 0;
-}
-
-/* KSysDirResolvePath
- * resolves path to an absolute or directory-relative path
- *
- * "absolute" [ IN ] - if non-zero, always give a path starting
- * with '/'. NB - if the directory is chroot'd, the absolute path
- * will still be relative to directory root.
- *
- * "resolved" [ OUT ] and "rsize" [ IN ] - buffer for
- * NUL terminated result path in directory-native character sets
- * the resolved path will be directory relative
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target path. NB - need not exist.
- */
-static
-rc_t CC KSysDirResolvePath ( const KSysDir *self, bool absolute,
- char *resolved, size_t rsize, const char *path, va_list args )
-{
- wchar_t temp [ MAX_PATH ];
- size_t temp_size;
- uint32_t temp_length;
-
- /* convert the utf8-input-parameter path into wchar_t */
- rc_t rc = KSysDirMakePath ( self, rcResolving, true, temp, sizeof temp, path, args );
- if ( rc != 0 )
- return rc;
-
- temp[ 0 ] = tolower( temp[ 0 ] ); /* this is important:
- otherwise the comparison for is_on_same_drive_letter fails
- AND
- KSysDirRelativePath() fails too! */
-
- temp_length = wchar_string_measure ( temp, &temp_size );
- if ( absolute )
- {
- /* test buffer capacity */
- if ( temp_length - self->root >= rsize )
- return RC ( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- else
- {
- /* we are on windows, only if the path has a drive letter and it is the same
- one as in KSysDir itself, we should try to create a relative path */
- wchar_t colon = ':';
- bool is_on_same_drive_letter = ( iswascii ( temp[ 0 ] ) && iswascii ( self->path[ 0 ] ) &&
- ( temp[ 1 ] == colon ) && ( self->path[ 1 ] == colon ) &&
- ( towlower ( temp[ 0 ] ) == towlower ( self->path[ 0 ] ) ) );
- if ( is_on_same_drive_letter )
- {
- rc = KSysDirRelativePath( self, rcResolving, self->path, temp, sizeof temp );
- if ( rc == 0 )
- {
- uint32_t temp_length = wchar_string_measure ( temp, &temp_size );
- if ( temp_length >= rsize )
- return RC ( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- }
- else
- {
- /* treat it as if absolute were requested ( see above ) */
- if ( temp_length - self->root >= rsize )
- return RC ( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- }
-
- if ( rc == 0 )
- {
- uint32_t i;
- /* convert it back to utf8 */
- utf16_cvt_string_copy ( resolved, rsize, temp, temp_size );
-
- /* convert it back to POSIX */
- if ( isalpha ( resolved[ 0 ] ) && resolved[ 1 ] == ':' )
- {
- /* rewrite drive letter */
- resolved[ 1 ] = tolower ( resolved [ 0 ] );
- resolved[ 0 ] = '/';
- }
-
- /* convert backward to forward slashes */
- for ( i = 0; resolved[ i ]; ++ i )
- {
- if ( resolved[ i ] == '\\' )
- resolved[ i ] = '/';
- }
- }
-
- return rc;
-}
-
-/* KSysDirResolveAlias
- * resolves an alias path to its immediate target
- * NB - the resolved path may be yet another alias
- *
- * "alias" [ IN ] - NUL terminated string in directory-native
- * character set denoting an object presumed to be an alias.
- *
- * "resolved" [ OUT ] and "rsize" [ IN ] - buffer for
- * NUL terminated result path in directory-native character set
- */
-static
-rc_t CC KSysDirResolveAlias ( const KSysDir *self, bool absolute,
- char *resolved, size_t rsize,
- const char *alias, va_list args )
-{
- KSysDir temp;
- size_t temp_size;
- uint32_t temp_length, path_type;
- wchar_t * w_resolved;
-
- rc_t rc = KSysDirMakePath( self, rcResolving, true, temp.path, sizeof temp.path, alias, args );
- if ( rc != 0 )
- return rc;
-
- temp_length = wchar_string_measure ( temp.path, &temp_size );
- path_type = KSysDirFullPathType ( temp.path );
- if ( path_type == kptFile || path_type == kptDir )
- {
- /* if the path points to a file or a dir, then there is no alias involved at all */
- if ( temp_size >= rsize )
- {
- return RC ( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- /* we have to convert temp.path back from wchar_t to char ! */
- wchar_cvt_string_copy ( resolved, rsize, temp.path, temp_size );
- return 0;
- }
-
-
- /* trying to attach a .lnk to the path, if it resolves it is a link... */
- if ( temp_size + 10 >= rsize )
- {
- return RC( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- temp.path[ temp_length + 0 ] = '.';
- temp.path[ temp_length + 1 ] = 'l';
- temp.path[ temp_length + 2 ] = 'n';
- temp.path[ temp_length + 3 ] = 'k';
- temp.path[ temp_length + 4 ] = 0;
-
- if ( lnk_file_resolve( temp.path, &w_resolved ) != LNK_RES_ERROR )
- {
- size_t w_size;
- uint32_t w_len;
-
- /* we have to copy the resolved path into temp to use KSysDirCanonPath() */
- w_len = wchar_string_measure ( w_resolved, &w_size );
- if ( w_size > sizeof temp.path )
- {
- free( w_resolved );
- return RC( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- wcscpy( temp.path, w_resolved );
- free( w_resolved );
-
- rc = KSysDirCanonPath( &temp, rcResolving, temp.path, w_len );
- if ( rc == 0 )
- {
- /* the path in full is an absolute path
- if outside of chroot, it's a bad link */
- if (wstrcase_cmp (temp.path, self->root + 1,
- self->path, self->root + 1,self->root + 1) != 0)
- return RC( rcFS, rcDirectory, rcResolving, rcLink, rcInvalid );
-
- /* this is the absolute path length */
- w_len = wchar_string_measure ( temp.path, &w_size );
-
- /* if not requesting absolute, make self relative */
- if( !absolute )
- {
- rc = KSysDirRelativePath( self, rcResolving, self->path,
- temp.path, w_len );
- if ( rc != 0 )
- return rc;
- w_len = wchar_string_measure ( temp.path, &w_size );
- }
- if ( ( size_t ) w_len >= rsize )
- return RC(rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
-
- w_len = wchar_string_measure ( &(temp.path[ self -> root ]), &w_size );
- wchar_cvt_string_copy ( resolved, rsize, &(temp.path[ self -> root ]), w_size );
- }
- }
-
-
-#if 0
- /* NEXT - attach ".lnk" to the path and see if it resolves
- if not, the supplied path simply does not exist */
- if ( ( wcslen( full.path ) + 5 ) >= rsize )
- {
- return RC( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- wcscpy( resolved, full.path );
- wcscat( resolved, L".lnk" );
- refnum = FindFirstFile( resolved, &info );
- if ( refnum == INVALID_HANDLE_VALUE )
- {
- wcscpy( resolved, L"\0" );
- return RC( rcFS, rcDirectory, rcResolving, rcPath, rcNotFound );
- }
- FindClose( refnum );
-
- {
-
- /* get a COM reference to the Explorer. we should be
- able to do this in C with no problem */
- HRESULT rslt = ERROR_INSUFFICIENT_BUFFER;
- IShellLink *shellLink;
- rslt = CoCreateInstance( &IID_IShellLink, 0, CLSCTX_INPROC_SERVER, &IID_IShellLink, &shellLink );
- if( !rslt )
- {
- /* get a file interface that isn't attached to anything */
- IPersistFile *persistFile;
- rslt = shellLink->lpVtbl->QueryInterface( shellLink, &IID_IPersistFile, (void**)&persistFile );
- if( !rslt )
- {
- /* now try to do the thing
- the link name needs to be in Unicode */
- rslt = persistFile->lpVtbl->Load(persistFile, resolved, STGM_READ );
- if( !rslt )
- {
- /* Unicode is no longer necessary */
- rslt = shellLink->lpVtbl->Resolve( shellLink, 0, SLR_NO_UI + SLR_ANY_MATCH );
- if ( !rslt )
- {
- /* read what the path is, i.e. read the shortcut file */
- rslt = shellLink->lpVtbl->GetPath( shellLink, resolved, rsize, &info, 0 );
- if( rslt )
- {
- wcscpy( resolved, L"\0" );
- }
- }
- }
- persistFile->lpVtbl->Release( persistFile );
- }
- shellLink->lpVtbl->Release( shellLink );
- }
- if ( wcslen( resolved ) == 0 )
- {
- return RC( rcFS, rcDirectory, rcResolving, rcPath, rcInvalid );
- }
-
- }
-
- len = wcslen( resolved );
- if( resolved[0] == '/' )
- {
- full.size = 1;
- wcscpy( full.path, resolved );
- }
- else
- {
- wchar_t *f = wcsrchr( full.path, '/' );
- full.size = f - full.path + 1;
- if ( full.size + len >= sizeof full.path )
- {
- return RC( rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
- }
- wcscpy( f, resolved );
- }
- full.root = 0;
-
- rc = KSysDirCanonPath( &full, rcResolving, full.path, len );
- if ( rc == 0 )
- {
- size_t f, s;
-
- f = wchar_string_size (full.path);
- s = wchar_string_size (self->path);
- /* the path in full is an absolute path
- if outside of chroot, it's a bad link */
- if ( wstrcase_cmp (full.path, f, self->path, s, self->root + 1 ) != 0 )
- {
- return RC( rcFS, rcDirectory, rcResolving, rcLink, rcInvalid );
- }
-
- /* this is the absolute path length */
- len = wchar_string_size( &full.path[self->root] );
-
- /* if not requesting absolute, make self relative */
- if( !absolute )
- {
- rc = KSysDirRelativePath( self, rcResolving, self->path, full.path, sizeof full.path /*len*/ );
- if ( rc != 0 )
- return rc;
- len = wchar_string_size(full.path);
- }
- if ( ( size_t ) len >= rsize )
- return RC(rcFS, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
-
- wcscpy ( resolved, & full . path [ self -> root ] );
- }
-#endif
- return rc;
-}
-
-/* KSysDirRename
- * rename an object accessible from directory, replacing
- * any existing target object of the same type
- *
- * "from" [ IN ] - NUL terminated string in directory-native
- * character set denoting existing object
- *
- * "to" [ IN ] - NUL terminated string in directory-native
- * character set denoting existing object
- */
-static
-rc_t CC KSysDirRename ( KSysDir *self, bool force, const char *from, const char *to )
-{
- wchar_t current_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcRenaming, false, current_name, sizeof current_name, from, NULL );
- if ( rc == 0 )
- {
-
- wchar_t new_name[ MAX_PATH ];
- rc = KSysDirMakePath ( self, rcRenaming, false, new_name, sizeof new_name, to, NULL );
- if ( rc == 0 )
- {
- DWORD err = 0;
- uint32_t try = 0;
-
- do
- {
- BOOL success = false;
- if ( force ) {
- DWORD dwFlags = MOVEFILE_REPLACE_EXISTING;
- success = MoveFileEx ( current_name, new_name, dwFlags );
- }
- else {
- success = MoveFileW ( current_name, new_name );
- }
- if ( success )
- {
- rc = 0;
- }
- else
- {
- err = GetLastError();
- switch( err )
- {
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_INVALID_DRIVE:
- return RC ( rcFS, rcDirectory, rcRenaming, rcFile, rcNotFound );
- case ERROR_ACCESS_DENIED:
- try++;
- Sleep( 500 ); /* sleep for a half a second */
- rc = RC ( rcFS, rcDirectory, rcRenaming, rcFile, rcUnauthorized );
- break;
- case ERROR_SHARING_VIOLATION:
- return RC ( rcFS, rcDirectory, rcRenaming, rcFile, rcBusy );
- default:
- return RC ( rcFS, rcDirectory, rcRenaming, rcNoObj, rcUnknown );
- }
- }
- } while ( err == ERROR_ACCESS_DENIED && try < 30 );
- }
- }
- return rc;
-}
-
-
-/* helper function for KSysDirCreateParents() */
-static
-rc_t directory_exists( const wchar_t *path, bool *exists )
-{
- /* try it with CreateFileW() */
- *exists = win_path_exists( path );
- return 0;
-#if 0
- wchar_t temp[ MAX_PATH ];
- WIN32_FIND_DATA find_data;
- HANDLE h_find;
- size_t path_size;
- uint32_t path_length = utf16_string_measure( path, &path_size );
-
- *exists = false;
-
- if ( ( path_size + 10 ) > sizeof temp )
- return RC( rcFS, rcDirectory, rcCreating, rcMemory, rcExhausted );
-
- wcscpy( temp, path );
- if ( temp[ path_length - 1 ] != '\\' )
- temp[ path_length++ ] = '\\';
- temp[ path_length + 0 ] = '*';
- temp[ path_length + 1 ] = '.';
- temp[ path_length + 2 ] = '*';
- temp[ path_length + 3 ] = 0;
-
- h_find = FindFirstFileW( temp, &find_data );
- if ( h_find != INVALID_HANDLE_VALUE )
- {
- *exists = true;
- FindClose( h_find );
- }
-
- return 0;
-#endif
-}
-
-
-static
-rc_t KSysDirRemoveEntry ( wchar_t *path, size_t path_max, bool force );
-
-
-static
-rc_t KSysDirEmptyDir ( wchar_t *path, size_t path_max, bool force )
-{
- rc_t rc;
- KSysDirEnum list;
- size_t path_size;
- uint32_t path_length = wchar_string_measure ( path, &path_size );
-
- if ( ( path_size + 10 ) > path_max )
- return RC( rcFS, rcDirectory, rcListing, rcMemory, rcExhausted );
-
- rc = KSysDirEnumInitAll ( & list, path, path_length );
- if ( rc != 0 )
- {
- rc = ResetRCContext ( rc, rcFS, rcDirectory, rcClearing );
- }
- else
- {
- const wchar_t *leaf;
-
- /* we keep only the appended '\\' for the loop... */
- path_length++;
- path_size += sizeof *path;
-
- for ( leaf = KSysDirEnumNext( &list );
- leaf != NULL;
- leaf = KSysDirEnumNext( &list ) )
- {
- size_t leaf_size;
- uint32_t leaf_length = wchar_string_measure ( leaf, &leaf_size );
- if ( path_size + leaf_size >= path_max )
- {
- rc = RC ( rcFS, rcDirectory, rcClearing, rcPath, rcExcessive );
- break;
- }
-
- /* wcscpy adds termination, so wprintf is safe to call */
- wcscpy ( & path [ path_length ], leaf );
-
- rc = KSysDirRemoveEntry ( path, path_max, force );
- if ( rc != 0 )
- {
- rc = ResetRCContext ( rc, rcFS, rcDirectory, rcClearing );
- break;
- }
- }
- KSysDirEnumWhack ( & list );
- /* restore the original path... */
- path [ path_length - 1 ] = 0;
- }
- return rc;
-}
-
-
-/* KSysDirClearDir
- * remove all directory contents
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target directory
- *
- * "force" [ IN ] - if non-zero and directory entry is a
- * sub-directory, remove recursively
- */
-static
-rc_t CC KSysDirClearDir ( KSysDir *self, bool force, const char *path, va_list args )
-{
- wchar_t dir_name [ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcClearing, false, dir_name, sizeof dir_name, path, args );
- if ( rc == 0 )
- rc = KSysDirEmptyDir ( dir_name, sizeof dir_name, force );
- return rc;
-}
-
-
-/* KSysDirRemove
- * remove an accessible object from its directory
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target object
- *
- * "force" [ IN ] - if non-zero and target is a directory,
- * remove recursively
- */
-static
-rc_t KSysDirRemoveEntry ( wchar_t *path, size_t path_max, bool force )
-{
- if ( !DeleteFileW( path ) )
- {
- DWORD file_error = GetLastError();
-
- switch ( file_error )
- {
- case ERROR_PATH_NOT_FOUND :
- return 0;
-/*
- case ERROR_ACCESS_DENIED :
- !!! Do not use this error code here, it occurs if path is not a file, but
- a directory instead. Handling it here would prevent the remaining code
- from beeing executed !!!
- return RC( rcFS, rcDirectory, rcRemoving, rcDirectory, rcUnauthorized );
-*/
-
- default :
-#if _DEBUGGING && 0
- OUTMSG (( "DeleteFileW returned '%#X'\n", file_error ));
-#endif
- break;
- }
-
- /* we have not been able to delete it as a file,
- we try to delete it as a directory... */
- if ( !RemoveDirectoryW( path ) )
- {
- rc_t rc;
- DWORD error = GetLastError();
-
- /* find out if the reason is that it is not empty and force = true --->
- in this case delete all files and directories in it
- and then try again... */
- switch ( error )
- {
- case ERROR_DIR_NOT_EMPTY :
- if ( force )
- {
- rc = KSysDirEmptyDir ( path, path_max, force );
- if ( rc == 0 )
- {
- if ( !RemoveDirectoryW( path ) )
- {
- rc = RC ( rcFS, rcDirectory, rcRemoving, rcDirectory, rcUnauthorized );
- print_error_for( error, path, "RemoveDirectoryW", rcRemoving, klogErr );
- }
- }
- return rc;
- }
- else
- rc = RC ( rcFS, rcDirectory, rcRemoving, rcDirectory, rcUnauthorized );
- break;
-
- case ERROR_ACCESS_DENIED :
- rc = RC ( rcFS, rcDirectory, rcRemoving, rcDirectory, rcUnauthorized );
- break;
-
- case ERROR_DIRECTORY: /* not a directory */
- /* looks like it was a file after all; report the original error */
- error = file_error;
- print_error_for( file_error, path, "DeleteFileW", rcRemoving, klogInfo);
- return RC ( rcFS, rcDirectory, rcRemoving, rcDirectory, rcUnauthorized );
-
- default :
- rc = RC ( rcFS, rcDirectory, rcCreating, rcNoObj, rcUnknown );
- break;
- }
-
- print_error_for( error, path, "RemoveDirectoryW", rcRemoving, klogInfo);
- return rc;
- }
- }
- return 0;
-}
-
-
-static
-rc_t CC KSysDirRemove ( KSysDir *self, bool force, const char *path, va_list args )
-{
- wchar_t dir_name [ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcRemoving, false, dir_name, sizeof dir_name, path, args );
- if ( rc == 0 )
- rc = KSysDirRemoveEntry ( dir_name, sizeof dir_name, force );
- return rc;
-}
-
-/* KSysDirAccess
- * get access to object
- *
- * "access" [ OUT ] - return parameter for Unix access mode
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target object
- */
-
-#define DEFAULT_WIN_ACCESS 0555
-#define DEFAULT_WRITE_ACCESS 0222
-
-
-/* FromMSDN */
-#define UNIX_EPOCH_IN_WIN 116444736000000000
-#define UINX_TIME_UNITS_IN_WIN 10000000
-static __inline__
-void KTimeToWinTime ( KTime_t unix, LPFILETIME win )
-{
- uint64_t ll = ( ( unix * UINX_TIME_UNITS_IN_WIN ) + UNIX_EPOCH_IN_WIN );
- win->dwLowDateTime = (DWORD)ll;
- win->dwHighDateTime = ll >> 32;
-}
-
-
-static __inline__
-KTime_t WinTimeToKTime ( LPFILETIME win )
-{
- uint64_t ll = (uint64_t)win->dwLowDateTime + ((int64_t)win->dwHighDateTime << 32);
-
-/* DBGMSG(DBG_KFS,DBG_FLAG(DBG_KFS_DIR),("%s %x %x %lx %lx\n", */
-/* __func__,win->dwLowDateTime,win->dwHighDateTime, */
-/* ll,( ll - UNIX_EPOCH_IN_WIN ) / 10000000)); */
-
- /* if its negative, so be it */
- return ( ll - UNIX_EPOCH_IN_WIN ) / UINX_TIME_UNITS_IN_WIN;
-}
-
-
-static __inline
-rc_t get_attributes ( const wchar_t * wpath, uint32_t * access, KTime_t * date )
-{
- WIN32_FIND_DATA fd;
- rc_t rc;
- HANDLE h = FindFirstFile ( wpath, &fd );
- if ( h != INVALID_HANDLE_VALUE )
- {
- if ( access != NULL )
- {
-/* TBD - track user's main group and group Everyone */
- *access = DEFAULT_WIN_ACCESS |
- (((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)
- ? 0 : DEFAULT_WRITE_ACCESS);
- }
- if ( date != NULL )
- {
- *date = WinTimeToKTime ( &fd.ftLastWriteTime );
- }
- FindClose ( h );
- return 0;
- }
-
-/* TBD check values in error */
- if ( access != NULL )
- *access = 0;
- if ( date != NULL )
- *date = 0;
-
- rc = print_error_for( GetLastError(), wpath, "FindFirstFile", rcAccessing, klogErr );
- return rc;
-}
-
-
-static
-rc_t CC KSysDirVAccess ( const KSysDir *self,
- uint32_t *access, const char *path, va_list args )
-{
- wchar_t winpath [ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcAccessing, false, winpath, sizeof winpath, path, args );
- if ( rc == 0 )
- rc = get_attributes ( winpath, access, NULL );
- return rc;
-}
-
-/* KSysDirSetAccess
- * set access to object a la Unix "chmod"
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target object
- *
- * "access" [ IN ] and "mask" [ IN ] - definition of change
- * where "access" contains new bit values and "mask defines
- * which bits should be changed.
- *
- * "recurse" [ IN ] - if non zero and "path" is a directory,
- * apply changes recursively.
- */
-static
-rc_t KSysDirChangeAccess ( char *path, size_t path_max,
- uint32_t access, uint32_t mask, bool recurse );
-
-
-static
-rc_t KSysDirChangeDirAccess ( char *path, size_t path_max,
- uint32_t access, uint32_t mask )
-{
- /*
- KSysDirEnum list;
- rc_t rc = KSysDirEnumInit ( & list, path );
- if ( rc == 0 )
- {
- bool eperm = false;
- size_t path_size = strlen ( path );
- path [ path_size ] = '/';
- if ( ++ path_size == path_max )
- rc = RC(rcFS, rcDirectory, rcUpdating, rcBuffer, rcInsufficient );
- else
- {
- const char *leaf;
- while ( ( leaf = KSysDirEnumNext ( & list ) ) != NULL )
- {
- size_t leaf_size = strlen ( leaf );
- if ( path_size + leaf_size >= path_max )
- {
- rc = RC(rcFS, rcDirectory, rcUpdating, rcBuffer, rcInsufficient );
- break;
- }
-
- strcpy ( & path [ path_size ], leaf );
- rc = KSysDirChangeAccess ( path, path_max, access, mask, 1 );
- if ( rc != 0 )
- {
- if ( GetRCState ( rc ) != rcUnauthorized )
- break;
- eperm = true;
- rc = 0;
- }
- }
-
- path [ path_size - 1 ] = 0;
- }
-
- KSysDirEnumWhack ( & list );
-
- if ( rc == 0 && eperm )
- rc = RC(rcFS, rcDirectory, rcUpdating, rcDirectory, rcUnauthorized );
- }
- return rc;
- */
- return 0;
-}
-
-
-static
-rc_t KSysDirChangeEntryAccess ( char *path, size_t path_max,
- uint32_t access, uint32_t mask, uint32_t st_mode )
-{
-#if 0
- /* keep old bits
- we have no chmod in Windows - leave it blank... */
- access &= mask;
- access |= st_mode & ~ mask;
-
- if ( chmod ( path, access & 07777 ) != 0 )
- switch ( errno )
- {
- case EPERM:
- case EACCES:
- case EROFS:
- return RC(rcFS, rcDirectory, rcUpdating, rcDirectory, rcUnauthorized );
- case ENOTDIR:
- case ELOOP:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcInvalid );
- case ENAMETOOLONG:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcExcessive );
- case ENOENT:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcNotFound );
- case ENOMEM:
- return RC(rcFS, rcDirectory, rcUpdating, rcMemory, rcExhausted );
- default:
- return RC(rcFS, rcDirectory, rcUpdating, rcNoObj, rcUnknown );
- }
-#endif
- return 0;
-}
-
-
-static
-rc_t KSysDirChangeAccess ( char *path, size_t path_max,
- uint32_t access, uint32_t mask, bool recurse )
-{
- /*
- struct stat st;
- if ( stat ( path, & st ) != 0 ) switch ( errno )
- {
- case ENOENT:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcNotFound );
- case ENOTDIR:
- case ELOOP:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcInvalid );
- case ENAMETOOLONG:
- return RC(rcFS, rcDirectory, rcUpdating, rcPath, rcExcessive );
- case EACCES:
- return RC(rcFS, rcDirectory, rcUpdating, rcDirectory, rcUnauthorized );
- case ENOMEM:
- return RC(rcFS, rcDirectory, rcUpdating, rcMemory, rcExhausted );
- default:
- return RC(rcFS, rcDirectory, rcUpdating, rcNoObj, rcUnknown );
- }
-
- if ( recurse && S_ISDIR ( st . st_mode ) )
- {
- rc_t rc;
- uint32_t enable = access & mask;
- if ( enable != 0 )
- {
- rc = KSysDirChangeEntryAccess ( path, path_max,
- access, enable, st . st_mode );
- if ( rc != 0 )
- return rc;
- }
-
- rc = KSysDirChangeDirAccess ( path, path_max, access, mask );
- if ( rc == 0 )
- {
- uint32_t disable = ~ access & mask;
- if ( disable != 0 )
- {
- rc = KSysDirChangeEntryAccess ( path, path_max,
- access, disable, st . st_mode | enable );
- }
- }
- return rc;
- }
-
- return KSysDirChangeEntryAccess ( path, path_max,
- access, mask, st . st_mode );
- */
- return 0;
-}
-
-
-static
-rc_t CC KSysDirSetAccess ( KSysDir *self, bool recurse,
- uint32_t access, uint32_t mask, const char *path, va_list args )
-{
- rc_t rc = 0;
- /*
- char full[MAX_PATH];
- rc_t rc = KSysDirMakePath ( self, rcUpdating, false, full, sizeof full, path, args );
- if ( rc == 0 )
- {
- if ( mask == 0 )
- mask = 07777;
-
- rc = KSysDirChangeAccess ( full, sizeof full,
- access, mask & 07777, recurse );
- }
- */
- return rc;
-}
-
-
-/* make_dir()
- * helper function that encapsulates the OS-specific call
- * to create a directory - the return codes are used by the
- * caller-functions to decide what to do in case of a error...
- * the callers are: KSysDirCreateParents() and KSysDirCreateDir()
- * special on windows: path is wchar_t and we ignore access !!!
- * TBD: translate access into a windows security descriptor...
- * find out the other possible ERROR_* 's produced
- */
-static
-rc_t make_dir ( const wchar_t *path, uint32_t access )
-{
- rc_t rc = 0;
- /* try to create the directory */
- if ( !CreateDirectoryW ( path, NULL ) )
- {
- DWORD error = GetLastError();
- rc = translate_file_error( error, rcCreating );
-/*
- Do not print an error code here, it is valid that this can happen!
- rc = print_error_for( error, path, "CreateDirectoryW", rcCreating, klogErr );
-*/
- }
- return rc;
-}
-
-
-#if OLD_CREATE_PARENTS
-static
-rc_t check_and_make( wchar_t *path, uint32_t access )
-{
- bool exists;
- rc_t rc = directory_exists( path, &exists );
- if ( rc == 0 && !exists )
- {
- rc = make_dir ( path, access );
- }
- return rc;
-}
-#endif
-
-
-/* KSysDirCreateParents
- * creates missing parent directories
- * Windows special: path is wide-char, separator is back-slash,
- * starts with drive-letter...
- */
-static
-rc_t KSysDirCreateParents ( const KSysDir *self, wchar_t *path, uint32_t access, bool strip )
-{
-#if ! OLD_CREATE_PARENTS
- rc_t rc;
- size_t len;
- wchar_t *p, *par = path;
-
- /* if directory is chroot'd, skip past root and slash */
- if ( self -> root != 0 )
- par += self -> root + 1;
- else
- {
- /* skip drive letter */
- if ( path [ 1 ] == ':' )
- par += 2;
- /* skip slashes, network or otherwise */
- while ( par [ 0 ] == '\\' )
- ++ par;
- }
-
- len = wcslen ( par );
-
- if ( ! strip )
- p = par + len;
- else
- {
- p = wcsrchr ( par, '\\' );
- if ( p == NULL )
- return 0;
- len = p - par;
- }
-
- while ( 1 )
- {
- /* crop string */
- p [ 0 ] = 0;
-
- /* try to create directory */
- rc = make_dir ( path, access );
- if ( GetRCState ( rc ) != rcNotFound )
- break;
-
- /* back up some more */
- p = wcsrchr ( par, '\\' );
- if ( p == NULL )
- {
- p = par + wcslen ( par );
- break;
- }
- }
-
- par += len;
- assert ( p != NULL );
-
- /* create directories from here */
- if ( rc == 0 ) while ( p < par )
- {
- p [ 0 ] = '\\';
- rc = make_dir ( path, access );
- if ( rc != 0 || ++ p >= par )
- break;
- p += wcslen ( p );
- }
-
- /* repair stripped path */
- if ( strip )
- par [ 0 ] = '\\';
-
- return rc;
-
-#else
-
- rc_t rc;
- wchar_t *separator = path;
- bool finished;
-
- do
- {
- /* find the next separator */
- separator = wcschr( separator + 1, '\\' );
-
- /* we are finished, if not found */
- finished = (bool)( separator == NULL );
- if ( !finished )
- {
- /* temporary terminate at the separator */
- *separator = 0;
- rc = check_and_make( path, access );
- finished = (bool)( rc != 0 );
- /* put the terminator back in place... */
- *separator = '\\';
- }
- } while ( !finished );
-
- /* finally test and make the whole path... */
- rc = check_and_make( path, access );
-
- return rc;
-#endif
-}
-
-/* KSysDirCreateAlias
- * creates a path alias according to create mode
- *
- * "targ" [ IN ] - NUL terminated string in directory-native
- * character set denoting target object
- *
- * "alias" [ IN ] - NUL terminated string in directory-native
- * character set denoting target alias
- *
- * "access" [ IN ] - standard Unix directory access mode
- * used when "mode" has kcmParents set and alias path does
- * not exist.
- *
- * "mode" [ IN ] - a creation mode ( see explanation above ).
- */
-static
-rc_t CC KSysDirCreateAlias ( KSysDir *self, uint32_t access, KCreateMode mode,
- const char *targ, const char *alias )
-{
- wchar_t w_target[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcCreating, true, w_target, sizeof w_target, targ, NULL );
- if ( rc == 0 )
- {
- wchar_t w_alias[ MAX_PATH ];
- rc = KSysDirMakePath ( self, rcCreating, true, w_alias, sizeof w_alias, alias, NULL );
- if ( rc == 0 )
- {
- bool alias_ok = true;
- if ( ! has_lnk_extension( w_alias ) ) /* lnk_tools.c */
- alias_ok = add_lnk_extension( w_alias, sizeof w_alias ); /* lnk_tools.c */
-
- if ( lnk_file_exists( w_alias ) )
- {
- DeleteFileW( w_alias );
- alias_ok = ( ! lnk_file_exists( w_alias ) );
- }
-
- if ( alias_ok )
- {
- /* if "alias" is relative or "self" is chroot'd,
- "w_alias" must be made relative */
- if ( alias [ 0 ] != '/' || self -> root != 0 )
- {
- rc = KSysDirRelativePath ( self, rcCreating, w_alias, w_target, sizeof w_target );
- if ( rc != 0 )
- return rc;
- }
- if ( win_CreateLink( w_target, w_alias, NULL ) ) /* lnk_tools.c */
- rc = 0;
- else
- rc = translate_file_error( GetLastError (), rcCreating );
- }
- else
- rc = RC ( rcFS, rcDirectory, rcCreating, rcMemory, rcExhausted );
- }
- }
- return rc;
-}
-
-
-/* KSysDirOpenFileRead
- * opens an existing file with read-only access
- *
- * "f" [ OUT ] - return parameter for newly opened file
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- */
-static
-rc_t CC KSysDirOpenFileRead ( const KSysDir *self,
- const KFile **f, const char *path, va_list args )
-{
- wchar_t file_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath( self, rcOpening, false, file_name, sizeof file_name, path, args );
- if ( rc == 0 )
- {
- HANDLE file_handle = CreateFileW( file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( file_handle == INVALID_HANDLE_VALUE )
- {
- rc = print_error_for( GetLastError(), file_name, "CreateFileW", rcOpening, klogInfo );
- }
- else
- {
- char buffer[ MAX_PATH ];
- wchar_2_char( file_name, buffer, sizeof buffer );
- rc = KSysFileMake ( ( KSysFile** ) f, file_handle, buffer, true, false );
- if ( rc != 0 )
- CloseHandle ( file_handle );
- }
- }
- return rc;
-}
-
-/* KSysDirOpenFileWrite
- * opens an existing file with write access
- *
- * "f" [ OUT ] - return parameter for newly opened file
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- *
- * "update" [ IN ] - if non-zero, open in read/write mode
- * otherwise, open in write-only mode
- */
-static
-rc_t CC KSysDirOpenFileWrite ( KSysDir *self,
- KFile **f, bool update, const char *path, va_list args )
-{
- wchar_t file_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcOpening, false, file_name, sizeof file_name, path, args );
- if ( rc == 0 )
- {
- DWORD dwDesiredAccess = update ? GENERIC_READ | GENERIC_WRITE : GENERIC_WRITE;
- HANDLE file_handle = CreateFileW( file_name, dwDesiredAccess, FILE_SHARE_READ, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
-
- if ( file_handle == INVALID_HANDLE_VALUE )
- {
- rc = print_error_for( GetLastError(), file_name, "CreateFileW", rcAccessing, klogErr );
-
- }
- else
- {
- char buffer[ MAX_PATH ];
- wchar_2_char( file_name, buffer, sizeof buffer );
- rc = KSysFileMake ( ( KSysFile** ) f, file_handle, buffer, update, true );
- if ( rc != 0 )
- CloseHandle ( file_handle );
- }
- }
- return rc;
-}
-
-/* KSysDirCreateFile
- * opens a file with write access
- *
- * "f" [ OUT ] - return parameter for newly opened file
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- *
- * "access" [ IN ] - standard Unix access mode, e.g. 0664
- *
- * "update" [ IN ] - if non-zero, open in read/write mode
- * otherwise, open in write-only mode
- *
- * "mode" [ IN ] - a creation mode ( see explanation above ).
- */
-static
-rc_t CC KSysDirCreateFile ( KSysDir *self, KFile **f, bool update,
- uint32_t access, KCreateMode cmode, const char *path_fmt, va_list args )
-{
- wchar_t file_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath( self, rcCreating, true, file_name, sizeof file_name, path_fmt, args );
- if ( rc == 0 )
- {
- HANDLE file_handle;
- DWORD dwDesiredAccess = update ? GENERIC_READ | GENERIC_WRITE : GENERIC_WRITE;
- DWORD dwCreationDisposition = CREATE_ALWAYS;
- DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
- DWORD dwShareMode = FILE_SHARE_READ;
-
- switch ( cmode & kcmValueMask )
- {
- case kcmOpen : /* open if it exists, create if it does not exist */
- dwCreationDisposition = OPEN_ALWAYS;
- break;
-
- case kcmInit : /* always create, if it already exists truncate to zero */
- dwCreationDisposition = CREATE_ALWAYS;
- break;
-
- case kcmCreate : /* create and open only if does not already exist */
- dwCreationDisposition = CREATE_NEW;
- break;
- case kcmSharedAppend :
- dwCreationDisposition = OPEN_ALWAYS;
- dwDesiredAccess = FILE_APPEND_DATA;
- dwFlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
- dwShareMode |= FILE_SHARE_WRITE;
- break;
- }
-
- file_handle = CreateFileW ( file_name, dwDesiredAccess, dwShareMode,
- NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL );
- while ( file_handle == INVALID_HANDLE_VALUE )
- {
- DWORD error;
-
- if ( ( cmode & kcmParents ) != 0 )
- {
- /* maybe there were missing parent directories */
- uint32_t dir_access = access |
- ( ( access & 0444 ) >> 2 ) | ( ( access & 0222 ) >> 1 );
- KSysDirCreateParents ( self, file_name, dir_access, true );
-
- /* try creating the file again */
- file_handle = CreateFileW ( file_name, dwDesiredAccess, dwShareMode,
- NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL );
- if ( file_handle != INVALID_HANDLE_VALUE )
- break;
- }
-
- error = GetLastError();
- rc = translate_file_error( error, rcCreating );
-
- /* disabled 12/12/2012 : it prints an error message, if vdb tries to open
- the same reference-object twice via http. The lock-file for the 2nd try
- does already exist. This is not an error, just a condition. */
-
- /*
- PLOGERR ( klogErr,
- ( klogErr, rc, "error CreateFileW - $(E) - $(C)",
- "E=%!,C=%u", error, error ) );
- */
-
- /* Unix code has a special case when creating an empty file, which is
- to say, creating a directory entry without needing to write to file */
- return rc;
- }
-
- {
- char buffer[ MAX_PATH ];
- char path[4096];
- int size = ( args == NULL) ?
- snprintf ( path, sizeof path, "%s", path_fmt) :
- vsnprintf ( path, sizeof path, path_fmt, args );
- if ( size < 0 || size >= ( int ) sizeof path )
- rc = RC ( rcFS, rcFile, rcCreating, rcPath, rcExcessive );
- else
- {
- wchar_2_char( file_name, buffer, sizeof buffer );
- rc = KSysFileMake ( ( KSysFile** ) f, file_handle, path, update, true );
- }
- if ( rc != 0 )
- CloseHandle ( file_handle );
- }
- }
- return rc;
-}
-
-/* KSysDirFileSize
- * returns size in bytes of target file
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- *
- * "size" [ OUT ] - return parameter for file size
- */
-static
-rc_t CC KSysDirFileSize ( const KSysDir *self,
- uint64_t *size, const char *path, va_list args )
-{
- wchar_t file_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath( self, rcAccessing, false, file_name, sizeof file_name, path, args );
- if ( rc == 0 )
- {
- WIN32_FILE_ATTRIBUTE_DATA file_data;
- if ( GetFileAttributesEx ( file_name, GetFileExInfoStandard, &file_data ) )
- {
- *size = file_data.nFileSizeHigh;
- *size <<= 32;
- *size |= file_data.nFileSizeLow;
- }
- else
- {
- rc = print_error_for( GetLastError(), file_name, "GetFileAttributesEx", rcAccessing, klogErr );
- }
- }
- return rc;
-}
-
-/* KSysDirSetFileSize
- * sets size in bytes of target file
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- *
- * "size" [ IN ] - new file size
- */
-static
-rc_t CC KSysDirSetFileSize ( KSysDir *self,
- uint64_t size, const char *path, va_list args )
-{
- wchar_t file_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcUpdating, false, file_name, sizeof file_name, path, args );
- if ( rc == 0 )
- {
- HANDLE file_handle = CreateFileW( file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( file_handle != INVALID_HANDLE_VALUE )
- {
- DWORD file_pos_low, file_pos_high, file_set_res;
-
- file_pos_low = (DWORD)( size & 0xFFFFFFFF );
- size >>= 32;
- file_pos_high = (DWORD)( size & 0xFFFFFFFF );
- file_set_res = SetFilePointer ( file_handle, file_pos_low, (PLONG)&file_pos_high, FILE_BEGIN );
- if ( file_set_res != INVALID_SET_FILE_POINTER )
- {
- if ( SetEndOfFile ( file_handle ) )
- rc = 0; /* success !!! */
- else
- rc = translate_file_error( GetLastError(), rcUpdating );
- }
- CloseHandle ( file_handle );
- }
- else
- {
- rc = print_error_for( GetLastError(), file_name, "CreateFileW", rcUpdating, klogErr );
- }
- }
- return rc;
-}
-
-/* KSysDirOpenDirRead
- * KSysDirOpenDirUpdate
- * opens a sub-directory
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target directory
- *
- * "chroot" [ IN ] - if non-zero, the new directory becomes
- * chroot'd and will interpret paths beginning with '/'
- * relative to itself.
- */
-static
-rc_t CC KSysDirOpenDirRead ( const KSysDir *self,
- const KDirectory **subp, bool chroot, const char *path, va_list args )
-{
- wchar_t dir_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcOpening, true, dir_name, sizeof dir_name, path, args );
- if ( rc == 0 )
- {
- int t;
- KSysDir *sub;
-
- size_t dir_size;
- uint32_t dir_length = utf16_string_measure( dir_name, &dir_size );
- uint32_t length_org = dir_length;
- while ( dir_length > 0 && dir_name [ dir_length - 1 ] == '/' )
- dir_name [ -- dir_length ] = 0;
- if ( dir_length != length_org )
- dir_length = utf16_string_measure( dir_name, &dir_size );
-
- t = KSysDirFullPathType ( dir_name ) & ( kptAlias - 1 );
- if ( t == kptNotFound )
- return RC ( rcFS, rcDirectory, rcOpening, rcPath, rcNotFound );
- if ( t != kptDir )
- return RC(rcFS, rcDirectory, rcOpening, rcPath, rcIncorrect );
-
- sub = KSysDirMake ( dir_size );
- if ( sub == NULL )
- rc = RC(rcFS, rcDirectory, rcOpening, rcMemory, rcExhausted );
- else
- {
- rc = KSysDirInit ( sub, rcOpening, self -> root, dir_name,
- dir_size, dir_length, false, chroot );
- if ( rc == 0 )
- {
- * subp = & sub -> dad;
- return 0;
- }
-
- free ( sub );
- }
- }
- return rc;
-}
-
-static
-rc_t CC KSysDirOpenDirUpdate ( KSysDir *self,
- KDirectory **subp, bool chroot, const char *path, va_list args )
-{
- wchar_t dir_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcOpening, true, dir_name, sizeof dir_name, path, args );
- if ( rc == 0 )
- {
- KSysDir *sub;
-
- size_t dir_size;
- uint32_t dir_length = utf16_string_measure( dir_name, &dir_size );
- uint32_t length_org = dir_length;
- while ( dir_length > 0 && dir_name [ dir_length - 1 ] == '/' )
- dir_name [ -- dir_length ] = 0;
- if ( dir_length != length_org )
- dir_length = utf16_string_measure( dir_name, &dir_size );
-
- switch ( KSysDirFullPathType ( dir_name ) )
- {
- case kptNotFound:
- return RC( rcFS, rcDirectory, rcOpening, rcPath, rcNotFound );
- case kptBadPath:
- return RC( rcFS, rcDirectory, rcOpening, rcPath, rcInvalid );
- case kptDir:
- case kptDir | kptAlias:
- break;
- default:
- return RC( rcFS, rcDirectory, rcOpening, rcPath, rcIncorrect );
- }
-
- sub = KSysDirMake ( dir_size );
- if ( sub == NULL )
- rc = RC( rcFS, rcDirectory, rcOpening, rcMemory, rcExhausted );
- else
- {
- rc = KSysDirInit ( sub, rcOpening, self -> root, dir_name,
- dir_size, dir_length, true, chroot );
- if ( rc == 0 )
- {
- * subp = & sub -> dad;
- return 0;
- }
-
- free ( sub );
- }
- }
- return rc;
-}
-
-/* KSysDirCreateDir
- * create a sub-directory
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target directory
- *
- * "access" [ IN ] - standard Unix directory permissions
- *
- * "mode" [ IN ] - a creation mode ( see explanation above ).
- */
-static
-rc_t CC KSysDirCreateDir ( KSysDir *self,
- uint32_t access, KCreateMode mode, const char *path, va_list args )
-{
- wchar_t dir_name[ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcCreating, true, dir_name, sizeof dir_name, path, args );
- if ( rc == 0 )
- {
- if ( ( mode & kcmValueMask ) == kcmCreate )
- {
- switch ( KSysDirFullPathType ( dir_name ) )
- {
- case kptNotFound:
- break;
- case kptBadPath:
- return RC(rcFS, rcDirectory, rcCreating, rcPath, rcInvalid );
- case kptDir:
- return RC(rcFS, rcDirectory, rcCreating, rcDirectory, rcExists );
- default:
- return RC(rcFS, rcDirectory, rcCreating, rcPath, rcIncorrect );
- }
- }
- rc = make_dir ( dir_name, access );
- if ( rc != 0 )
- {
- switch ( GetRCState ( rc ) )
- {
- case rcExists:
- rc = 0;
- if ( ( mode & kcmValueMask ) == kcmInit )
- rc = KSysDirEmptyDir ( dir_name, sizeof dir_name, 1 );
- break;
- case rcNotFound:
- if ( ( mode & kcmParents ) != 0 )
- rc = KSysDirCreateParents ( self, dir_name, access, false );
- break;
- }
- }
- }
- return rc;
-}
-
-/* KSysDirDate
- * get access to object
- *
- * "date" [ OUT ] - return parameter for Unix access mode
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target object
- */
-static
-rc_t CC KSysDirVDate ( const KSysDir *self,
- KTime_t * date, const char *path, va_list args )
-{
- wchar_t full [ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcAccessing, false, full, sizeof full, path, args );
- if ( rc == 0 )
- {
- rc = get_attributes ( full, NULL, date );
- }
- return rc;
-}
-
-
-static
-rc_t change_item_date( wchar_t *path, LPFILETIME win_time, bool dir_flag )
-{
- rc_t rc;
- HANDLE file_handle;
-
- if ( dir_flag )
- file_handle = CreateFileW( path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
- else
- file_handle = CreateFileW( path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( file_handle == INVALID_HANDLE_VALUE )
- {
- rc = print_error_for( GetLastError(), path, "CreateFileW", rcUpdating, klogErr );
- }
- else
- {
- if ( SetFileTime ( file_handle, NULL, NULL, win_time ) )
- {
- rc = 0;
- }
- else
- {
- rc = print_error_for( GetLastError(), path, "SetFileTime", rcUpdating, klogErr );
- }
- CloseHandle ( file_handle );
- }
-
- return rc;
-}
-
-
-static
-rc_t change_dir_date( wchar_t *path, size_t path_max, LPFILETIME win_time, bool recurse )
-{
- KSysDirEnum list;
- const wchar_t *leaf;
- size_t path_size;
- uint32_t path_length;
-
- rc_t rc = change_item_date( path, win_time, true );
- if ( rc != 0 || !recurse )
- return rc;
-
- path_length = wchar_string_measure ( path, &path_size );
- if ( ( path_size + 10 ) > path_max )
- return RC( rcFS, rcDirectory, rcListing, rcMemory, rcExhausted );
-
- rc = KSysDirEnumInitAll ( & list, path, path_length );
- if ( rc != 0 )
- return ResetRCContext ( rc, rcFS, rcDirectory, rcUpdating );
-
- /* we keep only the appended '\\' for the loop... */
- path_length++;
- path_size += sizeof *path;
-
- for ( leaf = KSysDirEnumNext( &list );
- leaf != NULL && rc == 0;
- leaf = KSysDirEnumNext( &list ) )
- {
- size_t leaf_size;
- int32_t path_type;
- uint32_t leaf_length = wchar_string_measure ( leaf, &leaf_size );
- if ( path_size + leaf_size >= path_max )
- rc = RC ( rcFS, rcDirectory, rcUpdating, rcPath, rcExcessive );
- else
- {
-
- /* wcscpy adds termination, so wprintf is safe to call */
- wcscpy ( & path [ path_length ], leaf );
-
- path_type = KSysDirFullPathType ( path );
- switch( path_type )
- {
- case kptFile : rc = change_item_date( path, win_time, false );
- break;
- case kptDir : rc = change_dir_date( path, path_max, win_time, true );
- break;
- }
- }
- }
-
- KSysDirEnumWhack ( & list );
- /* restore the original path... */
- path [ path_length - 1 ] = 0;
-
- return rc;
-}
-
-
-static
-rc_t KSysDirChangeDate ( wchar_t *path, size_t path_max,
- KTime_t date, bool recurse )
-{
- FILETIME win_time;
- int32_t path_type;
- rc_t rc;
-
- KTimeToWinTime ( date, &win_time );
- path_type = KSysDirFullPathType ( path );
- switch( path_type )
- {
- case kptFile : rc = change_item_date( path, &win_time, false );
- break;
-
- case kptDir : rc = change_dir_date( path, path_max, &win_time, recurse );
- break;
-
- default : rc = RC( rcFS, rcDirectory, rcUpdating, rcNoObj, rcUnsupported );
- break;
- }
- return rc;
-}
-
-
-/*
- struct stat st;
- struct utimbuf u;
-
- if ( stat ( path, & st ) != 0 ) switch ( errno )
- {
- case ENOENT:
- return RC ( rcFS, rcDirectory, rcUpdating, rcPath, rcNotFound );
- case ENOTDIR:
- case ELOOP:
- return RC ( rcFS, rcDirectory, rcUpdating, rcPath, rcInvalid );
- case ENAMETOOLONG:
- return RC ( rcFS, rcDirectory, rcUpdating, rcPath, rcExcessive );
- case EACCES:
- return RC ( rcFS, rcDirectory, rcUpdating, rcDirectory, rcUnauthorized );
- case ENOMEM:
- return RC ( rcFS, rcDirectory, rcUpdating, rcMemory, rcExhausted );
- default:
- return RC ( rcFS, rcDirectory, rcUpdating, rcNoObj, rcUnknown );
- }
- u . actime = u . modtime = date;
-
- if ( recurse && S_ISDIR ( st . st_mode ) )
- {
- rc_t rc;
-
- rc = KSysDirChangeEntryDate ( path, path_max, & u );
- if ( rc != 0 )
- return rc;
-
- rc = KSysDirChangeDirDate ( path, path_max, date );
- if ( rc == 0 )
- {
- rc = KSysDirChangeEntryDate ( path, path_max, & u );
- }
- return rc;
- }
-
- return KSysDirChangeEntryDate ( path, path_max, & u );
-*/
-
-static
-rc_t CC KSysDirVSetDate ( KSysDir * self, bool recurse,
- KTime_t date, const char *path, va_list args )
-{
- wchar_t full [ MAX_PATH ];
- rc_t rc = KSysDirMakePath ( self, rcUpdating, false, full, sizeof full, path, args );
- if ( rc == 0 )
- {
- rc = KSysDirChangeDate ( full, sizeof full, date, recurse );
- }
- return rc;
-}
-
-static
-KSysDir *CC KSysDirGetSysdir ( const KSysDir *cself )
-{
- return ( KSysDir* ) cself;
-}
-
-static KDirectory_vt_v1 vtKSysDir =
-{
- /* version 1.0 */
- 1, 1,
-
- /* start minor version 0 methods*/
- KSysDirDestroy,
- KSysDirList,
-
- /* the following two messages map to the same method, requiring type casting */
- ( rc_t ( CC * ) ( const KSysDir*, bool,
- rc_t ( CC * ) ( const KDirectory*, uint32_t, const char*, void* ), void*,
- const char*, va_list ) ) KSysDirVisit,
- ( rc_t ( CC * ) ( KSysDir*, bool,
- rc_t ( CC * ) ( KDirectory*, uint32_t, const char*, void* ), void*,
- const char*, va_list ) ) KSysDirVisit,
-
- KSysDirPathType,
- KSysDirResolvePath,
- KSysDirResolveAlias,
- KSysDirRename,
- KSysDirRemove,
- KSysDirClearDir,
- KSysDirVAccess,
- KSysDirSetAccess,
- KSysDirCreateAlias,
- KSysDirOpenFileRead,
- KSysDirOpenFileWrite,
- KSysDirCreateFile,
- KSysDirFileSize,
- KSysDirSetFileSize,
- KSysDirOpenDirRead,
- KSysDirOpenDirUpdate,
- KSysDirCreateDir,
- NULL, /* we don't track files*/
- /* end minor version 0 methods*/
-
- /* start minor version 1 methods*/
- KSysDirVDate,
- KSysDirVSetDate,
- KSysDirGetSysdir
- /* end minor version 1 methods*/
-};
-
-/* KSysDirInit
- */
-#if TRACK_REFERENCES
-static
-const char *convert_wide_path ( const wchar_t *path, const size_t path_size )
-{
- /* copy wide string to static */
- static char static_path [ MAX_PATH ];
- wchar_cvt_string_copy ( static_path, sizeof static_path, path, path_size );
-
- return static_path;
-}
-#else
-#define convert_wide_path( path, path_size ) "ignore"
-#endif
-
-static
-rc_t KSysDirInit ( KSysDir *self, enum RCContext ctx, uint32_t dad_root,
- const wchar_t *path, size_t path_size, uint32_t path_length,
- bool update, bool chroot )
-{
- rc_t rc;
- if ( path == NULL )
- {
- rc = KDirectoryInit( &self->dad, (const KDirectory_vt*)&vtKSysDir,
- "KSysDir", NULL, update );
- }
- else
- {
- rc = KDirectoryInit( &self->dad, (const KDirectory_vt*)&vtKSysDir,
- "KSysDir", convert_wide_path ( path, path_size ), update );
- }
-
- if ( rc != 0 )
- {
- return ResetRCContext ( rc, rcFS, rcDirectory, ctx );
- }
-
- if ( path != NULL )
- {
- memcpy( self->path, path, path_size );
- }
-
- self->root = chroot ? path_length : dad_root;
- self->length = path_length + 1;
- self->path[ path_length ] = '\\';
- self->path[ path_length + 1 ] = 0;
- return 0;
-}
-
-
-/* MakeFromRealPath
- * creates a KDirectory from a Windows path
- */
-rc_t KDirectoryMakeFromRealPath ( KDirectory **dirp, const wchar_t *real, bool update, bool chroot )
-{
- rc_t rc;
- size_t size;
- uint32_t length = wchar_string_measure ( real, & size );
- if ( length + 4 > MAX_PATH )
- rc = RC ( rcFS, rcDirectory, rcCreating, rcPath, rcExcessive );
- else
- {
- KSysDir *dir = KSysDirMake ( size );
- if ( dir == NULL )
- rc = RC ( rcFS, rcDirectory, rcAccessing, rcMemory, rcExhausted );
- else
- {
- rc = KSysDirInit ( dir, rcAccessing, 0, real, size, length, update, chroot );
- if ( rc == 0 )
- {
- * dirp = & dir -> dad;
- return 0;
- }
- KSysDirDestroy ( dir );
- }
- }
-
- * dirp = NULL;
- return rc;
-}
-
-/* KDirectoryNativeDir
- * returns a native file-system directory node reference
- * the directory root will be "/" and set to the native
- * idea of current working directory
- *
- * NB - the returned reference will be non-const, allowing
- * modification operations to be attempted. these operations
- * may still fail if the underlying FS disallows them.
- *
- * "dir" [ OUT ] - return parameter for native directory
- */
-extern rc_t CC ReportCWD ( const ReportFuncs *f, uint32_t indent );
-extern rc_t CC ReportRedirect ( KWrtHandler* handler,
- const char* filename, bool* to_file, bool finalize );
-
-LIB_EXPORT rc_t CC KDirectoryNativeDir ( KDirectory **dirp )
-{
- rc_t rc;
-
- static bool latch;
- if ( ! latch )
- {
- ReportInitKFS ( ReportCWD, ReportRedirect );
- latch = true;
- }
-
- if ( dirp == NULL )
- rc = RC ( rcFS, rcDirectory, rcAccessing, rcParam, rcNull );
- else
- {
- wchar_t wd [ MAX_PATH ];
- DWORD error;
- DWORD wd_len = GetCurrentDirectoryW ( sizeof wd / sizeof wd [ 0 ], wd );
- if ( wd_len != 0 )
- return KDirectoryMakeFromRealPath ( dirp, wd, true, false );
-
- error = GetLastError();
- switch ( error )
- {
- case ERROR_ACCESS_DENIED:
- rc = RC ( rcFS, rcDirectory, rcAccessing, rcDirectory, rcUnauthorized );
- break;
- default:
- rc = RC ( rcFS, rcDirectory, rcAccessing, rcNoObj, rcUnknown );
- }
- PLOGERR ( klogErr,
- ( klogErr, rc, "error GetCurrentDirectoryW - $(E) - $(C)",
- "E=%!,C=%u", error, error ) );
-
- * dirp = NULL;
- }
-
- return rc;
-}
-
-
-/* RealPath
- * exposes functionality of system directory
- */
-LIB_EXPORT rc_t CC KSysDirRealPath ( struct KSysDir const *self,
- char *real, size_t bsize, const char *path, ... )
-{
- rc_t rc;
- va_list args;
-
- va_start ( args, path );
- rc = KSysDirVRealPath ( self, real, bsize, path, args );
- va_end ( args );
-
- return rc;
-}
-
-LIB_EXPORT rc_t CC KSysDirVRealPath ( struct KSysDir const *self,
- char *real, size_t bsize, const char *path, va_list args )
-{
- /* Windows is ... challenged when it comes to answering
- this question. What is needed is to 1) convert the path
- to a Windows-style wchar path, then 2) resolve each of
- its components, etc. to come up with a real path, then
- 3) rewrite the path as a UTF-8 POSIX path */
- return KSysDirResolvePath ( self, true, real, bsize, path, args );
-}
diff --git a/libs/kfs/win/sysdll.c b/libs/kfs/win/sysdll.c
deleted file mode 100644
index bd75027..0000000
--- a/libs/kfs/win/sysdll.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _WIN32_WINNT /* This file requires OS newer than Windows 2000 */
-# define _WIN32_WINNT 0x0501
-#endif
-
-#include <kfs/extern.h>
-
-#define TRACK_REFERENCES 0
-
-#include "va_copy.h"
-#include "sysdir-priv.h"
-
-#include <kfs/dyload.h>
-#include <kfs/directory.h>
-#include <kfs/kfs-priv.h>
-#include <klib/refcount.h>
-#include <klib/vector.h>
-#include <klib/text.h>
-#include <klib/out.h>
-#include <klib/log.h>
-#include <klib/status.h>
-#include <klib/debug.h>
-#include <klib/rc.h>
-#include <os-native.h>
-#include <sysalloc.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <WINDOWS.H>
-
-#define ALWAYS_ADD_EXE 1
-
-
-
-/*--------------------------------------------------------------------------
- * WString
- */
-typedef struct WString WString;
-struct WString
-{
- const wchar_t *addr;
- size_t size;
- uint32_t len;
-};
-
-#define WStringInit( s, val, sz, length ) \
- StringInit ( s, val, sz, length )
-
-#define WStringInitCString( s, cstr ) \
- ( void ) ( ( s ) -> len = ( uint32_t )( wcslen ( ( s ) -> addr = ( cstr ) ) ), \
- ( s ) -> size = ( ( size_t ) ( s ) -> len * sizeof ( wchar_t ) ) )
-
-#define CONST_WSTRING( s, val ) \
- WStringInitCString ( s, L ## val )
-
-static
-int64_t WStringCaseCompare ( const WString *a, const WString *b )
-{
- int64_t diff;
-
- uint32_t min_len = a -> len;
- if ( a -> len > b -> len )
- min_len = b -> len;
-
- diff = _wcsnicmp ( a -> addr, b -> addr, min_len );
- if ( diff == 0 )
- diff = ( int64_t ) a -> len - ( int64_t ) b -> len;
-
- return diff;
-}
-
-
-/*--------------------------------------------------------------------------
- * KDirectory
- */
-static
-void CC KDirRefRelease ( void *item, void *ignore )
-{
- KDirectoryRelease ( ( const void* ) item );
-}
-
-/*--------------------------------------------------------------------------
- * KDyld
- * dynamic library loader
- *
- * maintains cache of libraries it has opened while they remain open
- * such that subsequent requests for an open library will return a
- * new reference to the existing library.
- */
-struct KDyld
-{
- Vector search;
- KRefcount refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KDyldWhack ( KDyld *self )
-{
- KRefcountWhack ( & self -> refcount, "KDyld" );
-
- VectorWhack ( & self -> search, KDirRefRelease, NULL );
- free ( self );
-
- return 0;
-}
-
-
-/* Make
- * create a dynamic loader object
- *
- * "dl" [ OUT ] - return parameter for loader
- */
-LIB_EXPORT rc_t CC KDyldMake ( KDyld **dlp )
-{
- rc_t rc;
-
- if ( dlp == NULL )
- rc = RC ( rcFS, rcDylib, rcConstructing, rcParam, rcNull );
- else
- {
- KDyld *dl = malloc ( sizeof * dl );
- if ( dl == NULL )
- rc = RC ( rcFS, rcDylib, rcConstructing, rcMemory, rcExhausted );
- else
- {
- VectorInit ( & dl -> search, 1, 8 );
- KRefcountInit ( & dl -> refcount, 1, "KDyld", "make", "dl" );
-
- * dlp = dl;
- return 0;
- }
-
- * dlp = NULL;
- }
-
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KDyldAddRef ( const KDyld *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAdd ( & self -> refcount, "KDyld" ) )
- {
- case krefLimit:
- return RC ( rcFS, rcDylib, rcAttaching, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-LIB_EXPORT rc_t CC KDyldRelease ( const KDyld *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDrop ( & self -> refcount, "KDyld" ) )
- {
- case krefWhack:
- return KDyldWhack ( ( KDyld* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-
-/* Attach
- * Sever
- */
-static
-KDyld *KDyldAttach ( const KDyld *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAddDep ( & self -> refcount, "KDyld" ) )
- {
- case krefLimit:
- return NULL;
- }
- }
- return ( KDyld* ) self;
-}
-
-static
-rc_t KDyldSever ( const KDyld *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDropDep ( & self -> refcount, "KDyld" ) )
- {
- case krefWhack:
- return KDyldWhack ( ( KDyld* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-
-/* AddSearchPath
- * add a search path to loader for locating library files
- */
-LIB_EXPORT rc_t CC KDyldVAddSearchPath ( KDyld *self, const char *path, va_list args )
-{
- rc_t rc;
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcUpdating, rcSelf, rcNull );
- else
- {
- KDirectory *wd;
- rc = KDirectoryNativeDir ( & wd );
- if ( rc == 0 )
- {
- const KDirectory *dir;
- rc = KDirectoryVOpenDirRead ( wd, & dir, false, path, args );
- if ( rc == 0 )
- {
- rc = VectorAppend ( & self -> search, NULL, dir );
- if ( rc != 0 )
- KDirectoryRelease ( dir );
- }
-
- KDirectoryRelease ( wd );
- }
- }
- return rc;
-}
-
-LIB_EXPORT rc_t CC KDyldAddSearchPath ( KDyld *self, const char *path, ... )
-{
- rc_t rc;
- va_list args;
-
- va_start ( args, path );
- rc = KDyldVAddSearchPath ( self, path, args );
- va_end ( args );
-
- return rc;
-}
-
-static
-void KDyldForEach ( const KDyld *self,
- void ( CC * f ) ( const KDirectory *dir, void *data ), void *data )
-{
- VectorForEach ( & self -> search, false,
- ( void ( CC * ) ( void*, void* ) ) f, data );
-}
-
-
-/* HomeDirectory
- * returns a KDirectory where the binary for a given function is located
- *
- * "dir" [ OUT ] - return paraeter for home directory, if found
- *
- * "func" [ IN ] - function pointer within binary to be located
- */
-LIB_EXPORT rc_t CC KDyldHomeDirectory ( const KDyld *self, const KDirectory **dir, fptr_t func )
-{
- rc_t rc;
-
- if ( dir == NULL )
- rc = RC ( rcFS, rcDylib, rcSearching, rcParam, rcNull );
- else
- {
- * dir = NULL;
-
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcSearching, rcSelf, rcNull );
- else if ( func == NULL )
- rc = RC ( rcFS, rcDylib, rcSearching, rcFunction, rcNull );
- else
- {
- HMODULE h;
- /* casting a function pointer to a string pointer because the Windows API
- * allows a name or an address within to be passed in but doesn't provide
- * a type safe way to do this */
- BOOL success = GetModuleHandleEx ( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
- | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- ( const TCHAR * )func, & h );
- if ( success )
- {
- wchar_t fname [ MAX_PATH ];
- DWORD name_len = GetModuleFileNameW ( h, fname, ( DWORD ) sizeof fname / sizeof fname [ 0 ] );
- if ( name_len >= sizeof fname / sizeof fname [ 0 ] )
- rc = RC ( rcFS, rcDylib, rcSearching, rcPath, rcExcessive );
- else
- {
- /* trim off module name */
- while ( name_len > 0 )
- {
- if ( fname [ -- name_len ] == '\\' )
- {
- fname [ name_len ] = 0;
- break;
- }
- }
-
- /* now use directory path */
- rc = KDirectoryMakeFromRealPath ( ( KDirectory** ) dir, fname, false, false );
- }
- }
- }
- }
-
- return rc;
-}
-
-
-/*--------------------------------------------------------------------------
- * KDylib
- * Windows dynamic library
- */
-struct KDylib
-{
- HMODULE handle;
- WString path;
- KRefcount refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KDylibWhack ( KDylib *self )
-{
- KRefcountWhack ( & self -> refcount, "KDylib" );
-
- /* try to close library */
- if ( !FreeLibrary( self -> handle ) )
- {
- /* report error */
-/* const char *msg = dlerror (); */
- rc_t rc = RC ( rcFS, rcDylib, rcClosing, rcNoObj, rcUnknown );
-/* LOGERR ( klogInt, rc, msg );
- ( void ) msg; */
- return rc;
- }
-
- free ( self );
- return 0;
-}
-
-
-/* Make
- */
-static
-rc_t KDylibMake ( KDylib **libp, const WString *path )
-{
- wchar_t *cpy;
- KDylib *lib = malloc ( sizeof * lib + path -> size + 4 );
- if ( lib == NULL )
- return RC ( rcFS, rcDylib, rcConstructing, rcMemory, rcExhausted );
-
- cpy = ( wchar_t* ) ( lib + 1 );
- lib -> handle = NULL;
-
- memcpy ( cpy, path -> addr, path -> size );
- cpy [ path -> len ] = 0;
-
- WStringInit ( & lib -> path, cpy, path -> size, path -> len );
-
- KRefcountInit ( & lib -> refcount, 1, "KDylib", "make", "WinDLL" );
-
- * libp = lib;
- return 0;
-}
-
-/* SetLogging
- */
-static
-rc_t KDylibSetLogging ( const KDylib *self )
-{
- rc_t ( CC * set_formatter ) ( KFmtWriter writer, KLogFmtFlags flags, void *data );
- rc_t ( CC * set_writer ) ( KWrtWriter writer, void *data );
-
- /* set the current logging level */
- rc_t ( CC * set_level ) ( KLogLevel lvl ) = ( void* ) GetProcAddress ( self -> handle, "KLogLevelSet" );
- if ( set_level != NULL )
- {
- KLogLevel lvl = KLogLevelGet ();
- ( * set_level ) ( lvl );
- }
-
- /* determine current library logging */
- set_writer = ( void* ) GetProcAddress ( self -> handle, "KOutHandlerSet" );
- if ( set_writer != NULL )
- {
- const KWrtHandler* handler = KOutHandlerGet ();
- ( * set_writer ) ( handler -> writer, handler -> data );
- }
-
- set_formatter = ( void* ) GetProcAddress ( self -> handle, "KLogLibFmtHandlerSet" );
- if ( set_formatter != NULL )
- {
- KLogFmtFlags flags = KLogLibFmtFlagsGet ();
- const KFmtHandler* fmt_handler = KLogFmtHandlerGet ();
- ( * set_formatter ) ( fmt_handler -> formatter, flags, fmt_handler -> data );
- }
- set_writer = ( void* ) GetProcAddress ( self -> handle, "KLogLibHandlerSet" );
- if ( set_writer != NULL )
- {
- const KWrtHandler* handler = KLogLibHandlerGet ();
- ( * set_writer ) ( handler -> writer, handler -> data );
- }
-
- set_formatter = ( void* ) GetProcAddress ( self -> handle, "KStsLibFmtHandlerSet" );
- if ( set_formatter != NULL )
- {
- KStsFmtFlags flags = KStsLibFmtFlagsGet ();
- const KFmtHandler* fmt_handler = KStsFmtHandlerGet ();
- ( * set_formatter ) ( fmt_handler -> formatter, flags, fmt_handler -> data );
- }
- set_writer = ( void* ) GetProcAddress ( self -> handle, "KStsLibHandlerSet" );
- if ( set_writer != NULL )
- {
- const KWrtHandler* handler = KStsLibHandlerGet ();
- ( * set_writer ) ( handler -> writer, handler -> data );
- }
-#if _DEBUGGING
- set_writer = ( void* ) GetProcAddress ( self -> handle, "KDbgHandlerSet" );
- if ( set_writer != NULL )
- {
- const KWrtHandler* handler = KDbgHandlerGet ();
- ( * set_writer ) ( handler -> writer, handler -> data );
- }
-#endif
- return 0;
-}
-
-/* LoadLib
- * load a dynamic library
- *
- * "lib" [ OUT ] - return parameter for loaded library
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target library
- */
-static
-rc_t KDyldLoad ( KDyld *self, KDylib *lib, const wchar_t *path )
-{
-#if USE_DYLOAD
-
- DWORD err;
-#if WE_WERE_BUILDING_FOR_WINDOWS_7_ALONE
- UINT errMode = GetErrorMode();
-#endif
-
- if ( path == NULL )
- {
- if ( GetModuleHandleExW( 0, NULL, &( lib -> handle ) ) )
- return 0;
-
- return RC ( rcFS, rcDylib, rcLoading, rcNoObj, rcUnknown );
- }
-
- SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); /* suppress the message box in case of an error */
- lib -> handle = LoadLibraryW ( path );
-#if WE_WERE_BUILDING_FOR_WINDOWS_7_ALONE
- SetErrorMode(errMode);
-#endif
- if ( lib -> handle != NULL )
- return KDylibSetLogging ( lib );
-
- err = GetLastError ();
- switch ( err )
- {
- case ERROR_MOD_NOT_FOUND :
- return RC ( rcFS, rcDylib, rcLoading, rcPath, rcNotFound );
- case ERROR_BAD_EXE_FORMAT :
- return RC ( rcFS, rcDylib, rcLoading, rcFormat, rcInvalid );
- }
-
- return RC ( rcFS, rcDylib, rcLoading, rcNoObj, rcUnknown );
-
-#else
- lib -> handle = NULL;
- return 0;
-#endif
-}
-
-static
-rc_t KDyldVTryLoadLib ( KDyld *self, KDylib **lib,
- const KDirectory *dir, const char *path, va_list args )
-{
- rc_t rc;
-
- const KSysDir *sdir = KDirectoryGetSysDir ( dir );
- if ( sdir == NULL )
- rc = RC ( rcFS, rcDylib, rcLoading, rcDirectory, rcIncorrect );
- else
- {
- wchar_t real [ MAX_PATH ];
-
- rc = KSysDirOSPath ( sdir, real, sizeof real, path, args );
- if ( rc == 0 )
- {
- WString pstr;
- WStringInitCString ( & pstr, real );
-
- rc = KDylibMake ( lib, & pstr );
- if ( rc == 0 )
- {
- rc = KDyldLoad ( self, * lib, real );
- if ( rc == 0 )
- return 0;
- free ( * lib );
- }
- }
- }
-
- * lib = NULL;
-
- return rc;
-}
-
-static
-rc_t KDyldTryLoadLib ( KDyld *self, KDylib **lib,
- const KDirectory *dir, const char *path, ... )
-{
- rc_t rc;
- va_list args;
- va_start ( args, path );
- rc = KDyldVTryLoadLib ( self, lib, dir, path, args );
- va_end ( args );
- return rc;
-}
-
-LIB_EXPORT rc_t CC KDyldVLoadLib ( KDyld *self,
- KDylib **lib, const char *path, va_list args )
-{
- rc_t rc;
-
- if ( lib == NULL )
- rc = RC ( rcFS, rcDylib, rcLoading, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcLoading, rcSelf, rcNull );
- else if ( path == NULL || path [ 0 ] == 0 )
- {
- WString pstr;
- CONST_WSTRING ( & pstr, "" );
-
- rc = KDylibMake ( lib, & pstr );
- if ( rc == 0 )
- {
- rc = KDyldLoad ( self, * lib, NULL );
- if ( rc == 0 )
- return 0;
-
- free ( * lib );
- }
- }
- else
- {
- uint32_t i = VectorStart ( & self -> search );
- uint32_t end = i + VectorLength ( & self -> search );
-
- if ( i == end )
- {
- char name [ 4096 ];
- int len = ( args == NULL ) ?
- snprintf ( name, sizeof name, "%s", path ) :
- vsnprintf ( name, sizeof name, path, args );
- if ( len < 0 || len >= sizeof name )
- rc = RC ( rcFS, rcDylib, rcLoading, rcPath, rcExcessive );
- else
- {
- WString pstr;
- wchar_t wname [ 4096 ];
- size_t wsize = string_cvt_wchar_copy ( wname, sizeof wname, name, len );
- WStringInit ( & pstr, wname, wsize * sizeof wname [ 0 ], string_len ( name, len ) );
-
- rc = KDylibMake ( lib, & pstr );
- if ( rc == 0 )
- {
- rc = KDyldLoad ( self, * lib, wname );
- if ( rc == 0 )
- return 0;
-
- free ( * lib );
- }
- }
- }
- else
- {
- for ( * lib = NULL; i < end; ++ i )
- {
- const KDirectory *dir;
-
- va_list cpy;
- va_copy ( cpy, args );
-
- dir = ( const void* ) VectorGet ( & self -> search, i );
- rc = KDyldVTryLoadLib ( self, lib, dir, path, cpy );
-
- va_end ( cpy );
-
- if ( rc == 0 || GetRCState ( rc ) != rcNotFound )
- return rc;
- }
-
- rc = RC ( rcFS, rcDylib, rcLoading, rcPath, rcNotFound );
- }
- }
-
- * lib = NULL;
- }
-
- return rc;
-}
-
-LIB_EXPORT rc_t CC KDyldLoadLib ( KDyld *self,
- KDylib **lib, const char *path, ... )
-{
- rc_t rc;
- va_list args;
-
- va_start ( args, path );
- rc = KDyldVLoadLib ( self, lib, path, args );
- va_end ( args );
-
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KDylibAddRef ( const KDylib *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAdd ( & self -> refcount, "KDylib" ) )
- {
- case krefLimit:
- return RC ( rcFS, rcDylib, rcAttaching, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-LIB_EXPORT rc_t CC KDylibRelease ( const KDylib *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDrop ( & self -> refcount, "KDylib" ) )
- {
- case krefWhack:
- return KDylibWhack ( ( KDylib* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-static
-void CC KDylibVectRelease ( void *item, void *ignore )
-{
- KDylib *self = item;
- KDylibRelease ( self );
-}
-
-
-/* Attach
- * Sever
- */
-static
-KDylib *KDylibAttach ( const KDylib *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAddDep ( & self -> refcount, "KDylib" ) )
- {
- case krefLimit:
- return NULL;
- }
- }
- return ( KDylib* ) self;
-}
-
-static
-rc_t KDylibSever ( const KDylib *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDropDep ( & self -> refcount, "KDylib" ) )
- {
- case krefWhack:
- return KDylibWhack ( ( KDylib* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-/* Sort
- */
-static
-int64_t CC KDylibSort ( const void *item, const void *n )
-{
- const KDylib *a = item;
- const KDylib *b = n;
- return WStringCaseCompare ( & a -> path, & b -> path );
-}
-
-
-/* FullPath
- * return full path to library
- */
-LIB_EXPORT rc_t CC KDylibFullPath ( const KDylib *self, char *path, size_t psize )
-{
- rc_t rc;
-
- if ( psize == 0 )
- rc = RC ( rcFS, rcDylib, rcAccessing, rcBuffer, rcInsufficient );
- else if ( path == NULL )
- rc = RC ( rcFS, rcDylib, rcAccessing, rcBuffer, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcAccessing, rcSelf, rcNull );
- else
- {
- size_t i, bytes = wchar_cvt_string_copy ( path, psize,
- self -> path . addr, self -> path . size );
- if ( bytes < psize )
- {
- if ( isalpha ( path [ 0 ] ) && path [ 1 ] == ':' )
- {
- path [ 1 ] = path [ 0 ];
- path [ 0 ] = '/';
- }
- for ( i = 0; i < bytes; ++ i )
- {
- if ( path [ i ] == '\\' )
- path [ i ] = '/';
- }
-
- return 0;
- }
-
- rc = RC ( rcFS, rcDylib, rcAccessing, rcBuffer, rcInsufficient );
- }
-
- path [ 0 ] = 0;
- }
-
- return rc;
-}
-
-
-/*--------------------------------------------------------------------------
- * KDlset
- * ordered set of dynamic libraries
- * contained libraries remain resident until set is released
- */
-struct KDlset
-{
- KDyld *dl;
- Vector name, ord;
- KRefcount refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KDlsetWhack ( KDlset *self )
-{
- KRefcountWhack ( & self -> refcount, "KDlset" );
-
- VectorWhack ( & self -> name, NULL, NULL );
- VectorWhack ( & self -> ord, KDylibVectRelease, NULL );
- KDyldSever ( self -> dl );
- free ( self );
-
- return 0;
-}
-
-#define STRINGIZE(s) #s
-#define LIBNAME(pref, name, suff) STRINGIZE(pref) name STRINGIZE(suff)
-/* MakeSet
- * load a dynamic library
- *
- * "set" [ OUT ] - return parameter for lib set
- */
-LIB_EXPORT rc_t CC KDyldMakeSet ( const KDyld *self, KDlset **setp )
-{
- rc_t rc = 0;
-
- if ( setp == NULL )
- rc = RC ( rcFS, rcDylib, rcConstructing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcConstructing, rcSelf, rcNull );
- else
- {
- KDlset *set = malloc ( sizeof * set );
- if ( set == NULL )
- rc = RC ( rcFS, rcDylib, rcConstructing, rcMemory, rcExhausted );
- else
- {
- set -> dl = KDyldAttach ( self );
- VectorInit ( & set -> name, 0, 16 );
- VectorInit ( & set -> ord, 0, 16 );
- KRefcountInit ( & set -> refcount, 1, "KDlset", "make", "dlset" );
-#if ! ALWAYS_ADD_EXE
- {
- KDylib *jni;
- const char* libname = "vdb_jni.dll";
- rc = KDyldLoadLib ( ( KDyld* ) self, & jni, libname );
- if ( rc == 0 )
- {
- rc = KDlsetAddLib ( set, jni );
- KDylibRelease ( jni );
- }
- /*if (rc == 0)*/ /* if JNI code is not there, C tools should not suffer */
- {
- * setp = set;
- return 0;
- }
- }
-#else
- {
- KDylib *exe;
- rc = KDyldLoadLib ( ( KDyld* ) self, & exe, NULL );
- if ( rc == 0 )
- {
- rc = KDlsetAddLib ( set, exe );
- KDylibRelease ( exe );
- if ( rc == 0 )
- {
- * setp = set;
- return 0;
- }
- }
- }
-
- KDlsetRelease ( set );
-#endif
- }
- }
-
- * setp = NULL;
- }
-
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KDlsetAddRef ( const KDlset *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAdd ( & self -> refcount, "KDlset" ) )
- {
- case krefLimit:
- return RC ( rcFS, rcDylib, rcAttaching, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-LIB_EXPORT rc_t CC KDlsetRelease ( const KDlset *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDrop ( & self -> refcount, "KDlset" ) )
- {
- case krefWhack:
- return KDlsetWhack ( ( KDlset* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-
-/* AddLib
- * adds a dynamic library to end of ordered set
- *
- * "lib" [ IN ] - library returned from KDyldLoadLib
- */
-static
-rc_t KDlsetAddLibInt ( KDlset *self, KDylib *lib )
-{
- uint32_t idx;
- rc_t rc = VectorAppend ( & self -> ord, & idx, lib );
- if ( rc == 0 )
- {
- void *ignore;
-
- rc = VectorInsertUnique ( & self -> name,
- lib, NULL, KDylibSort );
- if ( rc == 0 )
- return 0;
-
- VectorSwap ( & self -> ord, idx, NULL, & ignore );
- }
-
- return rc;
-}
-
-LIB_EXPORT rc_t CC KDlsetAddLib ( KDlset *self, KDylib *lib )
-{
- rc_t rc;
-
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcInserting, rcSelf, rcNull );
- else if ( lib == NULL )
- rc = RC ( rcFS, rcDylib, rcInserting, rcDylib, rcNull );
- else
- {
- rc = KDylibAddRef ( lib );
- if ( rc == 0 )
- {
- rc = KDlsetAddLibInt ( self, lib );
- if ( rc == 0 )
- return 0;
-
- KDylibRelease ( lib );
- }
- }
-
- return rc;
-}
-
-
-/* AddAll
- * adds all dynamic libraries found in dl search path
- */
-static
-rc_t CC KDlsetTryLib ( const KDirectory *dir,
- uint32_t type, const char *name, void *data )
-{
- KDlset *self = data;
-
- if ( ( type & ~ kptAlias ) == kptFile )
- {
- rc_t rc;
- KDylib *lib;
-#ifdef SHLX
- /* force simple shared library extension */
- if ( sizeof SHLX >= 2 )
- {
- /* SHLX has at least 1 character plus NUL byte */
- size_t len = strlen ( name );
- /* name must be at least 1 character larger */
- if ( len <= ( sizeof SHLX - 1 ) )
- return 0;
- /* name must end with shared library extension */
- if ( memcmp ( & name [ len - ( sizeof SHLX - 1 ) ], SHLX, sizeof SHLX - 1 ) != 0 )
- return 0;
- }
-#endif
- rc = KDyldTryLoadLib ( self -> dl, & lib, dir, name );
- if ( rc == 0 )
- {
- rc = KDlsetAddLibInt ( self, lib );
- if ( rc == 0 )
- return 0;
-
- KDylibRelease ( lib );
- }
- }
-
- return 0;
-}
-
-static
-void CC KDlsetVisitDir ( const KDirectory *dir, void *data )
-{
- KDirectoryVisit ( dir, false, KDlsetTryLib, data, "." );
-}
-
-LIB_EXPORT rc_t CC KDlsetAddAll ( KDlset *self )
-{
- if ( self == NULL )
- return RC ( rcFS, rcDylib, rcInserting, rcSelf, rcNull );
- KDyldForEach ( self -> dl, KDlsetVisitDir, self );
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- * KSymAddr
- * symbol address within a dynamic library
- */
-struct KSymAddr
-{
- KDylib *lib;
- void *addr;
- KRefcount refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KSymAddrWhack ( KSymAddr *self )
-{
- KRefcountWhack ( & self -> refcount, "KSymAddr" );
-
- KDylibSever ( self -> lib );
- free ( self );
-
- return 0;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KSymAddrAddRef ( const KSymAddr *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountAdd ( & self -> refcount, "KSymAddr" ) )
- {
- case krefLimit:
- return RC ( rcFS, rcDylib, rcAttaching, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-LIB_EXPORT rc_t CC KSymAddrRelease ( const KSymAddr *self )
-{
- if ( self != NULL )
- {
- switch ( KRefcountDrop ( & self -> refcount, "KSymAddr" ) )
- {
- case krefWhack:
- return KSymAddrWhack ( ( KSymAddr* ) self );
- case krefNegative:
- return RC ( rcFS, rcDylib, rcReleasing, rcRange, rcExcessive );
- }
- }
- return 0;
-}
-
-
-/* Make
- */
-static
-rc_t KSymAddrMake ( KSymAddr **symp,
- const KDylib *lib, const char *name )
-{
- FARPROC addr = GetProcAddress ( lib -> handle, name );
- if ( addr != NULL )
- {
- KSymAddr *sym = malloc ( sizeof * sym );
- if ( sym == NULL )
- return RC ( rcFS, rcDylib, rcConstructing, rcMemory, rcExhausted );
-
- sym -> lib = KDylibAttach ( lib );
- sym -> addr = (void *)addr;
- KRefcountInit ( & sym -> refcount, 1, "KSymAddr", "make", name );
- * symp = sym;
- return 0;
- }
-
- * symp = NULL;
- return RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound );
-}
-
-
-/* Symbol
- * find a symbol within dynamic library
- *
- * "sym" [ OUT ] - return parameter for exported symbol address
- *
- * "name" [ IN ] - NUL terminated symbol name in
- * library-native character set
- */
-LIB_EXPORT rc_t CC KDylibSymbol ( const KDylib *self, KSymAddr **sym, const char *name )
-{
- rc_t rc;
-
- if ( sym == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull );
- else if ( name == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull );
- else if ( name [ 0 ] == 0 )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty );
- else
- {
- return KSymAddrMake ( sym, self, name );
- }
-
- * sym = NULL;
- }
-
- return rc;
-}
-
-typedef struct KDlsetTrySymData KDlsetTrySymData;
-struct KDlsetTrySymData
-{
- const KDlset *self;
- const char *name;
-
- bool ( CC * test ) ( const KSymAddr *sym, void *data );
- void *data;
-
- KSymAddr *sym;
- rc_t rc;
- bool first;
-};
-
-static
-bool CC KDlsetTrySymbol ( void *item, void *data )
-{
- KSymAddr *sym;
- KDlsetTrySymData *pb = data;
- pb -> rc = KDylibSymbol ( item, & sym, pb -> name );
- if ( pb -> rc == 0 )
- {
- /* simple case */
- if ( pb -> test == NULL )
- {
- pb -> sym = sym;
- return true;
- }
-
- /* apply filter function */
- if ( ( * pb -> test ) ( sym, pb -> data ) )
- {
- KSymAddrRelease ( pb -> sym );
- pb -> sym = sym;
- return pb -> first;
- }
-
- KSymAddrRelease ( sym );
- }
- return false;
-}
-
-LIB_EXPORT rc_t CC KDlsetSymbol ( const KDlset *self, KSymAddr **sym, const char *name )
-{
- rc_t rc;
-
- if ( sym == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull );
- else if ( name == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull );
- else if ( name [ 0 ] == 0 )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty );
- else
- {
- KDlsetTrySymData pb;
- memset ( & pb, 0, sizeof pb );
- pb . self = self;
- pb . name = name;
- pb . rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound );
-
- if ( VectorDoUntil ( & self -> ord, false, KDlsetTrySymbol, & pb ) )
- {
- * sym = pb . sym;
- return 0;
- }
-
- rc = pb . rc;
- }
-
- * sym = NULL;
- }
-
- return rc;
-}
-
-
-/* FirstSymbol
- * LastSymbol
- * find a symbol within dynamic library set matching criteria
- *
- * "sym" [ OUT ] - return parameter for exported symbol address
- *
- * "name" [ IN ] - NUL terminated symbol name in
- * library-native character set
- *
- * "test" [ IN ] and "data" [ IN, OPAQUE ] - callback filter function
- * return true if symbol matches criteria
- */
-LIB_EXPORT rc_t CC KDlsetFirstSymbol ( const KDlset *self, KSymAddr **sym, const char *name,
- bool ( CC * test ) ( const KSymAddr *sym, void *data ), void *data )
-{
- rc_t rc;
-
- if ( sym == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull );
- else if ( name == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull );
- else if ( name [ 0 ] == 0 )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty );
- else if ( test == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcFunction, rcNull );
- else
- {
- KDlsetTrySymData pb;
- memset ( & pb, 0, sizeof pb );
- pb . self = self;
- pb . name = name;
- pb . test = test;
- pb . data = data;
- pb . rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound );
- pb . first = true;
-
- if ( VectorDoUntil ( & self -> ord, false, KDlsetTrySymbol, & pb ) )
- {
- * sym = pb . sym;
- return 0;
- }
-
- rc = pb . rc;
- }
-
- * sym = NULL;
- }
-
- return rc;
-}
-
-LIB_EXPORT rc_t CC KDlsetLastSymbol ( const KDlset *self, KSymAddr **sym, const char *name,
- bool ( CC * test ) ( const KSymAddr *sym, void *data ), void *data )
-{
- rc_t rc;
-
- if ( sym == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull );
- else if ( name == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull );
- else if ( name [ 0 ] == 0 )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty );
- else if ( test == NULL )
- rc = RC ( rcFS, rcDylib, rcSelecting, rcFunction, rcNull );
- else
- {
- KDlsetTrySymData pb;
- memset ( & pb, 0, sizeof pb );
- pb . self = self;
- pb . name = name;
- pb . test = test;
- pb . data = data;
- pb . rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound );
-
- VectorDoUntil ( & self -> ord, false, KDlsetTrySymbol, & pb );
- if ( pb . sym != NULL )
- {
- * sym = pb . sym;
- return 0;
- }
-
- rc = pb . rc;
- }
-
- * sym = NULL;
- }
-
- return rc;
-}
-
-
-/* List - PRIVATE
- * list the paths to the libraries in the set
- */
-typedef struct list_dylib_param list_dylib_param;
-struct list_dylib_param
-{
- VNamelist *list;
- rc_t rc;
-};
-
-static
-bool CC list_dylib ( void *item, void *data )
-{
- size_t bytes;
- char utf8 [ 4096 ], *p;
-
- list_dylib_param *pb = data;
- const KDylib *lib = ( const void* ) item;
-
- /* "lib" was created with KDylibMake
- which creates a NUL terminated path.
- of course, this could seg-fault if bad... */
- assert ( lib -> path . addr [ lib -> path . len ] == 0 );
-
- /* convert wide-character to UTF-8 */
- bytes = wchar_cvt_string_copy ( utf8, sizeof utf8, lib -> path . addr, lib -> path . size );
- if ( bytes < sizeof utf8 )
- {
- pb -> rc = VNamelistAppend ( pb -> list, utf8 );
- return pb -> rc != 0;
- }
-
- p = malloc ( 16 * 1024 );
- if ( p == NULL )
- {
- pb -> rc = RC ( rcFS, rcDylib, rcListing, rcMemory, rcExhausted );
- return true;
- }
-
- bytes = wchar_cvt_string_copy ( p, 16 * 1024, lib -> path . addr, lib -> path . size );
- if ( bytes >= 16 * 1024 )
- pb -> rc = RC ( rcFS, rcDylib, rcListing, rcPath, rcTooLong );
- else
- pb -> rc = VNamelistAppend ( pb -> list, p );
-
- free ( p );
- return pb -> rc != 0;
-}
-
-LIB_EXPORT rc_t CC KDlsetList ( const KDlset *self, KNamelist **listp )
-{
- list_dylib_param pb;
-
- assert ( listp != NULL );
-
- if ( self == NULL )
- pb . rc = RC ( rcFS, rcDylib, rcListing, rcSelf, rcNull );
- else
- {
- pb . rc = VNamelistMake ( & pb . list, VectorLength ( & self -> name ) );
- if ( pb . rc == 0 )
- {
- bool fail = VectorDoUntil ( & self -> name, false, list_dylib, & pb );
- if ( ! fail )
- pb . rc = VNamelistToNamelist ( pb . list, listp );
-
- VNamelistRelease ( pb . list );
- }
- }
-
- return pb . rc;
-}
-
-
-/* AsObj
- * AsFunc
- * retrieve symbol address as pointer to object
- */
-LIB_EXPORT void * CC KSymAddrAsObj ( const KSymAddr *self )
-{
- if ( self != NULL )
- return self -> addr;
- return NULL;
-}
-
-LIB_EXPORT void CC KSymAddrAsFunc ( const KSymAddr *self, fptr_t *fp )
-{
- if ( self != NULL && fp != NULL )
- * fp = ( fptr_t ) self -> addr;
-}
-
-
diff --git a/libs/kfs/win/sysfile-priv.h b/libs/kfs/win/sysfile-priv.h
deleted file mode 100644
index 2fd8ed2..0000000
--- a/libs/kfs/win/sysfile-priv.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_sysfile_priv_
-#define _h_sysfile_priv_
-
-#ifndef _h_os_native_
-#include <os-native.h>
-#endif
-
-#ifndef _h_kfs_impl_
-#include <kfs/impl.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*--------------------------------------------------------------------------
- * KSysFile
- * a Windows file
- */
-typedef struct KSysFile_v1 KSysFile_v1;
-struct KSysFile_v1
-{
- KFile_v1 dad;
- HANDLE handle;
- uint64_t pos;
- bool failed_set_sparse;
- bool is_sparse; /* throws off size dang it */
- CRITICAL_SECTION lock;
-};
-
-typedef struct KSysFile_v2 KSysFile_v2;
-struct KSysFile_v2
-{
- KFile_v2 dad;
- HANDLE handle;
- uint64_t pos;
- bool failed_set_sparse;
- bool is_sparse; /* throws off size dang it */
- CRITICAL_SECTION lock;
-};
-
-/* KSysFileMake
- * create a new file object
- * from file descriptor
- */
-rc_t KSysFileMake_v1 ( KSysFile_v1 **fp, HANDLE fd, const char *path, bool read_enabled, bool write_enabled );
-KSysFile_v2 * KSysFileMake_v2 ( ctx_t ctx, HANDLE fd, const char *path, bool read_enabled, bool write_enabled );
-
-#define KSysFileMake NAME_VERS ( KSysFileMake, KFILE_VERS )
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_sysfile_priv_ */
diff --git a/libs/kfs/win/sysfile-v2.c b/libs/kfs/win/sysfile-v2.c
deleted file mode 100644
index eb5d936..0000000
--- a/libs/kfs/win/sysfile-v2.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-
-
-/*--------------------------------------------------------------------------
- * forwards
- */
-struct KSysFile_v2;
-#define KFILE_IMPL struct KSysFile_v2
-#define KFILE_VERS 2
-
-#include <kfc/ctx.h>
-#include <kfc/except.h>
-#include <kfc/xc.h>
-
-#include "sysfile-priv.h"
-#include <kfs/kfs-priv.h>
-#include <klib/rc.h>
-#include <klib/log.h>
-#include <klib/text.h>
-#include <sysalloc.h>
-
-/* temporary */
-/* #include <klib/out.h> */
-
-
-
-#include <Windows.h>
-/* #include <WinIoCtl.h> nested include in Windows.h? */
-
-/*--------------------------------------------------------------------------
- * KSysFile
- * a Windows file
- */
-
-/* minimum set size or write beyond size difference to trigger setting sparse */
-/* tune this if too many or too few sparse files */
-#define MIN_SET_SPARSE_DIFF (16*1024)
-#define MIN_SPARSE_BLOCK_DIFF (4*1024)
-
-
-/* ----------
- * Some functions to isolate the calls to Windows functions as I feel dirty
- * just using them.
- * really its to isolate some calls the very different style of parmaters
- * for the calls from the usualy project approach.
- *
- * if the compiler inlines them it's all good.
- */
-
-/*
- * Get file size
- */
-static rc_t get_file_size ( const KSysFile_v2 *self, uint64_t *size )
-{
- LARGE_INTEGER sz;
-
- if ( GetFileSizeEx ( self -> handle, & sz ) == 0 )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcAccessing, rcFileDesc, rcInvalid );
- break;
- default:
- rc = RC ( rcFS, rcFile, rcAccessing, rcNoObj, rcUnknown );
- break;
- }
- PLOGERR (klogErr,
- (klogErr, rc, "error accessing file system status - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- return rc;
- }
- *size = sz.QuadPart;
-
- return 0;
-}
-
-
-/* returns (and side effect sets in structure)
- * if the file is already a sparse file
- */
-static bool check_if_sparse ( KSysFile_v2 *self )
-{
- BY_HANDLE_FILE_INFORMATION info;
- BOOL worked;
-
- if (self->is_sparse)
- return true;
-
- /*
- * we don't use the GetFileInformationBy HandleEx as we don't want to
- * exclude Win XP yet.
- */
- worked = GetFileInformationByHandle (self->handle, &info);
-
- self->is_sparse =
- ((info.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)
- == FILE_ATTRIBUTE_SPARSE_FILE);
-
- return self->is_sparse;
-}
-
-/*
- * make a file sparse set_it == true
- * return is like Windows funcs with true being good
- *
- * we can't set if the Windows Volume doesn't allow it
- * but we'll let the function fail rather than try to get the value at
- * CREATE (open) time because we'd be then checking at all file CREATE
- * whether we'd ever make it sparse or not
- */
-static
-bool set_sparse ( KSysFile_v2 *self )
-{
- FILE_SET_SPARSE_BUFFER b = { true };
- DWORD ret;
- BOOL worked;
- bool rreett = false;
-
- /* don't duplicate effort */
- if (self->is_sparse)
- rreett = true;
-
- else if (self->failed_set_sparse)
- rreett = false;
-
- else
- {
- worked = DeviceIoControl ( self->handle, FSCTL_SET_SPARSE, &b, sizeof b,
- NULL, 0, &ret, NULL );
-/* KOutMsg ("%s: %u\n",__func__,worked); */
-
- /* not trusting bool is BOOL cause I don't trust Microsoft */
- self->failed_set_sparse = (worked == 0);
- self->is_sparse = !self->failed_set_sparse;
- rreett = self->is_sparse;
- }
-/* KOutMsg ("%s: %d\n",__func__,rreett); */
- return rreett;
-}
-
-
-static bool set_not_sparse ( KSysFile_v2 *self )
-{
- FILE_SET_SPARSE_BUFFER b = { false };
- DWORD ret;
- BOOL worked;
-
- /* don't duplicate effort */
- if (!check_if_sparse (self))
- return true;
-
- if (self->failed_set_sparse)
- return false;
-
- worked = DeviceIoControl (self->handle, FSCTL_SET_SPARSE, &b, sizeof b,
- NULL, 0, &ret, NULL);
-
- /* not trusting bool is BOOL cause I don't trust Microsoft */
- self->failed_set_sparse = (worked == 0);
- self->is_sparse = self->failed_set_sparse;
- return ! self->is_sparse;
-}
-
-/*
- * this one works for non-sparse files too but what evs.
- */
-static rc_t set_zero_region ( KSysFile_v2 *self, uint64_t start, uint64_t size)
-{
- FILE_ZERO_DATA_INFORMATION b = { ( DWORD ) start, ( LONG ) ( start + size ) };
- DWORD ret;
- BOOL worked;
-
- worked = DeviceIoControl (self->handle, FSCTL_SET_ZERO_DATA,
- &b, sizeof b,
- NULL, 0,
- &ret, NULL);
-
- /* TODO: check error codes with GetLastError and better rc values */
- return (worked != 0) ? 0 : RC (rcFS, rcFile, rcWriting, rcBuffer, rcUnexpected);
-}
-
-
-/*
- * returns true if we can convert this file into a non-sparse file
- *
- * We went simple and fast. We ask about zero regions.
- * if we specifically get back that there are none we say true
- * otherwise we say false.
- *
- * self can be modified so it can not be const
- */
-static bool can_be_made_not_sparse ( KSysFile_v2 *self )
-{
-#if 1
- return false;
-#else
- /* this is backwards - the list of os non-zero regions not zero regions */
- LARGE_INTEGER fo;
- LARGE_INTEGER l;
- uint64_t size;
- FILE_ALLOCATED_RANGE_BUFFER i;
- FILE_ALLOCATED_RANGE_BUFFER o [16]; /* some none 0 number */
- uint64_t count;
- DWORD ret;
- BOOL worked;
- rc_t rc;
-
- /* if is isn't sparse we can't make it not sparse */
- /* first might be not yet set */
- if (!check_if_sparse (self))
- return true;
-
- /* we can't scan for zero regions if we can't get a size */
- rc = get_file_size (self, &size);
- if (rc)
- return false;
-
- /* Microsoft APIs can be fairly odd */
- fo.QuadPart = 0;
- l.QuadPart = size;
- i.FileOffset = fo;
- i.Length = l;
-
- worked = DeviceIoControl (self->handle, FSCTL_QUERY_ALLOCATED_RANGES,
- &i, sizeof i, o, sizeof o, & ret, NULL);
- /* we can't change to non-sparse if we can't scan for zero regions */
- if (worked == 0)
- return false;
-
- return (ret == 0);
-#endif
-}
-
-
-/* Destroy
- */
-static
-void CC KSysFileDestroy_v2 ( KSysFile_v2 *self, ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcDestroying );
-
- if ( CloseHandle (self -> handle ) == 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error closing system file" );
- }
- return;
- }
-
- free ( self );
-}
-
-
-static
-void CC KSysStdIOFileDestroy_v2 ( KSysFile_v2 *self, ctx_t ctx )
-{
- free ( self );
-}
-
-
-/* GetSysFile
- * returns an underlying system file object
- * and starting offset to contiguous region
- * suitable for memory mapping, or NULL if
- * no such file is available.
- */
-static
-KSysFile_v2 * CC KSysFileGetSysFile_v2 ( const KSysFile_v2 * self, ctx_t ctx, uint64_t *offset )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcAccessing );
-
- * offset = 0;
- return ( KSysFile_v2 * ) self;
-}
-
-/* RandomAccess
- * returns 0 if random access, error code otherwise
- */
-static
-bool CC KSysDiskFileRandomAccess_v2 ( const KSysFile_v2 *self, ctx_t ctx )
-{
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
- return false;
-}
-static
-bool CC KSysFileRandomAccess_v2 ( const KSysFile_v2 *self, ctx_t ctx )
-{
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
- return false;
-}
-
-
-/* Type
- * returns a KFileDesc
- * not intended to be a content type,
- * but rather an implementation class
- */
-static
-uint32_t CC KSysFileType_v2 ( const KSysFile_v2 *self, ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcEvaluating );
-
- switch ( GetFileType ( self -> handle ) )
- {
- case FILE_TYPE_DISK:
- return kfdFile;
- case FILE_TYPE_CHAR:
- return kfdCharDev;
- case FILE_TYPE_PIPE:
- return kfdSocket;
- }
-
- return kfdInvalid;
-}
-
-
-/* Size
- * returns size in bytes of file
- *
- * "size" [ OUT ] - return parameter for file size
- */
-static
-uint64_t CC KSysDiskFileSize_v2 ( const KSysFile_v2 *self, ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcAccessing );
-#if 1
-/* KOutMsg ("%s:\n",__func__); */
- uint64_t size;
- rc_t rc = get_file_size (self, &size);
- if ( rc )
- return 0 ;
-
- return size;
-#else
-
- LARGE_INTEGER sz;
-
- if ( GetFileSizeEx ( self -> handle, & sz ) == 0 )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error accessing file system status" );
- break;
- }
- return 0;
- }
-
- return sz . QuadPart;
-#endif
-}
-
-
-static
-uint64_t CC KSysFileSize_v2 ( const KSysFile_v2 *self, ctx_t ctx )
-{
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
- return 0;
-}
-
-
-/* SetSize
- * sets size in bytes of file
- *
- * "size" [ IN ] - new file size
- */
-static
-void CC KSysDiskFileSetSize_v2 ( KSysFile_v2 *self, ctx_t ctx, uint64_t size )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcUpdating );
-
- rc_t rc;
- LARGE_INTEGER p;
- uint64_t prev_size;
-
-/* KOutMsg ("%s:\n",__func__); */
- /* get previous size for setting or clearing sparse */
- rc = get_file_size ( self, &prev_size);
- if (rc)
- return;
-/* KOutMsg ("%s: %lu\n",__func__, prev_size); */
-
- p . QuadPart = size;
-
- if ( ! SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) )
- rc = 1;
- else
- {
- self -> pos = size;
- if ( ! SetEndOfFile( self -> handle ) )
- rc = 1;
- }
-
- /* failure to set size*/
- if ( rc != 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error accessing file system status" );
- }
- return;
- }
-
- /* check for wanting to be sparse file */
- if (size > prev_size)
- {
- uint64_t diff;
-
-/* KOutMsg ("%s: size(%lu) larger than prev_size(%lu)\n",__func__, size, prev_size); */
-
- diff = size - prev_size;
-
- /* if block size if big enough we'll try to make it a sparse block */
- if (diff >= MIN_SPARSE_BLOCK_DIFF)
- {
-/* KOutMsg ("%s: diff(%lu) larger than block constant(%lu)\n",__func__, diff, MIN_SPARSE_BLOCK_DIFF); */
- /* set sparse? */
- if (!check_if_sparse(self)) /* isn't sparse now */
- {
- if (diff >= MIN_SET_SPARSE_DIFF)
- {
-/* KOutMsg ("%s: diff(%lu) larger than sparse constant(%lu)\n",__func__, diff, MIN_SET_SPARSE_DIFF); */
- (void)set_sparse (self);
- }
- }
- /* ordered to try to set before looking to set the zero region */
- if (self->is_sparse)
- {
- /* set sparse region at end */
- set_zero_region (self, prev_size, diff);
- }
- }
- }
- else if (can_be_made_not_sparse (self))
- (void)set_not_sparse (self);
-}
-
-
-static
-void CC KSysFileSetSize_v2 ( KSysFile_v2 *self, ctx_t ctx, uint64_t size )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcUpdating );
-
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
-}
-
-
-/* Read
- * read file from known position
- *
- * "pos" [ IN ] - starting position within file
- *
- * "buffer" [ OUT ] and "bsize" [ IN ] - return buffer for read
- *
- * "num_read" [ OUT, NULL OKAY ] - optional return parameter
- * giving number of bytes actually read
- */
-static
-size_t KSysFileReadCommon_v2 ( const KSysFile_v2 *cself, ctx_t ctx,
- void *buffer, size_t bsize )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcReading );
-
- DWORD to_read, bytes_read;
- KSysFile_v2 *self = ( KSysFile* ) cself;
-
- to_read = ( DWORD ) bsize;
- if ( sizeof bsize > sizeof to_read && ( size_t ) to_read != bsize )
- to_read = ~ 0U;
-
- while ( 1 )
- {
- bytes_read = 0;
- if ( ReadFile ( self -> handle, buffer, to_read, & bytes_read, NULL ) == 0 )
- {
- DWORD last_error;
-
- switch ( last_error = GetLastError () )
- {
- case ERROR_HANDLE_EOF:
- break;
- case ERROR_IO_PENDING:
- continue;
- default:
- {
- INTERNAL_ERROR ( xcErrorUnknown, "error reading system file" );
- return 0;
- }
- }
- }
-
- self -> pos += bytes_read;
- break;
- }
-
- return bytes_read;
-}
-
-static
-size_t CC KSysDiskFileRead_v2 ( const KSysFile_v2 *cself, ctx_t ctx, uint64_t pos,
- void *buffer, size_t bsize )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcReading );
-
- KSysFile_v2 *self = ( KSysFile* ) cself;
-
- if ( self -> pos != pos )
- {
- LARGE_INTEGER p;
-
- if ( !GetFileSizeEx( self -> handle, &p ) )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error positioning system file" );
- break;
- }
- return 0;
- }
-
- /* if we try to read beyond the end of the file... */
- if ( ( LONGLONG ) pos >= p . QuadPart )
- { /* We've defined reading beyond EOF as return RC of 0 but bytes read as 0 */
- /*return RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcInvalid );*/
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle" );
- return 0;
- }
-
- p . QuadPart = pos;
- if ( !SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error positioning system file" );
- break;
- }
- return 0;
- }
-
- self -> pos = p . QuadPart;
- if ( pos != p . QuadPart )
- {
- if ( pos > (uint64_t)( p . QuadPart ) )
- {
- INTERNAL_ERROR ( xcErrorUnknown, "positioning error while writing to system file" );
- return 0;
- }
-
- INTERNAL_ERROR ( xcErrorUnknown, "error positioning system file" );
- return 0;
- }
- }
-
- return KSysFileReadCommon_v2 ( cself, ctx, buffer, bsize );
-}
-
-static
-size_t CC KSysFileRead_v2 ( const KSysFile_v2 *cself, ctx_t ctx, uint64_t pos,
- void *buffer, size_t bsize )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcReading );
-
- KSysFile_v2 *self = ( KSysFile* ) cself;
-
- if ( self -> pos != pos )
- {
- INTERNAL_ERROR ( xcFileDescInvalid, "incorrect file descriptor handle = %zu", self->handle );
- return 0;
- }
-
- return KSysFileReadCommon_v2 ( cself, ctx, buffer, bsize );
-}
-
-
-/* Write
- * write file at known position
- *
- * "pos" [ IN ] - starting position within file
- *
- * "buffer" [ IN ] and "size" [ IN ] - data to be written
- *
- * "num_writ" [ OUT, NULL OKAY ] - optional return parameter
- * giving number of bytes actually written
- */
-
-#define WINDOWS_HEAP_LIMIT (32*1024)
-
-static
-size_t KSysFileWriteCommon_v2 ( KSysFile_v2 *self, ctx_t ctx,
- const void *_buffer, size_t size )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcWriting );
-
- DWORD to_write;
- DWORD bytes_writ;
- DWORD iter_writ;
- const char * buffer = _buffer;
-
- to_write = (DWORD) size;
-
- if (sizeof size > sizeof to_write && ( size_t ) to_write != size )
- to_write = ~ 0U;
-
- for ( bytes_writ = 0; to_write > 0; )
- {
- DWORD iter_to_write =
- (to_write > WINDOWS_HEAP_LIMIT)? WINDOWS_HEAP_LIMIT : to_write;
-
-
- for (iter_writ = 0;
- ! WriteFile ( self -> handle, buffer, iter_to_write, &iter_writ, NULL);
- iter_writ = 0)
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_IO_PENDING:
- Sleep (100); /* sure let's give it a chance to settle */
- if (iter_writ)
- {
- buffer += iter_writ;
- iter_to_write -= iter_writ;
- to_write -= iter_writ;
- bytes_writ += iter_writ;
- }
- continue; /* back to while() */
-
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "invalid system file handle = %zu", self->handle );
- break;
-
- case ERROR_NOT_ENOUGH_MEMORY:
- INTERNAL_ERROR ( xcNoMemory, "out of memory for WindowWriteFile" );
- break;
-
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error writing system file" );
- break;
- }
- return 0;
- }
-
- buffer += iter_writ;
- to_write -= iter_writ;
- bytes_writ += iter_writ;
- }
-
- self -> pos += bytes_writ;
-
- return (size_t)bytes_writ;
-}
-
-static
-size_t CC KSysDiskFileWrite_v2 ( KSysFile_v2 *self, ctx_t ctx, uint64_t pos,
- const void *buffer, size_t size )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcWriting );
-
- rc_t rc;
- if ( self -> pos != pos )
- {
- LARGE_INTEGER p;
- uint64_t curr_size;
-
- rc = get_file_size ( self, &curr_size );
- if ( rc != 0 )
- {
- INTERNAL_ERROR ( xcErrorUnknown, "failed to get file size" );
- return 0;
- }
-
- if ( curr_size < pos )
- {
- KSysDiskFileSetSize_v2 (self, ctx, pos);
- if ( FAILED () )
- {
- INTERNAL_ERROR ( xcErrorUnknown, "failed to set file size" );
- return 0;
- }
- }
-
-
- p . QuadPart = pos;
-
- if ( SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) == 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- INTERNAL_ERROR ( xcFileDescInvalid, "invalid system file handle = %zu", self->handle );
- break;
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error writing system file" );
- break;
- }
- return 0;
- }
-
- self -> pos = p . QuadPart;
- if ( pos != p . QuadPart )
- {
- INTERNAL_ERROR ( xcErrorUnknown, "positioning error while writing to system file" );
- }
- }
-
- return KSysFileWriteCommon_v2 ( self, ctx, buffer, size );
-}
-static
-size_t CC KSysFileWrite_v2 ( KSysFile_v2 *self, ctx_t ctx, uint64_t pos,
- const void *buffer, size_t size )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcWriting );
-
- if ( self -> pos != pos )
- {
- INTERNAL_ERROR ( xcFileDescInvalid, "incorrect file descriptor handle = %zu", self->handle );
- return 0;
- }
-
- return KSysFileWriteCommon_v2 ( self, ctx, buffer, size );
-}
-
-
-/* Make
- * create a new file object
- * from file descriptor
- */
-static const KFile_vt_v2 vtKSysDiskFile =
-{
- /* version 2.0 */
- 2, 0,
-
- /* start minor version 0 methods */
- KSysFileDestroy_v2,
- KSysFileGetSysFile_v2,
- KSysDiskFileRandomAccess_v2,
- KSysDiskFileSize_v2,
- KSysDiskFileSetSize_v2,
- KSysDiskFileRead_v2,
- KSysDiskFileWrite_v2,
- KSysFileType_v2
-
-};
-static const KFile_vt_v2 vtKSysOtherFile =
-{
- /* version 2.0 */
- 2, 0,
-
- /* start minor version 0 methods */
- KSysFileDestroy_v2,
- KSysFileGetSysFile_v2,
- KSysFileRandomAccess_v2,
- KSysFileSize_v2,
- KSysFileSetSize_v2,
- KSysFileRead_v2,
- KSysFileWrite_v2,
- KSysFileType_v2
-
-};
-static const KFile_vt_v2 vtKSysStdIODiskFile =
-{
- /* version 2.0 */
- 2, 0,
-
- /* start minor version 0 methods */
- KSysStdIOFileDestroy_v2,
- KSysFileGetSysFile_v2,
- KSysDiskFileRandomAccess_v2,
- KSysDiskFileSize_v2,
- KSysDiskFileSetSize_v2,
- KSysDiskFileRead_v2,
- KSysDiskFileWrite_v2,
- KSysFileType_v2
-
-};
-static const KFile_vt_v2 vtKSysStdIOOtherFile =
-{
- /* version 2.0 */
- 2, 0,
-
- /* start minor version 0 methods */
- KSysStdIOFileDestroy_v2,
- KSysFileGetSysFile_v2,
- KSysFileRandomAccess_v2,
- KSysFileSize_v2,
- KSysFileSetSize_v2,
- KSysFileRead_v2,
- KSysFileWrite_v2,
- KSysFileType_v2
-
-};
-
-
-static
-KSysFile_v2 * KSysFileMakeVT_v2 ( ctx_t ctx, HANDLE fd, const KFile_vt *vt, const char *path,
- uint64_t initial_pos, bool read_enabled, bool write_enabled )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- KSysFile_v2 *f;
-
- if( fd == INVALID_HANDLE_VALUE ) /* ? */
- {
- INTERNAL_ERROR ( xcFileDescInvalid, "bad file descriptor error fd = %zu", fd );
- return NULL;
- }
-
-
- f = malloc ( sizeof *f );
- if ( f == NULL )
- {
- SYSTEM_ERROR ( xcNoMemory, "out of memory" );
- return NULL;
- }
- else
- {
- TRY ( KFileInit ( & f -> dad, ctx, vt, "KSysFile", path, read_enabled, write_enabled ) )
- {
- f -> handle = fd;
- f -> pos = initial_pos;
- f -> failed_set_sparse = f->is_sparse = false;
- check_if_sparse (f);
- return f;
- }
-
- free ( f );
- }
- return NULL;
-}
-
-/* bit flags */
-#define ISDISK 1
-#define ISSTDIO 2
-
-static
-KSysFile_v2 * KSysFileMakeInt_v2 ( ctx_t ctx, HANDLE fd, const char *path, bool read_enabled, bool write_enabled, unsigned flags )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- DWORD ret;
- const KFile_vt * vt;
- uint64_t initial_pos;
-
-
- ret = GetFileType (fd);
-
- switch (ret)
- {
- case FILE_TYPE_DISK:
- flags |= ISDISK;
- initial_pos = -1;
- break;
-
- case FILE_TYPE_UNKNOWN:
- ret = GetLastError();
- switch (ret)
- {
- default:
- INTERNAL_ERROR ( xcErrorUnknown, "error unknown file type" );
- return NULL;
-
- /* specific errors can be added here */
-
- case NO_ERROR:
- break;
- }
-
- initial_pos = 0;
- flags &= ~ISDISK;
- break;
-
- default:
- initial_pos = 0;
- flags &= ~ISDISK;
- break;
- }
-
- switch (flags & (ISDISK|ISSTDIO))
- {
- case 0:
- vt = (const KFile_vt*)&vtKSysOtherFile;
- break;
-
- case ISDISK:
- vt = (const KFile_vt*)&vtKSysDiskFile;
- break;
-
- case ISSTDIO:
- vt = (const KFile_vt*)&vtKSysStdIOOtherFile;
- break;
-
- case ISDISK|ISSTDIO:
- vt = (const KFile_vt*)&vtKSysStdIODiskFile;
- break;
- }
-
- return KSysFileMakeVT_v2 ( ctx, fd, vt, path, initial_pos, read_enabled, write_enabled );
-}
-
-/* extern, but internal to libkfs */
-KSysFile_v2 * KSysFileMake_v2 ( ctx_t ctx, HANDLE fd, const char *path, bool read_enabled, bool write_enabled )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- return KSysFileMakeInt_v2 ( ctx, fd, path, read_enabled, write_enabled, 0 );
-}
-
-
-/* MakeStdIn
- * creates a read-only file on stdin
- */
-LIB_EXPORT const KFile_v2 * CC KFileMakeStdIn_v2 ( ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- HANDLE fd = GetStdHandle ( STD_INPUT_HANDLE );
- return ( KFile_v2 * ) KSysFileMakeInt_v2 ( ctx, fd, "stdin", true, false, ISSTDIO );
-}
-
-/* MakeStdOut
- * MakeStdErr
- * creates a write-only file on stdout or stderr
- */
-LIB_EXPORT const KFile_v2 * CC KFileMakeStdOut_v2 ( ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- HANDLE fd = GetStdHandle ( STD_OUTPUT_HANDLE );
- return ( const KFile_v2 * ) KSysFileMakeInt_v2 ( ctx, fd, "stdout", false, true, ISSTDIO );
-}
-
-LIB_EXPORT const KFile_v2 * CC KFileMakeStdErr_v2 ( ctx_t ctx )
-{
- FUNC_ENTRY ( ctx, rcFS, rcFile, rcConstructing );
-
- HANDLE fd = GetStdHandle ( STD_ERROR_HANDLE );
- return ( const KFile_v2 * ) KSysFileMakeInt_v2 ( ctx, fd, "stderr", false, true, ISSTDIO );
-}
-
-/* MakeFDFile
- * creates a file from a file-descriptor
- * not supported under Windows
- */
-LIB_EXPORT const KFile_v2 * CC KFileMakeFDFileRead_v2 ( ctx_t ctx, int fd )
-{
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
-
- return NULL;
-}
-
-LIB_EXPORT KFile_v2 * CC KFileMakeFDFileWrite_v2 ( ctx_t ctx, bool update, int fd )
-{
- INTERNAL_ERROR ( xcFunctionUnsupported, "function is not supported" );
-
- return NULL;
-}
diff --git a/libs/kfs/win/sysfile.c b/libs/kfs/win/sysfile.c
deleted file mode 100644
index bb39d79..0000000
--- a/libs/kfs/win/sysfile.c
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-
-
-/*--------------------------------------------------------------------------
- * forwards
- */
-struct KSysFile_v1;
-#define KFILE_IMPL struct KSysFile_v1
-
-#include "sysfile-priv.h"
-#include <klib/rc.h>
-#include <klib/log.h>
-#include <klib/text.h>
-#include <sysalloc.h>
-
-/* temporary */
-/* #include <klib/out.h> */
-
-/* do not include windows.h it is already included by os-native.h */
-#include <os-native.h>
-#include <WinIoCtl.h>
-
-/*--------------------------------------------------------------------------
- * KSysFile
- * a Windows file
- */
-
-/* minimum set size or write beyond size difference to trigger setting sparse */
-/* tune this if too many or too few sparse files */
-#define MIN_SET_SPARSE_DIFF (16*1024)
-#define MIN_SPARSE_BLOCK_DIFF (4*1024)
-
-
-/* ----------
- * Some functions to isolate the calls to Windows functions as I feel dirty
- * just using them.
- * really its to isolate some calls the very different style of parmaters
- * for the calls from the usualy project approach.
- *
- * if the compiler inlines them it's all good.
- */
-
-/*
- * Get file size
- */
-static rc_t get_file_size ( const KSysFile_v1 *self, uint64_t *size )
-{
- LARGE_INTEGER sz;
-
- if ( GetFileSizeEx ( self -> handle, & sz ) == 0 )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcAccessing, rcFileDesc, rcInvalid );
- break;
- default:
- rc = RC ( rcFS, rcFile, rcAccessing, rcNoObj, rcUnknown );
- break;
- }
- PLOGERR (klogErr,
- (klogErr, rc, "error accessing file system status - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- return rc;
- }
- *size = sz.QuadPart;
-
- return 0;
-}
-
-
-/* returns (and side effect sets in structure)
- * if the file is already a sparse file
- */
-static bool check_if_sparse ( KSysFile_v1 *self )
-{
- BY_HANDLE_FILE_INFORMATION info;
- BOOL worked;
-
- if (self->is_sparse)
- return true;
-
- /*
- * we don't use the GetFileInformationBy HandleEx as we don't want to
- * exclude Win XP yet.
- */
- worked = GetFileInformationByHandle (self->handle, &info);
-
- self->is_sparse =
- ((info.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)
- == FILE_ATTRIBUTE_SPARSE_FILE);
-
- return self->is_sparse;
-}
-
-/*
- * make a file sparse set_it == true
- * return is like Windows funcs with true being good
- *
- * we can't set if the Windows Volume doesn't allow it
- * but we'll let the function fail rather than try to get the value at
- * CREATE (open) time because we'd be then checking at all file CREATE
- * whether we'd ever make it sparse or not
- */
-static
-bool set_sparse ( KSysFile_v1 *self )
-{
- FILE_SET_SPARSE_BUFFER b = { true };
- DWORD ret;
- BOOL worked;
- bool rreett = false;
-
- /* don't duplicate effort */
- if (self->is_sparse)
- rreett = true;
-
- else if (self->failed_set_sparse)
- rreett = false;
-
- else
- {
- worked = DeviceIoControl ( self->handle, FSCTL_SET_SPARSE, &b, sizeof b,
- NULL, 0, &ret, NULL );
-/* KOutMsg ("%s: %u\n",__func__,worked); */
-
- /* not trusting bool is BOOL cause I don't trust Microsoft */
- self->failed_set_sparse = (worked == 0);
- self->is_sparse = !self->failed_set_sparse;
- rreett = self->is_sparse;
- }
-/* KOutMsg ("%s: %d\n",__func__,rreett); */
- return rreett;
-}
-
-
-static bool set_not_sparse ( KSysFile_v1 *self )
-{
- FILE_SET_SPARSE_BUFFER b = { false };
- DWORD ret;
- BOOL worked;
-
- /* don't duplicate effort */
- if (!check_if_sparse (self))
- return true;
-
- if (self->failed_set_sparse)
- return false;
-
- worked = DeviceIoControl (self->handle, FSCTL_SET_SPARSE, &b, sizeof b,
- NULL, 0, &ret, NULL);
-
- /* not trusting bool is BOOL cause I don't trust Microsoft */
- self->failed_set_sparse = (worked == 0);
- self->is_sparse = self->failed_set_sparse;
- return ! self->is_sparse;
-}
-
-/*
- * this one works for non-sparse files too but what evs.
- */
-static rc_t set_zero_region ( KSysFile_v1 *self, uint64_t start, uint64_t size)
-{
- FILE_ZERO_DATA_INFORMATION b = { ( DWORD ) start, ( LONG ) ( start + size ) };
- DWORD ret;
- BOOL worked;
-
- worked = DeviceIoControl (self->handle, FSCTL_SET_ZERO_DATA,
- &b, sizeof b,
- NULL, 0,
- &ret, NULL);
-
- /* TODO: check error codes with GetLastError and better rc values */
- return (worked != 0) ? 0 : RC (rcFS, rcFile, rcWriting, rcBuffer, rcUnexpected);
-}
-
-
-/*
- * returns true if we can convert this file into a non-sparse file
- *
- * We went simple and fast. We ask about zero regions.
- * if we specifically get back that there are none we say true
- * otherwise we say false.
- *
- * self can be modified so it can not be const
- */
-static bool can_be_made_not_sparse ( KSysFile_v1 *self )
-{
-#if 1
- return false;
-#else
- /* this is backwards - the list of os non-zero regions not zero regions */
- LARGE_INTEGER fo;
- LARGE_INTEGER l;
- uint64_t size;
- FILE_ALLOCATED_RANGE_BUFFER i;
- FILE_ALLOCATED_RANGE_BUFFER o [16]; /* some none 0 number */
- uint64_t count;
- DWORD ret;
- BOOL worked;
- rc_t rc;
-
- /* if is isn't sparse we can't make it not sparse */
- /* first might be not yet set */
- if (!check_if_sparse (self))
- return true;
-
- /* we can't scan for zero regions if we can't get a size */
- rc = get_file_size (self, &size);
- if (rc)
- return false;
-
- /* Microsoft APIs can be fairly odd */
- fo.QuadPart = 0;
- l.QuadPart = size;
- i.FileOffset = fo;
- i.Length = l;
-
- worked = DeviceIoControl (self->handle, FSCTL_QUERY_ALLOCATED_RANGES,
- &i, sizeof i, o, sizeof o, & ret, NULL);
- /* we can't change to non-sparse if we can't scan for zero regions */
- if (worked == 0)
- return false;
-
- return (ret == 0);
-#endif
-}
-
-
-/* Destroy
- */
-static
-rc_t CC KSysFileDestroy_v1 ( KSysFile_v1 *self )
-{
- rc_t rc = 0;
-
- if ( CloseHandle (self -> handle ) == 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- break;
- default:
- rc = RC (rcFS, rcFile, rcDestroying, rcNoObj, rcUnknown);
- PLOGERR (klogErr,
- (klogErr, rc, "error closing system file - $(E)$($(C))",
- "E=%!,C=%u", last_error, last_error));
- }
- }
- DeleteCriticalSection(&self -> lock);
- free ( self );
- return rc;
-}
-
-
-static
-rc_t CC KSysStdIOFileDestroy_v1 ( KSysFile_v1 *self )
-{
- DeleteCriticalSection(&self -> lock);
- free ( self );
- return 0;
-}
-
-
-/* GetSysFile
- * returns an underlying system file object
- * and starting offset to contiguous region
- * suitable for memory mapping, or NULL if
- * no such file is available.
- */
-static
-KSysFile_v1 * CC KSysFileGetSysFile_v1 ( const KSysFile_v1 *self, uint64_t *offset )
-{
- * offset = 0;
- return ( KSysFile_v1 * ) self;
-}
-
-/* RandomAccess
- * returns 0 if random access, error code otherwise
- */
-static
-rc_t CC KSysDiskFileRandomAccess_v1 ( const KSysFile_v1 *self )
-{
- return 0;
-}
-static
-rc_t CC KSysFileRandomAccess_v1 ( const KSysFile_v1 *self )
-{
-/* return RC ( rcFS, rcFile, rcAccessing, rcFileDesc, rcIncorrect ); */
- return RC ( rcFS, rcFile, rcAccessing, rcFunction, rcUnsupported );
-}
-
-
-/* Type
- * returns a KFileDesc
- * not intended to be a content type,
- * but rather an implementation class
- */
-static
-uint32_t CC KSysFileType_v1 ( const KSysFile_v1 *self )
-{
- switch ( GetFileType ( self -> handle ) )
- {
- case FILE_TYPE_DISK:
- return kfdFile;
- case FILE_TYPE_CHAR:
- return kfdCharDev;
- case FILE_TYPE_PIPE:
- return kfdSocket;
- }
-
- return kfdInvalid;
-}
-
-
-/* Size
- * returns size in bytes of file
- *
- * "size" [ OUT ] - return parameter for file size
- */
-static
-rc_t CC KSysDiskFileSize_v1 ( const KSysFile_v1 *self, uint64_t *size )
-{
-#if 1
-/* KOutMsg ("%s:\n",__func__); */
- return get_file_size (self, size);
-#else
-
- LARGE_INTEGER sz;
-
- if ( GetFileSizeEx ( self -> handle, & sz ) == 0 )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcAccessing, rcFileDesc, rcInvalid );
- break;
- default:
- rc = RC ( rcFS, rcFile, rcAccessing, rcNoObj, rcUnknown );
- break;
- }
- PLOGERR (klogErr,
- (klogErr, rc, "error accessing file system status - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- return rc;
- }
-
- *size = sz . QuadPart;
- return 0;
-#endif
-}
-
-
-static
-rc_t CC KSysFileSize_v1 ( const KSysFile_v1 *self, uint64_t *size )
-{
- *size = 0;
-/* return RC ( rcFS, rcFile, rcAccessing, rcFileDesc, rcIncorrect ); */
- return RC ( rcFS, rcFile, rcAccessing, rcFunction, rcUnsupported );
-}
-
-
-/* SetSize
- * sets size in bytes of file
- *
- * "size" [ IN ] - new file size
- */
-static
-rc_t CC KSysDiskFileSetSize_v1 ( KSysFile_v1 *self, uint64_t size )
-{
- rc_t rc = 1;
- LARGE_INTEGER p;
- uint64_t prev_size;
-
- EnterCriticalSection(&self->lock);
-/* KOutMsg ("%s:\n",__func__); */
- /* get previous size for setting or clearing sparse */
- rc = get_file_size ( self, &prev_size);
- if (rc) {
- LeaveCriticalSection(&self->lock);
- return rc;
- }
-/* KOutMsg ("%s: %lu\n",__func__, prev_size); */
-
- p . QuadPart = size;
-
- if ( SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) )
- {
- self -> pos = size;
- if ( SetEndOfFile( self -> handle ) )
- {
- rc = 0;
- }
- }
-
- /* failure to set size*/
- if ( rc != 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcUpdating, rcFileDesc, rcInvalid );
- default:
- rc = RC ( rcFS, rcFile, rcUpdating, rcNoObj, rcUnknown );
- }
- PLOGERR ( klogErr,
- ( klogErr, rc, "error setting filesize - $(E) - $(C) to $(D)",
- "E=%!,C=%u,D=%lu", last_error, last_error, size ) );
- }
-
- /* check for wanting to be sparse file */
- if (size > prev_size)
- {
- uint64_t diff;
-
-/* KOutMsg ("%s: size(%lu) larger than prev_size(%lu)\n",__func__, size, prev_size); */
-
- diff = size - prev_size;
-
- /* if block size if big enough we'll try to make it a sparse block */
- if (diff >= MIN_SPARSE_BLOCK_DIFF)
- {
-/* KOutMsg ("%s: diff(%lu) larger than block constant(%lu)\n",__func__, diff, MIN_SPARSE_BLOCK_DIFF); */
- /* set sparse? */
- if (!check_if_sparse(self)) /* isn't sparse now */
- {
- if (diff >= MIN_SET_SPARSE_DIFF)
- {
-/* KOutMsg ("%s: diff(%lu) larger than sparse constant(%lu)\n",__func__, diff, MIN_SET_SPARSE_DIFF); */
- (void)set_sparse (self);
- }
- }
- /* ordered to try to set before looking to set the zero region */
- if (self->is_sparse)
- {
- /* set sparse region at end */
- set_zero_region (self, prev_size, diff);
- }
- }
- }
- else if (can_be_made_not_sparse (self))
- (void)set_not_sparse (self);
-
- LeaveCriticalSection(&self->lock);
- return rc;
-}
-
-
-static
-rc_t CC KSysFileSetSize_v1 ( KSysFile_v1 *self, uint64_t size )
-{
-/* return RC ( rcFS, rcFile, rcUpdating, rcFileDesc, rcIncorrect ); */
- return RC ( rcFS, rcFile, rcUpdating, rcFunction, rcUnsupported );
-}
-
-
-/* Read
- * read file from known position
- *
- * "pos" [ IN ] - starting position within file
- *
- * "buffer" [ OUT ] and "bsize" [ IN ] - return buffer for read
- *
- * "num_read" [ OUT, NULL OKAY ] - optional return parameter
- * giving number of bytes actually read
- */
-static
-rc_t KSysFileReadCommon_v1 ( const KSysFile_v1 *cself,
- void *buffer, size_t bsize, size_t *num_read )
-{
- DWORD to_read, bytes_read;
- KSysFile_v1 *self = ( KSysFile* ) cself;
-
- to_read = ( DWORD ) bsize;
- if ( sizeof bsize > sizeof to_read && ( size_t ) to_read != bsize )
- to_read = ~ 0U;
-
- for (;;)
- {
- bytes_read = 0;
- if ( ReadFile ( self -> handle, buffer, to_read, & bytes_read, NULL ) == 0 )
- {
- DWORD last_error;
-
- switch ( last_error = GetLastError () )
- {
- case ERROR_HANDLE_EOF:
- break;
- case ERROR_IO_PENDING:
- continue;
- default:
- {
- rc_t rc = RC ( rcFS, rcFile, rcReading, rcNoObj, rcUnknown);
- PLOGERR ( klogErr,
- ( klogErr, rc, "error reading system file - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error ) );
- return rc;
- }
- }
- }
-
- self -> pos += bytes_read;
- * num_read = bytes_read;
- break;
- }
-
- return 0;
-}
-
-static
-rc_t CC KSysDiskFileRead_v1 ( const KSysFile_v1 *cself, uint64_t pos,
- void *buffer, size_t bsize, size_t *num_read )
-{
- rc_t rc;
- KSysFile_v1 *self = ( KSysFile* ) cself;
-
- EnterCriticalSection(&self->lock);
-
- if ( self -> pos != pos )
- {
- LARGE_INTEGER p;
-
- if ( !GetFileSizeEx( self -> handle, &p ) )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcInvalid );
- break;
- default:
- rc = RC ( rcFS, rcFile, rcPositioning, rcNoObj, rcUnknown );
- break;
- }
- PLOGERR ( klogErr,
- ( klogErr, rc, "error positioning system file - $(E)($(C)) to $(D)",
- "E=%!,C=%u,D=%u", last_error, last_error, pos ) );
- LeaveCriticalSection(&self->lock);
- return rc;
- }
-
- /* if we try to read beyond the end of the file... */
- if ( ( LONGLONG ) pos >= p . QuadPart )
- { /* We've defined reading beyond EOF as return RC of 0 but bytes read as 0 */
- /*return RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcInvalid );*/
- LeaveCriticalSection(&self->lock);
- return 0;
- }
-
- p . QuadPart = pos;
- if ( !SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) )
- {
- rc_t rc;
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcInvalid );
- PLOGERR (klogErr,
- (klogErr, rc, "invalid system file handle - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- LeaveCriticalSection(&self->lock);
- return rc;
- default:
- rc = RC ( rcFS, rcFile, rcPositioning, rcNoObj, rcUnknown );
- PLOGERR ( klogErr,
- ( klogErr, rc, "error positioning system file - $(E)($(C)) to $(D)",
- "E=%!,C=%u,D=%lu", last_error, last_error, pos ) );
- LeaveCriticalSection(&self->lock);
- return rc;
- }
- }
-
- self -> pos = p . QuadPart;
- if ( pos != p . QuadPart )
- {
- if ( pos > (uint64_t)( p . QuadPart ) )
- {
- * num_read = 0;
- LeaveCriticalSection(&self->lock);
- return 0;
- }
-
- LeaveCriticalSection(&self->lock);
- return RC ( rcFS, rcFile, rcPositioning, rcNoObj, rcUnknown );
- }
- }
-
- rc = KSysFileReadCommon_v1 ( cself, buffer, bsize, num_read );
- LeaveCriticalSection(&self->lock);
- return rc;
-}
-
-static
-rc_t CC KSysFileRead_v1 ( const KSysFile_v1 *cself, uint64_t pos,
- void *buffer, size_t bsize, size_t *num_read )
-{
- rc_t rc;
- KSysFile_v1 *self = ( KSysFile* ) cself;
-
- EnterCriticalSection(&self->lock);
- if ( self -> pos != pos )
- {
- LeaveCriticalSection(&self->lock);
- *num_read = 0;
- return RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcIncorrect );
- }
-
- rc = KSysFileReadCommon_v1 ( cself, buffer, bsize, num_read );
- LeaveCriticalSection(&self->lock);
- return rc;
-}
-
-
-/* Write
- * write file at known position
- *
- * "pos" [ IN ] - starting position within file
- *
- * "buffer" [ IN ] and "size" [ IN ] - data to be written
- *
- * "num_writ" [ OUT, NULL OKAY ] - optional return parameter
- * giving number of bytes actually written
- */
-
-#define WINDOWS_HEAP_LIMIT (32*1024)
-
-static
-rc_t KSysFileWriteCommon_v1 ( KSysFile_v1 *self,
- const void *_buffer, size_t size, size_t *num_writ)
-{
- DWORD to_write;
- DWORD bytes_writ;
- DWORD iter_writ;
- const char * buffer = _buffer;
-
- to_write = (DWORD) size;
-
- if (sizeof size > sizeof to_write && ( size_t ) to_write != size )
- to_write = ~ 0U;
-
- for ( bytes_writ = 0; to_write > 0; )
- {
- DWORD iter_to_write =
- (to_write > WINDOWS_HEAP_LIMIT)? WINDOWS_HEAP_LIMIT : to_write;
-
-
- for (iter_writ = 0;
- ! WriteFile ( self -> handle, buffer, iter_to_write, &iter_writ, NULL);
- iter_writ = 0)
- {
- rc_t rc;
- DWORD last_error;
- const char * fmt;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_IO_PENDING:
- Sleep (100); /* sure let's give it a chance to settle */
- if (iter_writ)
- {
- buffer += iter_writ;
- iter_to_write -= iter_writ;
- to_write -= iter_writ;
- bytes_writ += iter_writ;
- }
- continue; /* back to while() */
-
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcWriting, rcFileDesc, rcInvalid );
- fmt = "invalid system file handle - $(E)($(C))";
- break;
-
- case ERROR_NOT_ENOUGH_MEMORY:
- rc = RC (rcFS, rcFile, rcWriting, rcMemory, rcExhausted);
- fmt = "error out of memory for WindowsWriteFile - $(E)($(C))";
- break;
-
- default:
- rc = RC ( rcFS, rcFile, rcWriting, rcNoObj, rcUnknown );
- fmt = "error writing system file - $(E)($(C))";
- break;
- }
-
- PLOGERR (klogErr,
- (klogErr, rc, fmt, "E=%!,C=%u", last_error, last_error));
- return rc;
- }
- buffer += iter_writ;
- to_write -= iter_writ;
- bytes_writ += iter_writ;
- }
-
- self -> pos += bytes_writ;
-
- if (num_writ != NULL)
- * num_writ = (size_t)bytes_writ;
-
- return 0;
-}
-static
-rc_t CC KSysDiskFileWrite_v1 ( KSysFile_v1 *self, uint64_t pos,
- const void *buffer, size_t size, size_t *num_writ)
-{
- rc_t rc;
- EnterCriticalSection(&self->lock);
- if ( self -> pos != pos )
- {
- LARGE_INTEGER p;
- uint64_t curr_size;
-
- rc = get_file_size ( self, &curr_size );
- if ( rc != 0 )
- {
- LeaveCriticalSection(&self->lock);
- return rc;
- }
-
- if ( curr_size < pos )
- {
- LeaveCriticalSection(&self->lock);
- rc = KSysDiskFileSetSize_v1 (self, pos);
- if (rc)
- return rc;
- EnterCriticalSection(&self->lock);
- }
-
-
- p . QuadPart = pos;
-
- if ( SetFilePointerEx ( self -> handle, p, & p, FILE_BEGIN ) == 0 )
- {
- DWORD last_error;
-
- last_error = GetLastError ();
- switch ( last_error )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcFS, rcFile, rcWriting, rcFileDesc, rcInvalid );
- PLOGERR (klogErr,
- (klogErr, rc, "invalid system file handle - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- break;
- default:
- rc = RC ( rcFS, rcFile, rcWriting, rcNoObj, rcUnknown );
- PLOGERR (klogErr,
- (klogErr, rc, "error writing system file - $(E)($(C))",
- "E=%!,C=%u", last_error, last_error));
- break;
- }
- LeaveCriticalSection(&self->lock);
- return rc;
- }
-
- self -> pos = p . QuadPart;
- if ( pos != p . QuadPart )
- {
- LeaveCriticalSection(&self->lock);
- return RC ( rcFS, rcFile, rcPositioning, rcNoObj, rcUnknown );
- }
- }
-
- rc = KSysFileWriteCommon_v1 ( self, buffer, size, num_writ );
- LeaveCriticalSection(&self->lock);
- return rc;
-}
-static
-rc_t CC KSysFileWrite_v1 ( KSysFile_v1 *self, uint64_t pos,
- const void *buffer, size_t size, size_t *num_writ)
-{
- rc_t rc;
- EnterCriticalSection(&self->lock);
- if ( self -> pos != pos )
- {
- *num_writ = 0;
- LeaveCriticalSection(&self->lock);
- return RC ( rcFS, rcFile, rcPositioning, rcFileDesc, rcIncorrect );
- }
-
- rc = KSysFileWriteCommon_v1 ( self, buffer, size, num_writ );
- LeaveCriticalSection(&self->lock);
- return rc;
-}
-
-
-/* Make
- * create a new file object
- * from file descriptor
- */
-static const KFile_vt_v1 vtKSysDiskFile =
-{
- /* version 1.1 */
- 1, 1,
-
- /* start minor version 0 methods */
- KSysFileDestroy_v1,
- KSysFileGetSysFile_v1,
- KSysDiskFileRandomAccess_v1,
- KSysDiskFileSize_v1,
- KSysDiskFileSetSize_v1,
- KSysDiskFileRead_v1,
- KSysDiskFileWrite_v1,
- /* end minor version 0 methods */
-
- /* start minor version == 1 */
- KSysFileType_v1
- /* end minor version == 1 */
-};
-static const KFile_vt_v1 vtKSysOtherFile =
-{
- /* version 1.1 */
- 1, 1,
-
- /* start minor version 0 methods */
- KSysFileDestroy_v1,
- KSysFileGetSysFile_v1,
- KSysFileRandomAccess_v1,
- KSysFileSize_v1,
- KSysFileSetSize_v1,
- KSysFileRead_v1,
- KSysFileWrite_v1,
- /* end minor version 0 methods */
-
- /* start minor version == 1 */
- KSysFileType_v1
- /* end minor version == 1 */
-};
-static const KFile_vt_v1 vtKSysStdIODiskFile =
-{
- /* version 1.1 */
- 1, 1,
-
- /* start minor version 0 methods */
- KSysStdIOFileDestroy_v1,
- KSysFileGetSysFile_v1,
- KSysDiskFileRandomAccess_v1,
- KSysDiskFileSize_v1,
- KSysDiskFileSetSize_v1,
- KSysDiskFileRead_v1,
- KSysDiskFileWrite_v1,
- /* end minor version 0 methods */
-
- /* start minor version == 1 */
- KSysFileType_v1
- /* end minor version == 1 */
-};
-static const KFile_vt_v1 vtKSysStdIOOtherFile =
-{
- /* version 1.1 */
- 1, 1,
-
- /* start minor version 0 methods */
- KSysStdIOFileDestroy_v1,
- KSysFileGetSysFile_v1,
- KSysFileRandomAccess_v1,
- KSysFileSize_v1,
- KSysFileSetSize_v1,
- KSysFileRead_v1,
- KSysFileWrite_v1,
- /* end minor version 0 methods */
-
- /* start minor version == 1 */
- KSysFileType_v1
- /* end minor version == 1 */
-};
-
-
-static
-rc_t KSysFileMakeVT ( KSysFile_v1 **fp, HANDLE fd, const KFile_vt *vt, const char *path,
- uint64_t initial_pos, bool read_enabled, bool write_enabled )
-{
- rc_t rc;
- KSysFile_v1 *f;
-
- if( fd == INVALID_HANDLE_VALUE ) /* ? */
- return RC ( rcFS, rcFile, rcConstructing, rcFileDesc, rcInvalid );
-
- f = malloc ( sizeof *f );
- if ( f == NULL )
- rc = RC(rcFS, rcFile, rcConstructing, rcMemory, rcExhausted);
- else
- {
- rc = KFileInit ( & f -> dad, vt, "KSysFile", path, read_enabled, write_enabled );
- if ( rc == 0 )
- {
- f -> handle = fd;
- f -> pos = initial_pos;
- f -> failed_set_sparse = f->is_sparse = false;
- check_if_sparse (f);
- InitializeCriticalSection(& f -> lock);
- *fp = f;
- return 0;
- }
-
- free ( f );
- }
- return rc;
-}
-
-/* bit flags */
-#define ISDISK 1
-#define ISSTDIO 2
-
-static
-rc_t KSysFileMakeInt ( KSysFile_v1 **fp, HANDLE fd, const char *path, bool read_enabled, bool write_enabled, unsigned flags )
-{
- DWORD ret;
- const KFile_vt * vt;
- uint64_t initial_pos;
-
- if (fp == NULL)
- return RC (rcFS, rcFile, rcConstructing, rcSelf, rcNull);
-
- *fp = NULL; /* pre-fail */
-
- ret = GetFileType (fd);
-
- switch (ret)
- {
- case FILE_TYPE_DISK:
- flags |= ISDISK;
- initial_pos = -1;
- break;
-
- case FILE_TYPE_UNKNOWN:
- ret = GetLastError();
- switch (ret)
- {
- default:
- return RC (rcFS, rcFile, rcConstructing, rcFileDesc, rcUnknown);
-
- /* specific errors can be added here */
-
- case NO_ERROR:
- break;
- }
-
- initial_pos = 0;
- flags &= ~ISDISK;
- break;
-
- default:
- initial_pos = 0;
- flags &= ~ISDISK;
- break;
- }
-
- switch (flags & (ISDISK|ISSTDIO))
- {
- case 0:
- vt = (const KFile_vt*)&vtKSysOtherFile;
- break;
-
- case ISDISK:
- vt = (const KFile_vt*)&vtKSysDiskFile;
- break;
-
- case ISSTDIO:
- vt = (const KFile_vt*)&vtKSysStdIOOtherFile;
- break;
-
- case ISDISK|ISSTDIO:
- vt = (const KFile_vt*)&vtKSysStdIODiskFile;
- break;
- }
-
- return KSysFileMakeVT ( fp, fd, vt, path, initial_pos, read_enabled, write_enabled );
-}
-
-/* extern, but internal to libkfs */
-rc_t KSysFileMake ( KSysFile_v1 **fp, HANDLE fd, const char *path, bool read_enabled, bool write_enabled )
-{
- return KSysFileMakeInt ( fp, fd, path, read_enabled, write_enabled, 0 );
-}
-
-
-/* MakeStdIn
- * creates a read-only file on stdin
- */
-LIB_EXPORT rc_t CC KFileMakeStdIn ( const KFile **fp )
-{
- HANDLE fd = GetStdHandle ( STD_INPUT_HANDLE );
- return KSysFileMakeInt ( (KSysFile**)fp, fd, "stdin", true, false, ISSTDIO );
-}
-
-/* MakeStdOut
- * MakeStdErr
- * creates a write-only file on stdout or stderr
- */
-LIB_EXPORT rc_t CC KFileMakeStdOut ( KFile **fp )
-{
- HANDLE fd = GetStdHandle ( STD_OUTPUT_HANDLE );
- return KSysFileMakeInt ( (KSysFile**)fp, fd, "stdout", false, true, ISSTDIO );
-}
-
-LIB_EXPORT rc_t CC KFileMakeStdErr ( KFile **fp )
-{
- HANDLE fd = GetStdHandle ( STD_ERROR_HANDLE );
- return KSysFileMakeInt ( (KSysFile**)fp, fd, "stderr", false, true, ISSTDIO );
-}
-
-/* MakeFDFile
- * creates a file from a file-descriptor
- * not supported under Windows
- */
-LIB_EXPORT rc_t CC KFileMakeFDFileRead ( const KFile **f, int fd )
-{
- return RC (rcFS, rcFile, rcConstructing, rcFunction, rcUnsupported);
-}
-
-LIB_EXPORT rc_t CC KFileMakeFDFileWrite ( KFile **f, bool update, int fd )
-{
- return RC (rcFS, rcFile, rcConstructing, rcFunction, rcUnsupported);
-}
diff --git a/libs/kfs/win/syslockfile.c b/libs/kfs/win/syslockfile.c
deleted file mode 100644
index 9b09f8d..0000000
--- a/libs/kfs/win/syslockfile.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-#include <kfs/lockfile.h>
-#include <kfs/directory.h>
-#include <klib/rc.h>
-
-
-/*--------------------------------------------------------------------------
- * KDirectory
- * interface extensions
- */
-
-
-/* CreateExclusiveAccessFile
- * opens a file with exclusive write access
- *
- * "f" [ OUT ] - return parameter for newly opened file
- *
- * "update" [ IN ] - if true, open in read/write mode
- * otherwise, open in write-only mode
- *
- * "access" [ IN ] - standard Unix access mode, e.g. 0664
- *
- * "mode" [ IN ] - a creation mode ( see explanation above ).
- *
- * "path" [ IN ] - NUL terminated string in directory-native
- * character set denoting target file
- */
-LIB_EXPORT rc_t CC KDirectoryVCreateExclusiveAccessFile ( KDirectory *self, struct KFile **f,
- bool update, uint32_t access, KCreateMode mode, const char *path, va_list args )
-{
- /* Windows should naturally behave as we want here... */
- rc_t rc = KDirectoryVCreateFile ( self, f, update, access, mode, path, args );
- if ( rc != 0 )
- {
- if ( GetRCState ( rc ) == rcExists )
- rc = RC ( rcFS, rcFile, rcLocking, rcLocking, rcBusy );
- else
- rc = ResetRCContext ( rc, rcFS, rcFile, rcLocking );
- }
- return rc;
-}
diff --git a/libs/kfs/win/sysmmap-priv.h b/libs/kfs/win/sysmmap-priv.h
deleted file mode 100644
index 71dbdf9..0000000
--- a/libs/kfs/win/sysmmap-priv.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_sysmmap_priv_
-#define _h_sysmmap_priv_
-
-#ifndef _h_mmap_priv_
-#include "../mmap-priv.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*--------------------------------------------------------------------------
- * KMMap
- * a memory mapped region
- */
-struct KMMap
-{
- uint64_t off;
- uint64_t pos;
- size_t size;
- char *addr;
-
- struct KFile *f;
- size_t pg_size;
-
- /* file mapping handle */
- HANDLE handle;
-
- uint32_t addr_adj;
- uint32_t size_adj;
-
- KRefcount refcount;
-
- bool read_only;
- bool sys_mmap;
- bool dirty;
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_sysmmap_priv_ */
diff --git a/libs/kfs/win/sysmmap.c b/libs/kfs/win/sysmmap.c
deleted file mode 100644
index 28c9873..0000000
--- a/libs/kfs/win/sysmmap.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kfs/extern.h>
-#include "sysmmap-priv.h"
-#include "sysfile-priv.h"
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <WINDOWS.H>
-
-
-/*--------------------------------------------------------------------------
- * KMMap
- * a memory mapped region
- */
-
-/* Make
- */
-rc_t KMMapMake ( KMMap **mmp )
-{
- SYSTEM_INFO sinfo;
-
- KMMap *mm = calloc ( 1, sizeof * mm );
- if ( mm == NULL )
- return RC ( rcFS, rcMemMap, rcConstructing, rcMemory, rcExhausted );
-
- GetSystemInfo ( & sinfo );
- mm -> pg_size = sinfo . dwAllocationGranularity;
-
- * mmp = mm;
-
- return 0;
-}
-
-
-/* RWSys
- */
-rc_t KMMapRWSys ( KMMap *self, uint64_t pos, size_t size )
-{
- DWORD status;
-
- KSysFile *sf = KFileGetSysFile ( self -> f, & self -> off );
- if ( sf == NULL )
- return RC ( rcFS, rcMemMap, rcConstructing, rcFile, rcIncorrect );
-
- self -> handle = CreateFileMapping ( sf -> handle, NULL, PAGE_READWRITE, 0, 0, NULL );
- if ( self -> handle != NULL )
- {
- self -> addr = MapViewOfFile ( self -> handle, FILE_MAP_ALL_ACCESS,
- ( DWORD ) ( pos >> 32 ), ( DWORD ) pos, size );
- if ( self -> addr != NULL )
- return 0;
- }
-
- switch ( status = GetLastError () )
- {
- /* NEED ERROR CODES - THANKS, REDMOND!! */
- default:
- break;
- }
-
- return RC ( rcFS, rcMemMap, rcConstructing, rcNoObj, rcUnknown );
-}
-
-
-/* ROSys
- */
-rc_t KMMapROSys ( KMMap *self, uint64_t pos, size_t size )
-{
- DWORD status;
-
- KSysFile *sf = KFileGetSysFile ( self -> f, & self -> off );
- if ( sf == NULL )
- return RC ( rcFS, rcMemMap, rcConstructing, rcFile, rcIncorrect );
-
- self -> handle = CreateFileMapping ( sf -> handle, NULL, PAGE_READONLY, 0, 0, NULL );
- if ( self -> handle != NULL )
- {
- self -> addr = MapViewOfFile ( self -> handle, FILE_MAP_READ,
- ( DWORD ) ( pos >> 32 ), ( DWORD ) pos, size );
- if ( self -> addr != NULL )
- return 0;
- }
-
- switch ( status = GetLastError () )
- {
- /* NEED ERROR CODES - THANKS, REDMOND!! */
- default:
- break;
- }
-
- return RC ( rcFS, rcMemMap, rcConstructing, rcNoObj, rcUnknown );
-}
-
-
-/* Unmap
- * removes a memory map
- */
-rc_t KMMapUnmap ( KMMap *self )
-{
- if ( self -> handle != NULL )
- {
- if ( ! CloseHandle ( self -> handle ) )
- return RC ( rcFS, rcMemMap, rcDestroying, rcNoObj, rcUnknown );
- if ( ! UnmapViewOfFile( self -> addr ) )
- return RC ( rcFS, rcMemMap, rcDestroying, rcNoObj, rcUnknown );
-
- self -> addr = NULL;
- self -> size = 0;
- self -> handle = NULL;
- }
-
- return 0;
-}
diff --git a/libs/klib/sun/syslog.c b/libs/klib/sun/syslog.c
deleted file mode 100644
index 387f76f..0000000
--- a/libs/klib/sun/syslog.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include "log-priv.h"
-#include <klib/log.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <time.h>
-#include <errno.h>
-
-
-/* LogTimestamp
- * generates a timestamp string
- */
-
-LIB_EXPORT rc_t CC LogTimestamp ( char *buffer, size_t bsize, size_t *num_writ )
-{
- int len;
- static time_t last_time = 0;
- static struct tm cal;
-
- /* get current time */
- time_t t = time ( 0 );
-
- /* initialize time on first run */
- if ( ! last_time )
- {
- last_time = t;
- cal = * gmtime ( & last_time );
- }
-
- /* or update if time has passed */
- else if ( t != last_time )
- {
- /* update every 5 minutes or so */
- time_t dt = t - last_time;
- last_time = t;
- if ( dt >= 300 )
- cal = * gmtime ( & last_time );
-
- /* otherwise, just update the struct manually */
- else
- {
- /* advance seconds */
- dt += cal . tm_sec;
- cal . tm_sec = ( int ) ( dt % 60 );
-
- /* detect a rolled-over minute */
- if ( ( dt /= 60 ) != 0 )
- {
- /* advance minutes */
- dt += cal . tm_min;
- cal . tm_min = ( int ) ( dt % 60 );
-
- /* detect a rolled-over hour */
- if ( ( dt /= 60 ) != 0 )
- {
- /* roll-over of an hour - refetch */
- cal = * gmtime ( & last_time );
- }
- }
- }
- }
-
- /* make the timestamp */
- len = snprintf ( buffer, bsize,
- "%04d-%02d-%02dT%02d:%02d:%02d"
- , cal . tm_year + 1900
- , cal . tm_mon + 1
- , cal . tm_mday
- , cal . tm_hour
- , cal . tm_min
- , cal . tm_sec
- );
-
- if ( num_writ != NULL )
- * num_writ = len;
-
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 && num_writ != NULL )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
-
- return 0;
-}
-
-/* LogSimpleTimestamp
- * generates a local timestamp string without time zone
- */
-LIB_EXPORT rc_t CC LogSimpleTimestamp ( char *buffer, size_t bsize, size_t *num_writ )
-{
- int len;
- static time_t last_time = 0;
- static struct tm cal;
-
- /* get current time */
- time_t t = time ( 0 );
-
- /* initialize time on first run */
- if ( ! last_time )
- {
- last_time = t;
- cal = * localtime ( & last_time );
- }
-
- /* or update if time has passed */
- else if ( t != last_time )
- {
- /* update every 5 minutes or so */
- time_t dt = t - last_time;
- last_time = t;
- if ( dt >= 300 )
- cal = * localtime ( & last_time );
-
- /* otherwise, just update the struct manually */
- else
- {
- /* advance seconds */
- dt += cal . tm_sec;
- cal . tm_sec = ( int ) ( dt % 60 );
-
- /* detect a rolled-over minute */
- if ( ( dt /= 60 ) != 0 )
- {
- /* advance minutes */
- dt += cal . tm_min;
- cal . tm_min = ( int ) ( dt % 60 );
-
- /* detect a rolled-over hour */
- if ( ( dt /= 60 ) != 0 )
- {
- /* roll-over of an hour - refetch */
- cal = * localtime ( & last_time );
- }
- }
- }
- }
-
- /* make the timestamp */
- len = snprintf ( buffer, bsize,
- "%04d-%02d-%02dT%02d:%02d:%02d"
- , cal . tm_year + 1900
- , cal . tm_mon + 1
- , cal . tm_mday
- , cal . tm_hour
- , cal . tm_min
- , cal . tm_sec
- );
- if ( num_writ != NULL )
- * num_writ = len;
-
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 && num_writ != NULL )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
-
- return 0;
-}
-
-/* LogPID
- * generates a process id
- */
-LIB_EXPORT rc_t CC LogPID ( char *buffer, size_t bsize, size_t *num_writ )
-{
- /* pid_t is signed not unsigned int */
- int len = snprintf ( buffer, bsize, "%d", getpid () );
- * num_writ = len;
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
- return 0;
-}
diff --git a/libs/klib/sun/systime.c b/libs/klib/sun/systime.c
deleted file mode 100644
index 08a50c3..0000000
--- a/libs/klib/sun/systime.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include <klib/time.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <time.h>
-#include <errno.h>
-
-
-/*--------------------------------------------------------------------------
- * KTime_t
- * 64 bit time_t
- */
-
-
-/* Stamp
- * current timestamp
- */
-LIB_EXPORT KTime_t CC KTimeStamp ( void )
-{
- return time ( NULL );
-}
-
-
-/*--------------------------------------------------------------------------
- * KTime
- * simple time structure
- */
-
-
-/* Make
- * make KTime from struct tm
- */
-static
-void KTimeMake ( KTime *kt, struct tm const *t )
-{
- kt -> year = t -> tm_year + 1900;
- kt -> month = t -> tm_mon;
- kt -> day = t -> tm_mday - 1;
- kt -> weekday = t -> tm_wday;
-#if 0
- kt -> tzoff = ( int16_t ) ( t -> tm_gmtoff / 60 );
-#else
- kt -> tzoff = 0;
-#endif
- kt -> hour = ( uint8_t ) t -> tm_hour;
- kt -> minute = ( uint8_t ) t -> tm_min;
- kt -> second = ( uint8_t ) t -> tm_sec;
- kt -> dst = t -> tm_isdst != 0;
-}
-
-
-/* Local
- * populate "kt" from "ts" in local time zone
- */
-LIB_EXPORT const KTime* CC KTimeLocal ( KTime *kt, KTime_t ts )
-{
- if ( kt != NULL )
- {
- struct tm t;
- time_t unix_time = ( time_t ) ts;
- t = * localtime ( & unix_time );
- KTimeMake ( kt, & t );
- }
- return kt;
-}
-
-
-/* Global
- * populate "kt" from "ts" in GMT
- */
-LIB_EXPORT const KTime* CC KTimeGlobal ( KTime *kt, KTime_t ts )
-{
- if ( kt != NULL )
- {
- struct tm t;
- time_t unix_time = ( time_t ) ts;
- t = * gmtime ( & unix_time );
- KTimeMake ( kt, & t );
- }
- return kt;
-}
diff --git a/libs/klib/win/misc.c b/libs/klib/win/misc.c
deleted file mode 100644
index f204e34..0000000
--- a/libs/klib/win/misc.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/misc.h> /* is_iser_an_admin */
-
-#include <Shlobj.h> /* IsUserAnAdmin */
-
-LIB_EXPORT bool CC is_iser_an_admin(void) {
- return IsUserAnAdmin();
-}
diff --git a/libs/klib/win/sysalloc.c b/libs/klib/win/sysalloc.c
deleted file mode 100644
index 7dfc73a..0000000
--- a/libs/klib/win/sysalloc.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#define _c_sysalloc_
-#include <sysalloc.h>
-
-#undef malloc
-#undef calloc
-#undef realloc
-#undef free
-
-#if _DEBUGGING
-#define _CRTDBG_MAP_ALLOC 1
-#include <crtdbg.h>
-#endif
-
-/* malloc
- */
-LIB_EXPORT void * CC klib_malloc ( size_t bytes )
-{
- return malloc ( bytes );
-}
-
-/* calloc
- */
-LIB_EXPORT void * CC klib_calloc ( size_t count, size_t size )
-{
- return calloc ( count, size );
-}
-
-/* realloc
- */
-LIB_EXPORT void * CC klib_realloc ( void *obj, size_t bytes )
-{
- return realloc ( obj, bytes );
-}
-
-
-/* free
- */
-LIB_EXPORT void CC klib_free ( void *obj )
-{
- free ( obj );
-}
diff --git a/libs/klib/win/syserrcode.c b/libs/klib/win/syserrcode.c
deleted file mode 100644
index 0c64db3..0000000
--- a/libs/klib/win/syserrcode.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include "writer-priv.h"
-#include <klib/writer.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <os-native.h>
-#include <Windows.h>
-
-#include <stdio.h>
-
-size_t KWrtFmt_error_code ( char * buffer, size_t buffer_size, uint32_t error_code )
-{
- char * tbuffer;
- char * pc;
- DWORD tbuffer_size;
- size_t z;
-
- tbuffer_size = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, /* dwFlags */
- NULL, /* lpSource */
- error_code, /* dwMessageId */
- 0, /* dwLanguageId - we're lazy on language right now */
- (LPSTR)&tbuffer,
- 0, /* nSize */
- NULL);/* Arguments */
- if (tbuffer_size == 0)
- {
- rc_t rc;
-
- rc = string_printf (buffer, buffer_size, &z,
- "Undefined error: %u", error_code);
- if (rc == 0)
- return z;
- else
- {
- static const char failed[] = "Failure to get Windows error string";
- return string_copy (buffer, buffer_size, failed, sizeof failed);
- }
- }
- else
- {
- for (pc = tbuffer; *pc ; ++pc)
- {
- if (*pc == '\r')
- {
- tbuffer_size = ( DWORD ) ( pc - tbuffer );
- break;
- }
- }
- z = string_copy (buffer, buffer_size, tbuffer, tbuffer_size);
-
- LocalFree (tbuffer);
- }
- return z;
-}
diff --git a/libs/klib/win/syslog.c b/libs/klib/win/syslog.c
deleted file mode 100644
index e260cbd..0000000
--- a/libs/klib/win/syslog.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include "../log-priv.h"
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* do not include windows.h, it is included already by os-native.h */
-#include <os-native.h>
-
-/* LogTimestamp
- * generates a timestamp-string in GMT-format
- */
-LIB_EXPORT rc_t CC LogTimestamp ( char *buffer, size_t bsize, size_t *num_writ )
-{
- int len;
- SYSTEMTIME my_time;
-
- GetSystemTime( &my_time );
-
- /* make the timestamp */
- len = snprintf ( buffer, bsize,
- "%04d-%02d-%02dT%02d:%02d:%02d",
- my_time.wYear,
- my_time.wMonth,
- my_time.wDay,
- my_time.wHour,
- my_time.wMinute,
- my_time.wSecond );
- if ( num_writ != NULL )
- {
- * num_writ = len;
- }
-
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 && num_writ != NULL )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
-
- return 0;
-}
-
-/* LogSimpleTimestamp
- * generates a local timestamp string without time zone
- */
-LIB_EXPORT rc_t CC LogSimpleTimestamp ( char *buffer, size_t bsize, size_t *num_writ )
-{
- int len;
- SYSTEMTIME my_time;
-
- GetLocalTime( &my_time );
-
- /* make the timestamp */
- len = snprintf ( buffer, bsize,
- "%04d-%02d-%02dT%02d:%02d:%02d",
- my_time.wYear,
- my_time.wMonth,
- my_time.wDay,
- my_time.wHour,
- my_time.wMinute,
- my_time.wSecond );
- if ( num_writ != NULL )
- {
- * num_writ = len;
- }
-
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 && num_writ != NULL )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
-
- return 0;
-}
-
-/* LogPID
- * generates a process id
- */
-LIB_EXPORT rc_t CC LogPID ( char *buffer, size_t bsize, size_t *num_writ )
-{
- DWORD my_process_id = GetCurrentProcessId();
- int len = snprintf ( buffer, bsize, "%u", my_process_id );
- * num_writ = len;
- if ( len < 0 || ( size_t ) len >= bsize )
- {
- if ( len < 0 )
- * num_writ = 0;
- return RC ( rcApp, rcLog, rcLogging, rcBuffer, rcInsufficient );
- }
- return 0;
-}
diff --git a/libs/klib/win/systime.c b/libs/klib/win/systime.c
deleted file mode 100644
index d7a24ad..0000000
--- a/libs/klib/win/systime.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include <klib/time.h>
-
-/* do not include windows.h, it is included already by os-native.h */
-#include <os-native.h>
-#include <time.h>
-
-
-/*--------------------------------------------------------------------------
- * KTime_t
- * 64 bit time_t
- */
-
-#if _ARCH_BITS == 32
-#define UNIX_EPOCH_IN_WIN 116444736000000000ULL
-#else
-#define UNIX_EPOCH_IN_WIN 116444736000000000UL
-#endif
-#define UNIX_TIME_UNITS_IN_WIN 10000000
-#define MS_TIME_UNITS_IN_WIN 10000
-
-/* KTime2FILETIME
- * convert from Unix to Windows
- */
-static
-const FILETIME *KTime2FILETIME ( KTime_t ts, FILETIME *ft )
-{
- uint64_t win_time = ( ts * UNIX_TIME_UNITS_IN_WIN ) + UNIX_EPOCH_IN_WIN;
- ft -> dwLowDateTime = ( DWORD ) win_time;
- ft -> dwHighDateTime = win_time >> 32;
- return ft;
-}
-
-/* FILETIME2KTime
- */
-static
-KTime_t FILETIME2KTime ( const FILETIME *ft )
-{
- uint64_t win_time = ft -> dwLowDateTime + ( ( int64_t ) ft -> dwHighDateTime << 32 );
- return ( KTime_t ) ( win_time - UNIX_EPOCH_IN_WIN ) / UNIX_TIME_UNITS_IN_WIN;
-}
-
-/* FILETIME2KTimeMs
- */
-static
-KTimeMs_t FILETIME2KTimeMs ( const FILETIME *ft )
-{
- uint64_t win_time = ft -> dwLowDateTime + ( ( int64_t ) ft -> dwHighDateTime << 32 );
- return ( KTimeMs_t ) ( win_time - UNIX_EPOCH_IN_WIN ) / MS_TIME_UNITS_IN_WIN;
-}
-
-
-/* Stamp
- * current timestamp
- */
-LIB_EXPORT KTime_t CC KTimeStamp ( void )
-{
- FILETIME ft;
- GetSystemTimeAsFileTime ( & ft );
- return FILETIME2KTime ( & ft );
-}
-
-LIB_EXPORT KTimeMs_t CC KTimeMsStamp ( void )
-{
- FILETIME ft;
- GetSystemTimeAsFileTime ( & ft );
- return FILETIME2KTimeMs ( & ft );
-}
-
-/*--------------------------------------------------------------------------
- * SYSTEMTIME
- */
-
-static
-int SYSTEMTIME_compare ( const SYSTEMTIME *a, const SYSTEMTIME *b )
-{
- int diff = a -> wMonth - b -> wMonth;
- if ( diff == 0 )
- {
- diff = a -> wDay - b -> wDay;
- if ( diff == 0 )
- {
- diff = a -> wHour - b -> wHour;
- if ( diff == 0 )
- {
- diff = a -> wMinute - b -> wMinute;
- if ( diff == 0 )
- diff = a -> wSecond - b -> wSecond;
- }
- }
- }
- return diff;
-}
-
-static
-void SYSTEMTIME_from_half_baked_SYSTEMTIME ( const SYSTEMTIME *half_baked, SYSTEMTIME *proper, WORD year )
-{
- FILETIME ft;
-
- * proper = * half_baked;
-
- /* fix some stuff */
- proper -> wYear = year;
- proper -> wMonth = half_baked -> wMonth;
- proper -> wDayOfWeek = 0; /* ignored */
- proper -> wDay = 1;
- proper -> wHour = half_baked -> wHour;
- proper -> wMinute = 0;
- proper -> wSecond = 0;
- proper -> wMilliseconds = 0;
-
- /* convert it to FILETIME and back, just to get the proper day of week
- if there's a better way to do it, go ahead.
- by now, my lunch is too difficult to keep down... */
- SystemTimeToFileTime ( proper, & ft );
- FileTimeToSystemTime ( & ft, proper );
-
- /* now, move ahead to the day of week */
- proper -> wDay += half_baked -> wDayOfWeek - proper -> wDayOfWeek;
- if ( half_baked -> wDayOfWeek < proper -> wDayOfWeek )
- proper -> wDay += 7;
- proper -> wDayOfWeek = half_baked -> wDayOfWeek;
-
- /* now find the occurrence of the weekday */
- if ( half_baked -> wDay > 1 )
- proper -> wDay += ( half_baked -> wDay - 1 ) * 7;
-}
-
-/*--------------------------------------------------------------------------
- * KTime
- * simple time structure
- */
-
-
-/* Make
- * make KTime from struct tm
- */
-static
-void KTimeMake ( KTime *kt, const SYSTEMTIME *st )
-{
- kt -> year = st -> wYear;
- kt -> month = st -> wMonth - 1;
- kt -> day = st -> wDay - 1;
- kt -> weekday = st -> wDayOfWeek;
- kt -> hour = ( uint8_t ) st -> wHour;
- kt -> minute = ( uint8_t ) st -> wMinute;
- kt -> second = ( uint8_t ) st -> wSecond;
-}
-
-
-/* Local
- * populate "kt" from "ts" in local time zone
- */
-LIB_EXPORT const KTime* CC KTimeLocal ( KTime *kt, KTime_t ts )
-{
- if ( kt != NULL )
- {
- DWORD tz_id;
- FILETIME ft;
- SYSTEMTIME gst, lst;
- TIME_ZONE_INFORMATION tz;
-
- /* generate windows time in 100nS units */
- KTime2FILETIME ( ts, & ft );
-
- /* generate a system time - almost what we need,
- except it's GMT and has no associated time zone */
- FileTimeToSystemTime ( & ft, & gst );
-
- /* assume we're NOT in DST */
- kt -> dst = false;
-
- /* get local timezone information */
- tz_id = GetTimeZoneInformation ( & tz );
- switch ( tz_id )
- {
- case TIME_ZONE_ID_STANDARD:
- case TIME_ZONE_ID_DAYLIGHT:
-
- /* convert GMT time to local time with tz info */
- SystemTimeToTzSpecificLocalTime ( & tz, & gst, & lst );
- KTimeMake ( kt, & lst );
-
- /* our gentle brothers and sisters in Redmond never
- cease to amaze... it's very nice - handy, even -
- to know that the system is "currently" operating
- in one mode or another, but that tells us nothing
- about the timestamp we're trying to interpret.
-
- to discover whether the timestamp we're converting
- is within daylight savings time, we can compare against
- the two railpost SYSTEMTIME entries, but then there's
- no telling whether we're in or out since the calendar
- is circular! aside from having to perform a multi-part
- comparison, we'll come to different conclusions depending
- upon whether the hemisphere is northern or southern!
-
- to disambiguate, we can use tz_id to detect hemisphere,
- and then know what's going on. Wow.
-
- also, it's not clear to the author whether the returned
- structures in tz will be proper or hacked, since the
- MSDN descriptions only describe how to hack them for
- input, but not how they will look on output. */
-
- if ( tz . StandardDate . wMonth == 0 || tz . DaylightDate . wMonth == 0 )
- kt -> tzoff = - ( int16_t ) tz . Bias;
- else
- {
- bool south = tz_id == TIME_ZONE_ID_DAYLIGHT;
-
- SYSTEMTIME cst, dst, std;
- GetSystemTime ( & cst );
-
- /* fill out proper structures, since those in tz are bad... */
- SYSTEMTIME_from_half_baked_SYSTEMTIME ( & tz . DaylightDate, & dst, cst . wYear );
- SYSTEMTIME_from_half_baked_SYSTEMTIME ( & tz . StandardDate, & std, cst . wYear );
-
- /* perform northern test for DST */
- if ( SYSTEMTIME_compare ( & lst, & dst ) >= 0 && SYSTEMTIME_compare ( & lst, & std ) < 0 )
- kt -> dst = true;
-
- /* test to see which hemisphere */
- south ^= ( SYSTEMTIME_compare ( & cst, & dst ) >= 0 && SYSTEMTIME_compare ( & cst, & std ) < 0 );
-
- /* correct for southern hemisphere */
- kt -> dst ^= south;
-
- /* set the timezone offset */
- kt -> tzoff = - ( int16_t ) ( tz . Bias +
- kt -> dst ? tz . DaylightBias : tz . StandardBias );
- }
- break;
-
- default:
-
- /* failed - use GMT instead */
- KTimeMake ( kt, & gst );
- kt -> tzoff = 0;
- }
- }
- return kt;
-}
-
-
-/* Global
- * populate "kt" from "ts" in GMT
- */
-LIB_EXPORT const KTime* CC KTimeGlobal ( KTime *kt, KTime_t ts )
-{
- if ( kt != NULL )
- {
- FILETIME ft;
- SYSTEMTIME gst;
-
- /* generate windows time in 100nS units */
- KTime2FILETIME ( ts, & ft );
-
- /* generate a system time */
- FileTimeToSystemTime ( & ft, & gst );
-
- /* fill out GMT time structure */
- KTimeMake ( kt, & gst );
- kt -> tzoff = 0;
- kt -> dst = false;
- }
- return kt;
-}
-
-/* MakeTime
- * make a KTime_t from KTime
- */
-LIB_EXPORT KTime_t CC KTimeMakeTime ( const KTime *self )
-{
- KTime_t ts = 0;
-
- if ( self != NULL )
- {
-#if USE_WINDOWS_NATIVE
- FILETIME ft;
- SYSTEMTIME st;
-
- st . wYear = self -> year;
- st . wMonth = self -> month + 1;
- st . wDay = self -> day + 1;
- st . wDayOfWeek = self -> weekday;
- st . wHour = self -> hour;
- st . wMinute = self -> minute;
- st . wSecond = self -> second;
-
-#if 0
- kt -> year = st -> wYear;
- kt -> month = st -> wMonth - 1;
- kt -> day = st -> wDay - 1;
- kt -> weekday = st -> wDayOfWeek;
- kt -> hour = ( uint8_t ) st -> wHour;
- kt -> minute = ( uint8_t ) st -> wMinute;
- kt -> second = ( uint8_t ) st -> wSecond;
-#endif
-
- SystemTimeToFileTime ( & st, & ft );
-#error "TBD - convert ft to seconds"
-
-#else /* USE_WINDOWS_NATIVE */
- struct tm t;
-
- assert ( self -> year >= 1900 );
- t . tm_year = self -> year - 1900;
- t . tm_mon = self -> month;
- t . tm_mday = self -> day + 1;
- t . tm_wday = self -> weekday;
- t . tm_hour = self -> hour;
- t . tm_min = self -> minute;
- t . tm_sec = self -> second;
- t . tm_isdst = self -> dst;
-
- ts = mktime ( &t );
-#endif /* USE_WINDOWS_NATIVE */
- }
-
- return ts;
-}
-
-LIB_EXPORT rc_t CC KSleepMs(uint32_t milliseconds)
-{
- Sleep ( milliseconds );
- return 0;
-}
-
diff --git a/libs/klib/win/syswriter.c b/libs/klib/win/syswriter.c
deleted file mode 100644
index 80c354a..0000000
--- a/libs/klib/win/syswriter.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/extern.h>
-#include <klib/writer.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include "writer-priv.h"
-
-#include <sysalloc.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#include <os-native.h>
-
-static HANDLE win_stdout;
-static HANDLE win_stderr;
-
-rc_t KWrtSysInit(void** h_stdout, void** h_stderr)
-{
- win_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
- win_stderr = GetStdHandle(STD_ERROR_HANDLE);
-
- if( h_stdout ) {
- *h_stdout = &win_stdout;
- }
- if( h_stderr ) {
- *h_stderr = &win_stderr;
- }
- return 0;
-}
-
-LIB_EXPORT int CC snprintf ( char * buffer, size_t bufsize, const char * format, ... )
-{
- int ret;
- size_t size;
- rc_t rc;
- va_list args;
-
- va_start (args, format);
- rc = string_vprintf ( buffer, bufsize, &size, format, args );
- if ( rc == 0 )
- {
- ret = ( int ) size;
- }
- else
- {
- if ( ( GetRCState( rc ) == rcInsufficient )&&( GetRCObject( rc ) == rcBuffer ) )
- ret = ( int ) size;
- else
- ret = -1;
- }
-/* ret = _vsnprintf (buffer, bufsize, format, args); */
- va_end (args);
- return ret;
-}
-
-/* ----
- * write 'count' bytes starting at 'buf' to a "stream/file" identified by 'fd'
- */
-rc_t CC KWrt_DefaultWriter( void * self, const char * buffer, size_t bufsize, size_t * num_writ )
-{
- size_t total;
- DWORD remaining;
- int num_written;
- const char * pbyte;
- HANDLE handle;
- rc_t rc;
-
- if ( self == NULL ) {
- return RC ( rcApp, rcLog, rcWriting, rcSelf, rcNull );
- }
-
- handle = *(HANDLE *)self;
- pbyte = buffer;
- rc = 0;
-
- total = 0;
- for (remaining = ( DWORD ) bufsize; remaining > 0; remaining -= num_written)
- {
- if (WriteFile (handle, pbyte, remaining, &num_written, NULL) == 0)
- {
- rc = RC ( rcApp, rcLog, rcWriting, rcTransfer, rcUnknown );
- break;
- }
- else
- total += num_written;
- }
- *num_writ = total;
- return rc;
-}
-
-void print_int_fixup ( char * fmt, size_t * len, size_t max )
-{
- char type;
- /* all the Unix flavors support a real printf
- * Only Windows does it "wrong".
- * In windows we can't just return like this but instead:
- * save fmt[len-1]
- * replace 'j' with I64
- * replace 'z' or 't', with 'I'
- * replace 'hh' with 'h'
- * append saved fmt[len-1] to its new place.
- *
- */
- if (*len > 2)
- {
- if ((fmt [*len-3] == 'l') && (fmt [*len-2] == 'l'))
- {
- fmt [*len-2] = fmt [*len-1];
- fmt [*len-1] = '\0';
- --*len;
- }
- }
- if (*len > 2)
- {
- switch (fmt[*len-2])
- {
- case 'h':
- if (fmt[*len-3] == 'h')
- {
- fmt [*len-2] = fmt [*len-1];
- fmt [*len-1] = '\0';
- *len --;
- }
- break;
-
- case 'z': /* 32-bit specific */
- case 't':
- fmt[*len-2] = 'l';
- break;
- case 'j':
- case 'l':
- type = fmt[*len-1];
- fmt[*len-2] = 'I';
- fmt[*len-1] = '6';
- fmt[*len] = '4';
- fmt[*len+1] = type;
- fmt[*len+2] = '\0';
- *len += 2;
- break;
- }
- }
- return;
-}
-
-void print_float_fixup ( char * fmt, size_t * len, size_t max )
-{
- /* all the Unix flavors support a real printf
- * Only Windows does it "wrong".
- */
- return;
-}
-
-void print_char_fixup ( char * fmt, size_t * len, size_t max )
-{
- /* all the Unix flavors support a real printf
- * Only Windows does it "wrong".
- */
- return;
-}
diff --git a/libs/kns/mac/sysendpoint.c b/libs/kns/mac/sysendpoint.c
deleted file mode 100644
index 6023cd0..0000000
--- a/libs/kns/mac/sysendpoint.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kns/impl.h>
-#include <kns/endpoint.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include <klib/rc.h>
-#include <klib/data-buffer.h>
-
-#include "stream-priv.h"
-
-#include <string.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <assert.h>
-
-#include <sysalloc.h>
-
-extern int h_errno;
-
-/* InitDNSEndpoint
- * initialize the endpoint with a DNS name and a port number
- *
- * "ep" [ OUT ] - address of endpoint block to be intialized
- *
- * "dns" [ IN ] - textual DNS address.
- *
- * "port" [ IN, DEFAULT 0 ] - binary port number in native integer byte order.
- * if the special port number 0 is given, it represents any available port.
- */
-LIB_EXPORT
-rc_t CC KNSManagerInitDNSEndpoint ( struct KNSManager const *self,
- KEndPoint *ep, struct String const *dns, uint16_t port )
-{
- rc_t rc = 0;
-
- if ( ep == NULL )
- rc = RC (rcNS, rcNoTarg, rcInitializing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcSelf, rcNull );
- else if ( dns == NULL )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcParam, rcNull );
- else if ( dns -> size == 0 )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcSelf, rcInsufficient );
- else
- {
- KDataBuffer b;
- char buffer [ 4096 ], * hostname = buffer;
- size_t buff_size = sizeof buffer;
-
- if ( dns -> size >= sizeof buffer )
- {
- rc = KDataBufferMakeBytes ( & b, dns -> size + 1 );
- if ( rc == 0 )
- {
- hostname = b . base;
- buff_size = ( size_t ) b . elem_count;
- }
- }
-
- if ( rc == 0 )
- {
- size_t size;
- rc = string_printf ( hostname, buff_size, & size, "%S", dns );
-
- assert ( rc == 0 );
- assert ( size < buff_size );
- assert ( hostname [ size ] == 0 );
-
- if ( rc == 0 )
- {
- struct hostent *remote = gethostbyname ( hostname );
- if ( remote != NULL )
- {
- ep -> type = epIPV4;
- memcpy ( & ep -> u . ipv4 . addr, remote -> h_addr_list [ 0 ], sizeof ep -> u . ipv4 . addr );
- ep -> u . ipv4 . addr = htonl ( ep -> u . ipv4 . addr );
- ep -> u . ipv4 . port = ( uint16_t ) port;
- }
- else switch ( h_errno )
- {
- case HOST_NOT_FOUND: /* The specified host is unknown */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcNotFound );
- break;
- case NO_ADDRESS: /* The requested names valid but does not have an IP address */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcInconsistent );
- break;
-#if ! defined NO_ADDRESS || ! defined NO_DATA || NO_ADDRESS != NO_DATA
- case NO_DATA: /* The requested name s valid but does not have an IP address */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcEmpty );
- break;
-#endif
- case NO_RECOVERY: /* A nonrecoverable name server error occured */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcDestroyed );
- break;
- case TRY_AGAIN: /* A temporary error occured on an authoritative name server. Try again later */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcBusy );
- break;
- default :
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcError, rcUnknown );
- }
- }
- }
-
- if ( hostname != buffer )
- KDataBufferWhack ( & b );
- }
-
- if ( rc != 0 )
- memset ( ep, 0, sizeof * ep );
- }
-
- return rc;
-}
diff --git a/libs/kns/mac/syspoll.c b/libs/kns/mac/syspoll.c
deleted file mode 100644
index 4c41f48..0000000
--- a/libs/kns/mac/syspoll.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-
-#include <kns/extern.h>
-#include <klib/log.h>
-#include <klib/out.h>
-#include <kproc/timeout.h>
-
-#include "poll-priv.h"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#include <os-native.h>
-
-#include <poll.h>
-#include <unistd.h>
-#include <errno.h>
-
-
-/* socket_wait
- * wait for an event or a timeout
- */
-int socket_wait ( int fd, int events, timeout_t *tm )
-{
- int i, status;
- struct pollfd fds [ 1 ];
-
- /* poll for data with no delay */
- for ( i = 0; i < 2; ++ i )
- {
- fds [ 0 ] . fd = fd;
- fds [ 0 ] . events = events;
- fds [ 0 ] . revents = 0;
-
- status = poll ( fds, sizeof fds / sizeof fds [ 0 ], 0 );
- if ( status > 0 )
- return fds [ 0 ] . revents;
- if ( status < 0 )
- return -1;
- }
-
- /* test for infinite timeout */
- while ( tm == NULL )
- {
- status = poll ( fds, sizeof fds / sizeof fds [ 0 ], 1000 );
- if ( status > 0 )
- return fds [ 0 ] . revents;
- if ( status < 0 )
- return -1;
-
- /* TBD - check for quitting event
- this may want to be a callback on the manager
- or on the socket */
- }
-
- /* no blocking */
- if ( tm -> mS == 0 )
- return 0;
-
- /* Darwin doesn't appear to support ppoll,
- so we just wait for the specified mS,
- regardless of how long we may have waited before */
-
- /* wait until final guy */
- status = poll ( fds, sizeof fds / sizeof fds [ 0 ], tm -> mS );
- if ( status > 0 )
- return fds [ 0 ] . revents;
-
- return status;
-}
diff --git a/libs/kns/win/sysendpoint.c b/libs/kns/win/sysendpoint.c
deleted file mode 100644
index acd6c20..0000000
--- a/libs/kns/win/sysendpoint.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kns/impl.h>
-#include <kns/endpoint.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include <klib/rc.h>
-#include <klib/data-buffer.h>
-
-#include <sysalloc.h>
-#include <os-native.h>
-
-#include "stream-priv.h"
-
-#include <assert.h>
-
-/* InitDNSEndpoint
- * initialize the endpoint with a DNS name and a port number
- *
- * "ep" [ OUT ] - address of endpoint block to be intialized
- *
- * "dns" [ IN ] - textual DNS address.
- *
- * "port" [ IN, DEFAULT 0 ] - binary port number in native integer byte order.
- * if the special port number 0 is given, it represents any available port.
- */
-LIB_EXPORT
-rc_t CC KNSManagerInitDNSEndpoint ( struct KNSManager const *self,
- KEndPoint *ep, struct String const *dns, uint16_t port )
-{
- rc_t rc = 0;
-
- if ( ep == NULL )
- rc = RC (rcNS, rcNoTarg, rcInitializing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcSelf, rcNull );
- else if ( dns == NULL )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcParam, rcNull );
- else if ( dns -> size == 0 )
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcSelf, rcInsufficient );
- else
- {
- KDataBuffer b;
- char buffer [ 4096 ], * hostname = buffer;
- size_t buff_size = sizeof buffer;
-
- if ( dns -> size >= sizeof buffer )
- {
- rc = KDataBufferMakeBytes ( & b, dns -> size + 1 );
- if ( rc == 0 )
- {
- hostname = b . base;
- buff_size = ( size_t ) b . elem_count;
- }
- }
-
- if ( rc == 0 )
- {
- size_t size;
- rc = string_printf ( hostname, buff_size, & size, "%S", dns );
-
- assert ( rc == 0 );
- assert ( size < buff_size );
- assert ( hostname [ size ] == 0 );
-
- if ( rc == 0 )
- {
- int lerrno;
- struct hostent *remote = gethostbyname ( hostname );
- if ( remote != NULL )
- {
- ep -> type = epIPV4;
- memcpy ( & ep -> u . ipv4 . addr, remote -> h_addr_list [ 0 ], sizeof ep -> u . ipv4 . addr );
- ep -> u . ipv4 . addr = htonl ( ep -> u . ipv4 . addr );
- ep -> u . ipv4 . port = ( uint16_t ) port;
- }
- else switch ( lerrno = WSAGetLastError () )
- {
- case WSANOTINITIALISED: /* Must have WSAStartup call */
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcEnvironment, rcUndefined );
- break;
- case WSAENETDOWN:/* network subsystem failed */
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcNoObj, rcFailed );
- break;
- case WSAHOST_NOT_FOUND: /* Answer host not found */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcNotFound );
- break;
- case WSATRY_AGAIN: /* host not found or server failure */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcBusy );
- break;
- case WSANO_RECOVERY: /* non-recoverable error */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcDestroyed );
- break;
- case WSANO_DATA: /* name is valid but no data */
- rc = RC ( rcNS, rcNoTarg, rcValidating, rcConnection, rcEmpty );
- break;
- case WSAEINPROGRESS: /* call is in progress */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUndefined );
- break;
- case WSAEFAULT: /* name paremeter is not valid part of addr space */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMemory, rcOutofrange );
- break;
- case WSAEINTR: /* socket call was calanceled */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcCanceled );
- break;
- default:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcError, rcUnknown );
- }
- }
- }
-
- if ( hostname != buffer )
- KDataBufferWhack ( & b );
- }
-
- if ( rc != 0 )
- memset ( ep, 0, sizeof * ep );
- }
-
- return rc;
-}
diff --git a/libs/kns/win/sysmgr.c b/libs/kns/win/sysmgr.c
deleted file mode 100644
index 6682f92..0000000
--- a/libs/kns/win/sysmgr.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <klib/rc.h>
-#include <atomic32.h>
-
-#include "sysmgr.h"
-
-#include <os-native.h>
-
-static atomic32_t mgr_count;
-
-rc_t KNSManagerInit ( void )
-{
- if ( atomic32_test_and_inc ( & mgr_count ) )
- {
- WSADATA wsaData;
- if ( WSAStartup ( MAKEWORD ( 2, 2 ), & wsaData ) != 0 )
- {
- int lerrno = WSAGetLastError ();
- switch ( lerrno )
- {
- case WSASYSNOTREADY:
- case WSAVERNOTSUPPORTED:
- case WSAEINPROGRESS:
- case WSAEPROCLIM:
- case WSAEFAULT:
- default:
- atomic32_dec ( & mgr_count );
- return RC ( rcNS, rcMgr, rcInitializing, rcLibrary, rcNotAvailable );
- }
- }
- }
-
- return 0;
-}
-
-void KNSManagerCleanup ( void )
-{
- if ( atomic32_dec_and_test ( & mgr_count ) )
- WSACleanup ();
-}
diff --git a/libs/kns/win/syssock.c b/libs/kns/win/syssock.c
deleted file mode 100644
index 3bf72f7..0000000
--- a/libs/kns/win/syssock.c
+++ /dev/null
@@ -1,1855 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-
-/*--------------------------------------------------------------------------
- * forwards
- */
-#define KSTREAM_IMPL KSocket
-typedef struct KSocket KSocket;
-
-#include <kns/extern.h>
-#include <kns/manager.h>
-#include <kns/socket.h>
-#include <kns/impl.h>
-#include <kns/endpoint.h>
-#include <klib/rc.h>
-#include <klib/debug.h>
-#include <klib/log.h>
-#include <klib/printf.h>
-#include <sysalloc.h>
-#include <kproc/timeout.h>
-
-#include "mgr-priv.h"
-#include "stream-priv.h"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-/* os-native.h includes windows.h and winsock2.h and klib/text.h !!! */
-#include <os-native.h>
-
-#define LOG
-
-#define SHUT_RD 0
-#define SHUT_WR 1
-typedef SSIZE_T ssize_t;
-
-static rc_t HandleErrnoEx ( const char *func, unsigned int lineno );
-#define HandleErrno() HandleErrnoEx ( __func__, __LINE__ )
-
-#define PIPE_NAME_LENGTH 256
-
-/*--------------------------------------------------------------------------
- * KSocket
- * a socket IS a stream
- *
- * in Berkeley socket terminology, a STREAM implies a CONTINUOUS stream,
- * which is implemented by the TCP connection. A "chunked" or discontiguous
- * stream would be a datagram stream, implemented usually by UDP.
- *
- * in VDB terminology, a STREAM is a fluid, moving target that is observed
- * from a stationary point, whereas a FILE or OBJECT is a static stationary
- * target observed from a movable window. This means that a STREAM cannot be
- * addressed randomly, whereas a FILE or OBJECT can.
- */
-
- /*
- * On Windows, we have 2 different mechanisms to implement KSockets,
- * WinSock based for Ipv4 connections and named pipes based for IPC
- */
-
-
-struct KSocketIPv4
-{
- SOCKET fd;
- struct sockaddr_in remote_addr; /* for ipv4 addr from accept */
- bool remote_addr_valid;
-};
-typedef struct KSocketIPv4 KSocketIPv4;
-
-
-struct KSocketIPv6
-{
- SOCKET fd;
- struct sockaddr_in6 remote_addr; /* for ipv6 addr from accept */
- bool remote_addr_valid;
-};
-typedef struct KSocketIPv6 KSocketIPv6;
-
-
-enum { isIpcListener, isIpcPipeServer, isIpcPipeClient };
-
-struct KSocketIPC
-{
- HANDLE pipe;
- wchar_t pipename [ PIPE_NAME_LENGTH ];
-
- uint8_t type;
- HANDLE listenerPipe; /* only used if type == isIpcListener */
-};
-typedef struct KSocketIPC KSocketIPC;
-
-
-struct KSocket
-{
- /* we have only one KSocket-type with a union of the implementation specific data */
- KStream dad;
-
- int32_t read_timeout;
- int32_t write_timeout;
- uint32_t type; /* epIPV4|epIPV6|epIPC ... KEndPointType from endpoint.h */
-
- union {
- KSocketIPv4 ipv4_data;
- KSocketIPv6 ipv6_data;
- KSocketIPC ipc_data;
- } type_data;
-};
-
-
-static rc_t CC KIpv4SocketWhack ( KSocket * self )
-{
- rc_t rc = 0;
- KSocketIPv4 * data;
-
- if ( self == NULL ) /* let's tolerate whacking NULL pointers... */
- return rc;
-
- if ( self->type != epIPV4 )
- return RC ( rcNS, rcSocket, rcClosing, rcParam, rcInvalid );
-
- data = &( self -> type_data.ipv4_data );
- if ( shutdown ( data -> fd, SHUT_WR ) != -1 )
- {
- while ( 1 )
- {
- char buffer [ 1024 ];
- ssize_t result = recv ( data -> fd, buffer, sizeof buffer, 0 );
- if ( result <= 0 )
- break;
- }
- if ( shutdown ( data -> fd, SHUT_RD ) != -1 )
- {
- if ( closesocket ( data -> fd ) == SOCKET_ERROR )
- rc = RC ( rcNS, rcSocket, rcClosing, rcError, rcUnknown );
- /* maybe report */
- }
- else
- rc = HandleErrno();
- }
- else
- rc = HandleErrno();
-
- free ( self );
-
- return rc;
-}
-
-
-static rc_t CC KIpv4SocketTimedRead ( const KSocket * self, void * buffer, size_t bsize,
- size_t * num_read, timeout_t * tm )
-{
- /* self != NULL and self->type == epIPV4 already checked by the caller */
-
- rc_t rc = 0;
- const KSocketIPv4 * data = &( self -> type_data.ipv4_data );
- struct timeval ts;
- fd_set readFds;
- int selectRes;
-
- /* convert timeout (relative time) */
- if ( tm != NULL )
- {
- ts.tv_sec = tm -> mS / 1000;
- ts.tv_usec = ( tm -> mS % 1000 ) * 1000;
- }
-
- /* wait for socket to become readable */
- FD_ZERO( &readFds );
- FD_SET( data -> fd, &readFds );
- selectRes = select( 0, &readFds, NULL, NULL, ( tm == NULL ) ? NULL : &ts );
-
- /* check for error */
- if ( selectRes == -1 )
- {
- rc = HandleErrno();
- }
- else if ( selectRes == 0 )
- {
- rc = RC ( rcNS, rcSocket, rcReading, rcTimeout, rcExhausted ); /* timeout */
- }
- else if ( FD_ISSET( data -> fd, &readFds ) )
- {
- while ( rc == 0 )
- {
- ssize_t count = recv ( data -> fd, buffer, ( int )bsize, 0 );
-
- if ( count >= 0 )
- {
- if ( num_read != NULL );
- * num_read = ( size_t ) count;
- return 0;
- }
- if ( WSAGetLastError() != WSAEINTR )
- rc = HandleErrno();
- break;
- }
- }
- else
- rc = HandleErrno();
-
- return rc;
-}
-
-
-static rc_t CC KIpv4SocketRead ( const KSocket * self, void * buffer, size_t bsize, size_t * num_read )
-{
- timeout_t tm;
-
- if ( self->type != epIPV4 )
- return RC ( rcNS, rcSocket, rcReading, rcParam, rcInvalid );
-
- if ( self -> read_timeout < 0 )
- return KIpv4SocketTimedRead ( self, buffer, bsize, num_read, NULL );
-
- TimeoutInit ( & tm, self -> read_timeout );
- return KIpv4SocketTimedRead ( self, buffer, bsize, num_read, & tm );
-}
-
-
-static rc_t CC KIpv4SocketTimedWrite ( KSocket * self, const void * buffer, size_t bsize,
- size_t * num_writ, timeout_t * tm )
-{
- /* self != NULL and self->type == epIPV4 already checked by the caller */
-
- rc_t rc = 0;
- KSocketIPv4 * data = &( self -> type_data.ipv4_data );
- struct timeval ts;
- fd_set writeFds;
- int selectRes;
-
- /* convert timeout (relative time) */
- if ( tm != NULL )
- {
- ts.tv_sec = tm -> mS / 1000;
- ts.tv_usec = ( tm -> mS % 1000 ) * 1000;
- }
-
- /* wait for socket to become writable */
- FD_ZERO( &writeFds );
- FD_SET( data -> fd, &writeFds );
- selectRes = select( 0, NULL, &writeFds, NULL, ( tm == NULL ) ? NULL : &ts );
-
- /* check for error */
- if ( selectRes == -1 )
- {
- rc = HandleErrno();
- }
- else if ( selectRes == 0 )
- {
- rc = RC ( rcNS, rcSocket, rcWriting, rcTimeout, rcExhausted ); /* timeout */
- }
- else if ( FD_ISSET( data -> fd, &writeFds ) )
- {
- while ( rc == 0 )
- {
- ssize_t count = send ( data -> fd , buffer, ( int )bsize, 0 );
- if ( count >= 0 )
- {
- if ( num_writ != NULL );
- * num_writ = count;
- return 0;
- }
- if ( WSAGetLastError() != WSAEINTR )
- rc = HandleErrno();
- break;
- }
- }
- else
- rc = HandleErrno();
-
- return rc;
-}
-
-
-static rc_t CC KIpv4SocketWrite ( KSocket *self, const void *buffer, size_t bsize, size_t *num_writ )
-{
- timeout_t tm;
-
- if ( self->type != epIPV4 )
- return RC ( rcNS, rcSocket, rcReading, rcParam, rcInvalid );
-
- if ( self -> write_timeout < 0 )
- return KIpv4SocketTimedWrite ( self, buffer, bsize, num_writ, NULL );
-
- TimeoutInit ( &tm, self -> write_timeout );
- return KIpv4SocketTimedWrite ( self, buffer, bsize, num_writ, & tm );
-}
-
-static KStream_vt_v1 vtKIpv4Socket =
-{
- 1, 1,
- KIpv4SocketWhack,
- KIpv4SocketRead,
- KIpv4SocketWrite,
- KIpv4SocketTimedRead,
- KIpv4SocketTimedWrite
-};
-
-void KStreamForceSocketClose(const struct KStream *self) {
- assert(self);
- closesocket(((KSocket*)self)->type_data.ipv4_data.fd);
-}
-
-/* *********************************************************************************************
-
- IPv4 implementation :
-
- KNSManagerMakeIPv4Connection() ... called from KNSManagerMakeRetryTimedConnection()
- KNSManagerMakeIPv4Listener() ... called from KNSManagerMakeListener()
- KListenerIPv4Accept() ... called from KListenerAccept()
- KSocketGetEndpointV4() ... called from KSocketGetEndpoint()
-
-********************************************************************************************* */
-
-static rc_t KNSManagerMakeIPv4Connection ( struct KNSManager const * self,
- KSocket ** out,
- const KEndPoint * from,
- const KEndPoint * to,
- int32_t retryTimeout,
- int32_t readMillis,
- int32_t writeMillis )
-{
- rc_t rc = 0;
- uint32_t retry_count = 0;
- SOCKET fd;
-
- * out = NULL;
-
- assert ( to != NULL );
- assert ( to -> type == epIPV4 );
- assert ( ( from == NULL || from -> type == to -> type ) );
-
- do
- {
- fd = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- if ( fd == INVALID_SOCKET )
- rc = HandleErrno();
- else
- {
- struct sockaddr_in ss;
- memset ( & ss, 0, sizeof ss );
- ss . sin_family = AF_INET;
- if ( from != NULL )
- {
- ss . sin_port = htons ( from -> u. ipv4 . port );
- ss . sin_addr . s_addr = htonl ( from -> u . ipv4 . addr );
- }
- if ( bind ( fd, ( const struct sockaddr* )&ss, sizeof ss ) == SOCKET_ERROR )
- rc = HandleErrno();
-
- if ( rc == 0 )
- {
- ss . sin_port = htons ( to -> u . ipv4 . port );
- ss . sin_addr . s_addr = htonl ( to -> u . ipv4 . addr );
-
- if ( connect ( fd, (const struct sockaddr*)&ss, sizeof ss ) != SOCKET_ERROR )
- { /* create the KSocket */
- KSocket * ksock = calloc ( sizeof * ksock, 1 );
- if ( ksock == NULL )
- rc = RC ( rcNS, rcSocket, rcAllocating, rcNoObj, rcNull );
- else
- { /* initialize the KSocket */
- rc = KStreamInit ( & ksock -> dad, ( const KStream_vt* ) & vtKIpv4Socket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- KSocketIPv4 * data = &( ksock -> type_data.ipv4_data );
- ksock -> read_timeout = readMillis;
- ksock -> write_timeout = writeMillis;
- ksock -> type = epIPV4;
- data -> fd = fd;
- *out = ( KSocket * )& ksock -> dad;
- return 0;
- }
- free( ksock );
- }
- /* we connected but then then ran out of memory or something bad like that, so no need to retry
- - simply close fd and return RC */
- closesocket( fd );
- return rc;
- }
- else /* connect () failed */
- rc = HandleErrno();
- }
- /* dump socket */
- closesocket( fd );
- }
-
- /* rc != 0 */
- if ( retryTimeout < 0 || ( int32_t )retry_count < retryTimeout )
- { /* retry */
- Sleep ( 1000 ); /*ms*/
- ++retry_count;
- rc = 0;
- }
- }
- while ( rc == 0 );
-
- return rc;
-}
-
-
-static rc_t KNSManagerMakeIPv4Listener ( const KNSManager *self, KSocket **out, const KEndPoint * ep )
-{
- rc_t rc = 0;
- KSocket * listener = calloc ( 1, sizeof * listener );
- if ( listener == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcMemory, rcExhausted );
- else
- {
- /* pass these along to accepted sockets */
- listener -> read_timeout = self -> conn_read_timeout;
- listener -> write_timeout = self -> conn_write_timeout;
-
- rc = KStreamInit ( & listener -> dad, ( const KStream_vt* ) & vtKIpv4Socket,
- "KSocket", "", true, true );
- if ( rc == 0 )
- {
- KSocketIPv4 * data = &( listener -> type_data . ipv4_data );
- data -> fd = socket ( AF_INET, SOCK_STREAM, 0 );
- if ( data -> fd < 0 )
- rc = HandleErrno ();
- else
- {
- struct sockaddr_in ss;
-
- int on = 1;
- setsockopt ( data -> fd, SOL_SOCKET, SO_REUSEADDR, ( char* ) & on, sizeof on );
-
- memset ( & ss, 0, sizeof ss );
- ss . sin_family = AF_INET;
- ss . sin_addr . s_addr = htonl ( ep -> u . ipv4 . addr );
- ss . sin_port = htons ( ep -> u . ipv4 . port );
-
- if ( bind ( data -> fd, ( struct sockaddr* ) & ss, sizeof ss ) == 0 )
- {
- if ( listen ( data -> fd, 5 ) == 0 )
- {
- * out = listener;
- return 0;
- }
- }
- rc = HandleErrno ();
- closesocket ( data -> fd );
- data -> fd = -1;
- }
- }
- free( listener );
- }
- return rc;
-}
-
-
-static rc_t KListenerIPv4Accept ( KSocket * self, struct KSocket ** out )
-{
- rc_t rc = 0;
- KSocket * new_socket = calloc ( 1, sizeof * new_socket );
- if ( new_socket == NULL )
- rc = RC ( rcNS, rcConnection, rcWaiting, rcMemory, rcExhausted );
- else
- {
- new_socket -> read_timeout = self -> read_timeout;
- new_socket -> write_timeout = self -> write_timeout;
-
- rc = KStreamInit ( & new_socket -> dad, ( const KStream_vt* ) & vtKIpv4Socket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- int len;
- KSocketIPv4 * new_data = &( new_socket -> type_data . ipv4_data );
- KSocketIPv4 * self_data = &( self -> type_data . ipv4_data );
-
- new_data -> remote_addr_valid = false;
- len = sizeof new_data -> remote_addr;
-
- new_data -> fd = accept ( self_data -> fd, ( struct sockaddr * ) & new_data -> remote_addr, & len );
- if ( new_data -> fd < 0 )
- rc = HandleErrno ();
- else if ( len > sizeof new_data -> remote_addr )
- {
- closesocket ( new_data -> fd );
- new_data -> fd = -1;
- rc = RC ( rcNS, rcConnection, rcWaiting, rcBuffer, rcInsufficient );
- }
- else
- new_data -> remote_addr_valid = true;
-
- if ( rc == 0 )
- {
- * out = new_socket;
- return 0;
- }
- }
- free( new_socket );
- }
- return rc;
-}
-
-
-static rc_t KSocketGetEndpointV4 ( const KSocket * self, KEndPoint * ep, bool remote )
-{
- rc_t rc = 0;
- const KSocketIPv4 * data = &( self -> type_data . ipv4_data );
- struct sockaddr_in addr;
- int l = sizeof( addr );
- int res = 0;
-
- if ( remote )
- {
- if ( data -> remote_addr_valid )
- {
- /* the remote part was already recorded through calling accept() */
- addr . sin_addr . s_addr = data -> remote_addr . sin_addr . s_addr;
- addr . sin_port = data -> remote_addr . sin_port;
- }
- else
- res = getpeername( data -> fd, ( struct sockaddr * )&addr, &l );
- }
- else
- res = getsockname( data -> fd, ( struct sockaddr * )&addr, &l );
-
- if ( res < 0 )
- rc = HandleErrno();
- else
- {
- ep -> u . ipv4.addr = ntohl( addr . sin_addr . s_addr );
- ep -> u . ipv4.port = ntohs( addr . sin_port );
- ep -> type = epIPV4;
- }
-
- return rc;
-}
-
-
-/* *********************************************************************************************
-
- IPv6 implementation :
-
- KNSManagerMakeIPv6Connection() ... called from KNSManagerMakeRetryTimedConnection()
- KNSManagerMakeIPv6Listener() ... called from KNSManagerMakeListener()
- KListenerIPv6Accept() ... called from KListenerAccept()
- KSocketGetEndpointV6() ... called from KSocketGetEndpoint()
-
-********************************************************************************************* */
-
-static rc_t KNSManagerMakeIPv6Connection ( struct KNSManager const * self,
- KSocket ** out,
- const KEndPoint * from,
- const KEndPoint * to,
- int32_t retryTimeout,
- int32_t readMillis,
- int32_t writeMillis )
-{
- return RC ( rcNS, rcSocket, rcAllocating, rcFunction, rcUnsupported );
-}
-
-
-static rc_t KNSManagerMakeIPv6Listener ( const KNSManager *self, KSocket **out, const KEndPoint * ep )
-{
- rc_t rc = 0;
- KSocket * listener = calloc ( 1, sizeof * listener );
- if ( listener == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcMemory, rcExhausted );
- else
- {
- /* pass these along to accepted sockets */
- listener -> read_timeout = self -> conn_read_timeout;
- listener -> write_timeout = self -> conn_write_timeout;
-
- rc = KStreamInit ( & listener -> dad, ( const KStream_vt* ) & vtKIpv4Socket,
- "KSocket", "", true, true );
- if ( rc == 0 )
- {
- KSocketIPv6 * data = &( listener -> type_data.ipv6_data );
-
- data -> fd = socket ( AF_INET6, SOCK_STREAM, 0 );
- if ( data -> fd < 0 )
- rc = HandleErrno ();
- else
- {
- struct sockaddr_in6 ss;
-
- int on = 1;
- setsockopt ( data -> fd, SOL_SOCKET, SO_REUSEADDR, ( char* ) & on, sizeof on );
-
- memset ( & ss, 0, sizeof ss );
- ss . sin6_family = AF_INET6;
- memcpy ( ss . sin6_addr . s6_addr,
- ep -> u . ipv6 . addr,
- sizeof ( ep -> u . ipv6 . addr ) );
- ss . sin6_port = htons ( ep -> u . ipv6 . port );
-
- if ( bind ( data -> fd, ( struct sockaddr* ) & ss, sizeof ss ) == 0 )
- {
- if ( listen ( data -> fd, 5 ) == 0 )
- {
- * out = listener;
- return 0;
- }
- }
- rc = HandleErrno ();
- closesocket ( data -> fd );
- data -> fd = -1;
- }
- }
- }
- return rc;
-}
-
-
-static rc_t KListenerIPv6Accept ( KSocket * self, struct KSocket ** out )
-{
- rc_t rc = 0;
- KSocket * new_socket = calloc ( 1, sizeof * new_socket );
- if ( new_socket == NULL )
- rc = RC ( rcNS, rcConnection, rcWaiting, rcMemory, rcExhausted );
- else
- {
- new_socket -> read_timeout = self -> read_timeout;
- new_socket -> write_timeout = self -> write_timeout;
-
- rc = KStreamInit ( & new_socket -> dad, ( const KStream_vt* ) & vtKIpv4Socket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- int len;
- KSocketIPv6 * new_data = &( new_socket -> type_data . ipv6_data );
- KSocketIPv6 * self_data = &( self -> type_data . ipv6_data );
-
- new_data -> remote_addr_valid = false;
- len = sizeof new_data -> remote_addr;
-
- new_data -> fd = accept ( self_data -> fd, ( struct sockaddr * ) & new_data -> remote_addr, & len );
- if ( new_data -> fd < 0 )
- rc = HandleErrno ();
- else if ( len > sizeof new_data -> remote_addr )
- {
- closesocket ( new_data -> fd );
- new_data -> fd = -1;
- rc = RC ( rcNS, rcConnection, rcWaiting, rcBuffer, rcInsufficient );
- }
- else
- new_data -> remote_addr_valid = true;
-
- if ( rc == 0 )
- {
- * out = new_socket;
- return 0;
- }
- }
- free( new_socket );
- }
- return rc;
-}
-
-
-static rc_t KSocketGetEndpointV6 ( const KSocket * self, KEndPoint * ep, bool remote )
-{
- rc_t rc = 0;
- const KSocketIPv6 * data = &( self -> type_data.ipv6_data );
- struct sockaddr_in6 addr;
- int l = sizeof( addr );
- int res = 0;
-
- if ( remote )
- {
- if ( data -> remote_addr_valid )
- {
- /* the remote part was already recorded through calling accept() */
- memcpy ( ep -> u . ipv6 . addr,
- data -> remote_addr . sin6_addr . s6_addr,
- sizeof ( ep -> u . ipv6 . addr ) );
- ep->u.ipv6.port = ntohs( data -> remote_addr . sin6_port );
- ep->type = epIPV6;
- return 0;
- }
- else
- res = getpeername( data -> fd, ( struct sockaddr * )&addr, &l );
- }
- else
- res = getsockname( data -> fd, ( struct sockaddr * )&addr, &l );
-
- if ( res < 0 )
- rc = HandleErrno();
- else
- {
- memcpy ( ep -> u . ipv6 . addr,
- addr . sin6_addr . s6_addr,
- sizeof ( ep -> u . ipv6 . addr ) );
- ep -> u.ipv6.port = ntohs( addr . sin6_port );
- ep -> type = epIPV6;
- }
-
- return rc;
-}
-
-
-/* *********************************************************************************************
-
- IPC implementation :
-
- static functions for vtable
- vtable
-
- KNSManagerMakeIPCConnection() ... called from KNSManagerMakeRetryTimedConnection()
- KNSManagerMakeIPCListener() ... called from KNSManagerMakeListener()
- KListenerIPCAccept() ... called from KListenerAccept()
-
-********************************************************************************************* */
-
-/* helper function called by KIPCSocketWhack() = static function for IPC-implementation vtable */
-static rc_t KIPCSocketWhack_unconnected_server_side_pipe ( KSocket * self )
-{
- rc_t rc = 0;
- KSocketIPC * data = &( self -> type_data.ipc_data );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: isIpcListener\n", self ) );
- if ( data->listenerPipe != INVALID_HANDLE_VALUE )
- {
- /* !!! In case there is an active call to ConnectNamedPipe()
- on some thread, "wake" the synchronous named pipe,
- otherwise DisconnectNamedPipe/CloseHandle will block forever */
- HANDLE hPipe = CreateFileW( data->pipename,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
-
- if ( hPipe != INVALID_HANDLE_VALUE )
- CloseHandle( hPipe );
-
- /* now, Disconnect/Close the original pipe */
- if ( !DisconnectNamedPipe( data->listenerPipe ) )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: DisconnectNamedPipe failed\n", self ) );
- }
-
- if ( !CloseHandle( data->listenerPipe ) )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: CloseHandle failed\n", self ) );
- }
- }
- return rc;
-}
-
-
-/* helper function called by KIPCSocketWhack() = static function for IPC-implementation vtable */
-static rc_t KIPCSocketWhack_server_side_pipe ( KSocket * self )
-{
- rc_t rc = 0;
- KSocketIPC * data = &( self -> type_data.ipc_data );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: isIpcPipeServer\n", self ) );
- if ( !FlushFileBuffers( data->pipe ) )
- {
- if ( GetLastError() != ERROR_BROKEN_PIPE )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: FlushFileBuffers failed, err=%d\n", self, GetLastError() ) );
- }
- }
- if ( !DisconnectNamedPipe( data -> pipe ) )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: DisconnectNamedPipe failed\n", self ) );
- }
- if ( !CloseHandle( data -> pipe ) )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: CloseHandle failed\n", self ) );
- }
- return rc;
-}
-
-
-/* helper function called by KIPCSocketWhack() = static function for IPC-implementation vtable */
-static rc_t KIPCSocketWhack_client_side_pipe ( KSocket * self )
-{
- rc_t rc = 0;
- KSocketIPC * data = &( self -> type_data.ipc_data );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: isIpcPipeClient\n", self ) );
- if ( !CloseHandle( data -> pipe ) )
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: CloseHandle failed\n", self ) );
- }
- return rc;
-}
-
-
-/* static function for IPC-implementation vtable */
-static rc_t CC KIPCSocketWhack ( KSocket * self )
-{
- rc_t rc = 0;
- /* we tolerate a whack on a NULL-pointer */
- if ( self == NULL ) return rc;
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: KIPCSocketWhack()...\n", self ) );
- switch ( self -> type_data.ipc_data.type )
- {
- case isIpcListener : rc = KIPCSocketWhack_unconnected_server_side_pipe ( self ); break;
-
- case isIpcPipeServer : rc = KIPCSocketWhack_server_side_pipe ( self ); break;
-
- case isIpcPipeClient : rc = KIPCSocketWhack_client_side_pipe ( self ); break;
- }
-
- free ( self );
- return rc;
-}
-
-
-/* helper function called by KIPCSocketTimedRead() = static function for IPC-implementation vtable */
-static rc_t WaitForData( const KSocket * self, void * buffer, size_t bsize,
- size_t * num_read, uint32_t * tmMs, OVERLAPPED * overlap )
-{
- /* received a ERROR_NO_DATA trying to read from a pipe; wait for the data to arrive or a time out to expire */
- /* on success, will leave tmMs set to the remaining portion of timeout, if specified */
-
- const KSocketIPC * data = &( self -> type_data.ipc_data );
- uint32_t tm_decrement = 100;
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: no data on the pipe - going into a wait loop, tm=%d\n",
- self, tmMs == 0 ? -1 : *tmMs ) );
- while ( true )
- {
- BOOL ret;
- DWORD count;
-
- if ( tmMs != NULL )
- {
- if ( *tmMs <= tm_decrement )
- {
- CloseHandle( overlap -> hEvent );
- return RC ( rcNS, rcFile, rcReading, rcTimeout, rcExhausted );
- }
- *tmMs -= tm_decrement;
- }
-
- /* *usually* returns FALSE in asynch mode */
- ret = ReadFile( data -> pipe, buffer, ( DWORD )bsize, &count, overlap );
- if ( ret )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: (wait loop) ReadFile completed synchronously, count=%d\n",
- self, count ) );
- assert ( num_read != NULL );
- * num_read = ( size_t ) count;
- CloseHandle( overlap -> hEvent );
- return 0;
- }
-
- switch ( GetLastError() )
- {
- case ERROR_IO_PENDING : return 0; /* the caller will wait for completion */
-
- case ERROR_NO_DATA :
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: (wait loop) Sleep(%d)\n", self, tm_decrement ) );
- Sleep( tm_decrement );
- break;
-
- case ERROR_SUCCESS: /* not expected in asynch mode */
- return RC ( rcNS, rcFile, rcReading, rcError, rcUnexpected);
-
- default:
- return HandleErrno();
- }
- }
- return 0;
-}
-
-
-/* static function for IPC-implementation vtable */
-static rc_t CC KIPCSocketTimedRead ( const KSocket * self, void * buffer, size_t bsize,
- size_t * num_read, timeout_t * tm )
-{
- rc_t rc = 0;
- const KSocketIPC * data = &( self -> type_data.ipc_data );
- OVERLAPPED overlap;
-
- if ( num_read == NULL )
- return RC ( rcNS, rcConnection, rcReading, rcParam, rcNull );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: KIPCSocketTimedRead(%d, %p, %d)... \n",
- self, tm == NULL ? -1 : tm -> mS, buffer, bsize ) );
-
- /* TODO: wait for pipe to become readable? */
- memset( &overlap, 0, sizeof( overlap ) );
- overlap.hEvent = CreateEvent( NULL, /* default security attribute */
- TRUE, /* manual reset event */
- FALSE, /* initial state = nonsignalled */
- NULL );
- if ( overlap.hEvent != NULL )
- {
- DWORD count;
-
- /* *usually* returns FALSE in asynch mode */
- BOOL ret = ReadFile( data->pipe, buffer, ( DWORD )bsize, &count, &overlap );
- if ( ret )
- {
- /* done: must be synch mode */
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: ReadFile completed synchronously, count=%d\n", self, count ) );
- * num_read = ( size_t ) count;
- CloseHandle( overlap.hEvent );
- return 0;
- }
-
- *num_read = 0;
-
- /* asynch mode - wait for the operation to complete */
- if ( GetLastError() == ERROR_NO_DATA ) /* 232 */
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: ReadFile(%x) returned FALSE, GetLastError() = ERROR_NO_DATA\n", self, data -> pipe ) );
- rc = WaitForData( self, buffer, bsize, num_read, tm == NULL ? NULL : &tm -> mS, &overlap );
- if ( *num_read != 0 ) /* read completed*/
- {
- CloseHandle( overlap.hEvent );
- return 0;
- }
- if ( rc != 0 )
- {
- CloseHandle( overlap.hEvent );
- return rc;
- }
- }
-
- if ( GetLastError() == ERROR_IO_PENDING ) /* 997 */
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: ReadFile(%x) returned FALSE, GetLastError() = ERROR_IO_PENDING\n",
- self, data -> pipe ) );
-
- if ( tm == NULL )
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: waiting forever\n", self ) );
- else
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: waiting for %d ms\n", self, tm -> mS ) );
-
- switch ( WaitForSingleObject( overlap.hEvent, tm == NULL ? INFINITE : tm -> mS ) )
- {
- case WAIT_TIMEOUT :
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: timed out\n", self ) );
- rc = RC ( rcNS, rcFile, rcReading, rcTimeout, rcExhausted );
- break;
-
- case WAIT_OBJECT_0 :
- {
- DWORD count;
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: successful\n", self ) );
- /* wait to complete if necessary */
- if ( GetOverlappedResult( data->pipe, &overlap, &count, TRUE ) )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: %d bytes read\n", self, count ) );
- * num_read = ( size_t ) count;
- rc = 0;
- }
- else
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: GetOverlappedResult() failed\n", self ) );
- }
- break;
- }
-
- default:
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: WaitForSingleObject() failed\n", self ) );
- break;
- }
- }
- else if ( GetLastError() == ERROR_SUCCESS )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: ReadFile(%x) returned FALSE, GetLastError() = ERROR_SUCCESS\n",
- self, data -> pipe ) );
- rc = RC ( rcNS, rcFile, rcReading, rcError, rcUnexpected );
- }
- else
- {
- rc = HandleErrno();
- }
- CloseHandle( overlap.hEvent );
- }
- else
- rc = HandleErrno();
-
- return rc;
-}
-
-
-/* static function for IPC-implementation vtable */
-static rc_t CC KIPCSocketRead ( const KSocket *self, void * buffer, size_t bsize, size_t *num_read )
-{
- timeout_t tm;
-
- if ( self == NULL )
- return RC ( rcNS, rcConnection, rcReading, rcSelf, rcNull );
-
- if ( self -> read_timeout < 0 )
- return KIPCSocketTimedRead ( self, buffer, bsize, num_read, NULL );
-
- TimeoutInit ( & tm, self -> read_timeout );
- return KIPCSocketTimedRead ( self, buffer, bsize, num_read, & tm );
-}
-
-
-/* static function for IPC-implementation vtable */
-static rc_t CC KIPCSocketTimedWrite ( KSocket * self, const void * buffer, size_t bsize,
- size_t * num_writ, timeout_t * tm )
-{
- rc_t rc = 0;
- KSocketIPC * data;
- OVERLAPPED overlap;
-
- if ( self == NULL )
- return RC ( rcNS, rcConnection, rcWriting, rcSelf, rcNull );
-
- data = &( self -> type_data.ipc_data );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: KIPCSocketTimedWrite(%d, %d)...", "b=%p,s=%d,t=%d\n",
- self, bsize, tm == NULL ? -1 : tm -> mS ) );
-
- memset( &overlap, 0, sizeof( overlap ) );
-
- overlap.hEvent = CreateEvent( NULL, /* default security attribute */
- TRUE, /* manual reset event */
- FALSE, /* initial state = nonsignalled */
- NULL);
- if ( overlap.hEvent != NULL )
- {
- DWORD count;
-
- /* returns FALSE in asynch mode */
- BOOL ret = WriteFile( data->pipe, buffer, ( DWORD )bsize, &count, &overlap );
- int err = GetLastError();
- /*DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: WriteFile returned %s, GetError() = %d\n", base, ret ? "TRUE" : "FALSE", err ) ); */
-
- /* completed synchronously; either message is so short that is went out immediately, or the pipe is full */
- if ( ret )
- {
- if ( count > 0 )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: %d bytes written\n", self, count ) );
- if ( num_writ != NULL )
- * num_writ = ( size_t ) count;
- CloseHandle( overlap.hEvent );
- return 0;
- }
- else
- {
- /* pipe is full - go into a wait loop */
- uint32_t tm_left = ( tm == NULL ) ? 0 : tm -> mS;
- uint32_t tm_decrement = 100;
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: pipe full - going into a wait loop for %d ms\n",
- self, ( tm == NULL ) ? -1 : tm -> mS ) );
- while ( count == 0 )
- {
- if ( tm != NULL )
- {
- if ( tm_left <= tm_decrement )
- {
- CloseHandle( overlap.hEvent );
- return RC ( rcNS, rcFile, rcWriting, rcTimeout, rcExhausted );
- }
- tm_left -= tm_decrement;
- }
-
- Sleep( 1 ); /*ms*/
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: write wait loop: attempting to WriteFile\n", self ) );
-
- /* returns FALSE in asynch mode */
- ret = WriteFile( data->pipe, buffer, ( DWORD )bsize, &count, &overlap );
- err = GetLastError();
- /* DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: WriteFile returned %s, GetError() = %d\n", base, ret ? "TRUE" : "FALSE", err ) ); */
- if ( !ret )
- break; /* and proceed to handling the asynch mode */
- }
- }
- }
-
- /* asynch mode - wait for the operation to complete */
- switch ( err ) /* set by the last call to WriteFile */
- {
- case NO_ERROR:
- case ERROR_IO_PENDING:
- {
- switch ( WaitForSingleObject( overlap.hEvent, tm == NULL ? INFINITE : tm -> mS ) )
- {
- case WAIT_TIMEOUT:
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: timed out\n", self ) );
- CloseHandle( overlap.hEvent );
- return RC ( rcNS, rcStream, rcWriting, rcTimeout, rcExhausted );
-
- case WAIT_OBJECT_0:
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: successful\n", self ) );
- /* wait to complete if necessary */
- if ( GetOverlappedResult( data->pipe, &overlap, &count, TRUE ) )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: %d bytes written\n", self, count ) );
- if ( num_writ != NULL )
- * num_writ = count;
- CloseHandle( overlap.hEvent );
- return 0;
- }
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: GetOverlappedResult() failed\n", self ) );
- break;
- }
-
- default:
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: WaitForSingleObject() failed\n", self ) );
- break;
- }
- }
- case ERROR_NO_DATA:
- /* the secret MS lore says when WriteFile to a pipe returns ERROR_NO_DATA, it's
- "Pipe was closed (normal exit path)." - see http://support.microsoft.com/kb/190351 */
- CloseHandle( overlap.hEvent );
- return 0;
-
- default:
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: WriteFile() failed\n", self ) );
- break;
- }
-
- CloseHandle( overlap.hEvent );
- }
- else
- rc = HandleErrno();
-
- return rc;
-}
-
-
-/* static function for IPC-implementation vtable */
-static rc_t CC KIPCSocketWrite ( KSocket *self, const void * buffer, size_t bsize, size_t * num_writ )
-{
- timeout_t tm;
-
- if ( self == NULL )
- return RC ( rcNS, rcConnection, rcWriting, rcSelf, rcNull );
-
- if ( self -> write_timeout < 0 )
- return KIPCSocketTimedWrite ( self, buffer, bsize, num_writ, NULL );
-
- TimeoutInit ( & tm, self -> write_timeout );
- return KIPCSocketTimedWrite ( self, buffer, bsize, num_writ, & tm );
-}
-
-
-static KStream_vt_v1 vtKIPCSocket =
-{
- 1, 1,
- KIPCSocketWhack,
- KIPCSocketRead,
- KIPCSocketWrite,
- KIPCSocketTimedRead,
- KIPCSocketTimedWrite
-};
-
-
-static rc_t KNSManagerMakeIPCConnection ( struct KNSManager const *self,
- KSocket **out,
- const KEndPoint *to,
- int32_t retryTimeout,
- int32_t readMillis,
- int32_t writeMillis )
-{
- rc_t rc = 0;
- uint8_t retry_count = 0;
- char pipename[ PIPE_NAME_LENGTH ];
- wchar_t pipenameW[ PIPE_NAME_LENGTH ];
- size_t num_writ;
-
- if ( self == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcSelf, rcNull );
- if ( out == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcNull );
-
- * out = NULL;
-
- if ( to == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcNull );
- if ( to -> type != epIPC )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcInvalid );
-
- /* use named pipes to implement unix domain socket - like behavior */
- rc = string_printf( pipename, sizeof( pipename ), &num_writ, "\\\\.\\pipe\\%s", to->u.ipc_name );
- if ( rc == 0 )
- string_cvt_wchar_copy( pipenameW, sizeof( pipenameW ), pipename, num_writ );
-
- while ( rc == 0 )
- {
- HANDLE h = CreateFileW( pipenameW, /* pipe name */
- GENERIC_READ | GENERIC_WRITE, /* read and write access */
- 0, /* no sharing */
- NULL, /* default security attributes */
- OPEN_EXISTING, /* opens existing pipe */
- FILE_FLAG_OVERLAPPED, /* using overlapped IO */
- NULL ); /* no template file */
- if ( h != INVALID_HANDLE_VALUE )
- { /* create the KSocket */
- /* need NOWAIT if pipe is created in asynch mode */
- DWORD dwMode = ( PIPE_READMODE_MESSAGE | PIPE_NOWAIT );
- if ( SetNamedPipeHandleState ( h, /* pipe handle */
- &dwMode, /* new pipe mode */
- NULL, /* don't set maximum bytes */
- NULL ) ) /* don't set maximum time */
- {
- KSocket* ksock = calloc ( sizeof * ksock, 1 );
-
- if ( ksock == NULL )
- rc = RC ( rcNS, rcNoTarg, rcAllocating, rcNoObj, rcNull );
- else
- {
- KSocketIPC * data;
- /* initialize the KSocket */
- rc = KStreamInit ( & ksock -> dad, ( const KStream_vt* ) & vtKIPCSocket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ),
- ( "%p: KNSManagerMakeIPCConnection(%p,'%s')\n",
- ksock, to, pipename ) );
-
- ksock -> read_timeout = readMillis;
- ksock -> write_timeout = writeMillis;
- ksock -> type = epIPC;
- data = &( ksock -> type_data.ipc_data );
- data -> type = isIpcPipeClient;
- data -> pipe = h;
- *out = ( KSocket * )& ksock -> dad;
- return 0;
- }
- free ( ksock );
- }
- }
- else
- rc = HandleErrno();
- }
- else /* CreateFileW failed */
- {
- switch ( GetLastError() )
- {
- case ERROR_PIPE_BUSY :
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KNSManagerMakeIPCConnection: pipe busy, retrying\n" ) );
- {
- BOOL pipeAvailable = WaitNamedPipeW( pipenameW, NMPWAIT_USE_DEFAULT_WAIT );
- if ( pipeAvailable )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KNSManagerMakeIPCConnection: WaitNamedPipeW returned TRUE\n" ) );
- continue;
- }
- /* time-out, try again */
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KNSManagerMakeIPCConnection: WaitNamedPipeW returned FALSE(timeout)\n" ) );
- if ( retryTimeout < 0 || retry_count < retryTimeout )
- {
- Sleep( 1000 ); /* ms */
- ++retry_count;
- rc = 0;
- continue;
- }
- }
- break;
-
- case ERROR_FILE_NOT_FOUND :
- if ( retryTimeout < 0 || retry_count < retryTimeout )
- {
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KNSManagerMakeIPCConnection: pipe not found, retrying\n" ) );
- Sleep( 1000 ); /* ms */
- ++retry_count;
- rc = 0;
- continue;
- }
- else
- rc = HandleErrno();
- break;
-
- default:
- rc = HandleErrno();
- break;
- }
- }
- break;
- }
- return rc;
-}
-
-
-static rc_t KNSManagerMakeIPCListener( struct KNSManager const *self, struct KSocket** out,
- struct KEndPoint const * ep )
-{
- rc_t rc = 0;
- KSocket * ksock;
-
- if ( self == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcSelf, rcNull );
- if ( out == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcNull );
-
- * out = NULL;
-
- if ( ep == NULL )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcNull );
- if ( ep -> type != epIPC )
- return RC ( rcNS, rcConnection, rcCreating, rcParam, rcInvalid );
-
-
- /* use named pipes to implement unix domain socket - like behavior */
- ksock = calloc ( sizeof *ksock, 1 );
- if ( ksock == NULL )
- rc = RC ( rcNS, rcNoTarg, rcAllocating, rcNoObj, rcNull );
- else
- {
- ksock -> read_timeout = self -> conn_read_timeout;
- ksock -> write_timeout = self -> conn_write_timeout;
-
- rc = KStreamInit ( & ksock -> dad, ( const KStream_vt* ) & vtKIPCSocket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- size_t num_writ;
- char pipename[ PIPE_NAME_LENGTH ];
- rc = string_printf( pipename, sizeof( pipename ), &num_writ, "\\\\.\\pipe\\%s", ep -> u . ipc_name );
- if ( rc == 0 )
- {
- KSocketIPC * data = &( ksock -> type_data.ipc_data );
- string_cvt_wchar_copy( data -> pipename, sizeof( data -> pipename ), pipename, num_writ );
-
- data -> type = isIpcListener;
- data -> listenerPipe = INVALID_HANDLE_VALUE;
- ksock -> type = epIPC;
- *out = ( KSocket * )& ksock -> dad;
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: KNSManagerMakeIPCListener(%p,'%s')\n",
- ksock, ep, pipename ) );
- return 0;
- }
- KIPCSocketWhack( ksock );
- }
- else
- free ( ksock );
- }
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: KNSManagerMakeIPCListener failed\n", ksock ) );
- return rc;
-}
-
-
-static rc_t KListenerIPCAccept ( KSocket * self, struct KSocket ** out )
-{
- rc_t rc = 0;
- KSocketIPC * data = &( self -> type_data.ipc_data );
-
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: KSocketAccept\n", self ) );
-
- /* make sure listener points to a KIPCSocket */
- if ( data->type != isIpcListener )
- return RC ( rcNS, rcNoTarg, rcValidating, rcParam, rcInvalid );
-
- data -> listenerPipe = CreateNamedPipeW( data -> pipename, /* pipe name */
- FILE_FLAG_OVERLAPPED | /* using overlapped IO */
- PIPE_ACCESS_DUPLEX, /* read/write access */
- PIPE_TYPE_MESSAGE | /* message type pipe */
- PIPE_READMODE_MESSAGE | /* message-read mode */
- PIPE_WAIT, /* blocking mode */
- PIPE_UNLIMITED_INSTANCES,/* max. instances */
- 1024, /* output buffer size */
- 1024, /* input buffer size */
- 0, /* client time-out */
- NULL ); /* default security attribute */
- if ( data -> listenerPipe != INVALID_HANDLE_VALUE )
- {
- OVERLAPPED overlap;
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: calling CreateEvent\n" ) );
- overlap.hEvent = CreateEvent( NULL, /* default security attribute */
- TRUE, /* manual reset event */
- FALSE, /* initial state = nonsignalled */
- NULL );
- if ( overlap.hEvent != NULL )
- {
- BOOL connected = ConnectNamedPipe( data -> listenerPipe, &overlap );
- /*DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: calling ConnectNamedPipe\n") );*/
- if ( !connected ) /* normal for asynch mode */
- {
- switch ( GetLastError() )
- {
- case ERROR_PIPE_CONNECTED: /* client connected since the call to CreateNamedPipeW */
- break;
-
- case ERROR_IO_PENDING:
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: calling WaitForSingleObject\n" ) );
- if ( WaitForSingleObject( overlap.hEvent, INFINITE ) != WAIT_OBJECT_0 )
- {
- rc = HandleErrno();
- CloseHandle( overlap.hEvent );
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: WaitForSingleObject failed\n" ) );
- return rc;
- }
- break;
-
- default:
- rc = HandleErrno();
- CloseHandle( overlap.hEvent );
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: ConnectNamedPipe failed\n" ) );
- return rc;
- }
- }
- /* we are connected, create the socket stream */
- {
- KSocket * ksock = calloc ( sizeof * ksock, 1 );
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "%p: KSocketAccept\n", ksock ) );
-
- if ( ksock == NULL )
- {
- rc = RC ( rcNS, rcSocket, rcAllocating, rcNoObj, rcNull );
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: calloc failed\n" ) );
- }
- else
- {
- rc = KStreamInit ( & ksock -> dad, ( const KStream_vt* ) & vtKIPCSocket,
- "KSocket", "tcp", true, true );
- if ( rc == 0 )
- {
- KSocketIPC * ksock_data = &( ksock -> type_data.ipc_data );
- ksock -> type = epIPC;
- ksock_data -> type = isIpcPipeServer;
- ksock_data -> pipe = data -> listenerPipe;
- ksock_data -> listenerPipe = INVALID_HANDLE_VALUE; /* this is only to be used while ConnectNamedPipe() is in progress */
- *out = ( KSocket * )& ksock -> dad;
- CloseHandle( overlap.hEvent );
- return 0;
- }
- free ( ksock );
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: KStreamInit failed\n" ) );
- }
- CloseHandle( overlap.hEvent );
- return rc;
- }
- }
- }
- else
- {
- rc = HandleErrno();
- DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_SOCKET ), ( "KSocketAccept: CreateNamedPipeW failed\n" ) );
- }
- return rc;
-}
-
-
-/* *********************************************************************************************
-
- exported KSocket - interface :
-
- KNSManagerMakeConnection() ... implemented in manager.c calling KNSManagerMakeRetryTimedConnection()
- KNSManagerMakeTimedConnection() ... like KNSManagerMakeConnection()
- KNSManagerMakeRetryConnection() ... like KNSManagerMakeConnection()
- KNSManagerMakeRetryTimedConnection() ... switches via endpoint.type into correct implementation specific creation
- KSocketAddRef(); ... delegates to KStreamAddRef()
- KSocketRelease(); ... delegates to KStreamRelease() calls correct destroy-function via vtable
- KSocketGetStream(); ... returns the internal KStream obj, which has its vtable wired to the implementation specific functions
- KSocketGetRemoteEndpoint(); ... delegates to KSocketGetEndpoint() which switches via socket.type into implementations specific functions
- KSocketGetLocalEndpoint(); ... same as above
-
-********************************************************************************************* */
-
-LIB_EXPORT rc_t CC KNSManagerMakeRetryTimedConnection ( const KNSManager * self,
- KSocket **out,
- int32_t retryTimeout,
- int32_t readMillis,
- int32_t writeMillis,
- const KEndPoint *from,
- const KEndPoint *to )
-{
- rc_t rc;
-
- if ( out == NULL )
- rc = RC ( rcNS, rcStream, rcConstructing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcStream, rcConstructing, rcSelf, rcNull );
- else if ( to == NULL )
- rc = RC ( rcNS, rcStream, rcConstructing, rcParam, rcNull );
- else if ( from != NULL && from -> type != to -> type )
- rc = RC ( rcNS, rcStream, rcConstructing, rcParam, rcIncorrect );
- else
- {
- switch ( to -> type )
- {
- case epIPV4 :
- rc = KNSManagerMakeIPv4Connection ( self, out, from, to, retryTimeout, readMillis, writeMillis );
- break;
-
- case epIPV6 :
- rc = KNSManagerMakeIPv6Connection ( self, out, from, to, retryTimeout, readMillis, writeMillis );
- break;
-
- case epIPC :
- rc = KNSManagerMakeIPCConnection ( self, out, to, retryTimeout, readMillis, writeMillis );
- break;
-
- default:
- rc = RC ( rcNS, rcStream, rcConstructing, rcParam, rcIncorrect );
- }
-
- if ( rc == 0 )
- return 0;
- }
-
- * out = NULL;
- }
- return rc;
-}
-
-
-LIB_EXPORT rc_t CC KSocketAddRef( const KSocket *self )
-{ /* this will handle all derived types */
- return KStreamAddRef( &self -> dad );
-}
-
-
-LIB_EXPORT rc_t CC KSocketRelease( const KSocket *self )
-{ /* this will handle all derived types, it will call the correct whack-function via VTable ! */
- return KStreamRelease( &self -> dad );
-}
-
-
-LIB_EXPORT rc_t CC KSocketGetStream ( const KSocket * self, KStream ** s )
-{
- rc_t rc;
-
- if ( s == NULL )
- rc = RC ( rcNS, rcSocket, rcOpening, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcSocket, rcOpening, rcSelf, rcNull );
- else
- {
- rc = KSocketAddRef ( self );
- if ( rc == 0 )
- {
- * s = & ( ( KSocket* ) self ) -> dad;
- return 0;
- }
- }
-
- * s = NULL;
- }
-
- return rc;
-}
-
-
-/* helper-function called by KSocketGetRemoteEndpoint() and KSocketGetLocalEndpoint() */
-static rc_t KSocketGetEndpoint ( const KSocket * self, KEndPoint * ep, bool remote )
-{
- rc_t rc = 0;
- if ( ep == NULL )
- rc = RC ( rcNS, rcSocket, rcEvaluating, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcSocket, rcEvaluating, rcSelf, rcNull );
- else
- {
- rc = RC ( rcNS, rcSocket, rcEvaluating, rcFunction, rcUnsupported );
- switch( self->type )
- {
- case epIPV4 : rc = KSocketGetEndpointV4( self, ep, remote ); break;
- case epIPV6 : rc = KSocketGetEndpointV6( self, ep, remote ); break;
- default : rc = RC ( rcNS, rcSocket, rcEvaluating, rcFunction, rcUnsupported );
- }
- }
- }
- return rc;
-}
-
-
-LIB_EXPORT rc_t CC KSocketGetRemoteEndpoint ( const KSocket * self, KEndPoint * ep )
-{
- return KSocketGetEndpoint ( self, ep, true );
-}
-
-
-LIB_EXPORT rc_t CC KSocketGetLocalEndpoint ( const KSocket * self, KEndPoint * ep )
-{
- return KSocketGetEndpoint ( self, ep, false );
-}
-
-
-/* *********************************************************************************************
-
- exported KListener - interface ( from kns/socket.h ):
-
- KNSManagerMakeListener() ... switches via endpoint.type into implementations
- KListenerAddRef() ... delegates to KSocketAddRef()
- KListenerRelease() ... delegates to KSocketRelease()
- KListenerAccept() ... switches via socket.type into implementations
-
-********************************************************************************************* */
-
-LIB_EXPORT rc_t CC KNSManagerMakeListener( struct KNSManager const *self,
- struct KListener ** out,
- struct KEndPoint const * ep )
-{
- rc_t rc;
-
- if ( out == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcSelf, rcNull );
- else if ( ep == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcParam, rcNull );
- else
- {
- switch ( ep -> type )
- {
- case epIPV4:
- rc = KNSManagerMakeIPv4Listener ( self, ( struct KSocket** ) out, ep );
- break;
-
- case epIPV6:
- rc = KNSManagerMakeIPv6Listener ( self, ( struct KSocket** ) out, ep );
- break;
-
- case epIPC:
- rc = KNSManagerMakeIPCListener ( self, ( struct KSocket** ) out, ep );
- break;
-
- default:
- rc = RC ( rcNS, rcSocket, rcConstructing, rcParam, rcIncorrect );
- }
-
- if ( rc == 0 )
- return 0;
- }
-
- * out = NULL;
- }
-
- return rc;
-}
-
-
-LIB_EXPORT rc_t CC KListenerAddRef( const KListener *self )
-{
- return KSocketAddRef ( ( const KSocket* ) self );
-}
-
-
-LIB_EXPORT rc_t CC KListenerRelease( const KListener *self )
-{
- return KSocketRelease ( ( const KSocket* ) self );
-}
-
-
-LIB_EXPORT rc_t CC KListenerAccept ( KListener * self, struct KSocket ** out )
-{
- rc_t rc;
-
- if ( out == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcParam, rcNull );
-
- * out = NULL;
-
- if ( self == NULL )
- rc = RC ( rcNS, rcSocket, rcConstructing, rcSelf, rcNull );
- else
- {
- KSocket * listener = ( KSocket * ) self;
- switch( listener -> type )
- {
- case epIPV4 : rc = KListenerIPv4Accept ( listener, out ); break;
- case epIPV6 : rc = KListenerIPv6Accept ( listener, out ); break;
- case epIPC : rc = KListenerIPCAccept ( listener, out ); break;
- }
- }
- return rc;
-}
-
-
-/* *********************************************************************************************
-
- Local helpers
-
-********************************************************************************************* */
-
-static rc_t HandleErrnoEx ( const char *func_name, unsigned int lineno )
-{
- rc_t rc;
- int lerrno = WSAGetLastError();
-
- switch ( lerrno )
- {
- case ERROR_FILE_NOT_FOUND:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcFile, rcNotFound );
- break;
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcInvalid );
- break;
- case ERROR_INVALID_PARAMETER:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcParam, rcInvalid );
- break;
- case ERROR_PIPE_BUSY:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcCanceled );
- break;
- case ERROR_SEM_TIMEOUT:
- rc = RC ( rcNS, rcStream, rcReading, rcTimeout, rcExhausted );
- break;
- case WSAEACCES: /* write permission denied */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMemory, rcUnauthorized );
- break;
- case WSAEADDRINUSE:/* address is already in use */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMemory, rcExists );
- break;
- case WSAEADDRNOTAVAIL: /* requested address was not local */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMemory, rcNotFound );
- break;
- case WSAEAFNOSUPPORT: /* address didnt have correct address family in ss_family field */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcName, rcInvalid );
- break;
- case WSAEALREADY: /* socket is non blocking and a previous connection has not yet completed */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUndefined );
- break;
- case WSAECONNABORTED: /* virtual circuit terminated. Application should close socket */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcInterrupted );
- break;
- case WSAECONNREFUSED: /* remote host refused to allow network connection */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcCanceled );
- break;
- case WSAECONNRESET: /* connection reset by peer */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcCanceled );
- break;
- case WSAEFAULT: /* name paremeter is not valid part of addr space */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMemory, rcOutofrange );
- break;
- case WSAEHOSTUNREACH: /* remote hoste cannot be reached at this time */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcNotAvailable );
- break;
- case WSAEINPROGRESS: /* call is in progress */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUndefined );
- break;
- case WSAEINVAL: /* invalid argument */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcParam, rcInvalid );
- break;
- case WSAEISCONN: /* connected already */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcExists );
- break;
- case WSAEMSGSIZE: /* msg size too big */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcMessage, rcExcessive );
- break;
- case WSAENETDOWN:/* network subsystem failed */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcNoObj, rcFailed );
- break;
- case WSAENETRESET: /* connection broken due to keep-alive activity that
- detected a failure while in progress */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcCanceled );
- break;
- case WSAENETUNREACH: /* network is unreachable */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcNotAvailable );
- break;
- case WSAENOBUFS: /* output queue for a network connection was full.
- ( wont typically happen in linux. Packets are just silently dropped */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcInterrupted );
- break;
- case ERROR_PIPE_NOT_CONNECTED:
- case WSAENOTCONN: /* socket is not connected */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcInvalid );
- break;
- case WSANOTINITIALISED: /* Must have WSAStartup call */
- rc = RC ( rcNS, rcNoTarg, rcInitializing, rcEnvironment, rcUndefined );
- break;
- case WSAENOTSOCK: /* sock fd is not a socket */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcInvalid );
- break;
- case WSAEOPNOTSUPP: /* socket is not stream-style such as SOCK_STREAM */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUnsupported );
- break;
- case WSAEPROTONOSUPPORT: /* specified protocol is not supported */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcAttr, rcUnsupported );
- break;
- case WSAEPROTOTYPE: /* wrong type of protocol for this socket */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUnsupported );
- break;
- case WSAEPROVIDERFAILEDINIT: /* service provider failed to initialize */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcTransfer, rcIncorrect );
- break;
- case ERROR_BROKEN_PIPE:
- case WSAESHUTDOWN: /* socket had been shutdown */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUnsupported );
- break;
- case WSAESOCKTNOSUPPORT: /* specified socket type is not supported */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcId, rcUnsupported );
- break;
- case WSAETIMEDOUT: /* connection dropped because of network failure */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcConnection, rcCanceled );
- break;
- case WSAEWOULDBLOCK: /* socket is marked as non-blocking but the recv operation
- would block */
- rc = RC ( rcNS, rcNoTarg, rcReading, rcCmd, rcBusy );
- break;
-
- case WSAEINTR: /* call was cancelled */
- case WSAEMFILE: /* no more socket fd available */
- default:
- rc = RC ( rcNS, rcNoTarg, rcReading, rcError, rcUnknown );
- PLOGERR ( klogErr, ( klogErr, rc, "unknown system error '$(S)($(E))', line=$(L)",
- "S=%!,E=%d,L=%d", lerrno, lerrno, lineno ) );
- }
- return rc;
-}
-
diff --git a/libs/kns/win/sysstream.c b/libs/kns/win/sysstream.c
deleted file mode 100644
index 55e7e87..0000000
--- a/libs/kns/win/sysstream.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-/*--------------------------------------------------------------------------
- * forwards
- */
-#define KSTREAM_IMPL KStdIOStream
-typedef struct KStdIOStream KStdIOStream;
-
-#include <kns/extern.h>
-#include <kns/stream.h>
-#include <kns/impl.h>
-#include <klib/rc.h>
-#include <klib/log.h>
-
-#include <sysalloc.h>
-
-#include "stream-priv.h"
-
-#include <assert.h>
-
-#include <os-native.h>
-
-/*--------------------------------------------------------------------------
- * KStdIOStream
- * a virtual stream
- */
-struct KStdIOStream
-{
- KStream dad;
- HANDLE fd;
-};
-
-static
-rc_t CC KStdIOStreamWhack ( KStdIOStream *self )
-{
- /* we don't close self->fd because we did not open it */
- free ( self );
- return 0;
-}
-
-static
-rc_t CC KStdIOStreamRead ( const KStdIOStream *self,
- void *buffer, size_t bsize, size_t *num_read )
-{
- DWORD to_read;
-
- assert ( self != NULL );
-
- to_read = ( DWORD ) bsize;
- if ( ( size_t ) to_read < bsize )
- to_read = -1;
-
- while ( 1 )
- {
- rc_t rc;
- DWORD count, lerrno;
-
- if ( ReadFile ( self -> fd, buffer, to_read, & count, NULL ) )
- {
- * num_read = count;
- break;
- }
-
- lerrno = GetLastError ();
- switch ( lerrno )
- {
- case ERROR_HANDLE_EOF:
- * num_read = 0;
- break;
- case ERROR_IO_PENDING:
- continue;
- default:
- rc = RC ( rcNS, rcStream, rcReading, rcNoObj, rcUnknown );
- PLOGERR ( klogErr,
- ( klogErr, rc, "unknown system error '$(S)($(E))'",
- "S=%!,E=%d", lerrno, lerrno ) );
- return rc;
- }
- break;
- }
-
- return 0;
-}
-
-static
-rc_t CC KStdIOStreamWrite ( KStdIOStream *self,
- const void *buffer, size_t size, size_t *num_writ )
-{
- DWORD to_write;
-
- assert ( self != NULL );
-
- to_write = ( DWORD ) size;
- if ( ( size_t ) to_write < size )
- to_write = -1;
-
- * num_writ = 0;
-
- while ( 1 )
- {
- rc_t rc;
- DWORD lerrno, count = 0;
-
- if ( WriteFile ( self -> fd, buffer, to_write, & count, NULL ) == 0 )
- {
- * num_writ += count;
- break;
- }
-
- lerrno = GetLastError ();
- switch ( lerrno )
- {
- case ERROR_IO_PENDING:
- if ( count != 0 )
- {
- buffer = & ( ( const char* ) buffer ) [ count ];
- to_write -= count;
- * num_writ += count;
- if ( to_write == 0 )
- break;
- }
- Sleep ( 100 );
- continue;
-
- case ERROR_NOT_ENOUGH_MEMORY:
- rc = RC ( rcNS, rcStream, rcWriting, rcStorage, rcExhausted );
- LOGERR ( klogSys, rc, "system device full error" );
- return rc;
-
- default:
- rc = RC ( rcNS, rcStream, rcWriting, rcNoObj, rcUnknown );
- PLOGERR ( klogErr,
- ( klogErr, rc, "unknown system error '$(S)($(E))'",
- "S=%!,E=%d", lerrno, lerrno ) );
- return rc;
- }
- break;
- }
-
- return 0;
-}
-
-static KStream_vt_v1 vtKStdIOStream =
-{
- 1, 0,
- KStdIOStreamWhack,
- KStdIOStreamRead,
- KStdIOStreamWrite
-};
-
-
-static
-rc_t KStdIOStreamMake ( KStream **sp, HANDLE fd, const char *strname,
- bool read_enabled, bool write_enabled )
-{
- rc_t rc;
-
- if ( sp == NULL )
- rc = RC ( rcNS, rcStream, rcConstructing, rcParam, rcNull );
- else
- {
- KStdIOStream *s = calloc ( sizeof *s, 1 );
- if ( s == NULL )
- rc = RC ( rcNS, rcStream, rcConstructing, rcMemory, rcExhausted );
- else
- {
- rc = KStreamInit ( & s -> dad, ( const KStream_vt* ) & vtKStdIOStream,
- "KStdIOStream", strname, read_enabled, write_enabled );
- if ( rc == 0 )
- {
- s -> fd = fd;
- * sp = & s -> dad;
- return 0;
- }
-
- free ( s );
- }
-
- * sp = NULL;
- }
-
- return rc;
-}
-
-/* MakeStdIn
- * creates a read-only stream on stdin
- */
-LIB_EXPORT rc_t CC KStreamMakeStdIn ( const KStream **std_in )
-{
- HANDLE fd = GetStdHandle ( STD_INPUT_HANDLE );
- return KStdIOStreamMake ( ( KStream** ) std_in, fd, "stdin", true, false );
-}
-
-/* MakeStdOut
- * MakeStdErr
- * creates a write-only stream on stdout or stderr
- */
-LIB_EXPORT rc_t CC KStreamMakeStdOut ( KStream **std_out )
-{
- HANDLE fd = GetStdHandle ( STD_OUTPUT_HANDLE );
- return KStdIOStreamMake ( std_out, fd, "stdout", false, true );
-}
-
-LIB_EXPORT rc_t CC KStreamMakeStdErr ( KStream **std_err )
-{
- HANDLE fd = GetStdHandle ( STD_ERROR_HANDLE );
- return KStdIOStreamMake ( std_err, fd, "stderr", false, true );
-}
diff --git a/libs/kproc/sun/sysbarrier.c b/libs/kproc/sun/sysbarrier.c
deleted file mode 100644
index 9fc3ddd..0000000
--- a/libs/kproc/sun/sysbarrier.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-#include <kproc/barrier.h>
-#include <klib/rc.h>
-#include <atomic32.h>
-#include <sysalloc.h>
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-
-/*--------------------------------------------------------------------------
- * KBarrier
- * a thread synchronization device
- * detains all callers until the required number has been reached
- */
-struct KBarrier
-{
- pthread_barrier_t barrier;
- atomic32_t refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KBarrierWhack ( KBarrier *self )
-{
- int status = pthread_barrier_destroy ( & self -> barrier );
- switch ( status )
- {
- case 0:
- break;
- case EBUSY:
- return RC ( rcPS, rcBarrier, rcDestroying, rcBarrier, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcBarrier, rcDestroying, rcBarrier, rcInvalid );
- default:
- return RC ( rcPS, rcBarrier, rcDestroying, rcNoObj, rcUnknown );
- }
- return 0;
-}
-
-
-/* Make
- * create a barrier
- *
- * "count" [ IN ] - the number of threads to block
- */
-LIB_EXPORT rc_t CC KBarrierMake ( KBarrier **bp, uint32_t count )
-{
- rc_t rc;
- if ( bp == NULL )
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcParam, rcNull );
- else
- {
- KBarrier *b = malloc ( sizeof * b );
- if ( b == NULL )
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcMemory, rcExhausted );
- else
- {
- int status = pthread_barrier_init ( & b -> barrier, NULL, count );
- if ( status == 0 )
- {
- atomic32_set ( & b -> refcount, 1 );
- * bp = b;
- return 0;
- }
-
- switch ( status )
- {
- case EINVAL:
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcParam, rcInvalid );
- break;
- case EBUSY:
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcBarrier, rcBusy );
- break;
- case EAGAIN:
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcBarrier, rcExhausted );
- break;
- case ENOMEM:
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcMemory, rcExhausted );
- break;
- default:
- rc = RC ( rcPS, rcBarrier, rcConstructing, rcNoObj, rcUnknown );
- }
-
- free ( b );
- }
-
- * bp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KBarrierAddRef ( const KBarrier *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KBarrier* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KBarrierRelease ( const KBarrier *cself )
-{
- KBarrier *self = ( KBarrier* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KBarrierWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* Wait
- * block until the required number of callers has been reached
- */
-LIB_EXPORT rc_t CC KBarrierWait ( KBarrier *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcBarrier, rcWaiting, rcSelf, rcNull );
-
- status = pthread_barrier_wait ( & self -> barrier );
- switch ( status )
- {
- case 0:
- break;
- case EINVAL:
- return RC ( rcPS, rcBarrier, rcWaiting, rcBarrier, rcInvalid );
- default:
- return RC ( rcPS, rcBarrier, rcWaiting, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
diff --git a/libs/kproc/sun/syslock-priv.h b/libs/kproc/sun/syslock-priv.h
deleted file mode 100644
index e47d508..0000000
--- a/libs/kproc/sun/syslock-priv.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_syslock_priv_
-#define _h_syslock_priv_
-
-/* BEGIN HACK to get rwlocks defined */
-#include <stdint.h>
-#include <stddef.h>
-
-#undef __USE_UNIX98
-#define __USE_UNIX98 1
-
-#undef __USE_XOPEN2K
-#define __USE_XOPEN2K 1
-/* END HACK */
-
-#include <pthread.h>
-#include <atomic32.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*--------------------------------------------------------------------------
- * KLock
- * a POSIX-style mutual exclusion lock
- */
-struct KLock
-{
- pthread_mutex_t mutex;
- atomic32_t refcount;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_syslock_priv_ */
diff --git a/libs/kproc/sun/syslock.c b/libs/kproc/sun/syslock.c
deleted file mode 100644
index 06d23ec..0000000
--- a/libs/kproc/sun/syslock.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-#include "syslock-priv.h"
-#include <os-native.h>
-#include <kproc/timeout.h>
-#include <kproc/lock.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <stdlib.h>
-#include <errno.h>
-
-/*--------------------------------------------------------------------------
- * KLock
- * a POSIX-style mutual exclusion lock
- */
-
-/* Whack
- */
-static
-rc_t KLockWhack ( KLock *self )
-{
- int status = pthread_mutex_destroy ( & self -> mutex );
- switch ( status )
- {
- case 0:
- break;
- case EBUSY:
- return RC ( rcPS, rcLock, rcDestroying, rcLock, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcLock, rcDestroying, rcLock, rcInvalid );
- default:
- return RC ( rcPS, rcLock, rcDestroying, rcNoObj, rcUnknown );
- }
-
- free ( self );
- return 0;
-}
-
-
-/* Make
- * make a simple mutex
- */
-LIB_EXPORT rc_t CC KLockMake ( KLock **lockp )
-{
- rc_t rc;
- if ( lockp == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcParam, rcNull );
- else
- {
- KLock *lock = malloc ( sizeof * lock );
- if ( lock == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcMemory, rcExhausted );
- else
- {
- int status = pthread_mutex_init ( & lock -> mutex, NULL );
- if ( status == 0 )
- {
- atomic32_set ( & lock -> refcount, 1 );
- * lockp = lock;
- return 0;
- }
-
- /* pthread_mutex_init is documented as always returning 0 */
- rc = RC ( rcPS, rcLock, rcConstructing, rcNoObj, rcUnknown );
-
- free ( lock );
- }
-
- * lockp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KLockAddRef ( const KLock *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KLock* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KLockRelease ( const KLock *cself )
-{
- KLock *self = ( KLock* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KLockWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* Acquire
- * acquires lock
- */
-LIB_EXPORT rc_t CC KLockAcquire ( KLock *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_mutex_lock ( & self -> mutex );
- switch ( status )
- {
- case 0:
- break;
- case EDEADLK:
- return RC ( rcPS, rcLock, rcLocking, rcThread, rcDeadlock );
- case EINVAL:
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcInvalid );
- default:
- return RC ( rcPS, rcLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KLockTimedAcquire ( KLock *self, timeout_t *tm )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_mutex_trylock ( & self -> mutex );
- switch ( status )
- {
- case 0:
- return 0;
- case EBUSY:
- if ( tm != NULL )
- break;
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcInvalid );
- default:
- return RC ( rcPS, rcLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- if ( ! tm -> prepared )
- TimeoutPrepare ( tm );
-
- status = pthread_mutex_timedlock ( & self -> mutex, & tm -> ts );
- switch ( status )
- {
- case 0:
- break;
- case ETIMEDOUT:
- return RC ( rcPS, rcLock, rcLocking, rcTimeout, rcExhausted );
- case EINVAL:
- return RC ( rcPS, rcLock, rcLocking, rcTimeout, rcInvalid );
- default:
- return RC ( rcPS, rcLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-/* Unlock
- * releases lock
- */
-LIB_EXPORT rc_t CC KLockUnlock ( KLock *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcUnlocking, rcSelf, rcNull );
-
- status = pthread_mutex_unlock ( & self -> mutex );
- switch ( status )
- {
- case 0:
- break;
- case EPERM:
- return RC ( rcPS, rcLock, rcUnlocking, rcThread, rcIncorrect );
- case EINVAL:
- return RC ( rcPS, rcLock, rcUnlocking, rcLock, rcInvalid );
- default:
- return RC ( rcPS, rcLock, rcUnlocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- * KRWLock
- * a POSIX-style read/write lock
- */
-struct KRWLock
-{
- pthread_rwlock_t lock;
- atomic32_t refcount;
-};
-
-
-/* Whack
- */
-static
-rc_t KRWLockWhack ( KRWLock *self )
-{
- int status = pthread_rwlock_destroy ( & self -> lock );
- switch ( status )
- {
- case 0:
- break;
- case EBUSY:
- return RC ( rcPS, rcRWLock, rcDestroying, rcRWLock, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcDestroying, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcDestroying, rcNoObj, rcUnknown );
- }
-
- free ( self );
- return 0;
-}
-
-
-/* Make
- * make a simple read/write lock
- */
-LIB_EXPORT rc_t CC KRWLockMake ( KRWLock **lockp )
-{
- rc_t rc;
-
- if ( lockp == NULL )
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcParam, rcNull );
- else
- {
- KRWLock *lock = malloc ( sizeof * lock );
- if ( lock == NULL )
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcMemory, rcExhausted );
- else
- {
- int status = pthread_rwlock_init ( & lock -> lock, NULL );
- if ( status == 0 )
- {
- atomic32_set ( & lock -> refcount, 1 );
- * lockp = lock;
- return 0;
- }
-
- switch ( status )
- {
- case EAGAIN:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcRWLock, rcExhausted );
- break;
- case ENOMEM:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcMemory, rcExhausted );
- break;
- case EPERM:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcProcess, rcUnauthorized );
- break;
- case EBUSY:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcRWLock, rcBusy );
- break;
- default:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcNoObj, rcUnknown );
- }
-
- free ( lock );
- }
-
- * lockp = NULL;
- }
-
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KRWLockAddRef ( const KRWLock *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KRWLock* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockRelease ( const KRWLock *cself )
-{
- KRWLock *self = ( KRWLock* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KRWLockWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* AcquireShared
- * acquires read ( shared ) lock
- */
-LIB_EXPORT rc_t CC KRWLockAcquireShared ( KRWLock *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_rwlock_rdlock ( & self -> lock );
- switch ( status )
- {
- case 0:
- break;
- case EDEADLK:
- return RC ( rcPS, rcRWLock, rcLocking, rcThread, rcDeadlock );
- case EAGAIN:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcExhausted );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockTimedAcquireShared ( KRWLock *self, timeout_t *tm )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_rwlock_tryrdlock ( & self -> lock );
- switch ( status )
- {
- case 0:
- return 0;
- case EBUSY:
- if ( tm != NULL )
- break;
- return RC ( rcPS, rcLock, rcLocking, rcRWLock, rcBusy );
- case EAGAIN:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcExhausted );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- if ( ! tm -> prepared )
- TimeoutPrepare ( tm );
-
- status = pthread_rwlock_timedrdlock ( & self -> lock, & tm -> ts );
- switch ( status )
- {
- case 0:
- break;
- case ETIMEDOUT:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
- case EAGAIN:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcExhausted );
- case EDEADLK:
- return RC ( rcPS, rcRWLock, rcLocking, rcThread, rcDeadlock );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/* AcquireExcl
- * acquires write ( exclusive ) lock
- */
-LIB_EXPORT rc_t CC KRWLockAcquireExcl ( KRWLock *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_rwlock_wrlock ( & self -> lock );
- switch ( status )
- {
- case 0:
- break;
- case EDEADLK:
- return RC ( rcPS, rcRWLock, rcLocking, rcThread, rcDeadlock );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockTimedAcquireExcl ( KRWLock *self, timeout_t *tm )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- status = pthread_rwlock_trywrlock ( & self -> lock );
- switch ( status )
- {
- case 0:
- return 0;
- case EBUSY:
- if ( tm != NULL )
- break;
- return RC ( rcPS, rcRWLock, rcLocking, rcLock, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- if ( ! tm -> prepared )
- TimeoutPrepare ( tm );
-
- status = pthread_rwlock_timedwrlock ( & self -> lock, & tm -> ts );
- switch ( status )
- {
- case 0:
- break;
- case ETIMEDOUT:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
- case EDEADLK:
- return RC ( rcPS, rcRWLock, rcLocking, rcThread, rcDeadlock );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/* Unlock
- * releases lock
- */
-LIB_EXPORT rc_t CC KRWLockUnlock ( KRWLock *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcUnlocking, rcSelf, rcNull );
-
- status = pthread_rwlock_unlock ( & self -> lock );
- switch ( status )
- {
- case 0:
- break;
- case EPERM:
- return RC ( rcPS, rcRWLock, rcUnlocking, rcThread, rcIncorrect );
- case EINVAL:
- return RC ( rcPS, rcRWLock, rcUnlocking, rcRWLock, rcInvalid );
- default:
- return RC ( rcPS, rcRWLock, rcUnlocking, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
diff --git a/libs/kproc/win/syscond-priv.h b/libs/kproc/win/syscond-priv.h
deleted file mode 100644
index 509a913..0000000
--- a/libs/kproc/win/syscond-priv.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_syscond_priv_
-#define _h_syscond_priv_
-
-#if 0
-#include <pthread.h>
-#endif
-
-#include <atomic32.h>
-
-#ifndef _h_klib_defs_
-#include <klib/defs.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*--------------------------------------------------------------------------
- * KCondition
- * a POSIX-style condition object
- * ( requires an external lock object )
- *
- * usage: the user first acquires an external lock. then, depending upon
- * the operation, will either test for a condition or establish it, where
- * the former involves the potential to wait for a signal and the latter
- * to generate a signal using the external lock for blocking.
- */
-struct KCondition;
-
-
-/* Init
- * initialize an inline KCondition
- */
-rc_t KConditionInit ( struct KCondition *self );
-
-/* Destroy
- * run destructor on inline KCondition
- */
-rc_t KConditionDestroy ( struct KCondition *self );
-
-/* DropRef
- * manipulates reference counter
- * returns true if last ref
- */
-int KConditionDropRef ( struct KCondition const *self );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_syscond_priv_ */
diff --git a/libs/kproc/win/syscond.c b/libs/kproc/win/syscond.c
deleted file mode 100644
index 9fb08a2..0000000
--- a/libs/kproc/win/syscond.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-
-#include "syslock-priv.h"
-#include "syscond-priv.h"
-
-#include <os-native.h>
-#include <kproc/timeout.h>
-#include <kproc/cond.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-#include <atomic32.h>
-
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <time.h> /* struct timespec */
-
-/* #include <stdio.h> */
-
-
-/*
-
-This Windows condition implementation is taken from
-"Strategies for Implementing POSIX Condition Variables on Win32"
-by Douglas C. Schmidt
-( http://www.cs.wustl.edu/~schmidt/win32-cv-1.html ) :
-
-3.4. The SignalObjectAndWait Solution
-The implementation relies on the Windows NT 4.0 SignalObjectAndWait function,
-thus it is not available in Windows CE, Windows '95, or Windows NT 3.51.
-
-The code was taken from the article.
-
-The C++ source code for POSIX condition variable on Win32
-described in the article is freely available with the ACE framework
-at //www.cs.wustl.edu/~schmidt/ACE.html.
-It is possible that the latter is better.
-
-*/
-
-
-typedef struct
-{
- int waiters_count_;
- // Number of waiting threads.
-
- CRITICAL_SECTION waiters_count_lock_;
- // Serialize access to <waiters_count_>.
-
- HANDLE sema_;
- // Semaphore used to queue up threads waiting for the condition to
- // become signaled.
-
- HANDLE waiters_done_;
- // An auto-reset event used by the broadcast/signal thread to wait
- // for all the waiting thread(s) to wake up and be released from the
- // semaphore.
-
- size_t was_broadcast_;
- // Keeps track of whether we were broadcasting or signaling. This
- // allows us to optimize the code if we're just signaling.
-} pthread_cond_t;
-
-
-/*--------------------------------------------------------------------------
- * KCondition
- * a POSIX-style condition object
- * ( requires an external lock object )
- *
- * usage: the user first acquires an external lock. then, depending upon
- * the operation, will either test for a condition or establish it, where
- * the former involves the potential to wait for a signal and the latter
- * to generate a signal using the external lock for blocking.
- */
-struct KCondition
-{
- pthread_cond_t cond;
-
- atomic32_t refcount;
-};
-
-
-typedef HANDLE pthread_mutex_t;
-typedef struct pthread_condattr_t { char dummy; } pthread_condattr_t;
-
-int
-pthread_cond_init (pthread_cond_t *cv,
- const pthread_condattr_t *dummy)
-{
- cv->waiters_count_ = 0;
- cv->was_broadcast_ = 0;
- cv->sema_ = CreateSemaphore (NULL, // no security
- 0, // initially 0
- 0x7fffffff, // max count
- NULL); // unnamed
- InitializeCriticalSection (&cv->waiters_count_lock_);
- cv->waiters_done_ = CreateEvent (NULL, // no security
- FALSE, // auto-reset
- FALSE, // non-signaled initially
- NULL); // unnamed
- return 0;
-}
-
-int pthread_cond_destroy (pthread_cond_t *cv) {
- CloseHandle(cv->sema_);
- DeleteCriticalSection(&cv->waiters_count_lock_);
- CloseHandle(cv->waiters_done_);
- memset(cv, 0, sizeof *cv);
- return 0;
-}
-
-#ifndef timespec
-typedef struct timespec
- {
- time_t tv_sec; /* Seconds. */
- long int tv_nsec; /* Nanoseconds. */
- } timespec;
-#endif
-
-int pthread_cond_waitImpl (pthread_cond_t *cv,
- pthread_mutex_t *external_mutex,
- const struct timespec *abstime,
- bool infinite)
-{
- int last_waiter;
- DWORD dwMilliseconds = INFINITE;
-
- // Avoid race conditions.
- EnterCriticalSection (&cv->waiters_count_lock_);
- cv->waiters_count_++;
- LeaveCriticalSection (&cv->waiters_count_lock_);
-
- // This call atomically releases the mutex and waits on the
- // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast>
- // are called by another thread.
- if (!infinite && abstime != NULL)
- { dwMilliseconds = ( DWORD ) ( abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000 ) ; }
- SignalObjectAndWait (*external_mutex, cv->sema_, dwMilliseconds, FALSE);
-
- // Reacquire lock to avoid race conditions.
- EnterCriticalSection (&cv->waiters_count_lock_);
-
- // We're no longer waiting...
- cv->waiters_count_--;
-
- // Check to see if we're the last waiter after <pthread_cond_broadcast>.
- last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
-
- LeaveCriticalSection (&cv->waiters_count_lock_);
-
- // If we're the last waiter thread during this particular broadcast
- // then let all the other threads proceed.
- if (last_waiter)
- // This call atomically signals the <waiters_done_> event and waits until
- // it can acquire the <external_mutex>.
- // This is required to ensure fairness.
- SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
- else {
- // Always regain the external mutex since that's the guarantee we
- // give to our callers.
-/* fprintf(stderr, "%s: WaitForSingleObject...\n", __func__); */
- WaitForSingleObject (*external_mutex, INFINITE);
-/* fprintf(stderr, "... %s: WaitForSingleObject\n", __func__); */
- }
-
- return 0;
-}
-
-int pthread_cond_timedwait(pthread_cond_t *cv,
- pthread_mutex_t *external_mutex,
- const struct timespec *abstime)
-{
- return pthread_cond_waitImpl(cv, external_mutex, abstime, false);
-}
-
-int
-pthread_cond_wait (pthread_cond_t *cv,
- pthread_mutex_t *external_mutex)
-{
- return pthread_cond_waitImpl(cv, external_mutex, NULL, true);
-}
-
-int
-pthread_cond_signal (pthread_cond_t *cv)
-{
- int have_waiters;
-
- EnterCriticalSection (&cv->waiters_count_lock_);
- have_waiters = cv->waiters_count_ > 0;
- LeaveCriticalSection (&cv->waiters_count_lock_);
-
- // If there aren't any waiters, then this is a no-op.
- if (have_waiters)
- ReleaseSemaphore (cv->sema_, 1, 0);
-
- return 0;
-}
-
-int
-pthread_cond_broadcast (pthread_cond_t *cv)
-{
- int have_waiters = 0;
-
- // This is needed to ensure that <waiters_count_> and <was_broadcast_> are
- // consistent relative to each other.
- EnterCriticalSection (&cv->waiters_count_lock_);
-
- if (cv->waiters_count_ > 0) {
- // We are broadcasting, even if there is just one waiter...
- // Record that we are broadcasting, which helps optimize
- // <pthread_cond_wait> for the non-broadcast case.
- cv->was_broadcast_ = 1;
- have_waiters = 1;
- }
-
- if (have_waiters) {
- // Wake up all the waiters atomically.
- ReleaseSemaphore (cv->sema_, cv->waiters_count_, 0);
-
- LeaveCriticalSection (&cv->waiters_count_lock_);
-
- // Wait for all the awakened threads to acquire the counting
- // semaphore.
- WaitForSingleObject (cv->waiters_done_, INFINITE);
- // This assignment is okay, even without the <waiters_count_lock_> held
- // because no other waiter threads can wake up to access it.
- cv->was_broadcast_ = 0;
- }
- else
- LeaveCriticalSection (&cv->waiters_count_lock_);
-
- return 0;
-}
-
-/*--------------------------------------------------------------------------
- * KCondition
- * a POSIX-style condition object
- * ( requires an external lock object )
- *
- * usage: the user first acquires an external lock. then, depending upon
- * the operation, will either test for a condition or establish it, where
- * the former involves the potential to wait for a signal and the latter
- * to generate a signal using the external lock for blocking.
- */
-
-/* Destroy
- */
-rc_t KConditionDestroy ( KCondition *self )
-{
- int status = pthread_cond_destroy ( & self -> cond );
- switch ( status )
- {
- case 0:
- break;
- case EBUSY:
- return RC ( rcPS, rcCondition, rcDestroying, rcCondition, rcBusy );
- default:
- return RC ( rcPS, rcCondition, rcDestroying, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/* Whack
- */
-static
-rc_t KConditionWhack ( KCondition *self )
-{
- rc_t rc = KConditionDestroy ( self );
- if ( rc == 0 )
- free ( self );
- return rc;
-}
-
-/* Init
- */
-rc_t KConditionInit ( KCondition *self )
-{
- int status;
-
- assert ( self != NULL );
- status = pthread_cond_init ( & self -> cond, NULL );
- switch ( status )
- {
- case 0:
- break;
- case EAGAIN:
- return RC ( rcPS, rcCondition, rcConstructing, rcCondition, rcExhausted );
- case ENOMEM:
- return RC ( rcPS, rcCondition, rcConstructing, rcMemory, rcExhausted );
- case EBUSY:
- return RC ( rcPS, rcCondition, rcConstructing, rcCondition, rcBusy );
- case EINVAL:
- return RC ( rcPS, rcCondition, rcConstructing, rcCondition, rcInvalid );
- default:
- return RC ( rcPS, rcCondition, rcConstructing, rcNoObj, rcUnknown );
- }
-
- atomic32_set ( & self -> refcount, 1 );
- return 0;
-}
-
-
-/* Make
- * create a condition
- */
-LIB_EXPORT rc_t CC KConditionMake ( KCondition **condp )
-{
- rc_t rc;
- if ( condp == NULL )
- rc = RC ( rcPS, rcCondition, rcConstructing, rcParam, rcNull );
- else
- {
- KCondition *cond = malloc ( sizeof * cond );
- if ( cond == NULL )
- rc = RC ( rcPS, rcCondition, rcConstructing, rcMemory, rcExhausted );
- else
- {
- rc = KConditionInit ( cond );
- if ( rc == 0 )
- {
- * condp = cond;
- return 0;
- }
-
- free ( cond );
- }
-
- * condp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KConditionAddRef ( const KCondition *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KCondition* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KConditionRelease ( const KCondition *cself )
-{
- KCondition *self = ( KCondition* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- return KConditionWhack ( self );
- }
- return 0;
-}
-
-/* DropRef
- * manipulates reference counter
- * returns true if last ref
- */
-int KConditionDropRef ( const KCondition *cself )
-{
- assert ( cself != NULL );
- return atomic32_dec_and_test ( & ( ( KCondition* ) cself ) -> refcount );
-}
-
-
-/* Wait
- * block on external lock until signaled
- */
-LIB_EXPORT rc_t CC KConditionWait ( KCondition *self, struct KLock *lock )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcCondition, rcWaiting, rcSelf, rcNull );
- if ( lock == NULL )
- return RC ( rcPS, rcCondition, rcWaiting, rcLock, rcNull );
-
- status = pthread_cond_wait ( & self -> cond, & lock -> mutex );
- switch ( status )
- {
- case 0:
- break;
- default:
- return RC ( rcPS, rcCondition, rcWaiting, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KConditionTimedWait ( KCondition *self, struct KLock *lock, timeout_t *tm )
-{
- int status;
- timespec ts;
-
- if ( self == NULL )
- return RC ( rcPS, rcCondition, rcWaiting, rcSelf, rcNull );
- if ( lock == NULL )
- return RC ( rcPS, rcCondition, rcWaiting, rcLock, rcNull );
- if ( tm == NULL )
- return RC ( rcPS, rcCondition, rcWaiting, rcTimeout, rcNull );
-
- if ( ! tm -> prepared )
- TimeoutPrepare ( tm );
-
- memset(&ts, 0, sizeof ts);
- ts.tv_sec = tm -> mS / 1000;
- ts.tv_nsec = ( long ) ( (tm -> mS - ts.tv_sec * 1000) * 1000000 );
-
- status = pthread_cond_timedwait ( & self -> cond, & lock -> mutex, & ts );
- switch ( status )
- {
- case 0:
- break;
-/* case ETIMEDOUT:
- return RC ( rcPS, rcCondition, rcWaiting, rcTimeout, rcExhausted ); */
- case EINTR:
- return RC ( rcPS, rcCondition, rcWaiting, rcThread, rcInterrupted );
- default:
- return RC ( rcPS, rcCondition, rcWaiting, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/* Signal
- * signal waiting threads
- * awaken at most a single thread
- */
-LIB_EXPORT rc_t CC KConditionSignal ( KCondition *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcCondition, rcSignaling, rcSelf, rcNull );
-
- status = pthread_cond_signal ( & self -> cond );
- switch ( status )
- {
- case 0:
- break;
- default:
- return RC ( rcPS, rcCondition, rcSignaling, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
-
-
-/* Broadcast
- * signal waiting threads
- * awaken all waiting thread
- */
-LIB_EXPORT rc_t CC KConditionBroadcast ( KCondition *self )
-{
- int status;
-
- if ( self == NULL )
- return RC ( rcPS, rcCondition, rcSignaling, rcSelf, rcNull );
-
- status = pthread_cond_broadcast ( & self -> cond );
- switch ( status )
- {
- case 0:
- break;
- default:
- return RC ( rcPS, rcCondition, rcSignaling, rcNoObj, rcUnknown );
- }
-
- return 0;
-}
diff --git a/libs/kproc/win/syslock-priv.h b/libs/kproc/win/syslock-priv.h
deleted file mode 100644
index 412cdf0..0000000
--- a/libs/kproc/win/syslock-priv.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#ifndef _h_syslock_priv_
-#define _h_syslock_priv_
-
-#ifndef _h_os_native_
-#include <os-native.h>
-#endif
-
-#ifndef _h_klib_refcount_
-#include <klib/refcount.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*--------------------------------------------------------------------------
- * KLock
- * a POSIX-style mutual exclusion lock
- */
-struct KLock
-{
- HANDLE mutex;
- KRefcount refcount;
-};
-
-/*--------------------------------------------------------------------------
- * KTimedLock
- * a POSIX-style mutual exclusion lock with wupport for timed Acquire
- */
-struct KTimedLock
-{
- HANDLE mutex;
- KRefcount refcount;
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_syslock_priv_ */
diff --git a/libs/kproc/win/syslock.c b/libs/kproc/win/syslock.c
deleted file mode 100644
index 4aefc1c..0000000
--- a/libs/kproc/win/syslock.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-
-#include "syslock-priv.h"
-#include <kproc/timeout.h>
-#include <kproc/lock.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-/*--------------------------------------------------------------------------
- * KLock
- * a mutual exclusion lock
- */
-
-/* Whack
- */
-static
-rc_t KLockWhack ( KLock *self )
-{
- if ( CloseHandle ( self -> mutex ) )
- {
- free ( self );
- return 0;
- }
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcDestroying, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcDestroying, rcNoObj, rcUnknown );
-}
-
-
-/* Make
- * make a simple mutex
- */
-LIB_EXPORT rc_t CC KLockMake ( KLock **lockp )
-{
- rc_t rc;
- if ( lockp == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcParam, rcNull );
- else
- {
- KLock *lock = malloc ( sizeof * lock );
- if ( lock == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcMemory, rcExhausted );
- else
- {
- lock -> mutex = CreateMutex ( NULL, false, NULL );
- if ( lock -> mutex != NULL )
- {
- atomic32_set ( & lock -> refcount, 1 );
- * lockp = lock;
- return 0;
- }
-
- switch ( GetLastError () )
- {
- default:
- rc = RC ( rcPS, rcLock, rcConstructing, rcNoObj, rcUnknown );
- }
-
- free ( lock );
- }
-
- * lockp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KLockAddRef ( const KLock *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KLock* ) cself ) -> refcount );
- return 0;
-}
-
-
-LIB_EXPORT rc_t CC KLockRelease ( const KLock *cself )
-{
- KLock *self = ( KLock* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KLockWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* Acquire
- * acquires lock
- */
-LIB_EXPORT rc_t CC KLockAcquire ( KLock *self )
-{
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcLocking, rcSelf, rcNull );
-
- switch ( WaitForSingleObject ( self -> mutex, INFINITE ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- return 0;
- case WAIT_TIMEOUT:
- return RC ( rcPS, rcLock, rcLocking, rcTimeout, rcExhausted );
- }
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcLocking, rcNoObj, rcUnknown );
-}
-
-/* Unlock
- * releases lock
- */
-LIB_EXPORT rc_t CC KLockUnlock ( KLock *self )
-{
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcUnlocking, rcSelf, rcNull );
-
- if ( ReleaseMutex ( self -> mutex ) )
- return 0;
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcUnlocking, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcUnlocking, rcNoObj, rcUnknown );
-}
-
-
-/*--------------------------------------------------------------------------
- * KTimedLock
- * a mutual exclusion lock with support for timed Acquire
- */
-
-/* Whack
- */
-static
-rc_t KTimedLockWhack ( KTimedLock *self )
-{
- if ( CloseHandle ( self -> mutex ) )
- {
- free ( self );
- return 0;
- }
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcDestroying, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcDestroying, rcNoObj, rcUnknown );
-}
-
-
-/* Make
- * make a simple mutex
- */
-LIB_EXPORT rc_t CC KTimedLockMake ( KTimedLock **lockp )
-{
- rc_t rc;
- if ( lockp == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcParam, rcNull );
- else
- {
- KTimedLock *lock = malloc ( sizeof * lock );
- if ( lock == NULL )
- rc = RC ( rcPS, rcLock, rcConstructing, rcMemory, rcExhausted );
- else
- {
- lock -> mutex = CreateMutex ( NULL, false, NULL );
- if ( lock -> mutex != NULL )
- {
- atomic32_set ( & lock -> refcount, 1 );
- * lockp = lock;
- return 0;
- }
-
- switch ( GetLastError () )
- {
- default:
- rc = RC ( rcPS, rcLock, rcConstructing, rcNoObj, rcUnknown );
- }
-
- free ( lock );
- }
-
- * lockp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KTimedLockAddRef ( const KTimedLock *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KTimedLock* ) cself ) -> refcount );
- return 0;
-}
-
-
-LIB_EXPORT rc_t CC KTimedLockRelease ( const KTimedLock *cself )
-{
- KTimedLock *self = ( KTimedLock* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KTimedLockWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* Acquire
- * acquires lock
- */
-LIB_EXPORT rc_t CC KTimedLockAcquire ( KTimedLock *self, timeout_t *tm )
-{
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcLocking, rcSelf, rcNull );
-
- switch ( WaitForSingleObject( self -> mutex, tm != NULL ? tm -> mS : 0 ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- return 0;
- case WAIT_TIMEOUT:
- if ( tm == NULL )
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcBusy );
- return RC ( rcPS, rcLock, rcLocking, rcTimeout, rcExhausted );
- }
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcLocking, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcLocking, rcNoObj, rcUnknown );
-}
-
-
-/* Unlock
- * releases lock
- */
-LIB_EXPORT rc_t CC KTimedLockUnlock ( KTimedLock *self )
-{
- if ( self == NULL )
- return RC ( rcPS, rcLock, rcUnlocking, rcSelf, rcNull );
-
- if ( ReleaseMutex ( self -> mutex ) )
- return 0;
-
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcLock, rcUnlocking, rcLock, rcInvalid );
- }
-
- return RC ( rcPS, rcLock, rcUnlocking, rcNoObj, rcUnknown );
-}
-
-
-/*--------------------------------------------------------------------------
- * KRWLock
- * a read/write lock
- */
-struct KRWLock
-{
- HANDLE mutex;
- HANDLE rcond;
- HANDLE wcond;
- HANDLE ack;
- atomic32_t refcount;
- uint32_t rwait;
- uint32_t wwait;
- int32_t busy;
-};
-
-
-/* Whack
- */
-static
-rc_t KRWLockWhack ( KRWLock *self )
-{
- switch ( WaitForSingleObject ( self -> mutex, 0 ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- if ( self -> busy != 0 || self -> rwait != 0 || self -> wwait != 0 )
- {
- ReleaseMutex ( self -> mutex );
- return RC ( rcPS, rcRWLock, rcDestroying, rcRWLock, rcBusy );
- }
- ReleaseMutex ( self -> mutex );
- break;
- case WAIT_TIMEOUT:
- return RC ( rcPS, rcRWLock, rcDestroying, rcRWLock, rcBusy );
- }
-
- CloseHandle ( self -> ack );
- CloseHandle ( self -> wcond );
- CloseHandle ( self -> rcond );
- CloseHandle ( self -> mutex );
-
- free ( self );
- return 0;
-}
-
-
-/* Make
- * make a simple read/write lock
- */
-LIB_EXPORT rc_t CC KRWLockMake ( KRWLock **lockp )
-{
- rc_t rc;
-
- if ( lockp == NULL )
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcParam, rcNull );
- else
- {
- KRWLock *lock = malloc ( sizeof * lock );
- if ( lock == NULL )
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcMemory, rcExhausted );
- else
- {
- DWORD status;
- lock -> mutex = CreateMutex ( NULL, false, NULL );
- if ( lock -> mutex == NULL )
- status = GetLastError ();
- else
- {
- lock -> rcond = CreateEvent ( NULL, true, false, NULL );
- if ( lock -> rcond == NULL )
- status = GetLastError ();
- else
- {
- lock -> wcond = CreateEvent ( NULL, true, false, NULL );
- if ( lock -> wcond == NULL )
- status = GetLastError ();
- else
- {
- lock -> ack = CreateEvent ( NULL, true, false, NULL );
- if ( lock -> ack != NULL )
- {
- atomic32_set ( & lock -> refcount, 1 );
- lock -> rwait = lock -> wwait = 0;
- lock -> busy = 0;
- * lockp = lock;
- return 0;
- }
-
- status = GetLastError ();
- CloseHandle ( lock -> wcond );
- }
-
- CloseHandle ( lock -> rcond );
- }
-
- CloseHandle ( lock -> mutex );
- }
-
- switch ( status )
- {
- default:
- rc = RC ( rcPS, rcRWLock, rcConstructing, rcNoObj, rcUnknown );
- }
-
- free ( lock );
- }
-
- * lockp = NULL;
- }
-
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KRWLockAddRef ( const KRWLock *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KRWLock* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockRelease ( const KRWLock *cself )
-{
- KRWLock *self = ( KRWLock* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- {
- atomic32_set ( & self -> refcount, 1 );
- return KRWLockWhack ( self );
- }
- }
- return 0;
-}
-
-
-/* AcquireShared
- * acquires read ( shared ) lock
- */
-static
-rc_t KRWLockAcquireSharedInt ( KRWLock *self, DWORD mS )
-{
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- /* acquire mutex */
- switch ( WaitForSingleObject ( self -> mutex, mS ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_TIMEOUT:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- /* don't allow readers if writers are waiting */
- if ( self -> rwait != 0 || self -> wwait != 0 || self -> busy < 0 )
- {
- /* indicate a waiting read lock request on our mutex */
- ++ self -> rwait;
-
- switch ( SignalObjectAndWait ( self -> mutex, self -> rcond, mS, false ) )
- {
- case WAIT_OBJECT_0:
-
- /* drop wait count under unlock mutex */
- -- self -> rwait;
-
- /* release unlock and reacquire */
- switch ( SignalObjectAndWait ( self -> ack, self -> mutex, INFINITE, false ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
- break;
-
- case WAIT_TIMEOUT:
-
- /* need to drop count, but don't have mutex */
- switch ( WaitForSingleObject ( self -> mutex, INFINITE ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- /* drop count and go */
- -- self -> rwait;
- ReleaseMutex ( self -> mutex );
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
-
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
-
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
- }
-
- assert ( self -> busy >= 0 );
- ++ self -> busy;
-
- ReleaseMutex ( self -> mutex );
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockAcquireShared ( KRWLock *self )
-{
- return KRWLockAcquireSharedInt ( self, INFINITE );
-}
-
-LIB_EXPORT rc_t CC KRWLockTimedAcquireShared ( KRWLock *self, timeout_t *tm )
-{
- return KRWLockAcquireSharedInt ( self, tm != NULL ? tm -> mS : 0 );
-}
-
-
-/* AcquireExcl
- * acquires write ( exclusive ) lock
- */
-static
-rc_t KRWLockAcquireExclInt ( KRWLock *self, DWORD mS )
-{
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcLocking, rcSelf, rcNull );
-
- /* acquire mutex */
- switch ( WaitForSingleObject ( self -> mutex, mS ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_TIMEOUT:
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- if ( self -> wwait != 0 || self -> busy != 0 )
- {
- /* indicate a waiting write lock request on our mutex */
- ++ self -> wwait;
-
- switch ( SignalObjectAndWait ( self -> mutex, self -> wcond, mS, false ) )
- {
- case WAIT_OBJECT_0:
-
- /* drop wait count under unlock mutex */
- -- self -> wwait;
-
- /* release unlock and reacquire */
- switch ( SignalObjectAndWait ( self -> ack, self -> mutex, INFINITE, false ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
- break;
-
- case WAIT_TIMEOUT:
-
- /* need to drop count, but don't have mutex */
- switch ( WaitForSingleObject ( self -> mutex, INFINITE ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
-
- /* drop count and go */
- -- self -> wwait;
- ReleaseMutex ( self -> mutex );
- return RC ( rcPS, rcRWLock, rcLocking, rcTimeout, rcExhausted );
-
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- return RC ( rcPS, rcRWLock, rcLocking, rcRWLock, rcInvalid );
- }
-
- default:
- return RC ( rcPS, rcRWLock, rcLocking, rcNoObj, rcUnknown );
- }
- }
-
- assert ( self -> busy == 0 );
- -- self -> busy;
-
- ReleaseMutex ( self -> mutex );
-
- return 0;
-}
-
-LIB_EXPORT rc_t CC KRWLockAcquireExcl ( KRWLock *self )
-{
- return KRWLockAcquireExclInt ( self, INFINITE );
-}
-
-LIB_EXPORT rc_t CC KRWLockTimedAcquireExcl ( KRWLock *self, timeout_t *tm )
-{
- return KRWLockAcquireExclInt ( self, tm != NULL ? tm -> mS : 0 );
-}
-
-
-/* Unlock
- * releases lock
- */
-LIB_EXPORT rc_t CC KRWLockUnlock ( KRWLock *self )
-{
- rc_t rc;
-
- if ( self == NULL )
- return RC ( rcPS, rcRWLock, rcUnlocking, rcSelf, rcNull );
-
- /* acquire mutex */
- switch ( WaitForSingleObject ( self -> mutex, INFINITE ) )
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- break;
- case WAIT_TIMEOUT:
- return RC ( rcPS, rcRWLock, rcUnlocking, rcTimeout, rcExhausted );
- default:
- return RC ( rcPS, rcRWLock, rcUnlocking, rcNoObj, rcUnknown );
- }
-
- /* adjust busy */
- if ( self -> busy > 0 )
- -- self -> busy;
- else if ( self -> busy < 0 )
- {
- ++ self -> busy;
- assert ( self -> busy == 0 );
- }
-
- /* detect a zero crossing and waiters */
- if ( self -> busy != 0 || ( self -> wwait == 0 && self -> rwait == 0 ) )
- rc = 0;
- else
- {
- HANDLE cond = self -> wwait != 0 ? self -> wcond : self -> rcond;
- switch ( SignalObjectAndWait ( cond, self -> ack, INFINITE, false ) )
- {
- case WAIT_OBJECT_0:
- rc = 0;
- break;
- case WAIT_FAILED:
- switch ( GetLastError () )
- {
- case ERROR_INVALID_HANDLE:
- rc = RC ( rcPS, rcRWLock, rcUnlocking, rcRWLock, rcInvalid );
- break;
- default:
- rc = RC ( rcPS, rcRWLock, rcUnlocking, rcNoObj, rcUnknown );
- }
- break;
-
- default:
- rc = RC ( rcPS, rcRWLock, rcUnlocking, rcNoObj, rcUnknown );
- }
- }
-
- ReleaseMutex ( self -> mutex );
- return rc;
-}
diff --git a/libs/kproc/win/sysmgr.c b/libs/kproc/win/sysmgr.c
deleted file mode 100644
index 02f2c32..0000000
--- a/libs/kproc/win/sysmgr.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-#include <kproc/procmgr.h>
-
-/* OnMainThread
- * returns true if running on main thread
- */
-LIB_EXPORT bool CC KProcMgrOnMainThread ( void )
-{
- /* don't know how to do this on Winders */
- return false;
-}
diff --git a/libs/kproc/win/systhread.c b/libs/kproc/win/systhread.c
deleted file mode 100644
index fbef9ce..0000000
--- a/libs/kproc/win/systhread.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-#include <kproc/thread.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-#include <atomic32.h>
-
-#include <stdlib.h>
-#include <errno.h>
-
-
-/*--------------------------------------------------------------------------
- * KThread
- * a CPU execution thread
- */
-struct KThread
-{
- /* thread entrypoint and data */
- rc_t ( * run ) ( const KThread*, void* );
- void *data;
-
- HANDLE thread_handle;
- DWORD thread_id;
- atomic32_t waiting;
- atomic32_t refcount;
- rc_t rc;
- bool join;
-};
-
-
-/* Whack
- */
-static
-rc_t KThreadWhack ( KThread *self )
-{
- if ( self -> join )
- {
- WaitForSingleObject( self->thread_handle, INFINITE );
- }
-
- free ( self );
- return 0;
-}
-
-
-/* Run
- */
-
-/*
-static
-void *KThreadRun ( void *td )
-{
- KThread *self = td;
-
- self -> rc = ( * self -> run ) ( self, self -> data );
-
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- free ( self );
-
- return NULL;
-}
-*/
-
-static DWORD WINAPI int_ThreadProc( LPVOID lpParameter )
-{
- KThread *self = ( KThread * )lpParameter;
-
- /* run the function */
- self -> rc = ( * self -> run ) ( self, self -> data );
-
- /* release thread's reference */
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- free ( self );
-
- return 0;
-}
-
-
-/* Make
- * create and run a thread
- *
- * "run_thread" [ IN ] - thread entrypoint
- *
- * "data" [ IN, OPAQUE ] - user-supplied thread data
- */
-LIB_EXPORT rc_t CC KThreadMake ( KThread **tp,
- rc_t ( CC * run_thread ) ( const KThread*, void* ), void *data )
-{
- rc_t rc;
- if ( tp == NULL )
- rc = RC ( rcPS, rcThread, rcCreating, rcParam, rcNull );
- else
- {
- if ( run_thread == NULL )
- rc = RC ( rcPS, rcThread, rcCreating, rcFunction, rcNull );
- else
- {
- KThread *t = malloc ( sizeof * t );
- if ( t == NULL )
- rc = RC ( rcPS, rcThread, rcCreating, rcMemory, rcExhausted );
- else
- {
- /* finish constructing thread */
- t -> run = run_thread;
- t -> data = data;
- atomic32_set ( & t -> waiting, 0 );
- atomic32_set ( & t -> refcount, 2 );
- t -> rc = 0;
- t -> join = true;
-
- /* attempt to create thread */
- t -> thread_handle = CreateThread(
- NULL, /* default security attributes */
- 0, /* use default stack size */
- int_ThreadProc, /* thread function */
- t, /* argument to thread function */
- 0, /* run immediately */
- &t->thread_id ); /* returns the thread identifier */
-
- /* status = pthread_create ( & t -> thread, 0, KThreadRun, t ); */
- if ( t->thread_handle != NULL )
- {
- * tp = t;
- return 0;
- }
-
- rc = RC ( rcPS, rcThread, rcCreating, rcNoObj, rcUnknown );
- /* see why we failed */
- /*
- switch ( status )
- {
- case EAGAIN:
- rc = RC ( rcPS, rcThread, rcCreating, rcThread, rcExhausted );
- break;
- default:
- rc = RC ( rcPS, rcThread, rcCreating, rcNoObj, rcUnknown );
- }
- */
-
- free ( t );
- }
- }
-
- * tp = NULL;
- }
- return rc;
-}
-
-
-/* AddRef
- * Release
- */
-LIB_EXPORT rc_t CC KThreadAddRef ( const KThread *cself )
-{
- if ( cself != NULL )
- atomic32_inc ( & ( ( KThread* ) cself ) -> refcount );
- return 0;
-}
-
-LIB_EXPORT rc_t CC KThreadRelease ( const KThread *cself )
-{
- KThread *self = ( KThread* ) cself;
- if ( cself != NULL )
- {
- if ( atomic32_dec_and_test ( & self -> refcount ) )
- return KThreadWhack ( self );
- }
- return 0;
-}
-
-
-/* Cancel
- * signal the thread to finish
- */
-LIB_EXPORT rc_t CC KThreadCancel ( KThread *self )
-{
-/* int status;*/
- bool success;
-
- if ( self == NULL )
- return RC ( rcPS, rcThread, rcSignaling, rcSelf, rcNull );
-
- success = TerminateThread( self->thread_handle, 0 );
- if ( !success )
- return RC ( rcPS, rcThread, rcSignaling, rcNoObj, rcUnknown );
-
-/*
- status = pthread_cancel ( self -> thread );
- switch ( status )
- {
- case 0:
- break;
- case ESRCH:
- self -> join = false;
- return RC ( rcPS, rcThread, rcSignaling, rcThread, rcDestroyed );
- default:
- return RC ( rcPS, rcThread, rcSignaling, rcNoObj, rcUnknown );
- }
-*/
-
- return 0;
-}
-
-
-/* Wait
- * waits for a thread to exit
- *
- * "status" [ OUT ] - return parameter for thread's exit code
- */
-LIB_EXPORT rc_t CC KThreadWait ( KThread *self, rc_t *out )
-{
- DWORD wait_res;
-
- if ( self == NULL )
- return RC ( rcPS, rcThread, rcWaiting, rcSelf, rcNull );
-
- /* prevent multiple waiters */
- if ( atomic32_test_and_set ( & self -> waiting, 0, 1 ) != 0 )
- return RC ( rcPS, rcThread, rcWaiting, rcThread, rcBusy );
-
- wait_res = WaitForSingleObject( self->thread_handle, INFINITE );
-
- /* release waiter lock */
- atomic32_set ( & self -> waiting, 0 );
-
- switch( wait_res )
- {
- case WAIT_FAILED :
- return RC ( rcPS, rcThread, rcWaiting, rcNoObj, rcUnknown );
- }
-/*
- switch ( status )
- {
- case 0:
- break;
- case ESRCH:
- return RC ( rcPS, rcThread, rcWaiting, rcThread, rcDestroyed );
- case EINVAL:
- return RC ( rcPS, rcThread, rcWaiting, rcThread, rcDetached );
- case EDEADLK:
- return RC ( rcPS, rcThread, rcWaiting, rcThread, rcDeadlock );
- default:
- return RC ( rcPS, rcThread, rcWaiting, rcNoObj, rcUnknown );
- }
-*/
-
- self -> join = false;
-
-/*
- if ( td == PTHREAD_CANCELED )
- self -> rc = RC ( rcPS, rcThread, rcWaiting, rcThread, rcCanceled );
-*/
- if ( out != NULL )
- * out = self -> rc;
-
- return 0;
-}
-
-
-/* Detach
- * allow thread to run independently of group
- */
-LIB_EXPORT rc_t CC KThreadDetach ( KThread *self )
-{
- return RC ( rcPS, rcThread, rcDetaching, rcMessage, rcUnsupported );
-}
diff --git a/libs/kproc/win/systimeout.c b/libs/kproc/win/systimeout.c
deleted file mode 100644
index 36473ab..0000000
--- a/libs/kproc/win/systimeout.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <kproc/extern.h>
-
-#include <os-native.h>
-#include <kproc/timeout.h>
-#include <klib/rc.h>
-#include <sysalloc.h>
-#include <atomic32.h>
-
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-
-/*--------------------------------------------------------------------------
- * timeout_t
- * a structure for communicating a timeout
- * which under Unix converts to an absolute time once prepared
- */
-
-
-/* Init
- * initialize a timeout in milliseconds
- */
-LIB_EXPORT rc_t TimeoutInit ( timeout_t *tm, uint32_t msec )
-{
- if ( tm == NULL )
- return RC ( rcPS, rcTimeout, rcConstructing, rcSelf, rcNull );
-
- tm -> mS = msec;
- tm -> prepared = true;
-
- return 0;
-}
-
-/* Prepare
- * ensures that a timeout is prepared with an absolute value
-*/
-LIB_EXPORT rc_t TimeoutPrepare ( timeout_t *self )
-{
- if ( self == NULL )
- return RC ( rcPS, rcTimeout, rcUpdating, rcSelf, rcNull );
-
- return 0;
-}
diff --git a/libs/krypto/win/sysrng.c b/libs/krypto/win/sysrng.c
deleted file mode 100644
index 8f0ac62..0000000
--- a/libs/krypto/win/sysrng.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-/* -----
- * this is a windows thing... MSDN said required so it's out of our
- * include normal order
- *
- * doing this define and include in this way brings in rand_s which is based on
- * the same RNG used in the fussy _CryptGenRandom. But without creating the
- * files and other stuff that is suitable for full Windows based cryptography
- * but not our virtual environment to get a simple seed for our OpenSSL based
- * cryptography.
- */
-#define _CRT_RAND_S
-#include <stdlib.h>
-
-#include <os-native.h>
-
-#include <krypto/extern.h>
-#include <krypto/rng.h>
-#include "rng-priv.h"
-
-#include <klib/rc.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include <klib/checksum.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <time.h>
-
-
-rc_t KRngSysEntropy (KRng * self, uint8_t * buffer, size_t buff_size)
-{
- MD5State state;
- uint64_t ul;
- size_t buffix;
- int len;
- char buff [4096];
- char obuff [4096];
- char digest [16];
-
- if (self == NULL)
- return RC (rcKrypto, rcRng, rcWriting, rcSelf, rcNull);
- if (buffer == NULL)
- return RC (rcKrypto, rcRng, rcWriting, rcParam, rcNull);
-
- while (buff_size > 0)
- {
- for (buffix = 0; buffix < 256 ; ++buffix)
- {
- unsigned int ui;
- if (rand_s (&ui))
- break;
- /* still paranoid about the old axiom of not using lowest
- * order bits in a random number */
- buff[buffix] = (char)(ui>>4);
- }
-
- len = gethostname (buff + buffix, sizeof (buff) - buffix);
- if (len == 0)
- buffix += strlen (buff + buffix);
- if (buffix >= sizeof (buff))
- break;
-
-
- _time64(&ul);
-
- string_printf (buff + buffix, sizeof (buff) - buffix,
- &len, "%ld", ul);
- if (len > 0)
- buffix += len;
- if (buffix >= sizeof (buff))
- break;
-
- ul = clock ();
-
- string_printf (buff + buffix, sizeof (buff) - buffix,
- &len, "%ld", ul);
- if (len > 0)
- buffix += len;
- if (buffix >= sizeof (buff))
- break;
-
- if (tmpnam_s(obuff, sizeof (obuff)))
- {
- string_printf (buff + buffix, sizeof (buff) - buffix,
- &len, "%s", obuff);
- if (len > 0)
- buffix += len;
- if (buffix >= sizeof (buff))
- break;
- }
-
-
- MD5StateInit (&state);
- MD5StateAppend (&state, buff, sizeof buff);
- MD5StateFinish (&state, digest);
-
- len = sizeof digest > buff_size ? buff_size : sizeof digest;
- memcpy (buffer, digest, len);
-
- buffer += len;
- buff_size -= len;
- }
-
- return 0;
-}
diff --git a/libs/ktst/win/systestenv.cpp b/libs/ktst/win/systestenv.cpp
deleted file mode 100644
index 6886684..0000000
--- a/libs/ktst/win/systestenv.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <ktst/unit_test_suite.hpp>
-
-#include <csignal>
-#include <sstream>
-#include <windows.h>
-#include <process.h>
-
-using namespace std;
-using namespace ncbi::NK;
-
-#undef REPORT_ERROR
-#define REPORT_ERROR(msg) _REPORT_CRITICAL_ERROR_(string("TestEnv::") + msg, __FILE__, __LINE__, true)
-
-/* signal handlers for a single-test case thread */
-void CC SigSubHandler(int sig)
-{
- _endthreadex(sig);
-}
-void CC TermSubHandler()
-{
- SigSubHandler(SIGTERM);
-}
-
-struct TestCaseCall
-{
- TestCaseCall(TestCase& obj, void(TestCase::*meth)())
- : object(&obj), method(meth)
- {
- }
-
- TestCase* object;
- void(TestCase::*method)();
-};
-
-void ThreadProc(void* call)
-{
- signal(SIGABRT, SigSubHandler);
- signal(SIGFPE, SigSubHandler);
- signal(SIGILL, SigSubHandler);
- signal(SIGINT, SigSubHandler);
- signal(SIGSEGV, SigSubHandler);
- signal(SIGTERM, SigSubHandler);
- set_terminate(TermSubHandler);
-
- try
- {
- TestCaseCall* c=(TestCaseCall*)call;
- ((c->object)->*(c->method))();
- }
- catch (...)
- {
- _endthreadex(TestEnv::TEST_CASE_FAILED);
- }
- _endthreadex(0);
-}
-
-int TestEnv::RunProcessTestCase(TestCase& obj, void(TestCase::*meth)(), int timeout)
-{
- TestCaseCall call(obj, meth);
- TestEnv::in_child_process = true;
- HANDLE thread = (HANDLE)_beginthread( ThreadProc, 0, &call );
- if (thread == NULL)
- {
- REPORT_ERROR("TestEnv::RunProcessTestCase: failed to start a test case thread");
- }
-
- // make sure to restore main process's signal handlers before re-throwing an exception
- DWORD rc=0;
- DWORD result=WaitForSingleObject( (HANDLE)thread, timeout == 0 ? INFINITE : timeout*1000);
- try
- {
- switch (result)
- {
- case WAIT_OBJECT_0:
- if (GetExitCodeThread(thread, &rc) == 0)
- REPORT_ERROR("RunProcessTestCase failed");
- break;
- case WAIT_TIMEOUT:
- if (!CloseHandle(thread))
- REPORT_ERROR("CloseHandle failed");
- cerr << "child process timed out" << endl;
- rc=TEST_CASE_TIMED_OUT;
- break;
- default:
- REPORT_ERROR("WaitForSingleObject failed");
- break;
- }
- }
- catch (const exception& ex)
- {
- REPORT_ERROR(obj.GetName() + " threw " + ex.what());
- rc=TEST_CASE_FAILED;
- }
- catch (const ncbi::NK::execution_aborted&)
- {
- REPORT_ERROR(obj.GetName() + " aborted ");
- rc=TEST_CASE_FAILED;
- }
- catch (...)
- {
- REPORT_ERROR(obj.GetName() + " threw something ");
- rc=TEST_CASE_FAILED;
- set_handlers();
- throw;
- }
-#undef CALL_FAILED
- set_handlers();
- in_child_process = false;
- return (int)rc;
-}
-
-bool TestEnv::SleepMs(unsigned int milliseconds)
-{
- ::Sleep((DWORD)milliseconds);
- return true;
-}
-
-void TestEnv::set_handlers(void)
-{
- signal(SIGABRT, SigHandler);
- signal(SIGFPE, SigHandler);
- signal(SIGILL, SigHandler);
- signal(SIGINT, SigHandler);
- signal(SIGSEGV, SigHandler);
- signal(SIGTERM, SigHandler);
- set_terminate(TermHandler);
-}
-
-string TestEnv::GetPidString()
-{
- ostringstream str;
- str << GetCurrentProcessId();
- return str.str();
-}
-
-string TestEnv::FormatLocation(const string& p_file, uint64_t p_line)
-{
- ostringstream out;
- out << p_file << "(" << p_line << "): ";
- return out.str();
-}
diff --git a/libs/tui/win/systui.c b/libs/tui/win/systui.c
deleted file mode 100644
index 1fd934e..0000000
--- a/libs/tui/win/systui.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <tui/extern.h>
-#include <tui/tui.h>
-#include "../tui-priv.h"
-#include <klib/rc.h>
-#include <sysalloc.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#include <assert.h>
-
-
-/**********************************************************************************/
-
-static WORD tui_color_to_win_fg( KTUI_color c)
-{
- switch ( c )
- {
- case KTUI_c_light_gray : return FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED;
- case KTUI_c_gray : return FOREGROUND_INTENSITY;
- case KTUI_c_white : return FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;
-
- case KTUI_c_dark_red : return FOREGROUND_RED;
- case KTUI_c_red : return FOREGROUND_RED|FOREGROUND_INTENSITY;
-
- case KTUI_c_dark_green : return FOREGROUND_GREEN;
- case KTUI_c_green : return FOREGROUND_GREEN|FOREGROUND_INTENSITY;
-
- case KTUI_c_brown : return FOREGROUND_RED|FOREGROUND_GREEN;
- case KTUI_c_yellow : return FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY;
-
- case KTUI_c_dark_blue : return FOREGROUND_BLUE;
- case KTUI_c_blue : return FOREGROUND_BLUE|FOREGROUND_INTENSITY;
-
- case KTUI_c_dark_magenta : return FOREGROUND_RED|FOREGROUND_BLUE;
- case KTUI_c_magenta : return FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
-
- case KTUI_c_dark_cyan : return FOREGROUND_GREEN|FOREGROUND_BLUE;
- case KTUI_c_cyan : return FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
-
-
- case KTUI_c_black :
- default : return 0;
- }
-}
-
-
-static WORD tui_color_to_win_bg( KTUI_color c )
-{
- switch ( c )
- {
- case KTUI_c_light_gray : return BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED;
- case KTUI_c_gray : return BACKGROUND_INTENSITY;
- case KTUI_c_white : return BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY;
-
- case KTUI_c_dark_red : return BACKGROUND_RED;
- case KTUI_c_red : return BACKGROUND_RED|BACKGROUND_INTENSITY;
-
- case KTUI_c_dark_green : return BACKGROUND_GREEN;
- case KTUI_c_green : return BACKGROUND_GREEN|BACKGROUND_INTENSITY;
-
- case KTUI_c_brown : return BACKGROUND_RED|BACKGROUND_GREEN;
- case KTUI_c_yellow : return BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_INTENSITY;
-
- case KTUI_c_dark_blue : return BACKGROUND_BLUE;
- case KTUI_c_blue : return BACKGROUND_BLUE|BACKGROUND_INTENSITY;
-
- case KTUI_c_dark_magenta : return BACKGROUND_RED|BACKGROUND_BLUE;
- case KTUI_c_magenta : return BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_INTENSITY;
-
- case KTUI_c_dark_cyan : return BACKGROUND_GREEN|BACKGROUND_BLUE;
- case KTUI_c_cyan : return BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY;
-
-
- case KTUI_c_black :
- default : return 0;
- }
-}
-
-
-static void set_tui_attrib_and_colors( HANDLE h, tui_ac * curr,
- KTUI_attrib attr,
- KTUI_color color_fg,
- KTUI_color color_bg )
-{
- if ( curr->attr != attr || curr->fg != color_fg || curr->bg != color_bg )
- {
- bool reverse = ( attr & KTUI_a_underline ) || ( attr & KTUI_a_inverse );
-
- if ( reverse )
- SetConsoleTextAttribute( h, tui_color_to_win_fg( color_bg ) |
- tui_color_to_win_bg( color_fg ) );
- else
- SetConsoleTextAttribute( h, tui_color_to_win_fg( color_fg ) |
- tui_color_to_win_bg( color_bg ) );
-
- curr->attr = attr;
- curr->fg = color_fg;
- curr->bg = color_bg;
- }
-}
-
-
-void CC tui_send_strip( int x, int y, int count, tui_ac * curr, tui_ac * v,
- const char * s )
-{
- HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
- if ( h != INVALID_HANDLE_VALUE )
- {
- DWORD nBytesWritten;
- COORD curpos = { (SHORT)x, (SHORT)y };
-
- set_tui_attrib_and_colors( h, curr, v->attr, v->fg, v->bg );
- SetConsoleCursorPosition( h, curpos );
- WriteConsoleA( h, s, ( DWORD )count, &nBytesWritten, NULL );
- }
-}
-
-
-/**********************************************************************************/
-
-
-typedef struct KTUI_pf
-{
- CONSOLE_SCREEN_BUFFER_INFO sbinfo;
- CONSOLE_CURSOR_INFO curinfo;
- DWORD bitsConsoleInputMode;
- int esc_count;
-
- int prev_x, prev_y;
- KTUI_mouse_button prev_button;
- KTUI_mouse_action prev_action;
-} KTUI_pf;
-
-
-static void store_mouse_event( struct KTUI_pf * pf, int x, int y, KTUI_mouse_button b, KTUI_mouse_action a )
-{
- pf -> prev_x = x;
- pf -> prev_y = y;
- pf -> prev_button = b;
- pf -> prev_action = a;
-}
-
-static bool different_mouse_event( struct KTUI_pf * pf, int x, int y, KTUI_mouse_button b, KTUI_mouse_action a )
-{
- return ( pf -> prev_x != x ||
- pf -> prev_y != y ||
- pf -> prev_button != b ||
- pf -> prev_action != a );
-}
-
-
-static KTUI_key g_VirtualCodeTable[ 256 ]; /* if max VK_* constant value is greater than 0xFF, then this code must be revised */
-
-
-static void InitTableRange( int* table, size_t offset_first, size_t offset_last, int val )
-{
- size_t i;
- assert( offset_first < 256 );
- assert( offset_last < 256 );
-
- for ( i = offset_first; i <= offset_last; ++i )
- table[ i ] = val;
-}
-
-
-static void InitVKTable( KTUI_key* table, size_t size )
-{
- /*
- the table is supposed to be used in a "white-list approach",
- so it initializes every code that is supposed to be processed
- */
- size_t i;
- for ( i = 0; i < size; ++i )
- table[ i ] = ktui_none;
-
- /* special key virtual codes */
- table[VK_DOWN] = ktui_down;
- table[VK_UP] = ktui_up;
- table[VK_LEFT] = ktui_left;
- table[VK_RIGHT] = ktui_right;
- table[VK_HOME] = ktui_home;
- table[VK_END] = ktui_end;
- table[VK_BACK] = ktui_bksp;
- table[VK_F1] = ktui_F1;
- table[VK_F2] = ktui_F2;
- table[VK_F3] = ktui_F3;
- table[VK_F4] = ktui_F4;
- table[VK_F5] = ktui_F5;
- table[VK_F6] = ktui_F6;
- table[VK_F7] = ktui_F7;
- table[VK_F8] = ktui_F8;
- table[VK_F9] = ktui_F9;
- table[VK_F10] = ktui_F10;
- table[VK_F11] = ktui_F11;
- table[VK_F12] = ktui_F12;
- table[VK_DELETE] = ktui_del;
- table[VK_INSERT] = ktui_ins;
- table[VK_NEXT] = ktui_pgdn;
- table[VK_PRIOR] = ktui_pgup;
- table[VK_RETURN] = ktui_enter;
- table[VK_TAB] = ktui_tab;
- /*
- for the numpad windows reports the same ascii characters
- as for standart number keys, so treat them as ktui_alpha
- */
- table[VK_NUMPAD0] = ktui_alpha;
- table[VK_NUMPAD1] = ktui_alpha;
- table[VK_NUMPAD2] = ktui_alpha;
- table[VK_NUMPAD3] = ktui_alpha;
- table[VK_NUMPAD4] = ktui_alpha;
- table[VK_NUMPAD5] = ktui_alpha;
- table[VK_NUMPAD6] = ktui_alpha;
- table[VK_NUMPAD7] = ktui_alpha;
- table[VK_NUMPAD8] = ktui_alpha;
- table[VK_NUMPAD9] = ktui_alpha;
- table[VK_MULTIPLY] = ktui_alpha;
- table[VK_ADD] = ktui_alpha;
- table[VK_SUBTRACT] = ktui_alpha;
- table[VK_DECIMAL] = ktui_alpha;
- table[VK_DIVIDE] = ktui_alpha;
-
- /* some other keys translated to ASCII */
- table[VK_SPACE] = ktui_alpha;
- table[VK_OEM_1] = ktui_alpha;
- table[VK_OEM_PLUS] = ktui_alpha;
- table[VK_OEM_COMMA] = ktui_alpha;
- table[VK_OEM_MINUS] = ktui_alpha;
- table[VK_OEM_PERIOD] = ktui_alpha;
- table[VK_OEM_2] = ktui_alpha;
- table[VK_OEM_3] = ktui_alpha;
- table[VK_OEM_4] = ktui_alpha;
- table[VK_OEM_5] = ktui_alpha;
- table[VK_OEM_6] = ktui_alpha;
- table[VK_OEM_7] = ktui_alpha;
- table[VK_OEM_8] = ktui_alpha;
- table[VK_OEM_102] = ktui_alpha;
- table[VK_OEM_CLEAR] = ktui_alpha;
- table[VK_ESCAPE] = ktui_alpha;
-
- /* keys */
- InitTableRange( table, 0x30, 0x39, ktui_alpha );
- InitTableRange( table, 0x41, 0x5A, ktui_alpha );
-}
-
-
-static KTUI_key TranslateVKtoKTUI( WORD wVirtualKeyCode )
-{
- KTUI_key res;
- if ( wVirtualKeyCode < _countof( g_VirtualCodeTable ) )
- res = g_VirtualCodeTable[ wVirtualKeyCode ];
- else
- res = ktui_none;
- return res;
-}
-
-
-static void save_current_console_settings( HANDLE hStdOut, HANDLE hStdIn, KTUI_pf * pWinSettings, KTUI * pCommonSettings )
-{
- GetConsoleScreenBufferInfo( hStdOut, &pWinSettings->sbinfo );
- GetConsoleCursorInfo( hStdOut, &pWinSettings->curinfo );
- GetConsoleMode( hStdIn, &pWinSettings->bitsConsoleInputMode );
-
- pCommonSettings->lines = ( pWinSettings->sbinfo.srWindow.Bottom - pWinSettings->sbinfo.srWindow.Top );
- pCommonSettings->cols = ( pWinSettings->sbinfo.srWindow.Right - pWinSettings->sbinfo.srWindow.Left );
-}
-
-
-static void set_tui_settings( HANDLE hStdOut, HANDLE hStdIn, KTUI_pf const * pWinSettings )
-{
- DWORD bitsMode = pWinSettings->bitsConsoleInputMode; /* use mostly default windows settings */
- CONSOLE_CURSOR_INFO curinfo = { 1, FALSE };
-
- bitsMode &= ~ENABLE_ECHO_INPUT; /* disable echo */
- bitsMode &= ~ENABLE_LINE_INPUT; /* something like raw mode? TODO: ask Wolfgang */
- bitsMode &= ~ENABLE_PROCESSED_INPUT; /* capture Ctrl-C by application rather than system, shold be reset along with ENABLE_LINE_INPUT */
-
- bitsMode |= ENABLE_MOUSE_INPUT; /* explicitly enabling mouse for the case when it was disabled in windows */
- /*bitsMode |= ENABLE_QUICK_EDIT_MODE; /* explicitly enabling user to use the mouse for text selection and editing*/
- bitsMode |= ENABLE_WINDOW_INPUT; /* process console screen buffer changes (?)*/
-
- SetConsoleMode( hStdIn, bitsMode );
- SetConsoleCursorInfo( hStdOut, &curinfo ); /* cursor off */
-}
-
-
-static void restore_console_settings( HANDLE hStdOut, HANDLE hStdIn, KTUI_pf const * pWinSettings )
-{
- SetConsoleMode( hStdIn, pWinSettings->bitsConsoleInputMode );
-
- SetConsoleCursorPosition( hStdOut, pWinSettings->sbinfo.dwCursorPosition );
- SetConsoleCursorInfo( hStdOut, &pWinSettings->curinfo );
- SetConsoleTextAttribute( hStdOut, pWinSettings->sbinfo.wAttributes );
- SetConsoleMode( hStdIn, pWinSettings->bitsConsoleInputMode );
-}
-
-
-/* This is from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx */
-void cls( HANDLE hConsole )
-{
- COORD coordScreen = { 0, 0 }; // home for the cursor
- DWORD cCharsWritten;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- DWORD dwConSize;
-
-/* Get the number of character cells in the current buffer. */
-
- if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
- {
- return;
- }
-
- dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
-
- /* Fill the entire screen with blanks. */
-
- if( !FillConsoleOutputCharacter( hConsole, /* Handle to console screen buffer */
- (TCHAR) ' ', /* Character to write to the buffer */
- dwConSize, /* Number of cells to write */
- coordScreen, /* Coordinates of first cell */
- &cCharsWritten ))/* Receive number of characters written */
- {
- return;
- }
-
- /* Get the current text attribute. */
-
- if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
- {
- return;
- }
-
- /* Set the buffer's attributes accordingly. */
-
- if( !FillConsoleOutputAttribute( hConsole, /* Handle to console screen buffer */
- csbi.wAttributes, /* Character attributes to use */
- dwConSize, /* Number of cells to set attribute */
- coordScreen, /* Coordinates of first cell */
- &cCharsWritten )) /* Receive number of characters written */
- {
- return;
- }
-
- /* Put the cursor at its home coordinates. */
-
- SetConsoleCursorPosition( hConsole, coordScreen );
-}
-
-
-rc_t CC KTUI_Init_platform( KTUI * self )
-{
- HANDLE hStdOut = INVALID_HANDLE_VALUE;
- HANDLE hStdIn = INVALID_HANDLE_VALUE;
- rc_t rc = 0;
- struct KTUI_pf * pf = malloc( sizeof(*pf) );
- if ( pf == NULL )
- rc = RC( rcApp, rcAttr, rcCreating, rcMemory, rcExhausted );
- else
- {
- memset( pf, 0, sizeof( *pf ) );
- hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
- hStdIn = GetStdHandle( STD_INPUT_HANDLE );
- if ( hStdOut != INVALID_HANDLE_VALUE && hStdIn != INVALID_HANDLE_VALUE )
- {
- save_current_console_settings( hStdOut, hStdIn, pf, self );
- set_tui_settings( hStdOut, hStdIn, pf );
- }
-
- self->pf = pf;
- InitVKTable( g_VirtualCodeTable, _countof( g_VirtualCodeTable ) );
- store_mouse_event( pf, 0, 0, ktui_mouse_button_none, ktui_mouse_action_none );
- }
- return rc;
-}
-
-
-rc_t CC KTUI_Destroy_platform ( struct KTUI_pf * pf )
-{
- HANDLE hStdOut = INVALID_HANDLE_VALUE;
- HANDLE hStdIn = INVALID_HANDLE_VALUE;
-
- if ( pf != NULL )
- {
- hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
- hStdIn = GetStdHandle( STD_INPUT_HANDLE );
- if ( hStdOut != INVALID_HANDLE_VALUE && hStdIn != INVALID_HANDLE_VALUE )
- {
- restore_console_settings( hStdOut, hStdIn, pf );
- cls( hStdOut );
- }
- free( ( void * ) pf );
- }
-
- return 0;
-}
-
-
-static BOOL KeyEventProc( KEY_EVENT_RECORD const* pEvent, struct KTUI * self )
-{
- BOOL ret = FALSE;
- if ( pEvent->bKeyDown )
- {
- struct KTUI_pf * pf = ( self->pf );
- int key = 0;
-
- KTUI_key code = TranslateVKtoKTUI( pEvent->wVirtualKeyCode );
-
- if ( code == ktui_alpha )
- {
- key = ( int )( pEvent->uChar.AsciiChar );
-
- /* we artificially let the user press ESC twice to make it do the same as a posix console */
- if ( key == 27 )
- {
- if ( pf->esc_count == 0 )
- {
- code = ktui_none;
- pf->esc_count = 1;
- }
- else
- pf->esc_count = 0;
- }
- else
- pf->esc_count = 0;
- }
- else
- pf->esc_count = 0;
-
- if ( code == ktui_tab && ( ( pEvent->dwControlKeyState & SHIFT_PRESSED ) == SHIFT_PRESSED ) )
- code = ktui_shift_tab;
-
- if ( code != ktui_none )
- {
- size_t i;
- for ( i = 0; i < pEvent->wRepeatCount; ++i )
- {
- put_kb_event( self, key, code );
- ret = TRUE;
- }
- }
- }
- return ret;
-}
-
-
-static KTUI_mouse_button get_button( DWORD btn_flags )
-{
- KTUI_mouse_button res = ktui_mouse_button_none;
- switch( btn_flags )
- {
- case FROM_LEFT_1ST_BUTTON_PRESSED : res = ktui_mouse_button_left; break;
- case FROM_LEFT_2ND_BUTTON_PRESSED : res = ktui_mouse_button_middle; break;
- case RIGHTMOST_BUTTON_PRESSED : res = ktui_mouse_button_right; break;
- case 0 : res = ktui_mouse_button_up; break;
- }
- return res;
-}
-
-static KTUI_mouse_action get_action( DWORD ev_flags, KTUI_mouse_button button )
-{
- KTUI_mouse_action res = ktui_mouse_action_none;
-
- if ( ev_flags == 0 || ( ( ev_flags & DOUBLE_CLICK ) == DOUBLE_CLICK ) )
- {
- res = ktui_mouse_action_button;
- }
- else if ( ( ev_flags & MOUSE_MOVED ) == MOUSE_MOVED )
- {
- /* to make the behavior the same as on posix:
- if not mouse-buttons is pressed, do not report a move action... */
- if ( button != ktui_mouse_button_up )
- res = ktui_mouse_action_move;
- }
- else if ( ( ev_flags & MOUSE_WHEELED ) == MOUSE_WHEELED )
- {
- res = ktui_mouse_action_scroll;
- }
- return res;
-}
-
-static void MouseEventProc( MOUSE_EVENT_RECORD const* pEvent, struct KTUI* self )
-{
- KTUI_mouse_button button = get_button( pEvent->dwButtonState );
- KTUI_mouse_action action = get_action( pEvent->dwEventFlags, button );
-
- if ( button != ktui_mouse_button_none && action != ktui_mouse_action_none )
- {
- int x = pEvent->dwMousePosition.X;
- int y = pEvent->dwMousePosition.Y;
- if ( different_mouse_event( self->pf, x, y, button, action ) )
- {
- put_mouse_event( self, x, y, button, action,
- ( uint32_t )( pEvent->dwEventFlags & 0xFFFFFFFF ) );
- store_mouse_event( self->pf, x, y, button, action );
- }
- }
-}
-
-
-static void WindowBufferSizeEventProc( WINDOW_BUFFER_SIZE_RECORD const* pEvent, struct KTUI* self )
-{
- put_window_event( self, pEvent->dwSize.Y, pEvent->dwSize.X );
-}
-
-
-#define INPUT_EVENT_BUF_SIZE 10
-
-static BOOL ReadAndProcessEvents( struct KTUI * self, HANDLE h )
-{
- DWORD nEventsRead;
- INPUT_RECORD arrInputEvents[ INPUT_EVENT_BUF_SIZE ];
- PINPUT_RECORD pInputEvents = arrInputEvents;
- BOOL res = ReadConsoleInput( h, pInputEvents, INPUT_EVENT_BUF_SIZE, &nEventsRead );
- if ( res )
- {
- DWORD i;
- for ( i = 0; i < nEventsRead; ++i )
- {
- switch ( pInputEvents[ i ].EventType )
- {
- case KEY_EVENT : KeyEventProc( &pInputEvents[ i ].Event.KeyEvent, self ); break;
- case MOUSE_EVENT : MouseEventProc( &pInputEvents[ i ].Event.MouseEvent, self ); break;
- case WINDOW_BUFFER_SIZE_EVENT : WindowBufferSizeEventProc( &pInputEvents[ i ].Event.WindowBufferSizeEvent, self ); break;
- }
- }
- }
- return res;
-}
-
-
-void CC read_from_stdin( struct KTUI * self, uint32_t timeout )
-{
- BOOL resEventProc;
- DWORD dwStartedWaitingTime, dwEffectiveTimeout, dwTimeElapsed, dwWaitRes;
- HANDLE h = INVALID_HANDLE_VALUE;
- DWORD const dwMinimumTimeout = 10;
-
- h = GetStdHandle( STD_INPUT_HANDLE );
- if ( h == INVALID_HANDLE_VALUE )
- return;
-
- /* blocking waiting with the timeout */
- dwEffectiveTimeout = min( ( DWORD )( timeout / 1000 ), dwMinimumTimeout );
- dwStartedWaitingTime = GetTickCount();
- dwTimeElapsed = 0;
- for ( ; ; )
- {
- dwWaitRes = WaitForSingleObject( h, dwEffectiveTimeout - dwTimeElapsed );
- if ( dwWaitRes == WAIT_OBJECT_0 )
- {
- resEventProc = ReadAndProcessEvents( self, h );
- if ( resEventProc )
- break;
- /*continue waiting for the remaining time */
- dwTimeElapsed = GetTickCount() - dwStartedWaitingTime;
- if ( dwTimeElapsed >= dwEffectiveTimeout )
- break;
- }
- else /* timeout, error */
- {
- break;
- }
- }
-}
diff --git a/libs/vfs/win/syskeyring.c b/libs/vfs/win/syskeyring.c
deleted file mode 100644
index 7f2b748..0000000
--- a/libs/vfs/win/syskeyring.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#include <vfs/keyring-priv.h>
-
-#include <kfg/config.h>
-#include <klib/text.h>
-
-const char* KeyRingDefaultDataDir = "%USERPROFILE%\\.ncbi";
-
-rc_t StartKeyRing(const char* dataDir)
-{
- KConfig* kfg;
- rc_t rc = KConfigMake(&kfg, NULL);
- if (rc == 0)
- {
- const KConfigNode *node;
- char path[] = "$(APPPATH)";
- char buf[4096];
- size_t num_read;
-
- rc_t rc=KConfigOpenNodeRead(kfg, &node, path, string_measure(path, NULL), "%s", buf);
- if (rc == 0)
- {
- rc = KConfigNodeRead(node, 0, buf, sizeof(buf), &num_read, NULL);
- if (rc == 0)
- {
-/*printf("apppath='%s'\n", buf); */
- }
- KConfigNodeRelease(node);
- }
- rc = KConfigRelease(kfg);
- }
- return rc;
-}
diff --git a/libs/vfs/win/syspath.c b/libs/vfs/win/syspath.c
deleted file mode 100644
index ca411c4..0000000
--- a/libs/vfs/win/syspath.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*===========================================================================
-*
-* PUBLIC DOMAIN NOTICE
-* National Center for Biotechnology Information
-*
-* This software/database is a "United States Government Work" under the
-* terms of the United States Copyright Act. It was written as part of
-* the author's official duties as a United States Government employee and
-* thus cannot be copyrighted. This software/database is freely available
-* to the public for use. The National Library of Medicine and the U.S.
-* Government have not placed any restriction on its use or reproduction.
-*
-* Although all reasonable efforts have been taken to ensure the accuracy
-* and reliability of the software and data, the NLM and the U.S.
-* Government do not and cannot warrant the performance or results that
-* may be obtained by using this software or data. The NLM and the U.S.
-* Government disclaim all warranties, express or implied, including
-* warranties of performance, merchantability or fitness for any particular
-* purpose.
-*
-* Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-*/
-
-#include <vfs/extern.h>
-
-#include <vfs/manager.h>
-#include <vfs/path.h>
-#include <klib/defs.h>
-#include <klib/rc.h>
-#include <klib/log.h>
-#include <klib/out.h>
-#include <klib/debug.h>
-
-#include "../path-priv.h"
-
-#include <wchar.h>
-#include <windows.h>
-#include <direct.h>
-
-#include <sysalloc.h>
-
-#include <os-native.h>
-/*--------------------------------------------------------------------------
- * VFSManager
- */
-
-
-/* MakeSysPath
- * make a path object from an OS native filesystem path string
- *
- * "new_path" [ OUT ] - return parameter for new path object
- *
- * "sys_path" [ IN ] - a UTF-8 NUL-terminated string
- * representing a native filesystem path
- *
- * "wide_sys_path" [ IN ] - a wide NUL-terminated string
- * representing a native filesystem path, where
- * wchar_t is either USC-2 or UTF-32 depending upon libraries
- */
-LIB_EXPORT rc_t CC VFSManagerMakeSysPath ( const VFSManager * self,
- VPath ** new_path, const char * sys_path )
-{
- rc_t rc = 0;
-
- /* this is all incorrect - the only reason we STILL use
- wchar_t in Windows is to guarantee UNICODE. most of the
- time, we'll have UTF-8, which is okay. but on older systems,
- it could still be something ancient. should use OS
- to convert from system path to UCS-2. */
-
- if ( new_path == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcSelf, rcNull );
- else if ( sys_path == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcNull );
- else
- {
- size_t src_size = string_size ( sys_path );
-
- /* transform to wchar_t */
- wchar_t wchar_path [ 4096 ], * dst = wchar_path;
- size_t copy_size, dst_size = src_size * sizeof wchar_path [ 0 ];
- if ( dst_size < sizeof wchar_path )
- dst_size = sizeof wchar_path;
- else
- {
- dst = malloc ( dst_size += sizeof * dst );
- if ( dst == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcMemory, rcExhausted );
- }
-
- if ( rc == 0 )
- {
- /* we need to call windows to do the conversion, because sys_path can
- be ascii or multi-byte */
- copy_size = MultiByteToWideChar ( CP_THREAD_ACP, MB_PRECOMPOSED,
- sys_path, ( int ) src_size, dst,
- ( int ) ( dst_size / sizeof dst [ 0 ] ) - 1 );
- if ( copy_size == 0 )
- {
- DWORD status = GetLastError ();
- DBGMSG ( DBG_VFS, DBG_FLAG_ANY, ( "MultiByteToWideChar: error code - %!.\n", status ) );
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcInvalid );
- }
- else
- {
- dst [ copy_size ] = 0;
- rc = VFSManagerWMakeSysPath ( self, new_path, dst );
- }
-
- if ( dst != wchar_path )
- free ( dst );
-
- if ( rc == 0 )
- return 0;
-
- }
- }
-
- * new_path = NULL;
- }
-
- return rc;
-}
-
-
-static
-rc_t transform_to_utf8_and_make_vpath ( const VFSManager * self,
- VPath ** new_path, const wchar_t * src, bool dos_path )
-{
- rc_t rc = 0;
- size_t src_size, dst_size;
- uint32_t len = wchar_cvt_string_measure ( src, & src_size, & dst_size );
- if ( len == 0 )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcEmpty );
- else
- {
- /* transform to UTF-8 */
- size_t copy_size;
- char utf8_path [ 4096 ], *dst = utf8_path;
- if ( dst_size < sizeof utf8_path )
- dst_size = sizeof utf8_path;
- else
- {
- dst = malloc ( ++ dst_size );
- if ( dst == NULL )
- return RC ( rcVFS, rcMgr, rcConstructing, rcMemory, rcExhausted );
- }
-
- copy_size = wchar_cvt_string_copy ( dst, dst_size, src, src_size );
- if ( copy_size >= dst_size )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcBuffer, rcInsufficient );
- else
- {
- size_t i = 0;
-
- dst [ copy_size ] = 0;
-
- /* encode drive letter */
- if ( dos_path )
- {
- assert ( isalpha ( dst [ 0 ] ) );
- assert ( dst [ 1 ] == ':' );
- dst [ 1 ] = dst [ 0 ];
- dst [ 0 ] = '/';
- i = 2;
- }
-
- /* convert '\\' to '/' */
- for ( ; i < copy_size; ++ i )
- {
- if ( dst [ i ] == '\\' )
- dst [ i ] = '/';
- }
-
- /* this is the final goal! */
- rc = VFSManagerMakePath ( self, new_path, "%.*s", ( uint32_t ) copy_size, dst );
- }
-
- if ( dst != utf8_path )
- free ( dst );
- }
- return rc;
-}
-
-
-static
-rc_t make_absolute_and_transform_to_utf8_and_make_vpath ( const VFSManager * self,
- VPath ** new_path, const wchar_t * src, bool have_drive )
-{
- rc_t rc;
- wchar_t full [ 4096 ];
-
- /* expand to full path - this is temporary, and will be replaced after KFS is updated */
- DWORD len = GetFullPathNameW ( src, sizeof full / sizeof full [ 0 ], full, NULL );
- if ( len == 0 )
- {
- /* we have an error */
- DWORD status = GetLastError ();
- DBGMSG ( DBG_VFS, DBG_FLAG_ANY, ( "GetFullPathNameW: error code - %u.\n", status ) );
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcInvalid );
- }
- else if ( len >= sizeof full / sizeof full [ 0 ] )
- {
- /* the buffer is too small ! */
- wchar_t * big_buf = malloc( ( ++len ) * ( sizeof full[ 0 ] ) );
- if ( big_buf == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcMemory, rcExhausted );
- else
- {
- DWORD len2 = GetFullPathNameW ( src, len, big_buf, NULL );
- if ( len2 == 0 )
- {
- /* we have an error */
- DWORD status = GetLastError ();
- DBGMSG ( DBG_VFS, DBG_FLAG_ANY, ( "GetFullPathNameW: error code - %u.\n", status ) );
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcInvalid );
- }
- else if ( len2 >= len )
- {
- DBGMSG ( DBG_VFS, DBG_FLAG_ANY, ( "GetFullPathNameW: buffer too small again - %u.\n", len2 ) );
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcInvalid );
- }
- else
- {
- /* now we can call the final transform and make */
- rc = transform_to_utf8_and_make_vpath( self, new_path, big_buf, true );
- }
- free( big_buf );
- }
- }
- else
- {
- /* now we can call the final transform and make */
- rc = transform_to_utf8_and_make_vpath( self, new_path, full, true );
- }
- return rc;
-}
-
-static
-bool could_be_url ( const wchar_t * wide_sys_path )
-{
- uint32_t i;
- for ( i = 0; wide_sys_path [ i ] != 0; ++ i )
- {
- if ( wide_sys_path [ i ] == ':' )
- {
- if ( i < 3 || i > 16 )
- break;
- for ( ++ i; wide_sys_path [ i ] != 0; ++ i )
- {
- if ( wide_sys_path [ i ] == '\\' )
- return false;
- }
- return true;
- }
-
- if ( wide_sys_path [ i ] == '\\' )
- break;
- }
- return false;
-}
-
-static
-bool could_be_accession ( const wchar_t * wide_sys_path )
-{
- uint32_t i;
- for ( i = 0; wide_sys_path [ i ] != 0; ++ i )
- {
- switch ( wide_sys_path [ i ] )
- {
- case '/':
- case '\\':
- return false;
- }
- }
- return true;
-}
-
-
-LIB_EXPORT rc_t CC VFSManagerWMakeSysPath ( const VFSManager * self,
- VPath ** new_path, const wchar_t * wide_sys_path )
-{
- rc_t rc = 0;
-
- /* what makes Windows paths exciting is that they
- have these drive letters, or they can be UNC,
- but they can be relative to the current drive,
- and they can use back-slashes because they're
- easy to type, or they can use forward-slashes,
- whatever. */
-
- if ( new_path == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcParam, rcNull );
- else
- {
- if ( self == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcSelf, rcNull );
- else if ( wide_sys_path == NULL )
- rc = RC ( rcVFS, rcMgr, rcConstructing, rcPath, rcNull );
- else
- {
- /* test for UNC path */
- if ( ( wide_sys_path [ 0 ] == '\\' && wide_sys_path [ 1 ] == '\\' ) ||
- ( wide_sys_path [ 0 ] == '/' && wide_sys_path [ 1 ] == '/' ) )
- {
- /* it is a UNC-path.
- reject IO or device namespaces */
- if ( ( wide_sys_path [ 2 ] == '?' || wide_sys_path [ 2 ] == '.' ) &&
- ( wide_sys_path [ 3 ] == '\\' || wide_sys_path [ 3 ] == '/' ) )
- return RC ( rcVFS, rcPath, rcConstructing, rcPath, rcIncorrect );
-
- /* produce the VPath-instance from the passed in string */
- rc = transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, false );
- }
- else
- {
- /* it is not a UNC-path.
- test for drive letter */
- if ( iswalpha ( wide_sys_path [ 0 ] ) && wide_sys_path [ 1 ] == ':' )
- {
- /* drive letter detected.
- test for absolute path */
- if ( wide_sys_path [ 2 ] != '\\' && wide_sys_path [ 2 ] != '/' )
- {
- /* drive-relative path.
- we have make an absolute path first */
- rc = make_absolute_and_transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, true );
- }
- else
- {
- /* already absolute path.
- produce the VPath-instance from the passed in string */
- rc = transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, true );
- }
- }
- /* test for URI syntax */
- else if ( could_be_url ( wide_sys_path ) )
- rc = transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, false );
- else if ( could_be_accession ( wide_sys_path ) )
- rc = transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, false );
- else
- {
- /* no drive letter detected, we have make a absolute path first */
- rc = make_absolute_and_transform_to_utf8_and_make_vpath ( self, new_path, wide_sys_path, false );
- }
- }
- }
- }
- return rc;
-}
-
-static
-void convert_fwd_to_rev_slashes ( char * buffer, size_t bytes )
-{
- size_t i;
- for ( i = 0; i < bytes; ++ i )
- {
- if ( buffer [ i ] == '/' )
- buffer [ i ] = '\\';
- }
-}
-
-LIB_EXPORT rc_t CC VPathReadSysPath ( const VPath * self,
- char * buffer, size_t buffer_size, size_t * num_read )
-{
- rc_t rc;
-
- if ( self == NULL )
- rc = RC ( rcVFS, rcPath, rcReading, rcSelf, rcNull );
- else if ( buffer== NULL && buffer_size != 0 )
- rc = RC ( rcVFS, rcPath, rcReading, rcParam, rcNull );
- else
- {
- size_t dummy, effective_size = buffer_size;
- if ( num_read == NULL )
- {
- num_read = & dummy;
- if ( buffer_size != 0 )
- -- effective_size;
- }
-
- rc = 0;
-
- switch ( self -> path_type )
- {
- case vpInvalid:
- rc = RC ( rcVFS, rcPath, rcReading, rcPath, rcInvalid );
- break;
- case vpOID:
- case vpAccession:
- case vpNameOrOID:
- case vpNameOrAccession:
- case vpName:
- /* copy as simple name */
- if ( effective_size < self -> path . size )
- rc = RC ( rcVFS, rcPath, rcReading, rcBuffer, rcInsufficient );
- else
- * num_read = string_copy ( buffer, buffer_size, self -> path . addr, self -> path . size );
- break;
- case vpRelPath:
- case vpUNCPath:
- /* copy and transform slashes */
- if ( effective_size < self -> path . size )
- rc = RC ( rcVFS, rcPath, rcReading, rcBuffer, rcInsufficient );
- else
- {
- * num_read = string_copy ( buffer, buffer_size, self -> path . addr, self -> path . size );
- convert_fwd_to_rev_slashes ( buffer, * num_read );
- }
- break;
- case vpFullPath:
- /* convert to full path */
- if ( effective_size < self -> path . size )
- rc = RC ( rcVFS, rcPath, rcReading, rcBuffer, rcInsufficient );
- else
- {
- * num_read = string_copy ( buffer, buffer_size, self -> path . addr, self -> path . size );
- if ( self -> scheme_type == vpuri_none ||
- self -> scheme_type == vpuri_ncbi_file ||
- self -> scheme_type == vpuri_file )
- {
- assert ( * num_read >= 2 );
- buffer [ 0 ] = buffer [ 1 ];
- buffer [ 1 ] = ':';
- convert_fwd_to_rev_slashes ( buffer, * num_read );
- }
- }
- break;
- case vpAuth:
- case vpHostName:
- case vpEndpoint:
- default:
- rc = RC ( rcVFS, rcPath, rcReading, rcPath, rcIncorrect );
- }
- }
-
- if ( rc != 0 )
- {
- if ( num_read != NULL )
- * num_read = 0;
- if ( buffer != NULL && buffer_size != 0 )
- buffer [ 0 ] = 0;
- }
-
- return rc;
-}
-
-
-
-/* ==========================================
- HACK O' MATIC
- */
-
-LIB_EXPORT rc_t LegacyVPathMakeSysPath ( VPath ** new_path, const char * sys_path )
-{
- VFSManager * vfs;
- rc_t rc = VFSManagerMake ( & vfs );
- if ( rc == 0 )
- {
- rc = VFSManagerMakeSysPath ( vfs, new_path, sys_path );
- VFSManagerRelease ( vfs );
- }
- return rc;
-}
diff --git a/libs/xfs/win/operations.c b/libs/xfs/win/operations.c
deleted file mode 100644
index b09bac3..0000000
--- a/libs/xfs/win/operations.c
+++ /dev/null
@@ -1,2666 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
- /* Something unusual: Lyrics
- *
- * That file contains only one useful function:
- *
- * XFS_Private_InitOperations
- *
- * it needed to fill _DOKAN_OPERATIONS structure.
- *
- * I put here all possible stubs to _DOKAN_OPERATIONS
- * functions. However, I will use only several of them while
- * structure initialisation. So, if You want to extend functionality,
- * please edit already ready stub and add new function to structure
- * initialized .
- *
- */
-
-#include <windows.h>
-
-#include <klib/out.h>
-#include <klib/log.h>
-#include <klib/namelist.h>
-#include <kfs/file.h>
-#include <kfs/directory.h>
-#include <kfs/impl.h> /* KDirectoryGetSysDir() */
-#include <vfs/path.h>
-#include <vfs/manager.h>
-
-#include <xfs/node.h>
-#include <xfs/tree.h>
-#include <xfs/editors.h>
-#include <xfs/handle.h>
-#include <xfs/perm.h>
-#include <xfs/path.h>
-
-#include <sysalloc.h>
-
-#include <WinBase.h>
-#include <WinNT.h>
-#include <wchar.h>
-
-#include "operations.h"
-#include "zehr.h"
-#include "schwarzschraube.h"
-
-/****************************************************************
- * Song over babalula
- ****************************************************************/
-#define USE_XFS_DOKAN_CREATEFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_OPENDIRECTORY 1 /* - */ /* */
-#define USE_XFS_DOKAN_CREATEDIRECTORY 1 /* - */ /* */
-#define USE_XFS_DOKAN_CLEANUP 1 /* - */ /* */
-#define USE_XFS_DOKAN_CLOSEFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_READFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_WRITEFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_FLUSHFILEBUFFERS 0 /* - */ /* */
-#define USE_XFS_DOKAN_GETFILEINFORMATION 1 /* - */ /* */
-#define USE_XFS_DOKAN_FINDFILES 1 /* - */ /* */
-#define USE_XFS_DOKAN_FINDFILESWITHPATTERN 0 /* - */ /* NO NEED */
-#define USE_XFS_DOKAN_SETFILEATTRIBUTES 0 /* - */ /* */
-#define USE_XFS_DOKAN_SETFILETIME 0 /* - */ /* */
-#define USE_XFS_DOKAN_DELETEFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_DELETEDIRECTORY 1 /* - */ /* */
-#define USE_XFS_DOKAN_MOVEFILE 1 /* - */ /* */
-#define USE_XFS_DOKAN_SETENDOFFILE 0 /* - */ /* */
-#define USE_XFS_DOKAN_SETALLOCATIONSIZE 0 /* - */ /* */
-#define USE_XFS_DOKAN_LOCKFILE 0 /* - */ /* */
-#define USE_XFS_DOKAN_UNLOCKFILE 0 /* - */ /* */
-#define USE_XFS_DOKAN_GETDISKFREESPACE 0 /* - */ /* NO NEED */
-#define USE_XFS_DOKAN_GETVOLUMEINFORMATION 1 /* - */ /* */
-#define USE_XFS_DOKAN_UNMOUNT 1 /* - */ /* */
-#define USE_XFS_DOKAN_GETFILESECURITY 1 /* - */ /* */
-#define USE_XFS_DOKAN_SETFILESECURITY 1 /* - */ /* */
-
-/*)))
- ||| Operations
- (((*/
-
-/*))
- //
-|| is using _DOKAN_OPTIONS structure for that goal. So, there
-|| is different way to access for XFSPeer for both libraries
- \\
- (*/
-
-/*)) KLog does not work with WCHAR :D
- ((*/
-XFS_EXTERN rc_t CC wLogMsg ( KLogLevel Level, LPCWSTR Format, ... );
-
-/*\
-|*| importante protopute
-\*/
-struct KSysDir;
-rc_t KSysDirOSPath (
- const struct KSysDir * self,
- wchar_t * real,
- size_t bsize,
- const char * path,
- va_list args
- );
-
-/*)))
- /// Some common things are here
-(((*/
-LIB_EXPORT
-rc_t CC
-XFSPathInnerToNative (
- WCHAR * NativePathBuffer,
- size_t NativePathBufferSize,
- const char * InnerPath,
- ...
-)
-{
- rc_t RCt;
- KDirectory * Dir;
- struct KSysDir * SysDir;
- va_list VaLsd;
-
- RCt = 0;
- Dir = NULL;
-
- if ( InnerPath == NULL || NativePathBuffer == NULL
- || NativePathBufferSize == 0 )
- {
- return XFS_RC ( rcNull );
- }
-
- RCt = KDirectoryNativeDir ( & Dir );
- if ( RCt == 0 ) {
- SysDir = KDirectoryGetSysDir(Dir);
-
- va_start ( VaLsd, InnerPath );
- RCt = KSysDirOSPath (
- SysDir,
- NativePathBuffer,
- NativePathBufferSize,
- InnerPath,
- VaLsd
- );
- va_end ( VaLsd );
- }
-
- return RCt;
-} /* XFSPathInnerToNative () */
-
-static
-rc_t CC
-_DOKAN_make_v_path ( LPCWSTR File, VPath ** Path )
-{
- rc_t RCt;
- char Buffer [ XFS_SIZE_4096 ];
- char * pChar;
- size_t Size;
-
- RCt = 0;
- Size = 0;
- pChar = NULL;
- * Buffer = 0;
-
- if ( File == NULL || Path == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Path = NULL;
-
- /* Quite stupid, but I don't know what to do
- */
- RCt = wcstombs_s (
- & Size,
- Buffer,
- sizeof ( Buffer ),
- File,
- wcslen ( File )
- );
-
- if ( RCt == 0 ) {
- /* That is kinda stupid, and I should think about it
- */
- pChar = Buffer;
- while ( * pChar != 0 ) {
- if ( * pChar == '\\' ) {
- * pChar = '/';
- }
- pChar ++;
- }
-
- RCt = VFSManagerMakePath ( XFS_VfsManager (), Path, Buffer );
- }
-
- return RCt;
-} /* _DOKAN_make_v_path () */
-
-static
-rc_t CC
-_DOKAN_get_node (
- const PDOKAN_FILE_INFO FileInfo,
- const struct VPath * Path,
- const struct XFSNode ** TheNode
-)
-{
- struct XFSTreeDepot * Depot;
- const struct XFSNode * Node;
- rc_t RCt;
-
- Depot = NULL;
- RCt = 0;
-
- if ( FileInfo == NULL || TheNode == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- * TheNode = NULL;
-
- Depot = ( struct XFSTreeDepot * ) FileInfo -> DokanOptions -> GlobalContext;
- if ( Depot == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- RCt = XFSTreeDepotFindNodeForPath ( Depot, Path, & Node );
-
- if ( RCt == 0 ) {
- * TheNode = Node;
- }
-
-/*
-//TT wLogMsg ( klogDebug, L"_DOKAB_get_node () TreeDepot [0x%p] Node [0x%p] Opts [0x%p]\n", TreeDepot, Node, FileInfo -> DokanOptions );
-*/
-
- return RCt;
-} /* _DOKAN_get_node () */
-
-static
-rc_t CC
-_DOKAN_get_path_and_node (
- LPCWSTR File,
- const PDOKAN_FILE_INFO Info,
- const struct VPath ** Path,
- const struct XFSNode ** Node,
- XFSNType * NodeType
-)
-{
- rc_t RCt;
- struct XFSNode * RNode;
- struct VPath * RPath;
- XFSNType Type;
- const struct XFSAttrEditor * Ediotr;
-
- RCt = 0;
- RNode = NULL;
- RPath = NULL;
- Type = kxfsBadPath;
- Ediotr = NULL;
-
- if ( File == NULL || Info == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- RCt = _DOKAN_make_v_path ( File, & RPath );
- if ( RCt == 0 ) {
-
- RCt = _DOKAN_get_node ( Info, RPath, & RNode );
- if ( RCt == 0 ) {
- if ( NodeType != NULL ) {
- RCt = XFSNodeAttrEditor ( RNode, & Ediotr );
- if ( RCt == 0 ) {
- RCt = XFSAttrEditorType ( Ediotr, & Type );
-
- XFSEditorDispose ( & ( Ediotr -> Papahen ) );
- }
- }
- }
- }
-
- if ( RCt == 0 ) {
- if ( Path != NULL ) {
- * Path = RPath;
- }
- else {
- VPathRelease ( RPath );
- }
-
- if ( Node != NULL ) {
- * Node = RNode;
- }
- else {
- XFSNodeRelease ( RNode );
- }
-
- if ( NodeType != NULL ) {
- * NodeType = Type;
- }
- }
- else {
- if ( RPath != NULL ) {
- VPathRelease ( RPath );
- }
-
- if ( RNode != NULL ) {
- XFSNodeRelease ( RNode );
- }
- }
-
- return RCt;
-} /* _DOKAN_get_path_and_node () */
-
-static
-rc_t
-_DOKAN_get_parent_node (
- const struct VPath * Path,
- DOKAN_FILE_INFO * TheFileInfo, /* Depot source */
- struct XFSNode ** Node, /* Ret node */
- XFSNType * Type, /* could be NULL */
- char ** NodeName /* could be NULL */
-)
-{
- rc_t RCt;
- struct XFSTreeDepot * Depot;
- char BB [ XFS_SIZE_4096 ];
- struct XFSPath * xPath;
- uint32_t xPathQ;
- struct XFSNode * xNode;
- struct XFSAttrEditor * xEditor;
- char * xName;
- const struct XFSPath * xParent;
-
- RCt = 0;
- Depot = NULL;
- * BB = 0;
- xPath = NULL;
- xPathQ = 0;
- xNode = NULL;
- xEditor = NULL;
- xName = NULL;
- xParent = NULL;
-
- if ( Node == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- * Node = NULL;
-
- if ( Path == NULL || TheFileInfo == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- if ( Type != NULL ) {
- * Type = kxfsNotFound;
- }
-
- if ( NodeName != NULL ) {
- * NodeName = NULL;
- }
-
- /*) First we should retrieve fresh instance of depot
- (*/
- Depot = ( struct XFSTreeDepot * ) TheFileInfo -> DokanOptions -> GlobalContext;
- if ( Depot == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- /*) Reading VPath
- (*/
- RCt = XFS_ReadVPath_ZHR ( Path, BB, sizeof ( BB ), "" );
- if ( RCt == 0 ) {
- /*) Making XFSPath
- (*/
- RCt = XFSPathMake ( & xPath, true, BB );
- if ( RCt == 0 ) {
- xPathQ = XFSPathPartCount ( xPath );
- if ( xPathQ < 2 ) {
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- /*) Here we are composing parent path
- (*/
- RCt = XFSPathParent ( xPath, & xParent );
- if ( RCt == 0 ) {
- /*) Here we are looking for NODE
- (*/
- RCt = XFSTreeDepotFindNode (
- Depot,
- XFSPathGet ( xParent ),
- & xNode
- );
- if ( RCt == 0 ) {
- if ( Type != NULL ) {
- RCt = XFSNodeAttrEditor ( xNode, & xEditor );
- if ( RCt == 0 ) {
- RCt = XFSAttrEditorType ( xEditor, Type );
- XFSEditorDispose ( & ( xEditor -> Papahen ) );
- }
- }
-
- if ( RCt == 0 ) {
- if ( NodeName != NULL ) {
- RCt = XFS_StrDup (
- XFSPathName ( xPath ),
- & xName
- );
- if ( RCt == 0 ) {
- * NodeName = xName;
- }
- }
- }
-
- if ( RCt == 0 ) {
- * Node = xNode;
- }
- }
- }
-
- XFSPathRelease ( xParent );
- }
-
- XFSPathRelease ( xPath );
- }
- }
-
- if ( RCt != 0 ) {
- * Node = NULL;
- if ( Type != NULL ) {
- * Type = kxfsNotFound;
- }
- if ( NodeName != NULL ) {
- * NodeName = NULL;
- }
- if ( xNode != NULL ) {
- XFSNodeRelease ( xNode );
- }
- if ( xName != NULL ) {
- free ( xName );
- }
- }
-
- return RCt;
-} /* _DOKAN_get_parent_node () */
-
-static
-rc_t
-_DOKAN_get_parent_node_from_char (
- LPCWSTR ThePath,
- DOKAN_FILE_INFO * TheFileInfo, /* Depot source */
- struct XFSNode ** Node, /* Ret node */
- XFSNType * Type, /* could be NULL */
- char ** NodeName /* could be NULL */
-)
-{
- rc_t RCt;
- struct VPath * Path;
-
- RCt = 0;
- Path = NULL;
-
- if ( ThePath == NULL || TheFileInfo == NULL || Node == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- * Node = NULL;
-
- RCt = _DOKAN_make_v_path ( ThePath, & Path );
- if ( RCt == 0 ) {
- RCt = _DOKAN_get_parent_node (
- Path,
- TheFileInfo,
- Node,
- Type,
- NodeName
- );
-
- VPathRelease ( Path );
- }
-
- return RCt;
-} /* _DOKAN_get_parent_node_from_char() */
-
-static
-rc_t
-_DOKAN_delete_file_dir (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSNode * Node;
- XFSNType Type;
- char * Name;
- struct XFSDirEditor * Editor;
-
- RCt = 0;
- Node = NULL;
- Type = kxfsNotFound;
- Name = NULL;
- Editor = NULL;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- RCt = _DOKAN_get_parent_node_from_char (
- FileName,
- TheFileInfo,
- & Node,
- & Type,
- & Name
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeDirEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSDirEditorDelete ( Editor, Name );
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- XFSNodeRelease ( Node );
- free ( Name );
- }
-
- return 0;
-} /* DOKAN_delete_file_dir () */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_CREATEFILE == 1
-
-static
-void
-__PrintDisposition__ ( LPCWSTR FileName, DWORD CreationDisposition )
-{
- WCHAR BF [ XFS_SIZE_4096 ];
-
- swprintf (
- BF,
- sizeof ( BF ) / sizeof ( WCHAR ),
- L"Disposition [%08x][%s]:",
- CreationDisposition ,
- FileName
- );
-
- switch ( CreationDisposition ) {
- case CREATE_NEW : wcscat ( BF, L" CREATE_NEW" ); break;
- case OPEN_ALWAYS : wcscat ( BF, L" OPEN_ALWAYS" ); break;
- case CREATE_ALWAYS : wcscat ( BF, L" CREATE_ALWAYS" ); break;
- case OPEN_EXISTING : wcscat ( BF, L" OPEN_EXISTING" ); break;
- case TRUNCATE_EXISTING : wcscat ( BF, L" TRUNCATE_EXISTING" ); break;
- default: wcscat ( BF, L" UNKNOWN" ); break;
- }
-
- wLogMsg ( klogDebug, L"%s (%d)\n", BF, CreationDisposition );
-} /* __PrintDisposition__ () */
-
-static
-void
-__PrintAccessMode__ ( LPCWSTR FileName, DWORD AccessMode )
-{
- int llp, klf;
- WCHAR BF [ XFS_SIZE_4096 ];
-
- swprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), L"AccessMode [%08x][%s]:", AccessMode, FileName );
-
- for ( llp = 31; 0 <= llp; llp -- ) {
- klf = 1 << llp;
- if ( llp % 8 == 0 ) {
- wcscat ( BF, L" " );
- }
-
- if ( ( AccessMode & klf ) == klf ) {
- wcscat ( BF, L"1" );
- }
- else {
- wcscat ( BF, L"0" );
- }
- }
- wLogMsg ( klogDebug, L"%s\n", BF );
-
- swprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), L"AccessMode [%08xl][%s]:", AccessMode, FileName );
- if ( ( AccessMode & FILE_READ_DATA ) == FILE_READ_DATA ) wcscat ( BF, L" FILE_READ_DATA" );
- if ( ( AccessMode & FILE_WRITE_DATA ) == FILE_WRITE_DATA ) wcscat ( BF, L" FILE_WRITE_DATA" );
- if ( ( AccessMode & FILE_APPEND_DATA ) == FILE_APPEND_DATA ) wcscat ( BF, L" FILE_APPEND_DATA" );
- if ( ( AccessMode & FILE_READ_EA ) == FILE_READ_EA ) wcscat ( BF, L" FILE_READ_EA" );
- if ( ( AccessMode & FILE_WRITE_EA ) == FILE_WRITE_EA ) wcscat ( BF, L" FILE_WRITE_EA" );
- if ( ( AccessMode & FILE_EXECUTE ) == FILE_EXECUTE ) wcscat ( BF, L" FILE_EXECUTE" );
- if ( ( AccessMode & FILE_DELETE_CHILD ) == FILE_DELETE_CHILD ) wcscat ( BF, L" FILE_DELETE_CHILD" );
- if ( ( AccessMode & FILE_READ_ATTRIBUTES ) == FILE_READ_ATTRIBUTES ) wcscat ( BF, L" FILE_READ_ATTRIBUTES" );
- if ( ( AccessMode & FILE_WRITE_ATTRIBUTES ) == FILE_WRITE_ATTRIBUTES ) wcscat ( BF, L" FILE_WRITE_ATTRIBUTES" );
- if ( ( AccessMode & FILE_ALL_ACCESS ) == FILE_ALL_ACCESS ) wcscat ( BF, L" FILE_ALL_ACCESS" );
- if ( ( AccessMode & READ_CONTROL ) == READ_CONTROL ) wcscat ( BF, L" READ_CONTROL" );
- if ( ( AccessMode & DELETE ) == DELETE ) wcscat ( BF, L" DELETE" );
-
- wLogMsg ( klogDebug, L"%s\n", BF );
-} /* __PrintAccessMode__ () */
-
-static
-int
-_HandleForNode (
- const struct XFSNode * Node,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- int RetVal;
- struct XFSHandle * Handle;
-
- RetVal = 0;
-
- if ( Node == NULL ) {
- return ERROR_INVALID_DATA;
- }
-
- if ( TheFileInfo == NULL ) {
- RetVal = ERROR_INVALID_DATA;
- } else {
- if ( XFSHandleMake ( Node, & Handle ) != 0 ) {
- RetVal = ERROR_INVALID_DATA;
- }
- else {
- TheFileInfo -> Context = ( ULONG ) Handle;
-
- RetVal = 0;
- }
- }
-
- XFSNodeRelease ( Node );
-
- return RetVal;
-} /* _HandleForNode () */
-
-static
-int
-_HandleOpenExistingFileEdit (
- const struct XFSNode * Node,
- PDOKAN_FILE_INFO TheFileInfo,
- bool Write,
- bool Read
-)
-{
- struct XFSFileEditor * Editor;
- rc_t RCt;
- XFSNMode Mode;
- struct XFSHandle * Handle;
- int RetVal;
-
- Editor = NULL;
- Mode = 0;
- Handle = NULL;
- RCt= 0;
- RetVal = 0;
-
- if ( Node == NULL ) {
- return ERROR_INVALID_DATA;
- }
-
- if ( TheFileInfo == NULL ) {
- XFSNodeRelease ( Node );
-
- return ERROR_INVALID_DATA;
- }
-
- if ( Write ) {
- Mode |= kxfsWrite;
- }
-
- if ( Read ) {
- Mode |= kxfsRead;
- }
-
- RCt = XFSNodeFileEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSFileEditorOpen ( Editor, Mode );
- if ( RCt == 0 ) {
- RCt = XFSHandleMake ( Node, & Handle );
- if ( RCt == 0 ) {
- XFSHandleSet ( Handle, Editor );
-
- TheFileInfo -> Context = ( ULONG ) Handle;
- }
- }
- }
-
- if ( RCt != 0 ) {
- if ( Editor != NULL ) {
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
- }
-
- XFSNodeRelease ( Node );
-
- if ( RCt == 0 ) {
- RetVal = 0;
- }
- else {
- if ( RCt == XFS_RC ( rcBusy ) ) {
- RetVal = ERROR_PATH_BUSY;
- }
- else {
- RetVal = ERROR_ACCESS_DENIED;
- }
- }
-
- return RetVal;
-} /* _HandleOpenExistingFileEdit () */
-
-static
-int
-_HandleCreateNewFileEdit (
- const struct VPath * Path,
- DOKAN_FILE_INFO * TheFileInfo,
- bool Write,
- bool Read
-)
-{
- rc_t RCt;
- struct XFSNode * Node;
- struct XFSDirEditor * DirEditor;
- struct XFSHandle * Handle;
- char * NodeName;
- XFSNType Type;
- XFSNMode Mode;
-
- RCt = 0;
- Node = NULL;
- DirEditor = NULL;
- Handle = NULL;
- NodeName = NULL;
- Type = kxfsNotFound;
- Mode = kxfsNone;
-
- if ( TheFileInfo == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- TheFileInfo -> Context = 0;
-
- if ( Write ) { Mode |= kxfsWrite; }
- if ( Read ) { Mode |= kxfsRead; }
-
- RCt = _DOKAN_get_parent_node (
- Path,
- TheFileInfo,
- & Node,
- & Type,
- & NodeName
- );
- if ( RCt == 0 ) {
- /* I do not check if node exists or not,
- * cuz Bogus node will fail on retrieving
- * DirEditor
- */
- RCt = XFSNodeDirEditor ( Node, & DirEditor );
- if ( RCt == 0 ) {
- RCt = XFSDirEditorCreate (
- DirEditor,
- NodeName,
- Mode,
- & Handle
- );
- if ( RCt == 0 ) {
- TheFileInfo -> Context = ( ULONG ) Handle;
- }
- }
-
- XFSNodeRelease ( Node );
- free ( NodeName );
- }
-
- if ( RCt != 0 ) {
- if ( DirEditor != NULL ) {
- XFSEditorDispose ( & ( DirEditor -> Papahen ) );
- }
- }
-
- return RCt == 0 ? 0 : ERROR_ACCESS_DENIED;
-} /* _HandleCreateNewFileEdit () */
-
-/*))
- (( Really strange method, long and stupid.
- ))
- ((*/
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_CreateFile (
- LPCWSTR FileName,
- DWORD AccessMode,
- DWORD ShareMode,
- DWORD CreationDisposition,
- DWORD FlagsAndAttributes,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- int RetValue;
- struct XFSNode * Node;
- XFSNType Type;
- bool Read, Write;
- VPath * Path;
-
- RCt = 0;
- RetValue = 0;
- Node = NULL;
- Type = kxfsBadPath;
- Read = Write = false;
- Path = NULL;
-
-#ifdef I_AM_AN_IMBECILE
-{
-if ( wcsstr ( FileName, klogDebug, L"CVS" ) != NULL
- || wcsstr ( FileName, klogDebug, L".svn" ) != NULL
- || wcsstr ( FileName, klogDebug, L"desktop.ini" ) != NULL
- || wcsstr ( FileName, klogDebug, L".gs" ) != NULL
- || wcsstr ( FileName, klogDebug, L"Authorun.inf" ) != NULL
- ) {
-wLogMsg ( klogDebug, L" CREATE File [%s][VYHUHOL]\n", FileName );
- return ERROR_PATH_NOT_FOUND * - 1;
-}
-}
-#endif /* I_AM_AN_IMBECILE */
-
-wLogMsg ( klogDebug, L" CREATE File [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return 1 * - 1; /* TODO !!! */
- }
- TheFileInfo -> Context = 0L;
-
-__PrintAccessMode__ ( FileName, AccessMode );
-__PrintDisposition__ ( FileName, CreationDisposition );
-
- /* Awkward attempt to reduce filesystem abuse from
- CVS agen and all other services, like gzip
- */
-
- /* First we should know what kind of file object do we have
- */
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- & Path,
- & Node,
- & Type
- );
- /* Something really wrong did happen
- */
- if ( RCt != 0 ) {
- return 1 * - 1;
- }
-
- /* Reading/Writing file
- */
- Read = ( AccessMode & FILE_READ_DATA ) == FILE_READ_DATA;
- Write = ( AccessMode & FILE_WRITE_DATA ) == FILE_WRITE_DATA;
-
- /* We need only existing file
- */
- if ( Type == kxfsNotFound && CreationDisposition == OPEN_EXISTING ) {
- TheFileInfo -> Context = 0L;
-
- XFSNodeRelease ( Node );
- VPathRelease ( Path );
-
- RetValue = ERROR_FILE_NOT_FOUND;
-
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=NULL][I=0x%p][%d]\n", FileName, RetValue, TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* We are trying to open new file
- */
- if ( Type == kxfsNotFound && CreationDisposition != OPEN_EXISTING
- && ( Read || Write )
- ) {
- RetValue = _HandleCreateNewFileEdit ( Path, TheFileInfo, Write, Read );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* Reading directory content
- */
- if ( Type == kxfsDir ) {
- /* Reading Directory Listing
- */
- if ( CreationDisposition == OPEN_EXISTING && Read ) {
- RetValue = _HandleForNode ( Node, TheFileInfo );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
- }
-
- /* Reading/Writin existing file
- */
- if ( ( Read || Write ) && Type != kxfsDir && Type != kxfsNotFound && Type != kxfsBadPath ) {
- RetValue = _HandleOpenExistingFileEdit ( Node, TheFileInfo, Write, Read );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* Reading/Writin file attributes
- */
- if ( ( AccessMode & FILE_GENERIC_READ ) == FILE_WRITE_ATTRIBUTES && CreationDisposition == OPEN_EXISTING ) {
- RetValue = _HandleOpenExistingFileEdit ( Node, TheFileInfo, Write, Read );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* Security read ... SACL DACL
- */
- if ( ( AccessMode & READ_CONTROL ) == READ_CONTROL
- && ( ! Read )
- && ( ! Write )
- ) {
- RetValue = _HandleForNode ( Node, TheFileInfo );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* We are reading file attributes, and all other requests
- */
- if ( ( AccessMode & FILE_GENERIC_READ ) == FILE_READ_ATTRIBUTES ) {
- RetValue = _HandleForNode ( Node, TheFileInfo );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* We are deleting file ...
- */
- if ( ( AccessMode & DELETE ) == DELETE ) {
- RetValue = _HandleForNode ( Node, TheFileInfo );
-
- VPathRelease ( Path );
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
- return RetValue * - 1;
- }
-
- /* Something else is here */
- RetValue = 1; // TODO
-
- XFSNodeRelease ( Node );
- VPathRelease ( Path );
-
-wLogMsg ( klogDebug, L" RETURNS [%s][RC=%d][I=0x%p][%d]\n", FileName, RetValue, TheFileInfo, __LINE__ );
-
- return RetValue * - 1;
-} /* CreateFile() */
-
-#endif /* USE_XFS_DOKAN_CREATEFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_OPENDIRECTORY == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_OpenDirectory (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- const struct XFSNode * TheNode;
- XFSNType Type;
- int RetVal;
-
- RCt = 0;
- TheNode = NULL;
- Type = kxfsNotFound;
- RetVal = 0;
-
-//TT wLogMsg ( klogDebug, L" OPEN directory [%s][I=0x%p][C=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return 1 * - 1;
- }
- TheFileInfo -> Context = 0L;
-
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- NULL,
- & TheNode,
- & Type
- );
- if ( RCt == 0 ) {
- if ( Type == kxfsDir ) {
- RetVal = _HandleForNode ( TheNode, TheFileInfo );
- }
- else {
- RetVal = ERROR_PATH_NOT_FOUND;
-
- XFSNodeRelease ( TheNode );
- }
- }
- else {
- RetVal = ERROR_INVALID_DATA;
- }
-
-//TT wLogMsg ( klogDebug, L" OPEN directory,cont [%s][I=0x%p][C=0x%p][RC=%lu]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RetVal );
- return RetVal * - 1;
-} /* OpenDirectory() */
-
-#endif /* USE_XFS_DOKAN_OPENDIRECTORY == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_CREATEDIRECTORY == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_CreateDirectory (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSNode * Node;
- char * Name;
- struct XFSDirEditor * Editor;
-
- RCt = 0;
- Node = NULL;
- Name = NULL;
- Editor = NULL;
-
-//TT wLogMsg ( klogDebug, L"CREATE Directory [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- RCt = _DOKAN_get_parent_node_from_char (
- FileName,
- TheFileInfo,
- & Node,
- NULL,
- & Name
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeDirEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSDirEditorCreateDir ( Editor, Name );
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- XFSNodeRelease ( Node );
- free ( Name );
- }
-
-//TT wLogMsg ( klogDebug, L" CREATE Directory [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
-
- return RCt == 0 ? 0 : - 1;
-} /* CreateDirectory() */
-
-#endif /* USE_XFS_DOKAN_CREATEDIRECTORY == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_CLEANUP == 1
-
- /*))
- // We should remember, all files are closing and deleting here
- ((*/
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_Cleanup (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- struct XFSHandle * Handle;
- struct XFSFileEditor * Editor;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
-
- if ( Handle == NULL ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
-//TT wLogMsg ( klogDebug, L" CLEANUP File [%s][I=0x%p][H=0x%p][Del=%d]\n", FileName, TheFileInfo, Handle, TheFileInfo -> DeleteOnClose );
-
- TheFileInfo -> Context = 0L;
-
- Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
- if ( Editor != NULL ) {
- /*)) I believe that if ... if here is non-NULL handle,
- // it could be only handle for KFile, will change if ...
- ((*/
- XFSFileEditorClose ( Editor );
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- XFSHandleSet ( Handle, NULL );
- }
- XFSHandleRelease ( Handle );
-
- if ( TheFileInfo -> DeleteOnClose ) {
-//TT wLogMsg ( klogDebug, L" CLEANUP File : DELETE ON CLOSE [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, Handle );
- _DOKAN_delete_file_dir ( FileName, TheFileInfo );
-
- }
-
- return 0;
-} /* Cleanup() */
-
-#endif /* USE_XFS_DOKAN_CLEANUP == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_CLOSEFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_CloseFile (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSHandle * Handle;
- struct XFSFileEditor * Editor;
-
- RCt = 0; Handle = NULL;
- Editor = NULL;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return 1 * - 1;
- }
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
-
-//TT wLogMsg ( klogDebug, L" CLOSE File [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, Handle );
-
- if ( Handle == NULL ) {
- /* That's is OK */
- return 0;
- }
-
-//TT wLogMsg ( klogDebug, L" CLOSE File: Cleanup method wasn't called [%s][E=0x%p]\n", FileName, Handle );
-
- TheFileInfo -> Context = 0L;
-
- Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
- if ( Editor != NULL ) {
-
- XFSFileEditorClose ( Editor );
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- XFSHandleSet ( Handle, NULL );
- }
- XFSHandleRelease ( Handle );
-
- if ( TheFileInfo -> DeleteOnClose ) {
- RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
- }
-
-//TT wLogMsg ( klogDebug, L" CLOSE File,cont [%s][I=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, Handle, RCt );
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* CloseFile() */
-
-#endif /* USE_XFS_DOKAN_CLOSEFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_READFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_ReadFile (
- LPCWSTR FileName,
- LPVOID Buffer,
- DWORD NumberOfBytesToRead,
- LPDWORD NumberOfBytesRead,
- LONGLONG Offset,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- struct XFSHandle * Handle;
- bool LocallyOpened;
- struct XFSFileEditor * Editor;
- const struct XFSNode * Node;
- rc_t RCt;
- int RetVal;
- size_t n2r, nRd;
-
- Handle = NULL;
- LocallyOpened = false;
- Editor = NULL;
- Node = NULL;
- RCt = 0;
- RetVal = 0;
- n2r = nRd = 0;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return 1 * - 1; /* TODO !!! */
- }
-
-//TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - [N=%lu][O=%lu]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, NumberOfBytesToRead, Offset );
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
- n2r = ( size_t ) NumberOfBytesToRead;
-
- /*)) That's could happen, and we need to reopen fiel
- ((*/
- if ( Handle == NULL ) {
-//TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - REOPENING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- /*)) First we are looking for a node
- ((*/
-
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- NULL, /* VPath, no need */
- & Node,
- NULL /* NodeType */
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeFileEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSFileEditorOpen ( Editor, kxfsRead );
- if ( RCt == 0 ) {
- LocallyOpened = true;
- }
- }
- }
- }
- else {
- Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
- if ( Editor == NULL ) {
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- Node = XFSHandleNode ( Handle );
- if ( Node == NULL ) {
- RCt = XFS_RC ( rcInvalid );
- }
- }
- }
-
- if ( RCt == 0 ) {
- /*) Here we are reading info
- (*/
- RCt = XFSFileEditorRead (
- Editor,
- Offset,
- Buffer,
- n2r,
- & nRd
- );
- * NumberOfBytesRead = nRd;
- }
-
- if ( LocallyOpened ) {
-//TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - RECLOSING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
- if ( Editor != NULL ) {
- XFSFileEditorClose ( Editor );
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- Editor = NULL;
-
- if ( Node != NULL ) {
- XFSNodeRelease ( Node );
-
- Node = NULL;
- }
- }
-
- RetVal = RCt == 0 ? 0 : ERROR_INVALID_DATA;
-
-//TT wLogMsg ( klogDebug, L" READ File,cont [%s][I=0x%p][H=0x%p] - [Read=%lu][RC=%d]!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, * NumberOfBytesRead, RetVal );
-
- return RetVal * - 1;
-} /* ReadFile() */
-
-#endif /* USE_XFS_DOKAN_READFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_WRITEFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_WriteFile (
- LPCWSTR FileName,
- LPCVOID Buffer,
- DWORD NumBytesWrite,
- LPDWORD NumBytesWritten,
- LONGLONG Offset,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- struct XFSHandle * Handle;
- bool LocallyOpened;
- struct XFSFileEditor * Editor;
- const struct XFSNode * Node;
- rc_t RCt;
- int RetVal;
- size_t n2w, nWr;
-
- Handle = NULL;
- LocallyOpened = false;
- Editor = NULL;
- Node = NULL;
- RCt = 0;
- RetVal = 0;
- n2w = nWr = 0;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return 1 * - 1; /* TODO !!! */
- }
-
-//TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - [O=%d][N=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, (int)Offset, (int)NumBytesWrite );
-
- n2w = ( size_t ) NumBytesWrite;
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
-
- /*)) That's could happen, and we need to reopen fiel
- ((*/
- if ( Handle == NULL ) {
-//TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - REOPENING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- /*)) First we are looking for a node
- ((*/
-
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- NULL, /* VPath, no need */
- & Node,
- NULL /* NodeType */
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeFileEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSFileEditorOpen ( Editor, kxfsWrite );
- if ( RCt == 0 ) {
- LocallyOpened = true;
- }
- }
- }
- }
- else {
- Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
- if ( Editor == NULL ) {
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- Node = XFSHandleNode ( Handle );
- if ( Node == NULL ) {
- RCt = XFS_RC ( rcInvalid );
- }
- }
- }
-
- if ( RCt == 0 ) {
- /*) Here we are reading info
- (*/
- RCt = XFSFileEditorWrite (
- Editor,
- Offset,
- Buffer,
- n2w,
- & nWr
- );
- * NumBytesWritten = nWr;
- }
-
- if ( LocallyOpened ) {
-//TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - RECLOSING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
- if ( Editor != NULL ) {
- XFSFileEditorClose ( Editor );
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- Editor = NULL;
-
- if ( Node != NULL ) {
- XFSNodeRelease ( Node );
-
- Node = NULL;
- }
- }
-
- RetVal = RCt == 0 ? 0 : ERROR_INVALID_DATA;
-
-//TT wLogMsg ( klogDebug, L" WRITE File,cont [%s][I=0x%p][H=0x%p] - [Wrote=%d][RC=%d]!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, (int)* NumBytesWritten, (int)RetVal );
-
- return RetVal * - 1;
-} /* WriteFile() */
-
-#endif /* USE_XFS_DOKAN_WRITEFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_FlushFileBuffers (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"FLUSHFILEBUFFERS(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* FlushFileBuffers() */
-
-#endif /* USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_GETFILEINFORMATION == 1
-
-/*))
- // TODO : introduce global handle class, which will represent all
-((*/
-
-static
-int
-_Read_HANDLE_FILE_INFORMATION (
- const struct XFSHandle * Handle,
- LPBY_HANDLE_FILE_INFORMATION HandleFileInfo
-)
-{
- rc_t RCt;
- int RetVal;
- const struct XFSNode * Node;
- struct XFSAttrEditor * Editor;
- struct XFSFileEditor * FileEditor;
- struct XFSPerm * Perm;
- const char * PermStr;
- XFSNType Type;
- ULONG64 Time;
- KTime_t TheTime;
- DWORD TimeHigh, TimeLow;
- LARGE_INTEGER FileSize;
- uint64_t Size;
-
- RCt = 0;
- RetVal = 0;
- Node = NULL;
- Editor = NULL;
- Perm = NULL;
- PermStr = NULL;
- Type = kxfsNotFound;
-
- if ( Handle == NULL || HandleFileInfo == NULL ) {
- return 1;
- }
-
- Node = XFSHandleNode ( Handle );
- if ( Node == NULL ) {
- return 1;
- }
-
- RCt = XFSNodeAttrEditor ( Node, & Editor );
- if ( RCt != 0 || Editor == NULL ) {
- return 1;
- }
-
- while ( true ) {
- ZeroMemory (
- HandleFileInfo,
- sizeof ( BY_HANDLE_FILE_INFORMATION )
- );
-
- /* File Attributes */
- if ( XFSAttrEditorType ( Editor, & Type ) != 0 ) {
- RetVal = 1;
- break;
- }
- HandleFileInfo -> dwFileAttributes
- = FILE_ATTRIBUTE_NORMAL;
- switch ( Type ) {
- case kxfsFile:
- break;
- case kxfsDir:
- HandleFileInfo -> dwFileAttributes
- |= FILE_ATTRIBUTE_DIRECTORY;
- break;
- case kxfsLink:
- default:
- HandleFileInfo -> dwFileAttributes
- = INVALID_FILE_ATTRIBUTES;
- break;
- }
-
- if ( HandleFileInfo -> dwFileAttributes != INVALID_FILE_ATTRIBUTES && Type != kxfsDir ) {
-/* ### Check permissions */
- if ( XFSAttrEditorPermissions ( Editor, & PermStr ) == 0 ) {
- if ( XFSPermMake ( PermStr, & Perm ) == 0 ) {
- if ( XFSPermAuth ( Perm, kxfsUser ) != NULL ) {
- if ( ! XFSAuthCanRead (
- XFSPermAuth ( Perm, kxfsUser )
- ) ) {
- HandleFileInfo -> dwFileAttributes
- |= FILE_ATTRIBUTE_READONLY;
- }
- }
- free ( Perm );
- }
- }
- }
-
- /* Times */
- if ( XFSAttrEditorDate ( Editor, & TheTime ) != 0 ) {
- RetVal = 1;
- break;
- }
- Time = ( TheTime * 10000000 ) + 116444736000000000;;
- TimeLow = ( DWORD ) Time;
- TimeHigh = Time >> 32;
- HandleFileInfo -> ftCreationTime.dwLowDateTime = TimeLow;
- HandleFileInfo -> ftCreationTime.dwHighDateTime = TimeHigh;
- HandleFileInfo -> ftLastAccessTime.dwLowDateTime = TimeLow;
- HandleFileInfo -> ftLastAccessTime.dwHighDateTime = TimeHigh;
- HandleFileInfo -> ftLastWriteTime.dwLowDateTime = TimeLow;
- HandleFileInfo -> ftLastWriteTime.dwHighDateTime = TimeHigh;
-
- /* Sizes: set default value and try to get some */
- FileSize.QuadPart = 0;
- HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
- HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
-
- FileEditor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
- if ( FileEditor == NULL ) {
- RCt = XFSNodeFileEditor ( Node, & FileEditor );
- if ( RCt == 0 ) {
- if ( FileEditor != NULL ) {
- if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
- FileSize.QuadPart = Size;
- HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
- HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
- }
-
- XFSEditorDispose ( & ( FileEditor -> Papahen ) );
- }
- }
- } else {
- if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
- FileSize.QuadPart = Size;
- HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
- HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
- }
- }
-
- break;
- }
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
-
- return RetVal;
-} /* _Read_HANDLE_FILE_INFORMATION () */
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_GetFileInformation (
- LPCWSTR FileName,
- LPBY_HANDLE_FILE_INFORMATION HandleFileInfo,
- PDOKAN_FILE_INFO FileInfo
-)
-{
- struct XFSHandle * Handle;
- int RetValue;
-
- RetValue = 0;
- Handle = NULL;
-
-//TT wLogMsg ( klogDebug, L" INFO file [%s][I=0x%p][H=0x%p]\n", FileName, FileInfo, (void * ) FileInfo -> Context );
-
- if ( FileName == NULL || HandleFileInfo == NULL || FileInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- Handle = ( struct XFSHandle * ) FileInfo -> Context;
-
- if ( Handle == NULL ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
- RetValue = _Read_HANDLE_FILE_INFORMATION ( Handle, HandleFileInfo );
-
-//TT wLogMsg ( klogDebug, L" INFO File,cont [%s][0x%p][RV=%d]\n", FileName, FileInfo, RetValue );
-
- return RetValue * - 1;
-} /* GetFileInformation() */
-
-#endif /* USE_XFS_DOKAN_GETFILEINFORMATION == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_FINDFILES == 1
-
-static
-rc_t CC
-_Read_PWIN32_FIND_DATA (
- const struct XFSNode * Node,
- LPWIN32_FIND_DATAW FindData
-)
-{
- rc_t RCt;
- struct XFSAttrEditor * Editor;
- struct XFSFileEditor * FileEditor;
- struct XFSPerm * Perm;
- const char * PermStr;
- ULONG64 Time;
- XFSNType Type;
- KTime_t TheTime;
- DWORD TimeHigh, TimeLow;
- LARGE_INTEGER FileSize;
- uint64_t Size;
- size_t CopyNum;
-
- RCt = 0;
- Editor = NULL;
- Perm = NULL;
- PermStr = NULL;
- Type = kxfsNotFound;
- CopyNum = 0;
-
- if ( Node == NULL || FindData == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- ZeroMemory ( FindData, sizeof ( WIN32_FIND_DATAW ) );
-
-
- RCt = XFSNodeAttrEditor ( Node, & Editor );
- if ( RCt != 0 || Editor == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( XFSAttrEditorType ( Editor, & Type ) != 0 ) {
- XFSEditorDispose ( & ( Editor -> Papahen ) );
-
- return XFS_RC ( rcInvalid );
- }
-
- FindData -> dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-
- switch ( Type ) {
- case kxfsFile:
- break;
- case kxfsDir:
- FindData -> dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- break;
- case kxfsLink:
- default:
- FindData -> dwFileAttributes = INVALID_FILE_ATTRIBUTES;
- break;
- }
-
- if ( FindData -> dwFileAttributes != INVALID_FILE_ATTRIBUTES && Type != kxfsDir ) {
-/* ### Check permissions */
- RCt = XFSAttrEditorPermissions ( Editor, & PermStr );
- if ( RCt == 0 ) {
- RCt = XFSPermMake ( PermStr, & Perm );
- if ( RCt == 0 ) {
- if ( XFSPermAuth ( Perm, kxfsUser ) == NULL ) {
- RCt = XFS_RC ( rcInvalid );
- }
- free ( Perm );
- }
- }
- }
-
- if ( RCt != 0 ) {
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- return RCt;
- }
-
- RCt = XFSAttrEditorDate ( Editor, & TheTime );
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- if ( RCt != 0 ) {
- return RCt;
- }
- Time = ( TheTime * 10000000 ) + 116444736000000000;;
- TimeLow = ( DWORD ) Time;
- TimeHigh = Time >> 32;
-
- FindData -> ftCreationTime.dwLowDateTime = TimeLow;
- FindData -> ftCreationTime.dwHighDateTime = TimeHigh;
- FindData -> ftLastAccessTime.dwLowDateTime = TimeLow;
- FindData -> ftLastAccessTime.dwHighDateTime = TimeHigh;
- FindData -> ftLastWriteTime.dwLowDateTime = TimeLow;
- FindData -> ftLastWriteTime.dwHighDateTime = TimeHigh;
-
- FileSize.QuadPart = 0;
- RCt = XFSNodeFileEditor ( Node, & FileEditor );
- if ( RCt == 0 ) {
- if ( FileEditor != NULL ) {
- RCt = XFSFileEditorSize ( FileEditor, & Size );
- if ( RCt == 0 ) {
- FileSize.QuadPart = Size;
- }
- XFSEditorDispose ( & ( FileEditor -> Papahen ) );
- }
- }
- if ( RCt != 0 ) {
- RCt = 0;
- }
- FindData -> nFileSizeHigh = FileSize.HighPart;
- FindData -> nFileSizeLow = FileSize.LowPart;
-
- /*))
- // And here is it ... dances with schimpanami
- ((*/
- if ( mbstowcs_s (
- & CopyNum,
- FindData -> cFileName,
- MAX_PATH,
- Node -> Name,
- string_size ( Node -> Name )
- ) != 0 ) {
- RCt = XFS_RC ( rcInvalid );
- }
-
- if ( RCt == 0 ) {
- GetShortPathNameW (
- FindData -> cFileName,
- FindData -> cAlternateFileName,
- sizeof ( FindData -> cAlternateFileName )
- / sizeof ( WCHAR )
- );
- }
-
- return RCt;
-} /* _Read_PWIN32_FIND_DATA () */
-
-static
-rc_t CC
-_FindDataForFile (
- const struct XFSDirEditor * Editor,
- const char * FileName,
- LPWIN32_FIND_DATAW FindData
-)
-{
- rc_t RCt;
- struct XFSNode * Child;
-
- RCt = 0;
- Child = NULL;
-
- if ( Editor == NULL || FileName == NULL || FindData == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- /*) First we are looking for child node
- (*/
- RCt = XFSDirEditorFind ( Editor, FileName, & Child );
- if ( RCt == 0 ) {
- /*) Second we are reading data for child node
- (*/
- RCt = _Read_PWIN32_FIND_DATA ( Child, FindData );
- }
-
- return RCt;
-} /* _FindDataForFile () */
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_FindFiles (
- LPCWSTR PathName,
- PFillFindData FindDataCallback,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSHandle * Handle;
- const struct XFSDirEditor * Editor;
- const struct XFSNode * Node;
- struct KNamelist * List;
- uint32_t ListQty, llp;
- const char * Name;
- WIN32_FIND_DATAW FindData;
- int RetVal;
-
- RCt = 0;
- Handle = NULL;
- Editor = NULL;
- Node = NULL;
- List = NULL;
- ListQty = llp = 0;
- Name = NULL;
- RetVal = 0;
-
- if ( PathName == NULL || FindDataCallback == NULL
- || TheFileInfo == NULL
- ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
-//TT wLogMsg ( klogDebug, L" FIND Files [%s][0x%p]\n", PathName, TheFileInfo );
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
- if ( Handle == NULL ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
- Node = XFSHandleNode ( Handle );
- if ( Node == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- if ( XFSNodeDirEditor ( Node, & Editor ) != 0 ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- if ( Editor == 0 ) {
- return ERROR_INVALID_FUNCTION * - 1;
- }
-
- if ( XFSDirEditorList ( Editor, & List ) == 0 ) {
- if ( KNamelistCount ( List, & ListQty ) == 0 ) {
- for ( llp = 0; llp < ListQty; llp ++ ) {
- RCt = KNamelistGet ( List, llp, & Name );
- if ( RCt == 0 ) {
- RCt = _FindDataForFile ( Editor, Name, & FindData );
- if ( RCt == 0 ) {
- FindDataCallback ( & FindData, TheFileInfo );
- }
- }
-
- if ( RCt != 0 ) {
-/* Do we need that? TODO!!!
- RetVal = ERROR_INVALID_DATA;
- break;
-*/
- RCt = 0; /* Right ? */
- }
- }
- }
- else {
- RetVal = ERROR_INVALID_DATA;
- }
-
- KNamelistRelease ( List );
- }
- else {
- RetVal = ERROR_INVALID_DATA;
- }
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
-
-//TT wLogMsg ( klogDebug, L" FIND Files [%s][0x%p][H=0x%p][V=%d]\n", PathName, TheFileInfo, Handle, RetVal );
-
- return RetVal * - 1;
-} /* FindFiles() */
-
-#endif /* USE_XFS_DOKAN_FINDFILES == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_FindFilesWithPattern (
- LPCWSTR PathName,
- LPCWSTR SearchPattern,
- PFillFindData FindDataCallback,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"FINDFILESWITHPATTERN(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* FindFilesWithPattern() */
-
-#endif /* USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_SETFILEATTRIBUTES == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_SetFileAttributes (
- LPCWSTR FileName,
- DWORD FileAttributes,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"SETFILEATTRIBUTES(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* SetFileAttributes() */
-
-#endif /* USE_XFS_DOKAN_SETFILEATTRIBUTES == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_SETFILETIME == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_SetFileTime (
- LPCWSTR FileName,
- CONST FILETIME * CreationTime,
- CONST FILETIME * LastAccessTime,
- CONST FILETIME * LastWriteTime,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSAttrEditor * Editor;
- const struct XFSNode * Node;
- KTime_t Time;
- ULONG64 xTime;
-
- RCt = 0;
- Editor = NULL;
- Node = NULL;
- Time = 0;
- xTime = 0;
-
-//TT wLogMsg ( klogDebug, L" SET file time: [%s][FI=0x%p]\n", FileName, TheFileInfo );
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- /*\ First we should convert time to time
- \*/
- xTime = LastWriteTime -> dwHighDateTime << 32;
- xTime += LastWriteTime -> dwLowDateTime;
- xTime -= 116444736000000000;
- xTime /= 10000000;
-
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- NULL, /* VPath, no need */
- & Node,
- NULL /* NodeType */
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeAttrEditor ( Node, & Editor );
-
- if ( RCt == 0 ) {
- RCt = XFSAttrEditorSetDate ( Editor, xTime );
- }
-
- XFSNodeRelease ( Node );
- }
-
-//TT wLogMsg ( klogDebug, L" SET file time,cont: [%s][FI=0x%p][RC=%d]\n", FileName, TheFileInfo, RCt );
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* SetFileTime() */
-
-#endif /* USE_XFS_DOKAN_SETFILETIME == 1 */
-
-/************************************************************/
-/************************************************************/
-#if USE_XFS_DOKAN_DELETEFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_DeleteFile (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
-
- RCt = 0;
-
-//TT wLogMsg ( klogDebug, L"DELETE File [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
-
-//TT wLogMsg ( klogDebug, L" DELETE File,cont [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* DeleteFile() */
-
-#endif /* USE_XFS_DOKAN_DELETEFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_DELETEDIRECTORY == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_DeleteDirectory (
- LPCWSTR FileName,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
-
- RCt = 0;
-
-//TT wLogMsg ( klogDebug, L"DELETE Directory [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
-
-//TT wLogMsg ( klogDebug, L" DELETE Directory [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* DeleteDirectory() */
-
-#endif /* USE_XFS_DOKAN_DELETEDIRECTORY == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_MOVEFILE == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_MoveFile (
- LPCWSTR OldFile,
- LPCWSTR NewFile,
- BOOL ReplaceExisting,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSNode * OldDir, * NewDir;
- char * OldName, * NewName;
- struct XFSDirEditor * Editor;
-
- RCt = 0;
- OldDir = NewDir = NULL;
- OldName = NewName = NULL;
- Editor = NULL;
-
-//TT wLogMsg ( klogDebug, L"MOVE File FR[%s]TO[%s][FI=0x%p][H=0x%p]\n", OldFile, NewFile, TheFileInfo, (void * ) TheFileInfo -> Context );
-
- RCt = _DOKAN_get_parent_node_from_char (
- OldFile,
- TheFileInfo,
- & OldDir,
- NULL,
- & OldName
- );
- if ( RCt == 0 ) {
- RCt = _DOKAN_get_parent_node_from_char (
- NewFile,
- TheFileInfo,
- & NewDir,
- NULL,
- & NewName
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeDirEditor ( OldDir, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSDirEditorMove (
- Editor,
- OldName,
- NewDir,
- NewName
- );
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- XFSNodeRelease ( NewDir );
- free ( NewName );
- }
-
- XFSNodeRelease ( OldDir );
- free ( OldName );
- }
-
-//TT wLogMsg ( klogDebug, L" MOVE File FR[%s]TO[%s][FI=0x%p][H=0x%p][RC=%d]\n", OldFile, NewFile, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* MoveFile() */
-
-#endif /* USE_XFS_DOKAN_MOVEFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_SETENDOFFILE == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_SetEndOfFile (
- LPCWSTR FileName,
- LONGLONG Length,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- struct XFSHandle * Handle;
- struct XFSFileEditor * FileEditor;
- const struct XFSNode * Node;
-
- RCt = 0;
- Handle = NULL;
- Editor = NULL;
- Node = NULL;
-
-//TT wLogMsg ( klogDebug, L" SET end of file: [%s][FI=0x%p]\n", FileName, TheFileInfo );
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
-
- Editor = Handle != NULL
- ? ( struct XFSFileEditor * ) XFSHandleGet ( Handle )
- : NULL
- ;
- if ( Editor == NULL ) {
- RCt = _DOKAN_get_path_and_node (
- FileName,
- TheFileInfo,
- NULL, /* VPath, no need */
- & Node,
- NULL /* NodeType */
- );
- if ( RCt == 0 ) {
- RCt = XFSNodeFileEditor ( Node, & Editor );
- if ( RCt == 0 ) {
- RCt = XFSFileEditorSetSize ( Editor, Length );
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
- }
-
- XFSNodeRelease ( Node );
- }
- }
- else {
- RCt = XFSFileEditorSetSize ( Editor, Length );
- }
-
- return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
-} /* SetEndOfFile() */
-
-#endif /* USE_XFS_DOKAN_SETENDOFFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_SETALLOCATIONSIZE == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_SetAllocationSize (
- LPCWSTR FileName,
- LONGLONG Length,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"SETALLOCATIONSIZE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* SetAllocationSize() */
-
-#endif /* USE_XFS_DOKAN_SETALLOCATIONSIZE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_LOCKFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_LockFile (
- LPCWSTR FileName,
- LONGLONG ByteOffset,
- LONGLONG Length,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"LOCKFILE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* LockFile() */
-
-#endif /* USE_XFS_DOKAN_LOCKFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_UNLOCKFILE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_UnlockFile (
- LPCWSTR FileName,
- LONGLONG ByteOffset,
- LONGLONG Length,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"UNLOCKFILE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* UnlockFile() */
-
-#endif /* USE_XFS_DOKAN_UNLOCKFILE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_GETDISKFREESPACE == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_GetDiskFreeSpace (
- PULONGLONG FreeBytesAvailable,
- PULONGLONG TotalNumberOfBytes,
- PULONGLONG TotalNumberOfFreeBytes,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"GETDISKFREESPACE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* GetDiskFreeSpace() */
-
-#endif /* USE_XFS_DOKAN_GETDISKFREESPACE == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_GetVolumeInformation (
- LPWSTR VolumeNameBuffer,
- DWORD VolumeNameSize,
- LPDWORD VolumeSerialNumber,
- LPDWORD MaximumComponentLength,
- LPDWORD FileSystemFlags,
- LPWSTR FileSystemNameBuffer,
- DWORD FileSystemNameSize,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"GETVOLUMEINFORMATION(DOKAN): [FI=0x%p]\n", TheFileInfo );
-
- wcscpy_s(
- VolumeNameBuffer,
- VolumeNameSize / sizeof(WCHAR),
- // L"NCBI&CO"
- L"dbGaP"
- );
-
- * VolumeSerialNumber = 0x19450509;
- * MaximumComponentLength = 256;
- * FileSystemFlags = FILE_CASE_SENSITIVE_SEARCH
- | FILE_CASE_PRESERVED_NAMES
- | FILE_SUPPORTS_REMOTE_STORAGE
- | FILE_UNICODE_ON_DISK
- | FILE_PERSISTENT_ACLS /* comment if ACL and
- security does not
- needed
- */
- ;
-
- wcscpy_s(
- FileSystemNameBuffer,
- FileSystemNameSize / sizeof(WCHAR),
- L"NCBI&CO"
- );
-
- return 0;
-} /* GetVolumeInformation() */
-
-#endif /* USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_UNMOUNT == 1
-
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_Unmount (
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-wLogMsg ( klogDebug, L"UNMOUNT(DOKAN): [FI=0x%p]\n", TheFileInfo );
- return - 0;
-} /* Unmount() */
-
-#endif /* USE_XFS_DOKAN_UNMOUNT == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_GETFILESECURITY == 1
-
-/************************************************************
- * Luriks : see file security.c
- ***********************************************************/
-
-static const char * _sDefaultPermissions = "rwxr-xr-x";
-
-XFS_EXTERN void CC _SI_Dump (
- SECURITY_INFORMATION Inf,
- char * Buff,
- size_t BuffSize
- );
-
-XFS_EXTERN rc_t CC XFSSecurityDescriptor (
- SECURITY_INFORMATION SecInfo,
- const char * Permissions,
- XFSNType NodeType,
- PSECURITY_DESCRIPTOR Descriptor,
- ULONG DescriptorLength
- );
-
-XFS_EXTERN rc_t CC XFSSecurityDescriptorSize (
- SECURITY_INFORMATION SecInfo,
- const char * Permissions,
- XFSNType NodeType,
- ULONG * DescSize
- );
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_GetFileSecurity (
- LPCWSTR FileName,
- PSECURITY_INFORMATION SecInfo,
- PSECURITY_DESCRIPTOR SecDsc,
- ULONG SecDscLen,
- PULONG SecDscLenNeeded,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
- rc_t RCt;
- int RetVal;
- SECURITY_INFORMATION Sinfo;
- const struct XFSHandle * Handle;
- const struct XFSNode * Node;
- const struct XFSAttrEditor * Editor;
- XFSNType Type;
- const char * Permissions;
-
- RetVal = 0;
- RCt = 0;
- Sinfo = 0;
- Handle = NULL;
- Node = NULL;
- Editor = NULL;
- Type = kxfsNotFound;
- Permissions = NULL;
-
- if ( FileName == NULL || TheFileInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
-
- if ( SecDscLenNeeded == NULL || SecDsc == NULL || SecInfo == NULL ) {
- return ERROR_INVALID_DATA * - 1;
- }
- * SecDscLenNeeded = 0;
- Sinfo = * SecInfo;
-
- Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
-
- if ( Handle == NULL ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
- Node = XFSHandleNode ( Handle );
- if ( Node == NULL ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
- if ( XFSNodeAttrEditor ( Node, & Editor ) != 0 ) {
- return ERROR_INVALID_HANDLE * - 1;
- }
-
-//TT wLogMsg ( klogDebug, L" SECURITY File [%s][0x%p][E=0x%p]\n", FileName, TheFileInfo, Editor );
-/*
-{
-char FU [ 64 ];
-_SI_Dump ( Sinfo, FU, sizeof ( FU ) );
-printf ( "SECURITY File [%s][0x%p]\n", FU, TheFileInfo );
-}
-*/
-
- RCt = XFSAttrEditorType ( Editor, & Type );
- if ( RCt == 0 ) {
- if ( Type == kxfsFile || Type == kxfsDir || Type == kxfsLink ) {
- RCt = XFSAttrEditorPermissions ( Editor, & Permissions );
- if ( RCt == 0 ) {
-
- if ( Permissions == NULL ) {
- Permissions = _sDefaultPermissions;
- }
-
- /* First we are going to check if here is enough space
- */
- RCt = XFSSecurityDescriptorSize (
- Sinfo,
- Permissions,
- Type,
- SecDscLenNeeded
- );
- if ( RCt == 0 && 0 < * SecDscLenNeeded ) {
- if ( SecDscLen == 0 || SecDscLen < * SecDscLenNeeded ) {
-//TT wLogMsg ( klogDebug, L" SECURITY File ( SIZE Requested ) [%s][NS=%d][BS=%d]\n", FileName, * SecDscLenNeeded, SecDscLen );
- RetVal = ERROR_INSUFFICIENT_BUFFER;
- }
- else {
- RCt = XFSSecurityDescriptor (
- Sinfo,
- Permissions,
- Type,
- SecDsc,
- SecDscLen
- );
- }
- }
- }
- }
- else {
- RCt = XFS_RC ( rcInvalid );
- }
- }
-
- if ( RCt != 0 ) {
- if ( RetVal == 0 ) {
- RetVal = ERROR_INVALID_HANDLE;
- }
- }
-
- XFSEditorDispose ( & ( Editor -> Papahen ) );
-//TT wLogMsg ( klogDebug, L" SECURITY File,cont [%s][0x%p][R=%d]\n", FileName, TheFileInfo, RetVal );
-
- return RetVal * - 1;
-} /* GetFileSecurity() */
-
-#endif /* USE_XFS_DOKAN_GETFILESECURITY == 1 */
-
-/************************************************************/
-/************************************************************/
-
-#if USE_XFS_DOKAN_SETFILESECURITY == 1
-
-static
-int DOKAN_CALLBACK
-XFS_DOKAN_SetFileSecurity (
- LPCWSTR FileName,
- PSECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR SecurityDescriptor,
- ULONG SecurityDescriptorLength,
- PDOKAN_FILE_INFO TheFileInfo
-)
-{
-//TT wLogMsg ( klogDebug, L"SETFILESECURITY(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
- return - 0;
-} /* SetFileSecurity() */
-
-#endif /* USE_XFS_DOKAN_SETFILESECURITY == 1 */
-
-/************************************************************/
-/************************************************************/
-
-/*))
- || Old good necessary method
- (*/
-LIB_EXPORT
-rc_t CC
-XFS_Private_InitOperations ( DOKAN_OPERATIONS * Operations )
-{
- if ( Operations == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- ZeroMemory ( Operations, sizeof( struct _DOKAN_OPERATIONS ) );
-
-
-#if USE_XFS_DOKAN_CREATEFILE == 1
- Operations -> CreateFile = XFS_DOKAN_CreateFile;
-#endif /* USE_XFS_DOKAN_CREATEFILE == 1 */
-
-#if USE_XFS_DOKAN_OPENDIRECTORY == 1
- Operations -> OpenDirectory = XFS_DOKAN_OpenDirectory;
-#endif /* USE_XFS_DOKAN_OPENDIRECTORY == 1 */
-
-#if USE_XFS_DOKAN_CREATEDIRECTORY == 1
- Operations -> CreateDirectory = XFS_DOKAN_CreateDirectory;
-#endif /* USE_XFS_DOKAN_CREATEDIRECTORY == 1 */
-
-#if USE_XFS_DOKAN_CLEANUP == 1
- Operations -> Cleanup = XFS_DOKAN_Cleanup;
-#endif /* USE_XFS_DOKAN_CLEANUP == 1 */
-
-#if USE_XFS_DOKAN_CLOSEFILE == 1
- Operations -> CloseFile = XFS_DOKAN_CloseFile;
-#endif /* USE_XFS_DOKAN_CLOSEFILE == 1 */
-
-#if USE_XFS_DOKAN_READFILE == 1
- Operations -> ReadFile = XFS_DOKAN_ReadFile;
-#endif /* USE_XFS_DOKAN_READFILE == 1 */
-
-#if USE_XFS_DOKAN_WRITEFILE == 1
- Operations -> WriteFile = XFS_DOKAN_WriteFile;
-#endif /* USE_XFS_DOKAN_WRITEFILE == 1 */
-
-#if USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1
- Operations -> FlushFileBuffers = XFS_DOKAN_FlushFileBuffers;
-#endif /* USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1 */
-
-#if USE_XFS_DOKAN_GETFILEINFORMATION == 1
- Operations -> GetFileInformation = XFS_DOKAN_GetFileInformation;
-#endif /* USE_XFS_DOKAN_GETFILEINFORMATION == 1 */
-
-#if USE_XFS_DOKAN_FINDFILES == 1
- Operations -> FindFiles = XFS_DOKAN_FindFiles;
-#endif /* USE_XFS_DOKAN_FINDFILES == 1 */
-
-#if USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1
- Operations -> FindFilesWithPattern = XFS_DOKAN_FindFilesWithPattern;
-#endif /* USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1 */
-
-#if USE_XFS_DOKAN_SETFILEATTRIBUTES == 1
- Operations -> SetFileAttributes = XFS_DOKAN_SetFileAttributes;
-#endif /* USE_XFS_DOKAN_SETFILEATTRIBUTES == 1 */
-
-#if USE_XFS_DOKAN_SETFILETIME == 1
- Operations -> SetFileTime = XFS_DOKAN_SetFileTime;
-#endif /* USE_XFS_DOKAN_SETFILETIME == 1 */
-
-#if USE_XFS_DOKAN_DELETEFILE == 1
- Operations -> DeleteFile = XFS_DOKAN_DeleteFile;
-#endif /* USE_XFS_DOKAN_DELETEFILE == 1 */
-
-#if USE_XFS_DOKAN_DELETEDIRECTORY == 1
- Operations -> DeleteDirectory = XFS_DOKAN_DeleteDirectory;
-#endif /* USE_XFS_DOKAN_DELETEDIRECTORY == 1 */
-
-#if USE_XFS_DOKAN_MOVEFILE == 1
- Operations -> MoveFile = XFS_DOKAN_MoveFile;
-#endif /* USE_XFS_DOKAN_MOVEFILE == 1 */
-
-#if USE_XFS_DOKAN_SETENDOFFILE == 1
- Operations -> SetEndOfFile = XFS_DOKAN_SetEndOfFile;
-#endif /* USE_XFS_DOKAN_SETENDOFFILE == 1 */
-
-#if USE_XFS_DOKAN_SETALLOCATIONSIZE == 1
- Operations -> SetAllocationSize = XFS_DOKAN_SetAllocationSize;
-#endif /* USE_XFS_DOKAN_SETALLOCATIONSIZE == 1 */
-
-#if USE_XFS_DOKAN_LOCKFILE == 1
- Operations -> LockFile = XFS_DOKAN_LockFile;
-#endif /* USE_XFS_DOKAN_LOCKFILE == 1 */
-
-#if USE_XFS_DOKAN_UNLOCKFILE == 1
- Operations -> UnlockFile = XFS_DOKAN_UnlockFile;
-#endif /* USE_XFS_DOKAN_UNLOCKFILE == 1 */
-
-#if USE_XFS_DOKAN_GETDISKFREESPACE == 1
- Operations -> GetDiskFreeSpace = XFS_DOKAN_GetDiskFreeSpace;
-#endif /* USE_XFS_DOKAN_GETDISKFREESPACE == 1 */
-
-#if USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1
- Operations -> GetVolumeInformation = XFS_DOKAN_GetVolumeInformation;
-#endif /* USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1 */
-
-#if USE_XFS_DOKAN_UNMOUNT == 1
- Operations -> Unmount = XFS_DOKAN_Unmount;
-#endif /* USE_XFS_DOKAN_UNMOUNT == 1 */
-
-#if USE_XFS_DOKAN_GETFILESECURITY == 1
- Operations -> GetFileSecurity = XFS_DOKAN_GetFileSecurity;
-#endif /* USE_XFS_DOKAN_GETFILESECURITY == 1 */
-
-#if USE_XFS_DOKAN_SETFILESECURITY == 1
- Operations -> SetFileSecurity = XFS_DOKAN_SetFileSecurity;
-#endif /* USE_XFS_DOKAN_SETFILESECURITY == 1 */
-
- return 0;
-} /* XFS_Private_InitOperations() */
-
-
-/****************************************************************
- * LogMsg as pLogMsg does not work with WCHAR ... so ... julep
- ****************************************************************/
-LIB_EXPORT
-rc_t CC
-wLogMsg ( KLogLevel Level, LPCWSTR Format, ... )
-{
- rc_t RCt;
- WCHAR BF [ XFS_SIZE_4096 ];
- char BFF [ XFS_SIZE_4096 ];
- va_list Args;
- size_t Size;
-
- RCt = 0;
- * BF = 0;
- * BFF = 0;
- Size = 0;
-
- if ( Level <= KLogLevelGet () ) {
- va_start ( Args, Format );
-
- if ( vswprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), Format, Args ) == - 1 ) {
- RCt = XFS_RC ( rcInvalid );
- }
-
- va_end ( Args );
-
- if ( RCt == 0 ) {
- if ( wcstombs_s ( & Size, BFF, sizeof ( BFF ), BF, wcslen ( BF ) ) == 0 ) {
- RCt = LogMsg ( Level, BFF );
- }
- else {
- RCt = XFS_RC ( rcInvalid );
- }
- }
- }
-
- return RCt;
-} /* wLogMsg () */
diff --git a/libs/xfs/win/operations.h b/libs/xfs/win/operations.h
deleted file mode 100644
index d82a898..0000000
--- a/libs/xfs/win/operations.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#ifndef _h_xfs_native_peer_operations_
-#define _h_xfs_native_peer_operations_
-
-#include <klib/rc.h>
-#include <WTypes.h>
-
- /* We are still working under the version 2.5 because there is
- port on MAC for that
- */
-#include <dokan.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
- /* Here we are going to fill that evis structure
- */
-XFS_EXTERN rc_t CC XFS_Private_InitOperations ( DOKAN_OPERATIONS * Ops );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _h_xfs_native_peer_operations_ */
diff --git a/libs/xfs/win/platform.c b/libs/xfs/win/platform.c
deleted file mode 100644
index e1cf4ac..0000000
--- a/libs/xfs/win/platform.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*===========================================================================
-
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#include <klib/rc.h>
-#include <klib/out.h>
-#include <klib/text.h>
-#include <klib/log.h>
-#include <kproc/thread.h>
-#include <xfs/xfs.h>
-#include <xfs/xlog.h>
-
-#include "xfs-priv.h"
-#include "platform.h"
-
-#include <sysalloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <Shlwapi.h>
-
-/* Some platform dependent headers
- */
-
-#include "operations.h"
-
-
-/* Some useless pranks
- */
-
-XFS_EXTERN rc_t CC XFSSecurityInit ();
-XFS_EXTERN rc_t CC XFSSecurityDeinit ();
-XFS_EXTERN rc_t CC wLogMsg ( KLogLevel Level, LPCWSTR Format, ... );
-
-/*
- * Virtuhai table and it's methods
- */
-static rc_t XFS_DOKAN_init_v1( struct XFSControl * self );
-static rc_t XFS_DOKAN_destroy_v1( struct XFSControl * self );
-static rc_t XFS_DOKAN_mount_v1( struct XFSControl * self );
-static rc_t XFS_DOKAN_loop_v1( struct XFSControl * self);
-static rc_t XFS_DOKAN_unmount_v1( struct XFSControl * self);
-
-static struct XFSControl_vt_v1 XFSControl_VT_V1 = {
- 1,
- 1,
- XFS_DOKAN_init_v1,
- XFS_DOKAN_destroy_v1,
- XFS_DOKAN_mount_v1,
- XFS_DOKAN_loop_v1,
- XFS_DOKAN_unmount_v1
-};
-
-/* Control init.
- */
-LIB_EXPORT
-rc_t CC
-XFSControlPlatformInit ( struct XFSControl * self )
-{
- if ( self == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- self -> vt = ( union XFSControl_vt * ) & XFSControl_VT_V1;
-
- return 0;
-} /* XFSControlInit () */
-
-/* Overloadable versions
- */
-rc_t
-XFS_DOKAN_init_v1( struct XFSControl * self )
-{
- rc_t RCt;
-
- RCt = 0;
-
- LogMsg ( klogDebug, "XFS_DOKAN_init()" );
-
- /*) Standard checks
- (*/
- if ( self -> Control != NULL ) {
- LogMsg ( klogDebug, "XFS_DOKAN_init(): control is not empty" );
- return XFS_RC ( rcUnexpected );
- }
-
- if ( self -> Arguments == NULL ) {
- LogMsg ( klogDebug, "XFS_DOKAN_init(): arguments are empty" );
- return XFS_RC ( rcUnexpected );
- }
-
- if ( XFSControlGetLabel ( self ) == NULL ) {
- RCt = XFSControlSetLabel ( self, "DOKAN" );
- }
-
- return RCt;
-} /* XFS_DOKAN_init() */
-
-rc_t
-XFS_DOKAN_destroy_v1( struct XFSControl * self )
-{
- PDOKAN_OPTIONS Options;
-
- Options = NULL;
-
- LogMsg ( klogDebug, "XFS_DOKAN_destroy()" );
-
- if ( self == NULL ) {
- LogMsg ( klogDebug, "XFS_DOKAN_destroy(): NULL self passed" );
-
- return XFS_RC ( rcNull );
- }
-
- Options = ( PDOKAN_OPTIONS ) self -> Control;
-
- if ( Options == NULL ) {
- LogMsg ( klogDebug, "XFS_DOKAN_destroy(): options are empty" );
- }
- else {
- if ( Options -> MountPoint != NULL ) {
- free ( ( char * ) Options -> MountPoint );
- Options -> MountPoint = NULL;
- }
-
- free ( Options );
- self -> Control = NULL;
- }
-
- return 0;
-} /* XFS_DOKAN_destroy() */
-
-static
-rc_t CC
-_InitDOKAN_OPERATIONS ( DOKAN_OPERATIONS ** Operations )
-{
- rc_t RCt;
- DOKAN_OPERATIONS * RetOp;
-
- RCt = 0;
- RetOp = NULL;
-
- XFS_CSAN ( Operations )
- XFS_CAN ( Operations )
-
- RetOp = calloc ( 1, sizeof ( DOKAN_OPERATIONS ) );
- if ( RetOp == NULL ) {
- RCt = XFS_RC ( rcExhausted );
- }
- else {
- RCt = XFS_Private_InitOperations ( RetOp );
- if ( RCt == 0 ) {
- * Operations = RetOp;
- }
- }
-
- if ( RCt != 0 ) {
- * Operations = NULL;
-
- if ( RetOp != NULL ) {
- free ( RetOp );
- }
- }
-
- return RCt;
-} /* _InitDOKAN_OPERATIONS () */
-
-XFS_EXTERN rc_t CC XFSPathInnerToNative (
- WCHAR * NativePathBuffer,
- size_t NativePathBufferSize,
- const char * InnerPath,
- ...
- );
-
-static
-rc_t CC
-_MakeMountPath ( const char * Inner, const WCHAR ** MountPath )
-{
- rc_t RCt;
- WCHAR BF [ XFS_SIZE_64 ];
- WCHAR * Path;
- size_t SZ;
-
- RCt = 0;
- * BF = 0;
- Path = NULL;
- SZ = 0;
-
- XFS_CSAN ( MountPath )
- XFS_CAN ( Inner )
- XFS_CAN ( MountPath )
-
- RCt = XFSPathInnerToNative ( BF, sizeof ( BF ), Inner );
- if ( RCt == 0 ) {
- SZ = wcslen ( BF );
- if ( BF [ SZ - 1 ] == L'\\' ) {
- BF [ SZ - 1 ] = 0;
- SZ --;
- }
-
- Path = calloc ( SZ + 1, sizeof ( WCHAR ) );
- if ( Path == NULL ) {
- RCt = XFS_RC ( rcExhausted );
- }
- else {
- wcscpy ( Path, BF );
-
- * MountPath = Path;
- }
- }
-
- if ( RCt != 0 ) {
- * MountPath = NULL;
-
- if ( Path != NULL ) {
- free ( Path );
- }
- }
-
- return RCt;
-} /* _MakeMountPath () */
-
-rc_t
-XFS_DOKAN_mount_v1( struct XFSControl * self )
-{
- rc_t RCt;
- DOKAN_OPTIONS * Options;
-
- RCt = 0;
- Options = NULL;
-
- LogMsg ( klogDebug, "XFS_DOKAN_mount()" );
-
- if ( self == NULL ) {
- LogMsg ( klogDebug, "ZERO self passed" );
- return XFS_RC ( rcNull );
- }
-
- if ( ( RCt = XFSSecurityInit () ) != 0 ) {
- LogMsg ( klogDebug, "Can not initialize DOKAN security" );
- return RCt;
- }
-
- /*) Here we are allocating DOKAN options and it's global context
- (*/
- Options = calloc ( 1, sizeof ( DOKAN_OPTIONS ) );
- if ( Options == NULL ) {
- RCt = XFS_RC ( rcNull );
- }
- else {
-
- Options -> Version = DOKAN_VERSION;
- Options -> ThreadCount = 0; /* Default Value */
- Options -> Options = 0L;
- Options -> Options |= DOKAN_OPTION_KEEP_ALIVE;
- Options -> Options |= DOKAN_OPTION_DEBUG;
- /*) using Peer as GlobalContext as for FUSE implementation
- (*/
- Options -> GlobalContext = ( ULONG64 )( self -> TreeDepot );
-
- RCt = _MakeMountPath (
- XFSControlGetMountPoint ( self ),
- & ( Options -> MountPoint )
- );
- if ( RCt == 0 ) {
- if ( PathFileExistsW ( Options -> MountPoint ) == TRUE ) {
- wLogMsg ( klogFatal, L"Mount point in use [%s]\n", Options -> MountPoint );
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- self -> Control = Options;
- }
- }
- }
-
- if ( RCt != 0 ) {
- self -> Control = NULL;
-
- if ( Options != NULL ) {
- if ( Options -> MountPoint != NULL ) {\
- free ( ( char * ) Options -> MountPoint );
- Options -> MountPoint = NULL;
- }
- free ( Options );
- }
- }
-
- return RCt;
-} /* XFS_DOKAN_mount() */
-
-rc_t
-XFS_DOKAN_loop_v1( struct XFSControl * self )
-{
- rc_t RCt;
- DOKAN_OPTIONS * Options;
- DOKAN_OPERATIONS * Operations;
- const struct XFSTree * Tree;
-
- RCt = 0;
- Operations = NULL;
- Options = NULL;
- Tree = NULL;
-
- LogMsg ( klogDebug, "XFS_DOKAN_loop()" );
-
- if ( self == NULL ) {
- LogMsg ( klogDebug, "XFSControl: ZERO self passed" );
- return XFS_RC ( rcNull );
- }
-
- if ( self -> TreeDepot == NULL ) {
- LogMsg ( klogDebug, "XFSControl: ZERO passed" );
- return XFS_RC ( rcNull );
- }
-
- RCt = XFSControlGetTree ( self, & Tree );
- if ( RCt != 0 || Tree == NULL ) {
- LogMsg ( klogDebug, "XFSControl: ZERO Tree DATA passed" );
- return XFS_RC ( rcNull );
- }
-
- Options = ( DOKAN_OPTIONS * ) self -> Control;
- if ( Options == NULL ) {
- LogMsg ( klogDebug, "XFSControl: ZERO options passed" );
- return XFS_RC ( rcNull );
- }
-
-pLogMsg ( klogDebug, "XFS_DOKAN_loop(): Tree [$(tree)] Data [$(data)]\n", "tree=%p,data=%p", self -> TreeDepot, Tree );
-
-
-/* We will split mount method for mount'n'loop later, so there is
- usual routine stuff
-*/
-
- RCt = _InitDOKAN_OPERATIONS ( & Operations );
- if ( RCt == 0 ) {
- /*)
- / There we are running DokanMain
- (*/
- switch ( DokanMain ( Options, Operations ) ) {
- case DOKAN_SUCCESS :
- LogMsg ( klogDebug, "DokanMain() : general success" );
- break;
- case DOKAN_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : general error" );
- break;
- case DOKAN_DRIVE_LETTER_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : bad drive letter" );
- break;
- case DOKAN_DRIVER_INSTALL_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : can't install driver" );
- break;
- case DOKAN_START_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : can't start, something wrong" );
- break;
- case DOKAN_MOUNT_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : can't assigh a drive letter or mount point" );
- break;
- case DOKAN_MOUNT_POINT_ERROR :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : mount point is invalid" );
- break;
- default :
- RCt = XFS_RC ( rcError );
- LogErr ( klogDebug, RCt, "DokanMain() : something wrong happens" );
- break;
- }
-
- free ( Operations );
- }
-
-pLogMsg ( klogDebug, "XFS_DOKAN_loop(): Exited Tree [$(tree)]", "tree=%p", self -> TreeDepot );
-
- return RCt;
-} /* XFS_DOKAN_loop() */
-
-rc_t
-XFS_DOKAN_unmount_v1( struct XFSControl * self )
-{
- rc_t RCt = 0;
-
- if ( self == NULL ) {
- LogMsg ( klogDebug, "ZERO self passed" );
- /*
- return XFS_RC ( rcNull );
- */
- return 0;
- }
-
- if ( self -> Control == NULL ) {
- LogMsg ( klogDebug, "ZERO self passed" );
- /*
- return XFS_RC ( rcNull );
- */
- return 0;
- }
-
- XFSSecurityDeinit ();
-
- return 0;
-} /* XFS_DOKAN_unmount() */
-
-/********************
- * Something extra
- *************/
-static
-rc_t CC
-_GetProgPath ( WCHAR * Path, DWORD PathSize)
-{
- const WCHAR * cP = L"\\Dokan\\DokanLibrary\\dokanctl.exe";
-
- /* First we are trying %ProgramFiles(x86)%
- */
- if ( GetEnvironmentVariableW ( L"%ProgramFiles(x86)%", Path, PathSize ) == 0 ) {
- wcscat ( Path, cP );
- if ( PathFileExistsW ( Path ) == TRUE ) {
- return 0;
- }
- }
-
- /* First we are trying %ProgramFiles%
- */
- if ( GetEnvironmentVariableW ( L"%ProgramFiles%", Path, PathSize ) == 0 ) {
- wcscat ( Path, cP );
- if ( PathFileExistsW ( Path ) == TRUE ) {
- return 0;
- }
- }
-
- wcscpy_s (
- Path,
- PathSize,
- L"C:\\Program Files (x86)\\Dokan\\DokanLibrary\\dokanctl.exe"
- );
- return PathFileExistsW ( Path ) == TRUE ? 0 : XFS_RC ( rcNotFound );
-} /* _GetProgPath () */
-
-/*)) Special platform dependent method
- || very specific method. It is looking for
- || %ProgramFiles(x86)%\Dokan\DokanLibrary\dokanctl.exe
- || or
- || %ProgramFiles%\Dokan\DokanLibrary\dokanctl.exe
- || or
- || C:\Program Files (x86)\Dokan\DokanLibrary\dokanctl.exe
- ((*/
-LIB_EXPORT
-rc_t CC
-XFSUnmountAndDestroy ( const char * MountPoint )
-{
- rc_t RCt;
- WCHAR Path [ XFS_SIZE_4096 ];
- WCHAR Comm [ XFS_SIZE_4096 ];
- WCHAR * MPath;
- BOOL Ret;
- STARTUPINFO StartInfo;
- PROCESS_INFORMATION Process;
- int Err;
-
- RCt = 0;
- * Path = 0;
- * Comm = 0;
- MPath = NULL;
- Ret = FALSE;
- ZeroMemory ( & StartInfo, sizeof( StartInfo ) );
- ZeroMemory ( & Process, sizeof( Process ) );
- Err = 0;
-
- RCt = _MakeMountPath ( MountPoint, & MPath );
- if ( RCt == 0 ) {
- if ( PathFileExistsW ( MPath ) == TRUE ) {
- wLogMsg ( klogInfo, L"Unmounting volume [%s]\n", MPath );
-
- RCt = _GetProgPath ( Path, sizeof ( Path ) / sizeof ( WCHAR ) );
- if ( RCt == 0 ) {
- swprintf (
- Comm,
- sizeof ( Comm ) / sizeof ( WCHAR ),
- L"\"%s\" /u %s",
- Path,
- MPath
- );
- wLogMsg ( klogInfo, L"Executing [%s]\n", Comm );
- Ret = CreateProcessW (
- NULL,
- Comm,
- NULL,
- NULL,
- FALSE,
- DETACHED_PROCESS,
- NULL,
- NULL,
- & StartInfo,
- & Process
- );
- if ( Ret == 0 ) {
- wLogMsg ( klogErr, L"Failed [%s] ErrNo [%d]\n", Comm, GetLastError () );
- }
- }
- else {
- wLogMsg ( klogErr, L"CRITICAL: Can not find 'dokanctl.exe' utility.\n" );
- wLogMsg ( klogErr, L" Please ask administrator about it location. \n" );
- wLogMsg ( klogErr, L" Please use command 'dokanctl.exe /u %s'. \n", MPath );
- }
- }
- else {
- wLogMsg ( klogErr, L"Can not find volume [%s]\n", MPath );
- }
-
- free ( MPath );
- }
-
-
- return RCt;
-} /* XFSUnmountAndDestroy () */
diff --git a/libs/xfs/win/security.c b/libs/xfs/win/security.c
deleted file mode 100644
index 4aa28f8..0000000
--- a/libs/xfs/win/security.c
+++ /dev/null
@@ -1,1935 +0,0 @@
-/*===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- */
-
-#include <windows.h>
-#include <WinBase.h>
-#include <AccCtrl.h>
-#include <AclApi.h>
-#include <WinNT.h>
-
-#include <klib/container.h>
-#include <klib/rc.h>
-#include <klib/text.h>
-#include <klib/printf.h>
-#include <kproc/lock.h>
-
-#include <xfs/editors.h>
-#include <xfs/perm.h>
-
-#include <sysalloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "zehr.h"
-
-/*)))
- /// This file contains security related stuff. Main goal is to
- \\\ convert XFSPerm object to security descriptor.
- (((*/
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*
- * That is simple storage for any used SID.
- *
- * The simple reason why I am organizing that storage is :
- * I should create SECURITY_DESCRIPTOR and convert it to
- * PSECURITY_DESCRIPTOR ( which is relative ) and there are
- * many phases where we should create and free SID by
- * different reason. And it will complicate uninitialising
- * procedure in the cases when, for example DACL constucting
- * failed.
- * There are several disadvantages, for example, if SID was
- * changed during program execution ... we will think about
- * that later
- * Another disadvantage is : it suppose to be thread safe
- *
- * SID is stored and accessed by name ( char * ) of account associated
- * User responsible for initializing SID storage before it's usage
- * and for destroying it after.
- * User could cal method "_SidStorageRehash ()" to renew all sids.
- *_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-
-/*) That is a lock which I will use to access stored SIDs
- (*/
-static struct KLock * _sMutabor = NULL;
-
-/*) That is a SIDs storage
- (*/
-static BSTree _sSidStorage;
-
-/*) That struct represents node with SID stored
- (*/
-struct __SidNode {
- /*) mandatory
- (*/
- BSTNode node;
-
- /*) Account name
- (*/
- const char * name;
-
- /*) SID associated with account
- (*/
- SID * sid;
- /*) SID size, You could always calculate it, but shortcut
- (*/
- DWORD size;
-};
-
-/*)))
- ||| Those are prototypes for storage data accessing funcions
- ||| Some are locking, and some are not. Those, which are withou
- ||| locking, they does not check for NuLL
- (((*/
-static rc_t CC _ClearSidStorageNoLock ();
-static const struct __SidNode * _FindSidNoLock ( const char * Name );
-static rc_t _GetSidAndSizeNoLock (
- const char * Name,
- SID ** Sid,
- DWORD * SidSize
- );
-
-static SID * _SidStorageGet ( const char * Name );
-static DWORD _SidStorageGetSize ( const char * Name );
-static rc_t _SidStorageRehash ();
-
-/*))) Returns true if storage is good and usable.
- /// Very simple check, but it is better to use method
- \\\ instead copy pasting code
- (((*/
-static
-bool
-_IsSidStorageGood ()
-{
- return _sMutabor != NULL;
-} /* _IsSidStorageGood () */
-
-/*))) Two methods: _InitSidStorage() and _DisposeSidStorage()
- /// You should call them before and after
-(((*/
-static
-rc_t CC
-_SidStorageInit ()
-{
- rc_t RCt;
- struct KLock * tLock;
-
- RCt = 0;
- tLock = NULL;
-
- if ( _IsSidStorageGood () ) {
- return XFS_RC ( rcInvalid );
- }
-
- RCt = KLockMake ( & tLock );
- if ( RCt == 0 ) {
- BSTreeInit ( & _sSidStorage );
- }
-
- if ( RCt == 0 ) {
- _sMutabor = tLock;
- }
- else {
- if ( tLock != NULL ) {
- KLockRelease ( tLock );
- }
- }
-
- return RCt;
-} /* _SidStorageInit () */
-
-static
-rc_t CC
-_SidStorageDispose ()
-{
- if ( ! _IsSidStorageGood () ) {
- return 0;
- }
-
- /*) No check for return code
- (*/
- _ClearSidStorageNoLock ();
-
- /*) Disengageing Lock
- (*/
- KLockRelease ( _sMutabor );
-
- return 0;
-} /* _SidStorageDispose () */
-
-SID * CC
-_SidStorageGet ( const char * Name )
-{
- SID * RetVal;
- rc_t RCt;
- const struct __SidNode * Node;
-
- RetVal = 0;
- RCt = 0;
- Node = NULL;
-
- if ( _IsSidStorageGood () ) {
- RCt = KLockAcquire ( _sMutabor );
- if ( RCt == 0 ) {
- Node = _FindSidNoLock ( Name );
-
- if ( Node != NULL ) {
- RetVal = Node -> sid;
- }
-
- KLockUnlock ( _sMutabor );
- }
- }
-
- return RetVal;
-} /* _SidStorageGet () */
-
-DWORD CC
-_SidStorageGetSize ( const char * Name )
-{
- DWORD RetVal;
- rc_t RCt;
- const struct __SidNode * Node;
-
- RetVal = 0;
- RCt = 0;
- Node = NULL;
-
- if ( _IsSidStorageGood () ) {
- RCt = KLockAcquire ( _sMutabor );
- if ( RCt == 0 ) {
- Node = _FindSidNoLock ( Name );
-
- if ( Node != NULL ) {
- RetVal = Node -> size;
- }
-
- KLockUnlock ( _sMutabor );
- }
- }
-
- return RetVal;
-} /* _SidStorageGetSize () */
-
-rc_t CC
-_SidStorageRehash ()
-{
- rc_t RCt;
-
- RCt = 0;
-
- if ( _IsSidStorageGood () ) {
- RCt = KLockAcquire ( _sMutabor );
- if ( RCt == 0 ) {
- RCt = _ClearSidStorageNoLock ();
-
- KLockUnlock ( _sMutabor );
- }
- }
-
- return RCt;
-} /* _SidStorageRehash () */
-
-static
-rc_t CC
-_SidNodeMake ( const char * Name, struct __SidNode ** Node )
-{
- struct __SidNode * Ret;
- SID * Sid;
- DWORD SidSize;
- rc_t RCt;
-
- Ret = NULL;
- Sid = NULL;
- SidSize = 0;
- RCt = 0;
-
- if ( Name == NULL || Node == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Node = NULL;
-
- /*)) If Account does not exist, we do create empty node, and
- // it is users responsibility to handle such account
- ((*/
- RCt = _GetSidAndSizeNoLock ( Name, & Sid, & SidSize );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- Ret = calloc ( 1, sizeof ( struct __SidNode ) );
- if ( Ret == NULL ) {
- if ( Sid != NULL ) {
- free ( Sid );
- }
-
- return XFS_RC ( rcExhausted );
- }
-
- Ret -> name = ( const char * ) string_dup_measure ( Name, NULL );
- if ( Ret -> name == NULL ) {
- if ( Sid != NULL ) {
- free ( Sid );
- }
-
- free ( Ret );
-
- return XFS_RC ( rcExhausted );
- }
-
- Ret -> sid = Sid;
- Ret -> size = SidSize;
-
- * Node = Ret;
-
- return 0;
-} /* _SidNodeMake () */
-
-static
-rc_t CC
-_SidNodeDispose ( struct __SidNode * self )
-{
- if ( self != NULL ) {
- if ( self -> name != NULL ) {
- free ( ( char * ) self -> name );
- }
-
- self -> name = NULL;
-
- if ( self -> sid != NULL ) {
- free ( self -> sid );
- }
-
- self -> sid = NULL;
-
- self -> size = 0;
- }
- return 0;
-} /* _SidNodeDispose () */
-
-static
-void CC
-_SidStorageWhackCallback ( BSTNode * Node, void * Unused )
-{
- if ( Node != NULL ) {
- _SidNodeDispose ( ( struct __SidNode * ) Node );
- }
-} /* _SidStorageWhackCallback () */
-
-rc_t CC
-_ClearSidStorageNoLock ()
-{
- BSTreeWhack ( & _sSidStorage, _SidStorageWhackCallback, NULL );
- return 0;
-} /* _ClearSidStorageNoLock () */
-
-static
-int64_t CC
-_SidStorageAddCallback ( const BSTNode * Node1, const BSTNode * Node2 )
-{
- return XFS_StringCompare4BST_ZHR (
- ( ( struct __SidNode * ) Node1 ) -> name,
- ( ( struct __SidNode * ) Node2 ) -> name
- );
-} /* _SidStorageAddCallback () */
-
-static
-rc_t CC
-_AddSidNoLock ( const char * Name, struct __SidNode ** Ret )
-{
- struct __SidNode * Node;
- rc_t RCt;
-
- Node = NULL;
- RCt = 0;
-
- if ( Name == NULL || Ret == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Ret = NULL;
-
- RCt = _SidNodeMake ( Name, & Node );
- if ( RCt == 0 ) {
- RCt = BSTreeInsert (
- & _sSidStorage,
- & ( Node -> node ),
- _SidStorageAddCallback
- );
- if ( RCt == 0 ) {
- * Ret = Node;
- }
- }
-
- if ( RCt != 0 ) {
- _SidNodeDispose ( Node );
- }
-
- return RCt;
-} /* _AddSidNoLock () */
-
-static
-int64_t CC
-_SidStorageFindCallback ( const void * Item, const BSTNode * Node )
-{
- return XFS_StringCompare4BST_ZHR (
- ( const char * ) Item,
- ( ( struct __SidNode * ) Node ) -> name
- );
-} /* _SidStorageFindCallback () */
-
-const struct __SidNode *
-_FindSidNoLock ( const char * Name )
-{
- const struct __SidNode * RetVal;
-
- RetVal = NULL;
-
- if ( Name != NULL ) {
- RetVal = ( const struct __SidNode * ) BSTreeFind (
- & _sSidStorage,
- Name,
- _SidStorageFindCallback
- );
- if ( RetVal == NULL ) {
- _AddSidNoLock ( Name, ( struct __SidNode ** ) & RetVal );
- }
- }
-
- return RetVal;
-} /* _FindSidNoLock () */
-
-rc_t
-_GetSidAndSizeNoLock ( const char * Name, SID ** Sid, DWORD * SidSize )
-{
- rc_t RCt;
- DWORD Size1, Size2;
- SID_NAME_USE NameUse;
- SID * RetSid;
- BYTE SomeByte [ XFS_SIZE_128 ];
-
- RCt = 0;
- Size1 = Size2 = 0;
- RetSid = NULL;
-
- if ( Name == NULL || Sid == NULL || SidSize == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Sid = NULL;
- * SidSize = 0;
-
- /*) First we should know size of SID
- (*/
- if ( LookupAccountNameA (
- NULL,
- Name,
- NULL,
- & Size1,
- NULL,
- & Size2,
- & NameUse
- ) == 0
- ) {
- if ( GetLastError () != ERROR_INSUFFICIENT_BUFFER ) {
- return XFS_RC ( rcExhausted );
- }
- }
-
- RetSid = calloc ( Size1, sizeof ( BYTE ) );
- if ( RetSid == NULL ) {
- return XFS_RC ( rcExhausted );
- }
-
- if ( LookupAccountNameA (
- NULL,
- Name,
- RetSid,
- & Size1,
- SomeByte,
- & Size2,
- & NameUse
- ) == 0
- ) {
- free ( RetSid );
-
- return XFS_RC ( rcInvalid );
- }
-
- * Sid = RetSid;
- * SidSize = Size1;
-
- return 0;
-} /* _GetSidAndSizeNoLock () */
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-/*
- * Another important part: Names.
- * We are trying to simulate Unix like permissions, and we are
- * going to use names for User and Group. We will ignore Other
- * group, however, we will reserve name for it. Also, there are
- * two special accounts which will have all permissions : Admin and
- * Systems ... So, here are all names
- */
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-/*))
- // Useful variables
-((*/
-static const char * _sOtherName = "Everyone";
-static const char * _sAdminName = "Administrators";
-static const char * _sSystemName = "SYSTEM";
-static const char * _sUsersName = "Users"; /* Users are not User */
-static const char * _sCreatorName = "CREATOR OWNER";
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-/*))
- // Statics but usefuls
-((*/
-static
-rc_t CC
-_GetUserName ( char * Buffer, size_t BufferSize )
-{
- DWORD BS;
-
- if ( Buffer == NULL || BufferSize == 0 ) {
- return XFS_RC ( rcNull );
- }
-
- BS = BufferSize;
-
- if ( GetUserNameA ( Buffer, & BS ) == 0 ) {
- return XFS_RC ( rcExhausted );
- }
-
- return 0;
-} /* _GetUserName () */
-
-static
-rc_t CC
-_GetGroupNameInLegitWay ( char * Buffer, size_t BufferSize )
-{
- rc_t RCt;
- HANDLE ThisProcess;
- HANDLE TokenHandle;
- char TokenInfo [ XFS_SIZE_128 ];
- DWORD LenghtInReturn;
- SID * TheSid;
- SID_NAME_USE peUse;
- char BSht [ XFS_SIZE_128 ];
- size_t BShtSz;
-
- RCt = 0;
- ThisProcess = TokenHandle = INVALID_HANDLE_VALUE;
- LenghtInReturn = 0;
- TheSid = NULL;
- BShtSz = sizeof ( BSht );
-
- ThisProcess = GetCurrentProcess ();
- if ( ! OpenProcessToken ( ThisProcess, TOKEN_READ, & TokenHandle ) ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( ! GetTokenInformation (
- TokenHandle,
- TokenPrimaryGroup,
- TokenInfo,
- sizeof ( TokenInfo ),
- & LenghtInReturn
- )
- ) {
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- TheSid = ( ( TOKEN_PRIMARY_GROUP * ) TokenInfo ) -> PrimaryGroup;
- if ( TheSid != NULL ) {
- if ( IsValidSid ( TheSid ) ) {
- if ( ! LookupAccountSidA (
- NULL,
- TheSid,
- Buffer,
- & BufferSize,
- BSht, & BShtSz, /* B-SH#T */
- & peUse
- )
- ) {
- RCt = XFS_RC ( rcInvalid );
- }
- }
- else {
- RCt = XFS_RC ( rcInvalid );
- }
- }
- else {
- RCt = XFS_RC ( rcNull );
- }
- }
-
- CloseHandle ( TokenHandle );
-
- return 0;
-} /* _GetGroupNameInLegitWay () */
-
-static
-rc_t CC
-_GetGroupName ( char * Buffer, size_t BufferSize )
-{
- size_t NWR;
-
- if ( Buffer == NULL || BufferSize == 0 ) {
- return XFS_RC ( rcNull );
- }
- * Buffer = 0;
-
- /*) First we should check if account with name "Users" exists
- (*/
- if ( _SidStorageGet ( _sUsersName ) ) {
- string_printf ( Buffer, BufferSize, &NWR, _sUsersName );
- return 0;
- }
-
- return _GetGroupNameInLegitWay ( Buffer, BufferSize );
-} /* _GetGroupName () */
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
- /****************************************************************
- * Here we are initializing security, which includes :
- * 1) Initializing SID storage
- * 2) Checking and resolving names for general accounts
- * which will be used by XFSPerm object.
- ****************************************************************/
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-LIB_EXPORT
-rc_t CC
-XFSSecurityInit ()
-{
- rc_t RCt;
- char Buffer [ XFS_SIZE_128 ];
-
- RCt = 0;
-
- /*) First we are initializing SID storage
- (*/
- RCt = _SidStorageInit ();
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /* First setting up default User name */
- * Buffer = 0;
-
- RCt = _GetUserName ( Buffer, sizeof ( Buffer ) );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = XFSPermSetDefaultName ( kxfsUser, Buffer );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /* Second setting up default Group name */
- * Buffer = 0;
-
- RCt = _GetGroupName ( Buffer, sizeof ( Buffer ) );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = XFSPermSetDefaultName ( kxfsGroup, Buffer );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /* Third setting up default Other name */
- RCt = XFSPermSetDefaultName ( kxfsOther, _sOtherName );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- return 0;
-} /* XFSSecurityInit () */
-
-LIB_EXPORT
-rc_t CC
-XFSSecurityDeinit ()
-{
- /*) I think that is enough
- (*/
- _SidStorageDispose ();
-
- return 0;
-} /* XFSSecirotuDeinit () */
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
- /****************************************************************
- * Here we are: making security descriptor
- * There will be two set of functions which will have that pattern
- * SD_XXXX_Set ()
- * and
- * SD_XXXX_Size ()
- * and XXXX will be identical. One set is for compiling security
- * descriptor, and another for calculateing it's size
- *
- * We grant all possible rights for Admin and System
- * We will grant/deny unix-like rights for user/group
- * We do not care about others
- *
- * SecurityDescriptor structure :
- * SecurityDescriptor header size 0x20 ( 32 )
- * sizeof ( _SECURITY_DESCRIPTOR_RELATIVE )
- * + Owner SID size 0x14 ( 20 )
- * GetSidLengthRequired ( 5 )
- * + Group SID size 0x14 ( 20 )
- * GetSidLengthRequired ( 5 )
- * + SACL size 0x00 ( 00 ) < don't have one
- * + DACL header size 0x08 ( 8 )
- * sizeof ( ACL )
- * + N * ACE QTY
- * ACE Header + SID size 0x1c ( 28 ) * N
- *
- *
- * We are adding 4 standard ACE GrantAccess entries for file
- * and 5 standard ACE GrantAccess entries for directory. If here are
- * DenyAccess ACEs, they will be added directly before GrantAccess
- * ACEs.
- *
- * DenyAccess ACEs will be added for owner and users only
- *
- * We are adding these GrantAccess ACE entries in that order:
- * For files :
- * administrators
- * system
- * owner
- * users
- * For Directories :
- * administrators
- * system
- * owner
- * creator owner
- * users
- *
- * We are setting only 3 types of security information :
- * OWNER_SECURITY_INFORMATION
- * GROUP_SECURITY_INFORMATION
- * DACL_SECURITY_INFORMATION
- *
- * We will return nothing for those :
- * SACL_SECURITY_INFORMATION
- * PROTECTED_DACL_SECURITY_INFORMATION
- * PROTECTED_SACL_SECURITY_INFORMATION
- * UNPROTECTED_DACL_SECURITY_INFORMATION
- * UNPROTECTED_SACL_SECURITY_INFORMATION
- *
- ****************************************************************/
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-
-/*)) Inheritance flags
- ((*/
-#define _ACE_CONTAINER_FLAGS \
- CONTAINER_INHERIT_ACE \
- | SUB_CONTAINERS_AND_OBJECTS_INHERIT \
- | SUB_CONTAINERS_ONLY_INHERIT \
- | SUB_OBJECTS_ONLY_INHERIT
-
- /*) Directories deny and grant access flags
- (*/
-static const DWORD _sAceFlagsDir =
- _ACE_CONTAINER_FLAGS
- | OBJECT_INHERIT_ACE
- ;
-
-static const DWORD _sCreatorAceGrantFlagsDir =
- _ACE_CONTAINER_FLAGS
- | INHERIT_ONLY
- | INHERIT_ONLY_ACE
- | OBJECT_INHERIT_ACE
- ;
-
-static const DWORD _sUsersAceGrantFlagsDir =
- _ACE_CONTAINER_FLAGS
- | OBJECT_INHERIT_ACE
- ;
-
-static const DWORD _sOwnerAceGrantFlagsDir =
- _ACE_CONTAINER_FLAGS
- | OBJECT_INHERIT_ACE
- ;
-
-/*))
-||| We will suppose that User and Group flags are inheritable
-|||
-||| static const DWORD _sUsersAceGrantFlagsDir =
-||| CONTAINER_INHERIT_ACE
-||| | SUB_CONTAINERS_ONLY_INHERIT
-||| ;
-|||
-||| static const DWORD _sOwnerAceGrantFlagsDir = NO_INHERITANCE;
-(((*/
-
- /*) Files deny and grant access flags
- (*/
-static const DWORD _sAceDenyFlags_File = NO_INHERITANCE;
-static const DWORD _sAceGrantFlags_File = NO_INHERITANCE;
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-
-/*))) Owner and Group for SD
- (((*/
-static
-rc_t CC
-_SD_OwnerGroup_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- enum XFSAType AccountType,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- SID * Sid;
- DWORD Flags;
- BOOL ( WINAPI * adder ) (
- SECURITY_DESCRIPTOR * SD,
- SID * Sid,
- BOOL Defaulted
- );
- const struct XFSAuth * Auth;
-
- Sid = NULL;
- Flags = 0;
- adder = NULL;
- Auth = NULL;
-
- if ( Descriptor == NULL || Permissions == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- if ( AccountType == kxfsUser ) {
- Flags = OWNER_SECURITY_INFORMATION;
- adder = SetSecurityDescriptorOwner;
- }
- else {
- if ( AccountType == kxfsGroup ) {
- Flags = GROUP_SECURITY_INFORMATION;
- adder = SetSecurityDescriptorGroup;
- }
- else {
- return XFS_RC ( rcInvalid );
- }
- }
-
- /*) That information does not needed
- (*/
- if ( ( SecInfo & Flags ) != Flags ) {
- return 0;
- }
-
- Auth = XFSPermAuth ( Permissions, AccountType );
- if ( Auth == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- Sid = _SidStorageGet ( XFSAuthName ( Auth ) );
- if ( Sid == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( adder ( Descriptor, Sid, FALSE ) == 0 ) {
- return XFS_RC ( rcInvalid );
- }
-
- return 0;
-} /* _SD_OwnerGroup_Set () */
-
-static
-rc_t CC
-_SD_OwnerGroup_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- enum XFSAType AccountType,
- ULONG * Size
-)
-{
- ULONG SidSize;
- DWORD Flags;
- const struct XFSAuth * Auth;
-
- SidSize = 0;
- Flags = 0;
- Auth = NULL;
-
- if ( Size == NULL || Permissions == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- if ( AccountType == kxfsUser ) {
- Flags = OWNER_SECURITY_INFORMATION;
- }
- else {
- if ( AccountType == kxfsGroup ) {
- Flags = GROUP_SECURITY_INFORMATION;
- }
- else {
- return XFS_RC ( rcInvalid );
- }
- }
-
- /*) That information does not needed
- (*/
- if ( ( SecInfo & Flags ) != Flags ) {
- return 0;
- }
-
- Auth = XFSPermAuth ( Permissions, AccountType );
- if ( Auth == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- SidSize = _SidStorageGetSize ( XFSAuthName ( Auth ) );
- if ( SidSize == 0 ) {
- return XFS_RC ( rcInvalid );
- }
- * Size = SidSize;
-
- return 0;
-} /* _SD_OwnerGroup_Size () */
-
-static
-rc_t CC
-_SD_Owner_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- return _SD_OwnerGroup_Set (
- SecInfo,
- Permissions,
- kxfsUser,
- Descriptor
- );
-} /* _SD_Owner_Set () */
-
-static
-rc_t CC
-_SD_Owner_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- ULONG * Size
-)
-{
- return _SD_OwnerGroup_Size ( SecInfo, Permissions, kxfsUser, Size );
-} /* _SD_Owner_Size () */
-
-static
-rc_t CC
-_SD_Group_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- return _SD_OwnerGroup_Set (
- SecInfo,
- Permissions,
- kxfsGroup,
- Descriptor
- );
-} /* _SD_Group_Set () */
-
-static
-rc_t CC
-_SD_Group_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- ULONG * Size
-)
-{
- return _SD_OwnerGroup_Size ( SecInfo, Permissions, kxfsGroup, Size );
-} /* _SD_Group_Size () */
-
-static
-rc_t CC
-_SD_Sacl_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- /*) He-he ... no SACL
- (*/
- return 0;
-} /* _SD_Sacl_Set () */
-
-static
-rc_t CC
-_SD_Sacl_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- ULONG * Size
-)
-{
- /*) He-he ... no SACL ... but ...
- (*/
- if ( Size == NULL || Permissions == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- return 0;
-} /* _SD_Sacl_Size () */
-
-static
-DWORD CC
-_AuthToGrantMode ( const struct XFSAuth * Auth )
-{
- DWORD Mode;
-
- Mode = 0;
-
- if ( XFSAuthCanRead ( Auth ) ) Mode |= GENERIC_READ;
- if ( XFSAuthCanWrite ( Auth ) ) Mode |= GENERIC_WRITE | DELETE;
- if ( XFSAuthCanExecute ( Auth ) ) Mode |= GENERIC_EXECUTE;
-
- Mode |= SYNCHRONIZE | 0x1FF;
-
- return Mode;
-} /* _AuthToGrantMode () */
-
-static
-DWORD CC
-_AuthToDenyMode ( const struct XFSAuth * Auth )
-{
- DWORD Mode;
-
- Mode = 0;
-
- if ( ! XFSAuthCanRead ( Auth ) ) Mode |= GENERIC_READ;
- if ( ! XFSAuthCanWrite ( Auth ) ) Mode |= GENERIC_WRITE | DELETE;
- if ( ! XFSAuthCanExecute ( Auth ) ) Mode |= GENERIC_EXECUTE;
-
- return Mode;
-} /* _AuthToDenyMode () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_Creator_Size ( XFSNType NodeType, ULONG * Size )
-{
- ULONG WholeSize;
- if ( Size == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- if ( NodeType != kxfsDir ) {
- return 0;
- }
-
- WholeSize = _SidStorageGetSize ( _sCreatorName );
- if ( WholeSize == 0 ) {
- return XFS_RC ( rcInvalid );
- }
-
- WholeSize += sizeof ( ACE_HEADER ); /* ACE header */
- WholeSize += sizeof ( DWORD ); /* ACE mask */
-
- * Size = WholeSize;
-
- return 0;
-} /* _SD_Dacl_Ace_Creator_Size () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_Creator_Set ( XFSNType NodeType, ACL * Dacl )
-{
- SID * Sid = NULL;
-
- if ( Dacl == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- if ( NodeType != kxfsDir ) {
- return 0;
- }
-
- Sid = _SidStorageGet ( _sCreatorName );
- if ( Sid == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( AddAccessAllowedAceEx (
- Dacl,
- ACL_REVISION,
- _sCreatorAceGrantFlagsDir,
- GENERIC_ALL,
- Sid
- ) == 0
- ) {
- return XFS_RC ( rcInvalid );
- }
-
- return 0;
-} /* _SD_Dacl_Ace_Creator_Set () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_Power_Size (
- const char * AccName,
- XFSNType NodeType, /* not needed really */
- ULONG * Size
-)
-{
- ULONG WholeSize;
- if ( AccName == NULL || Size == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- WholeSize = _SidStorageGetSize ( AccName );
- if ( WholeSize == 0 ) {
- return XFS_RC ( rcInvalid );
- }
-
- WholeSize += sizeof ( ACE_HEADER ); /* ACE header */
- WholeSize += sizeof ( DWORD ); /* ACE mask */
-
- * Size = WholeSize;
-
- return 0;
-} /* _SD_Dacl_Ace_Power_Size () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_Power_Set (
- const char * AccName,
- XFSNType NodeType,
- ACL * Dacl
-)
-{
- SID * Sid;
- DWORD Flags;
-
- Sid = NULL;
- Flags = 0;
-
- if ( AccName == NULL || Dacl == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- Sid = _SidStorageGet ( AccName );
- if ( Sid == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- Flags = NodeType == kxfsDir ? _sAceFlagsDir : _sAceGrantFlags_File;
-
- if ( AddAccessAllowedAceEx (
- Dacl,
- ACL_REVISION,
- Flags,
- SYNCHRONIZE | STANDARD_RIGHTS_REQUIRED | 0x1FF,
- Sid
- ) == 0
- ) {
- return XFS_RC ( rcInvalid );
- }
-
- return 0;
-} /* _SD_Dacl_Ace_Power_Set () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_GrantDeny_Size (
- const struct XFSPerm * Permissions,
- enum XFSAType AccountType,
- XFSNType NodeType, /* not needed really */
- bool Grant,
- ULONG * Size
-)
-{
- ULONG WholeSize;
- const struct XFSAuth * Auth;
- DWORD Mode;
-
- WholeSize = 0;
- Auth = NULL;
- Mode = 0;
-
- if ( Permissions == NULL || Size == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- if ( AccountType != kxfsUser && AccountType != kxfsGroup ) {
- return 0;
- }
-
- Auth = XFSPermAuth ( Permissions, AccountType );
- if ( Auth == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- Mode = Grant
- ? _AuthToGrantMode ( Auth )
- : _AuthToDenyMode ( Auth )
- ;
- if ( Mode == 0 ) {
- return 0;
- }
-
- WholeSize = _SidStorageGetSize ( XFSAuthName ( Auth ) );
- if ( WholeSize == 0 ) {
- return XFS_RC ( rcInvalid );
- }
-
- WholeSize += sizeof ( ACE_HEADER ); /* ACE header */
- WholeSize += sizeof ( DWORD ); /* ACE mask */
-
- * Size = WholeSize;
-
- return 0;
-} /* _SD_Dacl_Ace_GrantDeny_Size () */
-
-static
-rc_t CC
-_SD_Dacl_Ace_GrantDeny_Set (
- const struct XFSPerm * Permissions,
- enum XFSAType AccountType,
- XFSNType NodeType,
- bool Grant,
- ACL * Dacl
-)
-{
- const struct XFSAuth * Auth;
- SID * Sid;
- DWORD Flags;
- DWORD Mode;
- BOOL ( WINAPI * adder ) (
- ACL * Dacl,
- DWORD Revision,
- DWORD Flags,
- DWORD Mode,
- SID * Sid
- );
-
- Auth = NULL;
- Sid = NULL;
- Flags = 0;
- Mode = 0;
- adder = NULL;
-
-
- if ( Permissions == NULL || Dacl == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- if ( AccountType != kxfsUser && AccountType != kxfsGroup ) {
- return 0;
- }
-
- Auth = XFSPermAuth ( Permissions, AccountType );
- if ( Auth == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( Grant ) {
- Mode = _AuthToGrantMode ( Auth );
- Flags = NodeType == kxfsDir
- ? _sAceFlagsDir
- : _sAceGrantFlags_File
- ;
- adder = AddAccessAllowedAceEx;
- }
- else {
- Mode = _AuthToDenyMode ( Auth );
- Flags = NodeType == kxfsDir
- ? _sAceFlagsDir
- : _sAceDenyFlags_File
- ;
- adder = AddAccessDeniedAceEx;
- }
-
- if ( Mode == 0 ) {
- return 0;
- }
-
-
- Sid = _SidStorageGet ( XFSAuthName ( Auth ) );
- if ( Sid == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( adder ( Dacl, ACL_REVISION, Flags, Mode, Sid ) == 0 ) {
- return XFS_RC ( rcInvalid );
- }
-
- return 0;
-} /* _SD_Dacl_Ace_GrantDeny_Set () */
-
-static
-rc_t CC
-_SD_Dacl_Aces_Size (
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- ULONG * Size
-)
-{
- rc_t RCt;
- ULONG WholeSize, TempSize;
-
- RCt = 0;
- WholeSize = TempSize = 0;
-
- if ( Permissions == NULL || Size == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- /*) Ok, here we are adding denials if it is possible
- (*/
- RCt = _SD_Dacl_Ace_GrantDeny_Size (
- Permissions,
- kxfsUser,
- NodeType,
- false,
- & TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- RCt = _SD_Dacl_Ace_GrantDeny_Size (
- Permissions,
- kxfsGroup,
- NodeType,
- false,
- & TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- /*) Ok, here we are adding our power users
- (*/
- RCt = _SD_Dacl_Ace_Power_Size (
- _sAdminName,
- NodeType,
- &TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- RCt = _SD_Dacl_Ace_Power_Size (
- _sSystemName,
- NodeType,
- &TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- /*) Ok, here we are adding granted if it is possible
- (*/
- RCt = _SD_Dacl_Ace_GrantDeny_Size (
- Permissions,
- kxfsUser,
- NodeType,
- true,
- & TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- RCt = _SD_Dacl_Ace_Creator_Size ( NodeType, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- RCt = _SD_Dacl_Ace_GrantDeny_Size (
- Permissions,
- kxfsGroup,
- NodeType,
- true,
- & TempSize
- );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- * Size = WholeSize;
-
- return 0;
-} /* _SD_Dacl_Aces_Size () */
-
-static
-rc_t CC
-_SD_Dacl_Aces_Set (
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- ACL * Dacl
-)
-{
- rc_t RCt;
-
- if ( Permissions == NULL || Dacl == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- RCt = 0;
-
- /*) Ok, here we are adding denials if it is possible
- (*/
- RCt = _SD_Dacl_Ace_GrantDeny_Set (
- Permissions,
- kxfsUser,
- NodeType,
- false,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = _SD_Dacl_Ace_GrantDeny_Set (
- Permissions,
- kxfsGroup,
- NodeType,
- false,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /*) Ok, here we are adding our power users
- (*/
- RCt = _SD_Dacl_Ace_Power_Set (
- _sAdminName,
- NodeType,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = _SD_Dacl_Ace_Power_Set (
- _sSystemName,
- NodeType,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /*) Ok, here we are adding grants if it is possible
- (*/
- RCt = _SD_Dacl_Ace_GrantDeny_Set (
- Permissions,
- kxfsUser,
- NodeType,
- true,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = _SD_Dacl_Ace_Creator_Set ( NodeType, Dacl );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- RCt = _SD_Dacl_Ace_GrantDeny_Set (
- Permissions,
- kxfsGroup,
- NodeType,
- true,
- Dacl
- );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- return 0;
-} /* _SD_Dacl_Aces_Set () */
-
-static
-rc_t CC
-_SD_Dacl_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- ULONG * Size
-)
-{
- rc_t RCt;
- ULONG WholeSize, TempSize;
-
- RCt = 0;
- WholeSize = TempSize = 0;
-
- if ( Permissions == NULL || Size == NULL ) {
- return XFS_RC ( rcNull );
- }
- * Size = 0;
-
- if ( ( SecInfo & DACL_SECURITY_INFORMATION )
- != DACL_SECURITY_INFORMATION
- ) {
- /*) Dacl is not needed
- (*/
- return 0;
- }
-
- WholeSize += sizeof ( ACL );
-
- RCt = _SD_Dacl_Aces_Size ( Permissions, NodeType, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- WholeSize += TempSize;
-
- * Size = WholeSize;
-
- return 0;
-} /* _SD_Dacl_Size () */
-
-static
-rc_t CC
-_SD_Dacl_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- rc_t RCt;
- ACL * Dacl;
- ULONG DaclSize;
-
- RCt = 0;
- Dacl = NULL;
- DaclSize = 0;
-
- if ( Permissions == NULL || Descriptor == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- if ( ( SecInfo & DACL_SECURITY_INFORMATION )
- != DACL_SECURITY_INFORMATION
- ) {
- /*) Dacl is not needed
- (*/
- return 0;
- }
-
- /*) Initializing Dacl
- (*/
- RCt = _SD_Dacl_Size ( SecInfo, Permissions, NodeType, & DaclSize );
- if ( RCt == 0 ) {
- if ( DaclSize == 0 ) {
- /*) Apparently that is impossible
- (*/
- return XFS_RC ( rcInvalid );
- }
-
- Dacl = calloc ( DaclSize, sizeof ( BYTE ) );
- if ( Dacl == NULL ) {
- return XFS_RC ( rcExhausted );
- }
- }
-
- ZeroMemory ( Dacl, sizeof ( BYTE ) * DaclSize );
- if ( InitializeAcl ( Dacl, DaclSize, ACL_REVISION ) == 0 ) {
- free ( Dacl );
-
- return XFS_RC ( rcInvalid ) ;
- }
-
- RCt = _SD_Dacl_Aces_Set ( Permissions, NodeType, Dacl );
- if ( RCt != 0 ) {
- free ( Dacl );
-
- return RCt;
- }
-
- if ( SetSecurityDescriptorDacl (
- Descriptor,
- TRUE,
- Dacl,
- FALSE
- ) == 0
- ) {
- free ( Dacl );
-
- return XFS_RC ( rcInvalid );
- }
-
- return 0;
-} /* _SD_Dacl_Set () */
-
-/*)) That function will compose Absolute Security Descriptor
- // (see also _SD_Size)
-((*/
-static
-rc_t CC
-_SD_Set (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- SECURITY_DESCRIPTOR * Descriptor
-)
-{
- rc_t RCt;
-
- RCt = 0;
-
- /*) Standard checks
- (*/
- if ( Permissions == NULL || Descriptor == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- /*) Intializing security descriptor
- (*/
- ZeroMemory ( Descriptor, sizeof ( SECURITY_DESCRIPTOR ) );
- if ( InitializeSecurityDescriptor (
- Descriptor,
- SECURITY_DESCRIPTOR_REVISION
- ) == 0
- ) {
- return XFS_RC ( rcInvalid );
- }
-
- /*) Owner information
- (*/
- RCt = _SD_Owner_Set ( SecInfo, Permissions, Descriptor );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /*) Group information
- (*/
- RCt = _SD_Group_Set ( SecInfo, Permissions, Descriptor );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /*) SACL information
- (*/
- RCt = _SD_Sacl_Set ( SecInfo, Permissions, NodeType, Descriptor );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- /*) DACL information
- (*/
- RCt = _SD_Dacl_Set ( SecInfo, Permissions, NodeType, Descriptor );
- if ( RCt != 0 ) {
- return RCt;
- }
-
- return 0;
-} /* _SD_Set () */
-
-/*)) That function will calculate Security Descriptor size
- // (see also _SD_Set)
-((*/
-static
-rc_t CC
-_SD_Size (
- SECURITY_INFORMATION SecInfo,
- const struct XFSPerm * Permissions,
- XFSNType NodeType,
- ULONG * DescSize
-)
-{
- rc_t RCt;
- ULONG TempSize, WholeSize;
-
- RCt = 0;
- TempSize = WholeSize = 0;
-
- /*) Standard checks
- (*/
- if ( Permissions == NULL || DescSize == NULL ) {
- return XFS_RC ( rcNull );
- }
- * DescSize = 0;
-
- /*) Securit descriptor header
- (*/
- WholeSize += sizeof ( SECURITY_DESCRIPTOR_RELATIVE );
-
- /*) Owner information
- (*/
- RCt = _SD_Owner_Size ( SecInfo, Permissions, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- /*) Group information
- (*/
- RCt = _SD_Group_Size ( SecInfo, Permissions, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- /*) SACL information
- (*/
- RCt = _SD_Sacl_Size ( SecInfo, Permissions, NodeType, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- /*) DACL information
- (*/
- RCt = _SD_Dacl_Size ( SecInfo, Permissions, NodeType, & TempSize );
- if ( RCt != 0 ) {
- return RCt;
- }
- WholeSize += TempSize;
-
- * DescSize = WholeSize;
-
- return 0;
-} /* _SD_Size () */
-
-static
-void CC
-_SD_Dispose ( SECURITY_DESCRIPTOR * Descriptor )
-{
- /*)) dispose only Sacl and Dacl, since Owner and Group are reusable
- ((*/
- if ( Descriptor != 0 ) {
- if ( Descriptor -> Sacl != NULL ) {
- free ( Descriptor -> Sacl );
- }
- if ( Descriptor -> Dacl != NULL ) {
- free ( Descriptor -> Dacl );
- }
-
- ZeroMemory ( Descriptor, sizeof ( SECURITY_DESCRIPTOR ) );
- }
-} /* _SD_Dispose () */
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-/* Couple cool methods */
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-static
-void
-_SD_AB_Dump ( PSECURITY_DESCRIPTOR Ds, ULONG DsL )
-{
- BYTE * Ar;
- int ArL, llp;
-
- printf ( "[= DUMP SD: [0x%p] [%d]\n", Ds, DsL );
-
- if ( Ds == NULL || DsL == 0 ) {
- printf ( "INVALID SD\n" );
- return;
- }
-
- Ar = ( BYTE * ) Ds;
- ArL = DsL / sizeof ( BYTE );
-
- for ( llp = 0; llp < ArL; llp ++ ) {
- if ( llp % 4 == 0 ) {
- if ( llp != 0 ) { printf ( "\n" ); }
- printf ( " %04d (%02x) ", llp, llp );
- }
- else {
- if ( llp % 2 == 0 ) {
- printf ( " " );
- }
- }
-
- printf ( "%02x", ( int ) Ar [ llp ] );
- }
- printf ( "\n" );
-
-} /* _SD_AB_Dump () */
-
-LIB_EXPORT
-void
-_SD_SR_Dump ( SECURITY_DESCRIPTOR * Sd )
-{
- printf ( "[= DUMP USD: [0x%p]\n", Sd );
-
- if ( Sd == NULL ) {
- printf ( "INVALID SD\n" );
- return;
- }
-
- printf ( "REV : [%d]\n", Sd -> Revision );
- printf ( "SBZ1 : [%d]\n", Sd -> Sbz1 );
- printf ( "CNTR: [%d]\n", Sd -> Control );
- printf ( "OWNR: [0x%p]\n", Sd -> Owner );
- printf ( "GRUP: [0x%p]\n", Sd -> Group );
- printf ( "SACL: [0x%p]\n", Sd -> Sacl );
- printf ( "DACL: [0x%p]\n", Sd -> Dacl );
-
-} /* _SD_SR_Dump () */
-
-LIB_EXPORT
-void
-_SI_Dump ( SECURITY_INFORMATION Inf, char * Buff, size_t BuffSize )
-{
- if ( Buff == NULL || BuffSize < 8 ) {
- return;
- }
-
- ZeroMemory ( Buff, sizeof ( char ) * BuffSize );
-
- Buff [0] = ( Inf & OWNER_SECURITY_INFORMATION ) == 0 ? '_' : 'O';
- Buff [1] = ( Inf & GROUP_SECURITY_INFORMATION ) == 0 ? '_' : 'G';
- Buff [2] = ( Inf & DACL_SECURITY_INFORMATION ) == 0 ? '_' : 'D';
- Buff [3] = ( Inf & SACL_SECURITY_INFORMATION ) == 0 ? '_' : 'S';
- Buff [4] = ( Inf & PROTECTED_DACL_SECURITY_INFORMATION ) == 0 ? '_' : 'd';
- Buff [5] = ( Inf & PROTECTED_SACL_SECURITY_INFORMATION ) == 0 ? '_' : 's';
- Buff [6] = ( Inf & UNPROTECTED_DACL_SECURITY_INFORMATION ) == 0 ? '_' : 'c';
- Buff [7] = ( Inf & UNPROTECTED_SACL_SECURITY_INFORMATION ) == 0 ? '_' : 't';
-} /* _SI_Dump () */
-
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-/* Here are external functions */
-/*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
-
-/*))
- // NOTE!!! that does not check for length of Security Descriptor
- \\ so if buffer is unsufficient memory will be messed
- // To obtain size of buffer use XFSSecurityDescriptorSize()
-((*/
-LIB_EXPORT
-rc_t CC
-XFSSecurityDescriptor (
- SECURITY_INFORMATION SecInfo,
- const char * Permissions,
- XFSNType NodeType,
- PSECURITY_DESCRIPTOR Descriptor,
- ULONG DescriptorLength
-)
-{
- rc_t RCt;
- SECURITY_DESCRIPTOR AbsDescriptor;
- const struct XFSPerm * Perm;
- DWORD DscLen;
-
- RCt = 0;
- Perm = NULL;
- DscLen = DescriptorLength;
-
-
- if ( Permissions == NULL || Descriptor == NULL ) {
- return XFS_RC ( rcNull );
- }
-
- RCt = XFSPermMake ( Permissions, & Perm );
- if ( RCt != 0 || Perm == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- RCt = _SD_Set ( SecInfo, Perm, NodeType, & AbsDescriptor );
- if ( RCt == 0 ) {
- /*)) Checking if SD is valid
- ((*/
- if ( IsValidSecurityDescriptor ( & AbsDescriptor ) == 0 ) {
- RCt = XFS_RC ( rcInvalid );
- }
- else {
- /*)) we should convert absolute to selfrelative
- ((*/
- if ( MakeSelfRelativeSD (
- & AbsDescriptor,
- Descriptor,
- & DscLen
- ) == 0
- ) {
- RCt = XFS_RC ( rcInvalid );
- }
- }
-
- }
-
-/*
-_SD_SR_Dump ( & AbsDescriptor );
-_SD_AB_Dump ( Descriptor, DescriptorLength );
-*/
-
- free ( ( struct XFSPerm * ) Perm );
- _SD_Dispose ( & AbsDescriptor );
-
- return RCt;
-} /* XFSSecurityDescriptor () */
-
-LIB_EXPORT
-rc_t CC
-XFSSecurityDescriptorSize (
- SECURITY_INFORMATION SecInfo,
- const char * Permissions,
- XFSNType NodeType,
- ULONG * DescSize
-)
-{
- rc_t RCt;
- ULONG WholeSize;
- const struct XFSPerm * Perm;
-
- RCt = 0;
- WholeSize = 0;
- Perm = NULL;
-
- if ( Permissions == NULL || DescSize == NULL ) {
- return XFS_RC ( rcNull );
- }
- * DescSize = 0;
-
- /*) Creating permissions
- (*/
- RCt = XFSPermMake ( Permissions, & Perm );
- if ( RCt != 0 || Perm == NULL ) {
- return XFS_RC ( rcInvalid );
- }
-
- RCt = _SD_Size ( SecInfo, Perm, NodeType, & WholeSize );
- if ( RCt == 0 ) {
- * DescSize = WholeSize;
- }
-
- return RCt;
-} /* XFSSecurityDescriptorSize () */
-
diff --git a/test/vdb/kfg/mac/test-dependencies.kfg b/test/vdb/kfg/mac/test-dependencies.kfg
deleted file mode 100644
index 407f738..0000000
--- a/test/vdb/kfg/mac/test-dependencies.kfg
+++ /dev/null
@@ -1,3 +0,0 @@
-repository/site/main/tracearc/apps/sra/volumes/ncbi = "sra17:sra16:sra15:sra14:sra13:sra12:sra11:sra10:sra9:sra8:sra7:sra6:sra5:sra4:sra3:sra2:sra1:sra0"
-repository/site/main/tracearc/apps/refseq/volumes/refseq = "refseq"
-repository/site/main/tracearc/root = "/net/traces04"
diff --git a/test/vdb/kfg/win/test-dependencies.kfg b/test/vdb/kfg/win/test-dependencies.kfg
deleted file mode 100644
index ade9ac6..0000000
--- a/test/vdb/kfg/win/test-dependencies.kfg
+++ /dev/null
@@ -1,3 +0,0 @@
-repository/site/main/tracearc/apps/sra/volumes/ncbi = "sra17:sra16:sra15:sra14:sra13:sra12:sra11:sra10:sra9:sra8:sra7:sra6:sra5:sra4:sra3:sra2:sra1:sra0"
-repository/site/main/tracearc/apps/refseq/volumes/refseq = "refseq"
-repository/site/main/tracearc/root = "//traces04"
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/ncbi-vdb.git
More information about the debian-med-commit
mailing list