summaryrefslogtreecommitdiffstats
path: root/hl
diff options
context:
space:
mode:
Diffstat (limited to 'hl')
-rw-r--r--hl/src/H5LT.c121
-rw-r--r--hl/src/H5LTpublic.h17
2 files changed, 0 insertions, 138 deletions
diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c
index fc1279a..e44a4f6 100644
--- a/hl/src/H5LT.c
+++ b/hl/src/H5LT.c
@@ -3505,125 +3505,4 @@ out:
}
-#ifdef NOT_YET
-
-/*-------------------------------------------------------------------------
- * Function: H5LTcreate_compound_type
- *
- * Purpose:
- *
- * Return: Success: 0, Failure: -1
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: September 18, 2001
- *
- * Comments:
- *
- * Modifications:
- *
- *
- *-------------------------------------------------------------------------
- */
-
-hid_t H5LTcreate_compound_type( hsize_t nfields, size_t size, const char *field_names[],
- const size_t *field_offset, const hid_t *field_types )
-{
-
- hid_t tid;
- hsize_t i;
-
- /* Create the memory data type. */
- if ((tid = H5Tcreate (H5T_COMPOUND, size )) < 0 )
- goto out;
-
- /* Insert fields. */
- for ( i = 0; i < nfields; i++)
- {
- if ( H5Tinsert(tid, field_names[i], field_offset[i], field_types[i] ) < 0 )
- goto out;
- }
-
- return tid;
-
-out:
- return -1;
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5LTrepack
- *
- * Purpose: Packs/Unpacks data from buffers. This function transfers data from a packed
- * data, src_buf, to a "natural byte aligned" (an n-byte item at an n-byte boundary)
- * data, dst_buf, and vice-versa.
- *
- * Return: Success: 0, Failure: -1
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: January 17, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *
- *-------------------------------------------------------------------------
- */
-
-herr_t H5LTrepack( hsize_t nfields,
- hsize_t nrecords,
- size_t src_size,
- const size_t *src_offset,
- const size_t *src_sizes,
- size_t dst_size,
- const size_t *dst_offset,
- const size_t *dst_sizes,
- unsigned char *src_buf,
- unsigned char *dst_buf )
-{
- hsize_t i, j;
- /* size of each field of destination data counting with padding */
- size_t *size_pad = (size_t *)malloc((size_t)nfields * sizeof(size_t));
-
- /* Shut compiler */
- src_size=src_size;
- src_offset=src_offset;
-
- if ( size_pad == NULL )
- goto out;
-
- for ( i= 0; i < nfields; i++)
- {
-
- size_pad[i] = ( i == nfields-1 ? dst_size-dst_offset[i] : dst_offset[i+1]-dst_offset[i] );
-
- }
-
- /* Iterate tru the records */
- for ( i = 0; i < nrecords; i++)
- {
- /* Iterate tru the members */
- for ( j = 0; j < nfields; j++)
- {
-
- memcpy( dst_buf, src_buf, dst_sizes[j] );
- dst_buf += size_pad[j];
- src_buf += src_sizes[j];
-
- }
-
- }
-
- if ( size_pad != NULL )
- free( size_pad );
-
-return 0;
-
-out:
- return -1;
-
-}
-#endif /* NOT_YET */
-
diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h
index 67db49d..05670d2 100644
--- a/hl/src/H5LTpublic.h
+++ b/hl/src/H5LTpublic.h
@@ -343,23 +343,6 @@ H5_HLDLL herr_t H5LTdtype_to_text(hid_t dtype, char *str, H5LT_lang_t lang_type,
H5_HLDLL herr_t H5LTfind_attribute( hid_t loc_id, const char *name );
-#ifdef NOT_YET
-
-H5_HLDLL hid_t H5LTcreate_compound_type( hsize_t nfields, size_t size, const char *field_names[],
- const size_t *field_offset, const hid_t *field_types );
-H5_HLDLL herr_t H5LTrepack( hsize_t nfields,
- hsize_t nrecords,
- size_t src_size,
- const size_t *src_offset,
- const size_t *src_sizes,
- size_t dst_size,
- const size_t *dst_offset,
- const size_t *dst_sizes,
- unsigned char *src_buf,
- unsigned char *dst_buf );
-#endif /* NOT_YET */
-
-
#ifdef __cplusplus
}
#endif
08' href='#n308'>308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the files COPYING and Copyright.html.  COPYING can be found at the root   *
 * of the source code distribution tree; Copyright.html can be found at the  *
 * root level of an installed copy of the electronic HDF5 document set and   *
 * is linked from the top-level documents page.  It can also be found at     *
 * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
 * access to either file, you may request a copy from help@hdfgroup.org.     *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 * Programmer:  Scott Wegner <swegner@hdfgroup.org>
 *				Based on code by Robb Matzke
 *				May 24, 2007
 *
 * Purpose:	We would like to create a driver specifically for Windows
 *			to utilize the Win32 API, and reduce the maintenence demands
 *			for the other file drivers.  Our other motivation is that 
 *			the Windows system calls of the existing sec2 driver differ
 *			from those on other platforms, and are not 64-bit compatible.
 *			From the start, this will have the structure very similar 
 *			to our sec2 driver, but make system calls more similar to 
 *			our stdio driver.
 */

/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC	H5FD_windows_init_interface


#include "H5private.h"		/* Generic Functions		*/
#include "H5Eprivate.h"		/* Error handling		  	*/
#include "H5Fprivate.h"		/* File access				*/
#include "H5FDprivate.h"	/* File drivers				*/
#include "H5FDwindows.h"	/* Windows file driver		*/
#include "H5FLprivate.h"	/* Free Lists               */
#include "H5Iprivate.h"		/* IDs			  			*/
#include "H5MMprivate.h"	/* Memory management		*/
#include "H5Pprivate.h"		/* Property lists			*/

#ifdef H5_HAVE_WINDOWS

/* The driver identification number, initialized at runtime */
static hid_t H5FD_WINDOWS_g = 0;

/* File operations */
#define OP_UNKNOWN	0
#define OP_READ		1
#define OP_WRITE	2

/*
 * The description of a file belonging to this driver. The `eoa' and `eof'
 * determine the amount of hdf5 address space in use and the high-water mark
 * of the file (the current size of the underlying file). The `pos'
 * value is used to eliminate file position updates when they would be a
 * no-op. Unfortunately we've found systems that use separate file position
 * indicators for reading and writing so the lseek can only be eliminated if
 * the current operation is the same as the previous operation.  When opening
 * a file the `eof' will be set to the current file size, `eoa' will be set
 * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error
 * occurs), and `op' will be set to H5F_OP_UNKNOWN.
 */
typedef struct H5FD_windows_t {
    H5FD_t	pub;			/*public stuff, must be first	*/
	/* 
	 * .NET doesn't support our 64-bit safe stdio functions,
	 * so we will use io.h functions instead.
     */
#ifndef WINDOWS_USE_STDIO
	int		fd;				/*the file descriptor			*/
#else
    FILE 	*fp;			/*the file handle				*/
#endif /*MSC_VER */
    haddr_t	eoa;			/*end of allocated region		*/
    haddr_t	eof;			/*end of file; current file size*/
    haddr_t	pos;			/*current file I/O position		*/
    int		op;				/*last operation				*/
	unsigned write_access;	/*flag to indicate the file was opened with write access */
    /*
     * On _WIN32 the low-order word of a unique identifier associated with the
     * file and the volume serial number uniquely identify a file. This number
     * may change when the system is restarted or when the
     * file is opened. After a process opens a file, the identifier is
     * constant until the file is closed. An application can use this
     * identifier and the volume serial number to determine whether two
     * handles refer to the same file.
     */
    DWORD fileindexlo;
    DWORD fileindexhi;
	DWORD volumeserialnumber;
} H5FD_windows_t;


/* These are used by the macros below */
#define file_offset_t		__int64 
#define fseek_offset_t		__int64

/*
 * These macros check for overflow of various quantities.  These macros
 * assume that fseek_offset_t is signed and haddr_t and size_t are unsigned.
 *
 * ADDR_OVERFLOW:	Checks whether a file address of type `haddr_t'
 *			is too large to be represented by the second argument
 *			of the file seek function.
 *
 * SIZE_OVERFLOW:	Checks whether a buffer size of type `hsize_t' is too
 *			large to be represented by the `size_t' type.
 *
 * REGION_OVERFLOW:	Checks whether an address and size pair describe data
 *			which can be addressed entirely by the second
 *			argument of the file seek function.
 */
#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1)
#define ADDR_OVERFLOW(A)	(HADDR_UNDEF==(A) ||			      \
				 ((A) & ~(haddr_t)MAXADDR))
#define SIZE_OVERFLOW(Z)	((Z) & ~(hsize_t)MAXADDR)
#define REGION_OVERFLOW(A,Z)	(ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) ||      \
                                 HADDR_UNDEF==(A)+(Z) ||		      \
				 (fseek_offset_t)((A)+(Z))<(fseek_offset_t)(A))

/* Prototypes */
static H5FD_t *H5FD_windows_open(const char *name, unsigned flags, hid_t fapl_id,
			      haddr_t maxaddr);
static herr_t H5FD_windows_close(H5FD_t *_file);
static int H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_windows_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, 
			      hsize_t size);
static haddr_t H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
static haddr_t H5FD_windows_get_eof(const H5FD_t *_file);
static herr_t  H5FD_windows_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle);
static herr_t H5FD_windows_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
			     size_t size, void *buf);
static herr_t H5FD_windows_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
			      size_t size, const void *buf);
static herr_t H5FD_windows_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);

static const H5FD_class_t H5FD_windows_g = {
    "windows",				/*name			*/
    MAXADDR,				/*maxaddr		*/
    H5F_CLOSE_WEAK,			/* fc_degree	*/
    NULL,					/*sb_size		*/
    NULL,					/*sb_encode		*/
    NULL,					/*sb_decode		*/
    0, 						/*fapl_size		*/
    NULL,					/*fapl_get		*/
    NULL,					/*fapl_copy		*/
    NULL, 					/*fapl_free		*/
    0,						/*dxpl_size		*/
    NULL,					/*dxpl_copy		*/
    NULL,					/*dxpl_free		*/
    H5FD_windows_open,	    /*open			*/
    H5FD_windows_close,	    /*close			*/
    H5FD_windows_cmp,	    /*cmp			*/
    H5FD_windows_query,	    /*query			*/
    NULL,					/*alloc			*/
    NULL,					/*free			*/
    H5FD_windows_get_eoa,	/*get_eoa		*/
    H5FD_windows_set_eoa, 	/*set_eoa		*/
    H5FD_windows_get_eof,	/*get_eof		*/
    H5FD_windows_get_handle,/*get_handle    */
    H5FD_windows_read,		/*read			*/
    H5FD_windows_write,		/*write			*/
    H5FD_windows_flush,		/*flush			*/
    NULL,                   /*lock          */
    NULL,                   /*unlock        */
    H5FD_FLMAP_SINGLE 		/*fl_map		*/
};

/* Declare a free list to manage the H5FD_windows_t struct */
H5FL_DEFINE_STATIC(H5FD_windows_t);

/*--------------------------------------------------------------------------
NAME
   H5FD_windows_init_interface -- Initialize interface-specific information
USAGE
    herr_t H5FD_windows_init_interface()

RETURNS
    Non-negative on success/Negative on failure
DESCRIPTION
    Initializes any interface-specific data or routines.  (Just calls
    H5FD_windows_init currently).

--------------------------------------------------------------------------*/
static herr_t
H5FD_windows_init_interface(void)
{
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_init_interface)

    FUNC_LEAVE_NOAPI(H5FD_windows_init())
} /* H5FD_windows_init_interface() */

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_init
 *
 * Purpose:	Initialize this driver by registering the driver with the
 *			library.
 *
 * Return:	Success:	The driver ID for the windows driver.
 *			Failure:	Negative.
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24, 2007
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5FD_windows_init(void)
{
    hid_t ret_value;        /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_init, FAIL)

    if(H5I_VFL != H5I_get_type(H5FD_WINDOWS_g))
        H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t));

    /* Set return value */
    ret_value = H5FD_WINDOWS_g;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_windows_init() */

/*---------------------------------------------------------------------------
 * Function:	H5FD_windows_term
 *
 * Purpose:	Shut down the VFD
 *
 * Return:	<none>
 *
 * Programmer:  Scott Wegner
 *				Based on code by Quincey Koziol
 *              Thursday, May 24 2007
 *
 * Modification:
 *
 *---------------------------------------------------------------------------
 */
void
H5FD_windows_term(void)
{
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_term)

    /* Reset VFL ID */
    H5FD_WINDOWS_g=0;

    FUNC_LEAVE_NOAPI_VOID
} /* end H5FD_windows_term() */

/*-------------------------------------------------------------------------
 * Function:	H5Pset_fapl_windows
 *
 * Purpose:	Modify the file access property list to use the H5FD_WINDOWS
 *		driver defined in this source file.  There are no driver
 *		specific properties.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *				Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Pset_fapl_windows(hid_t fapl_id)
{
    H5P_genplist_t *plist;      /* Property list pointer */
    herr_t ret_value;

    FUNC_ENTER_API(H5Pset_fapl_windows, FAIL)
    H5TRACE1("e", "i", fapl_id);

    if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")

    ret_value= H5P_set_driver(plist, H5FD_WINDOWS, NULL);

done:
    FUNC_LEAVE_API(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_open
 *
 * Purpose:	Create and/or opens a Windows file as an HDF5 file.
 *
 * Return:	Success:	A pointer to a new file data structure. The
 *						public fields will be initialized by the
 *						caller, which is always H5FD_open().
 *
 *		Failure:	NULL
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static H5FD_t *
H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
				  haddr_t maxaddr)
{
    int             fd = -1;
    FILE			*f = NULL;
    H5FD_windows_t	*file = NULL;
    HANDLE			filehandle;
    struct _BY_HANDLE_FILE_INFORMATION fileinfo;
    H5FD_t			*ret_value;
    struct _stati64 sb;
#ifndef WINDOWS_USE_STDIO
    int o_flags;
#else
	unsigned		write_access = 0;
#endif /* WINDOWS_USE_STDIO */

    FUNC_ENTER_NOAPI(H5FD_windows_open, NULL)

    /* Sanity check on file offsets */
    assert(sizeof(file_offset_t)>=sizeof(size_t));

    /* Check arguments */
    if (!name || !*name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
    if (0==maxaddr || HADDR_UNDEF==maxaddr)
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
    if (ADDR_OVERFLOW(maxaddr))
        HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")

#ifndef WINDOWS_USE_STDIO
    /* Build the open flags */
    o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
    if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
    if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
    if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
	/* Windows needs O_BINARY to correctly handle eol characters */
	o_flags |= O_BINARY; 

    /* Open the file */
    if ((fd=_open(name, o_flags, 0666))<0)
        HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
    if (_fstati64(fd, &sb) == -1)
        HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")

#else /* WINDOWS_USE_STDIO */
	/* Translate our flags into a mode, and open the file */
    if (_access_s(name, F_OK)) {
        if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
            f = fopen(name, "wb+");
            write_access=1;     /* Note the write access */
        }
        else
			HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file doesn't exist and CREAT wasn't specified")
    } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
		HSYS_GOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file exists but CREAT and EXCL were specified")
    } else if (flags & H5F_ACC_RDWR) {
		if (flags & H5F_ACC_TRUNC)
            f = fopen(name, "wb+");
		else
            f = fopen(name, "rb+");
        write_access=1;     /* Note the write access */
    } else
        f = fopen(name, "rb");

    if (!f)
		HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "fsopen failed")

    if (_stati64(name, &sb) == -1)
        HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to stat file")
#endif /* WINDOWS_USE_STDIO */

	/* Create the new file struct */
    if (NULL==(file=H5FL_CALLOC(H5FD_windows_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")

    H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
    file->pos = HADDR_UNDEF;
    file->op = OP_UNKNOWN;
    
#ifndef WINDOWS_USE_STDIO
    file->fd = fd;
#else
    file->fp = f;
	if((fd = _fileno(f)) == -1)
		HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file descriptor for file")
    file->write_access=write_access;    /* Note the write_access for later */
#endif /* WINDOWS_USE_STDIO */

	if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
		HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file")
    if(!GetFileInformationByHandle(filehandle, &fileinfo))
		HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information")
    file->fileindexhi = fileinfo.nFileIndexHigh;
    file->fileindexlo = fileinfo.nFileIndexLow;
	file->volumeserialnumber = fileinfo.dwVolumeSerialNumber;

    /* Set return value */
    ret_value=(H5FD_t*)file;

done:
    if(ret_value==NULL) {
#ifndef WINDOWS_USE_STDIO
        if(fd>=0)
            _close(fd);
#else
        if(f)
			fclose(file->fp);
#endif /* WINDOWS_USE_STDIO */
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_close
 *
 * Purpose:	Closes a Windows file.
 *
 * Return:	Success:	0
 *
 *		Failure:	-1, file not closed.
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5FD_windows_close(H5FD_t *_file)
{
    H5FD_windows_t	*file = (H5FD_windows_t*)_file;
    herr_t			ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_close, FAIL)

#ifndef WINDOWS_USE_STDIO
    if (_close(file->fd)<0)
#else
    if (fclose(file->fp)<0)
#endif /* WINDOWS_USE_STDIO */
        HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")

    H5FL_FREE(H5FD_windows_t,file);

done:
    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_cmp
 *
 * Purpose:	Compares two files belonging to this driver using an
 *		arbitrary (but consistent) ordering.
 *
 * Return:	Success:	A value like strcmp()
 *
 *			Failure:	never fails (arguments were checked by the
 *						caller).
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
{
    const H5FD_windows_t	*f1 = (const H5FD_windows_t*)_f1;
    const H5FD_windows_t	*f2 = (const H5FD_windows_t*)_f2;
    int ret_value=0;

    FUNC_ENTER_NOAPI(H5FD_windows_cmp, H5FD_VFD_DEFAULT)

	if (f1->volumeserialnumber < f2->volumeserialnumber) HGOTO_DONE(-1)
	if (f1->volumeserialnumber > f2->volumeserialnumber) HGOTO_DONE(1)

    if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
    if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)

    if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
    if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)


done:
    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_query
 *
 * Purpose:	Set the flags that this VFL driver is capable of supporting.
 *              (listed in H5FDpublic.h)
 *
 * Return:	Success:	non-negative
 *
 *		    Failure:	negative
 *
 * Programmer:	Scott Wegner
				Based on code by Quincey Koziol
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static herr_t
H5FD_windows_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
{
    herr_t ret_value=SUCCEED;

    FUNC_ENTER_NOAPI(H5FD_windows_query, FAIL)

    /* Set the VFL feature flags that this driver supports */
    if(flags) {
        *flags = 0;
        *flags|=H5FD_FEAT_AGGREGATE_METADATA;	/* OK to aggregate metadata allocations */
        *flags|=H5FD_FEAT_ACCUMULATE_METADATA;	/* OK to accumulate metadata for faster writes */
        *flags|=H5FD_FEAT_DATA_SIEVE;			/* OK to perform data sieving for faster raw data reads & writes */
        *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA;	/* OK to aggregate "small" raw data allocations */
    }

done:
    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_get_eoa
 *
 * Purpose:	Gets the end-of-address marker for the file. The EOA marker
 *			is the first address past the last byte allocated in the
 *			format address space.
 *
 * Return:	Success:	The end-of-address marker.
 *
 *			Failure:	HADDR_UNDEF
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static haddr_t
H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
{
    const H5FD_windows_t	*file = (const H5FD_windows_t*)_file;
    haddr_t ret_value;  /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_get_eoa, HADDR_UNDEF)

    /* Set return value */
    ret_value=file->eoa;

done:
    FUNC_LEAVE_NOAPI(ret_value)
}


/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_set_eoa
 *
 * Purpose:	Set the end-of-address marker for the file. This function is
 *			called shortly after an existing HDF5 file is opened in order
 *			to tell the driver where the end of the HDF5 data is located.
 *
 * Return:	Success:	0
 *
 *			Failure:	-1
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, July 29, 1999
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
{
    H5FD_windows_t	*file = (H5FD_windows_t*)_file;
    herr_t ret_value=SUCCEED;   /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_set_eoa, FAIL)

    file->eoa = addr;

done:
    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_get_eof
 *
 * Purpose:	Returns the end-of-file marker, which is the greater of
 *			either the Windows end-of-file or the HDF5 end-of-address
 *			markers.
 *
 * Return:	Success:	End of file address, the first address past
 *						the end of the "file", either the Unix file
 *						or the HDF5 file.
 *
 *			Failure:	HADDR_UNDEF
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static haddr_t
H5FD_windows_get_eof(const H5FD_t *_file)
{
    const H5FD_windows_t	*file = (const H5FD_windows_t*)_file;
    haddr_t ret_value;  /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_get_eof, HADDR_UNDEF)

    /* Set return value */
    ret_value=MAX(file->eof, file->eoa);

done:
    FUNC_LEAVE_NOAPI(ret_value)
}


/*-------------------------------------------------------------------------
 * Function:		H5FD_windows_get_handle
 *
 * Purpose:			Returns the file handle of windows file driver.
 *
 * Returns:			Non-negative if succeed or negative if fails.
 *
 * Programmer:		Scott Wegner
					Based on code by Raymond Lu
 *					Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static herr_t
H5FD_windows_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
{
    H5FD_windows_t         *file = (H5FD_windows_t *)_file;
    herr_t              ret_value = SUCCEED;

    FUNC_ENTER_NOAPI(H5FD_windows_get_handle, FAIL)

    if(!file_handle)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid")
#ifndef WINDOWS_USE_STDIO
    *file_handle = &(file->fd);
#else
    *file_handle = &(file->fp);
#endif /* WINDOWS_USE_STDIO */
	if(*file_handle==NULL)
        HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "get handle failed")


done:
    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_alloc
 *
 * Purpose:	Allocates file memory.
 *
 * Return:	Success:	Address of new memory
 *
 *			Failure:	HADDR_UNDEF
 *
 * Programmer:	Scott Wegner
				Based on code by Raymond Lu
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static haddr_t
H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hsize_t size)
{
    H5FD_windows_t	*file = (H5FD_windows_t*)_file;
    haddr_t		addr;
    haddr_t ret_value;          /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_alloc, HADDR_UNDEF)

    /* Compute the address for the block to allocate */
    addr = file->eoa;

    /* Check if we need to align this block */
    if(size >= file->pub.threshold) {
        /* Check for an already aligned block */
        if((addr % file->pub.alignment) != 0)
            addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment;
    }


    file->eoa = addr + size;

    /* Set return value */
    ret_value = addr;

done:
    FUNC_LEAVE_NOAPI(ret_value)

}


/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_read
 *
 * Purpose:	Reads SIZE bytes of data from FILE beginning at address ADDR
 *			into buffer BUF according to data transfer properties in
 *			DXPL_ID.
 *
 * Return:	Success:	Zero. Result is stored in caller-supplied
 *						buffer BUF.
 *
 *			Failure:	-1, Contents of buffer BUF are undefined.
 *
 * Programmer:	Scott Wegner
				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static herr_t
H5FD_windows_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
	       size_t size, void *buf/*out*/)
{
    H5FD_windows_t		*file = (H5FD_windows_t*)_file;
    int					nbytes;
    herr_t				ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_read, FAIL)

    assert(file && file->pub.cls);
    assert(buf);

    /* Check for overflow conditions */
    if (HADDR_UNDEF==addr)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
    if (REGION_OVERFLOW(addr, size))
        HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
    if (addr+size>file->eoa)
        HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")

    /* Seek to the correct location */
    if ((addr!=file->pos || OP_READ!=file->op))
#ifndef WINDOWS_USE_STDIO
		if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
#else
        if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
#endif /* WINDOWS_USE_STDIO */
            file->op = OP_UNKNOWN;
            file->pos = HADDR_UNDEF;
			HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
		}

    /*
     * Read data, being careful of interrupted system calls, partial results,
     * and the end of the file.
     */
    while (size>0) {
#ifndef WINDOWS_USE_STDIO
        do {
			nbytes = _read(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
        } while (-1==nbytes && EINTR==errno);
        if (-1==nbytes) /* error */
            HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
        if (0==nbytes) {
            /* end of file but not end of format address space */
            HDmemset(buf, 0, size);
            break;
        }
#else
        do {
            nbytes = fread(buf,(size_t)1,(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
        } while (!nbytes && EINTR==errno);
		if(!nbytes) {
            if (ferror(file->fp)) /* error */
                HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
			if (feof(file->fp)) {
				/* end of file but not end of format address space */
				HDmemset(buf, 0, size);
				break;
			}	
		}
#endif /* WINDOWS_USE_STDIO */
        assert(nbytes>=0);
        assert((size_t)nbytes<=size);
        H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
        size -= (size_t)nbytes;
        H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
        addr += (haddr_t)nbytes;
        buf = (char*)buf + nbytes;
    }

    /* Update current position */
    file->pos = addr;
    file->op = OP_READ;

done:
    if(ret_value<0) {
        /* Reset last file I/O information */
        file->pos = HADDR_UNDEF;
        file->op = OP_UNKNOWN;
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
}


/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_write
 *
 * Purpose:	Writes SIZE bytes of data to FILE beginning at address ADDR
 *		from buffer BUF according to data transfer properties in
 *		DXPL_ID.
 *
 * Return:	Success:	Zero
 *
 *			Failure:	-1
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static herr_t
H5FD_windows_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
		size_t size, const void *buf)
{
    H5FD_windows_t		*file = (H5FD_windows_t*)_file;
    ssize_t		nbytes;
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5FD_windows_write, FAIL)

    assert(file && file->pub.cls);
    assert(buf);

    /* Check for overflow conditions */
    if (HADDR_UNDEF==addr)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
    if (REGION_OVERFLOW(addr, size))
        HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
    if (addr+size>file->eoa)
        HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")

    /* Seek to the correct location */
    if ((addr!=file->pos || OP_WRITE!=file->op))
	{
#ifndef WINDOWS_USE_STDIO
		if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
#else
        if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
#endif /* WINDOWS_USE_STDIO */
            file->op = OP_UNKNOWN;
            file->pos = HADDR_UNDEF;
	        HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
		}
	}

    /*
     * Write the data, being careful of interrupted system calls and partial
     * results
     */
	while (size>0) {
        do {
#ifndef WINDOWS_USE_STDIO
            nbytes = _write(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
        } while (-1==nbytes && EINTR==errno);
        if (-1==nbytes) /* error */
#else


		/* Write 1GB or less at a time */
			nbytes = fwrite(buf, 1, (size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
		} while (!nbytes && EINTR==errno);
        if (!nbytes) /* error */
#endif /* WINDOWS_USE_STDIO */
            HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
        assert(nbytes>0);
        assert((size_t)nbytes<=size);
        H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
        size -= (size_t)nbytes;
        H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
        addr += (haddr_t)nbytes;
        buf = (const char*)buf + nbytes;
	}

    /* Update current position and eof */
    file->pos = addr;
    file->op = OP_WRITE;
    if (file->pos>file->eof)
        file->eof = file->pos;

done:
    if(ret_value<0) {
        /* Reset last file I/O information */
        file->pos = HADDR_UNDEF;
        file->op = OP_UNKNOWN;
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
 * Function:	H5FD_windows_flush
 *
 * Purpose:	Makes sure that the true file size is the same (or larger)
 *			than the end-of-address.
 *
 * Return:	Success:	Non-negative
 *
 *			Failure:	Negative
 *
 * Programmer:	Scott Wegner
 *				Based on code by Robb Matzke
 *              Thursday, May 24 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
/* ARGSUSED */
static herr_t
H5FD_windows_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
{
    H5FD_windows_t	*file = (H5FD_windows_t*)_file;
    herr_t			ret_value=SUCCEED;       /* Return value */
#ifndef WINDOWS_USE_STDIO
	LARGE_INTEGER	li;
	HANDLE			filehandle;
#else
	int				fd;
#endif /* WINDOWS_USE_STDIO */

    FUNC_ENTER_NOAPI(H5FD_windows_flush, FAIL)

    assert(file);

	if (file->eoa != file->eof) {
#ifndef WINDOWS_USE_STDIO

		/* Extend the file to make sure it's large enough */
		if( (filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE)
			HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file")
		
		li.QuadPart = (__int64)file->eoa;
		(void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
		if(SetEndOfFile(filehandle) == 0)
			HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")

#else /* WINDOWS_USE_STDIO */
		/* Only try to flush if we have write access */
		if(!file->write_access)
			HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access")

		if((fd = _fileno(file->fp)) == -1)
			HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file")
		if(_chsize_s(fd, file->eoa))
			HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")

		/* Flush */
		if(!closing)
			if (fflush(file->fp) == EOF)
				HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed")
#endif /* WINDOWS_USE_STDIO */