summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/file_io/GetFileTime
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
commit4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch)
tree98110734c91668dfdbb126fcc0e15ddbd93738ca /src/pal/tests/palsuite/file_io/GetFileTime
parentfa45f57ed55137c75ac870356a1b8f76c84b229c (diff)
downloadcoreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/pal/tests/palsuite/file_io/GetFileTime')
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/CMakeLists.txt10
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c180
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c195
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test2/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c142
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c98
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c224
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test5/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c281
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c279
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/testinfo.dat15
22 files changed, 1644 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/CMakeLists.txt
new file mode 100644
index 0000000000..19ee487a6a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test5)
+add_subdirectory(test6)
+add_subdirectory(test7)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..6a89846d21
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileTime.c
+)
+
+add_executable(paltest_getfiletime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test1 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c
new file mode 100644
index 0000000000..fb7bcb8513
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c
@@ -0,0 +1,180 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the GetFileTime function.
+** This test checks the time of a file, writes to it, then checks the
+** time again to ensure that write time has increased. It
+** also checks that creation time is the same under WIN32 and has
+** increased under FreeBSD.
+**
+** Depends:
+** CreateFile
+** WriteFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME Creation,LastAccess,LastWrite;
+ HANDLE TheFileHandle;
+ ULONG64 FirstWrite, SecondWrite, FirstCreationTime, SecondCreationTime;
+ DWORD temp;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ "the_file", // File Name
+ GENERIC_READ|GENERIC_WRITE, // Access Mode
+ 0, // Share Mode
+ NULL, // SD
+ OPEN_ALWAYS, // Howto Create
+ FILE_ATTRIBUTE_NORMAL, // File Attributes
+ NULL // Template file
+ );
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+
+ /* Get the Last Write, Creation and Access File time of that File */
+ if(!GetFileTime(TheFileHandle,&Creation,&LastAccess,&LastWrite))
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure.");
+ }
+
+ /* Convert the structure to an ULONG64 */
+
+ FirstCreationTime = ((((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ FirstWrite = ((((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+ /* Write to the file -- this should change write access and
+ last access
+ */
+
+ result = WriteFile(TheFileHandle, // File handle
+ "something", // String to write
+ 9, // Bytes to write
+ &temp, // Bytes written
+ NULL);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to write to file. The file must be "
+ "written to in order to test that the write time is "
+ "updated.");
+ }
+
+ /* Close the File, so the changes are recorded */
+ result = CloseHandle(TheFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to close the file handle.");
+ }
+
+
+ /* Reopen the file */
+ TheFileHandle =
+ CreateFile(
+ "the_file", /* file name */
+ GENERIC_READ|GENERIC_WRITE, /* access mode */
+ 0, /* share mode */
+ NULL, /* SD */
+ OPEN_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to template file */
+ );
+
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to re-open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+
+
+ /* Call GetFileTime again */
+ if(!GetFileTime(TheFileHandle,&Creation,&LastAccess,&LastWrite))
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure.");
+ }
+
+ /* Store the results in a ULONG64 */
+
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ SecondWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+
+ /* Now -- to test. We'll ensure that the Second
+ LastWrite time is larger than the first. It tells us that
+ time is passing, which is good!
+ */
+
+ if(FirstWrite >= SecondWrite)
+ {
+ Fail("ERROR: The last-write-file-time after writing did not "
+ "increase from the original. The second value should be "
+ "larger.");
+ }
+
+#if WIN32
+ /* Then we can check to make sure that the creation time
+ hasn't changed. This should always stay the same.
+ */
+
+ if(FirstCreationTime != SecondCreationTime)
+ {
+ Fail("ERROR: The creation time after writing should not "
+ "not change from the original. The second value should be "
+ "equal.");
+ }
+#else
+ /* Then we can check to make sure that the creation time
+ has changed. Under FreeBSD it changes whenever the file is
+ access or written.
+ */
+
+ if(FirstCreationTime >= SecondCreationTime)
+ {
+ Fail("ERROR: The creation time after writing should be "
+ "greater than the original. The second value should be "
+ "larger.");
+ }
+
+#endif
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test1/testinfo.dat
new file mode 100644
index 0000000000..50cd35214d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test1/testinfo.dat
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Test the GetFileTime function. Open a file and get the time. Then write
+= to that file. This will change the write and under FreeBSD
+= the creation time. Ensure that all of these are increasing.
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt
new file mode 100644
index 0000000000..3d315e44de
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileTime.c
+)
+
+add_executable(paltest_getfiletime_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test2 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c
new file mode 100644
index 0000000000..5b14a1e357
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c
@@ -0,0 +1,195 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the GetFileTime function
+** Test to see that access date either stays the same or increases
+** when a read is performed. Write
+** and creation time should stay unchanged. Note: Under FreeBSD
+** the Creation time should not change with just a read.
+**
+** Depends:
+** FileTimeToDosDateTime
+** CreateFile
+** ReadFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME Creation,LastAccess,LastWrite;
+ HANDLE TheFileHandle;
+ ULONG64 FirstWrite, SecondWrite,
+ FirstCreationTime, SecondCreationTime;
+ DWORD temp;
+ char ReadBuffer[10];
+ BOOL result;
+ WORD DosDateOne, DosDateTwo, DosTime;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ "the_file",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+
+ /* Get the Last Write, Creation and Access File time of that File */
+ if(GetFileTime(TheFileHandle,&Creation,&LastAccess,&LastWrite)==0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure.");
+ }
+
+ /* Call FileTimeToDosDateTime so we can aquire just the date
+ portion of the Last Access FILETIME.
+ */
+ if(FileTimeToDosDateTime(&LastAccess, &DosDateOne, &DosTime) == 0)
+ {
+ Fail("ERROR: FiletimeToDosDateTime failed, returning 0. "
+ "GetLastError returned %d.\n",GetLastError());
+ }
+
+ /* Convert the structure to an ULONG64 */
+
+ FirstCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ FirstWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+ /* Read from the file -- this should change
+ last access, but we'll only check the date portion, because some file
+ systems have a resolution of a day.
+ */
+
+ result = ReadFile(TheFileHandle, // handle to file
+ &ReadBuffer, // data buffer
+ 2, // number of bytes to read
+ &temp, // number of bytes read
+ NULL);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to read from the file.");
+ }
+
+
+ /* Close the File, so the changes are recorded */
+ result = CloseHandle(TheFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to close the file handle.");
+ }
+
+
+ /* Reopen the file */
+ TheFileHandle =
+ CreateFile("the_file", /* file name */
+ GENERIC_READ, /* access mode */
+ 0, /* share mode */
+ NULL, /* SD */
+ OPEN_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to template file */
+ );
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to re-open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+ /* Call GetFileTime again */
+ if(GetFileTime(TheFileHandle,&Creation,&LastAccess,&LastWrite) == 0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure.");
+ }
+
+ /* Get the Date of the LastAccessTime here again. */
+ if(FileTimeToDosDateTime(&LastAccess, &DosDateTwo, &DosTime) == 0)
+ {
+ Fail("ERROR: FileTimeToDosDateTime failed, returning 0. "
+ "GetLastError returned %d.\n",GetLastError());
+ }
+
+
+ /* Store the results in a ULONG64 */
+
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ SecondWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Now -- to test. We'll ensure that the Second
+ LastWrite time is the same as the first. This shouldn't
+ have changed.
+ */
+
+ if(FirstWrite != SecondWrite)
+ {
+ Fail("ERROR: The last-write-file-time after reading "
+ "increased from the original. The second value should be "
+ "equal.");
+ }
+
+
+ /*
+ For LastAccessTime, just check that the date is greater or equal
+ for the second over the first. The time is not conisered on some
+ file systems. (such as fat32)
+ */
+
+ if(DosDateOne > DosDateTwo)
+ {
+ Fail("ERROR: The last-access-time after reading should have "
+ "stayed the same or increased, but it did not.\n");
+ }
+
+
+ /* Check to ensure CreationTime hasn't changed. This should not
+ have changed in either environment.
+ */
+
+ if(FirstCreationTime != SecondCreationTime)
+ {
+ Fail("ERROR: The creation time after reading should not "
+ "not change from the original. The second value should be "
+ "equal.");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test2/testinfo.dat
new file mode 100644
index 0000000000..a60dcf45a4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test2/testinfo.dat
@@ -0,0 +1,16 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Tests the PAL implementation of the GetFileTime function
+= Test to see that access date either stays the same or increases
+= when a read is performed. Write
+= and creation time should stay unchanged. Note: Under FreeBSD
+= the Creation time should not change with just a read.
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt
new file mode 100644
index 0000000000..34f7310464
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileTime.c
+)
+
+add_executable(paltest_getfiletime_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test3 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c
new file mode 100644
index 0000000000..a3f46c2bf8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c
@@ -0,0 +1,142 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the GetFileTime function
+** Test to see that creation time is changed when two different files
+** are created.
+**
+** Depends:
+** CreateFile
+** ReadFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME Creation;
+ HANDLE TheFileHandle, SecondFileHandle;
+ ULONG64 FirstCreationTime, SecondCreationTime;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ "the_file",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+
+ /* Get the Creation time of the File */
+ if(GetFileTime(TheFileHandle,&Creation,NULL,NULL)==0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure. "
+ "Two of the params were NULL in this case, did they "
+ "cause the probleM?");
+ }
+
+ /* Convert the structure to an ULONG64 */
+
+ FirstCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+
+ /* Close the File, so the changes are recorded */
+ result = CloseHandle(TheFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to close the file handle.");
+ }
+
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+
+
+ /* Open another file */
+ SecondFileHandle =
+ CreateFile("the_other_file", /* file name */
+ GENERIC_READ, /* access mode */
+ 0, /* share mode */
+ NULL, /* SD */
+ CREATE_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to template file */
+ );
+
+ if(SecondFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to open the second file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+
+ /* Call GetFileTime again */
+ if(GetFileTime(SecondFileHandle,&Creation,NULL,NULL) == 0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure. "
+ "Perhaps the NULLs in the function broke it?");
+ }
+
+ /* Close the File*/
+ result = CloseHandle(SecondFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to close the file handle.");
+ }
+
+
+ /* Store the results in a ULONG64 */
+
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+
+
+ /* Now -- to test. We ensure that the FirstCreationTime is
+ less than the SecondCreationTime
+ */
+
+
+ if(FirstCreationTime >= SecondCreationTime)
+ {
+ Fail("ERROR: The creation time of the two files should be "
+ "different. The first file should have a creation "
+ "time less than the second.");
+ }
+
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test3/testinfo.dat
new file mode 100644
index 0000000000..6d1eba739d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test3/testinfo.dat
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Test the GetFileTime function. This test creates two files and compares
+= their creation times. They should be different. It also tries to get the
+= file time of an invalid handle, which should cause the function to tail.
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt
new file mode 100644
index 0000000000..0c9dcf7802
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileTime.c
+)
+
+add_executable(paltest_getfiletime_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test4 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c
new file mode 100644
index 0000000000..ffba516e35
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c
@@ -0,0 +1,98 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the GetFileTime function
+** Test to see that passing NULL values to GetFileTime works and that
+** calling the function on a bad HANDLE causes the correct failure.
+**
+** Depends:
+** CreateFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME Creation,LastWrite,LastAccess;
+ HANDLE TheFileHandle;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ "the_file",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to open the file. The error number "
+ "returned was %d.",GetLastError());
+ }
+
+ /* Pass all NULLs, this is useless but should still work. */
+ if(GetFileTime(TheFileHandle,NULL,NULL,NULL)==0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure. "
+ "Three of the params were NULL in this case, did they "
+ "cause the problem?");
+ }
+
+
+ /* Get the Creation time of the File */
+ if(GetFileTime(TheFileHandle,&Creation,NULL,NULL)==0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure. "
+ "Two of the params were NULL in this case, did they "
+ "cause the probleM?");
+ }
+
+ /* Get the Creation, LastWrite time of the File */
+ if(GetFileTime(TheFileHandle,&Creation,&LastWrite,NULL)==0)
+ {
+ Fail("ERROR: GetFileTime returned 0, indicating failure. "
+ "One of the params were NULL in this case, did it "
+ "cause the problem?");
+ }
+
+
+ /* Close the File, so the changes are recorded */
+ result = CloseHandle(TheFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: Failed to close the file handle.");
+ }
+
+ /* Call GetFileTime again */
+ if(GetFileTime(TheFileHandle,&Creation,&LastWrite,&LastAccess) != 0)
+ {
+ Fail("ERROR: GetFileTime returned non zero, indicating success. "
+ "It was passed an invalid file HANDLE and should have "
+ "failed.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test4/testinfo.dat
new file mode 100644
index 0000000000..af90558cae
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test4/testinfo.dat
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Test the GetFileTime function. This test gets the file time of a given
+= file while passing all the combonations of NULL as parameters. The
+= function should handle these as unneeded times, and still succeed.
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt
new file mode 100644
index 0000000000..a82717e657
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getfiletime.c
+)
+
+add_executable(paltest_getfiletime_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test5 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test5
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c
new file mode 100644
index 0000000000..d8196d84bc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c
@@ -0,0 +1,224 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Test the PAL implementation of GetFileTime. This test
+** creates a file and compares create and write times between
+** writes, but before the close, and verifies the results are
+** as expected
+**
+** Depends:
+** CreateFile
+** WriteFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+ FILETIME Creation;
+ FILETIME LastAccess;
+ FILETIME LastWrite;
+ HANDLE hFile;
+ ULONG64 FirstWrite;
+ ULONG64 SecondWrite;
+ ULONG64 FirstCreationTime;
+ ULONG64 SecondCreationTime;
+ DWORD temp;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ hFile = CreateFile("test.tmp",
+ GENERIC_READ|GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to create the file. The error number "
+ "returned was %u.\n",
+ GetLastError());
+ }
+
+ /* Write to the file -- this should change write access and
+ last access
+ */
+ if(!WriteFile(hFile, "something", 9, &temp, NULL))
+ {
+ Trace("ERROR: Failed to write to file. The file must be "
+ "written to in order to test that the write time is "
+ "updated. GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ FlushFileBuffers(hFile);
+
+ /* Get the Last Write, Creation and Access File time of that File */
+ if(!GetFileTime(hFile, &Creation, &LastAccess, &LastWrite))
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure."
+ " GetLastError returned %u\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Convert the structure to an ULONG64 */
+
+ FirstCreationTime = ((((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ FirstWrite = ((((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+ /* Write to the file again -- this should change write access and
+ last access
+ */
+ if(!WriteFile(hFile, "something", 9, &temp, NULL))
+ {
+ Trace("ERROR: Failed to write to file. The file must be "
+ "written to in order to test that the write time is "
+ "updated. GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ FlushFileBuffers(hFile);
+
+ /* Call GetFileTime again */
+ if(!GetFileTime(hFile,&Creation,&LastAccess,&LastWrite))
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure."
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Store the results in a ULONG64 */
+
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ SecondWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+
+ /* Now -- to test. We'll ensure that the Second
+ LastWrite time is larger than the first. It tells us that
+ time is passing, which is good!
+ */
+
+ if(FirstWrite >= SecondWrite)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The last-write-file-time after writing did not "
+ "increase from the original. The second value should be "
+ "larger.\n");
+ }
+
+#if WIN32
+ /* Then we can check to make sure that the creation time
+ hasn't changed. This should always stay the same.
+ */
+
+ if(FirstCreationTime != SecondCreationTime)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The creation time after writing should not "
+ "not change from the original. The second value should be "
+ "equal.\n");
+ }
+#else
+ /* Then we can check to make sure that the creation time
+ has changed. Under FreeBSD it changes whenever the file is
+ access or written.
+ */
+
+ if(FirstCreationTime >= SecondCreationTime)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The creation time after writing should be "
+ "greater than the original. The second value should be "
+ "larger.\n");
+ }
+
+#endif
+
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Fail("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test5/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test5/testinfo.dat
new file mode 100644
index 0000000000..fd4112b1fa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test5/testinfo.dat
@@ -0,0 +1,15 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Test the PAL implementation of GetFileTime. This test
+= creates a file and compares create and write times between
+= writes, but before the close, and verifies the results are
+= as expected
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt
new file mode 100644
index 0000000000..24992dfa66
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getfiletime.c
+)
+
+add_executable(paltest_getfiletime_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test6 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c
new file mode 100644
index 0000000000..3eedddf82d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c
@@ -0,0 +1,281 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the GetFileTime function.
+** Perform two reads from a file without closing until the end
+** of the test and verify that only the access times change.
+** Note: Under Win32, modify time changes as well so we will
+** check that it doesn't go backwards
+**
+** Depends:
+** FileTimeToDosDateTime
+** CreateFile
+** ReadFile
+** WriteFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME Creation;
+ FILETIME LastAccess;
+ FILETIME LastWrite;
+ HANDLE hFile;
+ ULONG64 FirstWrite = (ULONG64)0;
+ ULONG64 SecondWrite = (ULONG64)0;
+ ULONG64 FirstCreationTime = (ULONG64)0;
+ ULONG64 SecondCreationTime = (ULONG64)0;
+ DWORD temp;
+ char ReadBuffer[10];
+ WORD DosDateOne;
+ WORD DosDateTwo;
+ WORD DosTime;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+ memset(&Creation, 0, sizeof(FILETIME));
+ memset(&LastAccess, 0, sizeof(FILETIME));
+ memset(&LastWrite, 0, sizeof(FILETIME));
+
+ /* Create the file to get a HANDLE */
+ hFile = CreateFile("test.tmp",
+ GENERIC_READ|GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to create the file. The error number "
+ "returned was %u.\n",
+ GetLastError());
+ }
+
+ /* give us something to read from the file */
+ if(!WriteFile(hFile, "something", 9, &temp, NULL))
+ {
+ Trace("ERROR: Failed to write to file. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* let's do a read to set the file times for our test */
+ if(!ReadFile(hFile, &ReadBuffer, 2, &temp, NULL))
+ {
+ Trace("ERROR: Failed to read from the file. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Get the Last Write, Creation and Access File time of the file */
+ if(GetFileTime(hFile, &Creation, &LastAccess, &LastWrite)==0)
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure."
+ " GetLastError returned %u\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Call FileTimeToDosDateTime so we can aquire just the date
+ portion of the Last Access FILETIME.
+ */
+ if(FileTimeToDosDateTime(&LastAccess, &DosDateOne, &DosTime) == 0)
+ {
+ Trace("ERROR: FiletimeToDosDateTime failed, returning 0. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Convert the structure to an ULONG64 */
+ FirstCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ FirstWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+ /* Read from the file -- this should change
+ last access, but we'll only check the date portion, because some file
+ systems have a resolution of a day.
+ */
+ memset(&Creation, 0, sizeof(FILETIME));
+ memset(&LastAccess, 0, sizeof(FILETIME));
+ memset(&LastWrite, 0, sizeof(FILETIME));
+
+ if(!ReadFile(hFile, &ReadBuffer, 2, &temp, NULL))
+ {
+ Trace("ERROR: Failed to read from the file. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ /* Call GetFileTime to get the updated time values*/
+ if(GetFileTime(hFile, &Creation, &LastAccess, &LastWrite) == 0)
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure. "
+ "GetLastError returned %d.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Get the Date of the LastAccessTime here again. */
+ if(FileTimeToDosDateTime(&LastAccess, &DosDateTwo, &DosTime) == 0)
+ {
+ Trace("ERROR: FileTimeToDosDateTime failed, returning 0. "
+ "GetLastError returned %d.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ /* Store the results in a ULONG64 */
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ SecondWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ /* Now -- to test. We'll ensure that the SecondWrite
+ time is not less than the FirstWrite time
+ */
+
+ if(SecondWrite < FirstWrite)
+ {
+ Trace("ERROR: The write-file-time (%I64d) after the first read "
+ "is less than the write-file-time (%I64d) after the second "
+ "read.\n",
+ FirstWrite,
+ LastWrite);
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /*
+ For LastAccessTime, just check that the date is greater or equal
+ for the second over the first. The time is not conisered on some
+ file systems. (such as fat32)
+ */
+
+ if(DosDateOne > DosDateTwo)
+ {
+ Trace("ERROR: The last-access-time after reading should have "
+ "stayed the same or increased, but it did not.\n");
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ /* Check to ensure CreationTime hasn't changed. This should not
+ have changed in either environment.
+ */
+
+ if(FirstCreationTime != SecondCreationTime)
+ {
+ Trace("ERROR: The creation time after reading should not "
+ "not change from the original. The second value should be "
+ "equal.\n");
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Close the File, so the changes are recorded */
+ if(!CloseHandle(hFile))
+ {
+ Fail("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test6/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test6/testinfo.dat
new file mode 100644
index 0000000000..844043689c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test6/testinfo.dat
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Tests the PAL implementation of the GetFileTime function.
+= Perform two reads from a file without closing until the end
+= of the test and verify that only the access times change.
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt
new file mode 100644
index 0000000000..6646fd9272
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getfiletime.c
+)
+
+add_executable(paltest_getfiletime_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletime_test7 coreclrpal)
+
+target_link_libraries(paltest_getfiletime_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c
new file mode 100644
index 0000000000..d33175b8ec
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c
@@ -0,0 +1,279 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: GetFileTime.c
+**
+** Purpose: Test the PAL implementation of GetFileTime. This test
+** creates a file and compares create and write times after
+** the buffers are flushed, but before the close, and verifies
+** the results are as expected
+**
+** Depends:
+** CreateFile
+** WriteFile
+** FlushFileBuffers
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+ FILETIME Creation;
+ FILETIME LastAccess;
+ FILETIME LastWrite;
+ HANDLE hFile;
+ ULONG64 FirstWrite;
+ ULONG64 SecondWrite;
+ ULONG64 FirstAccess;
+ ULONG64 SecondAccess;
+ ULONG64 FirstCreationTime;
+ ULONG64 SecondCreationTime;
+ DWORD temp;
+ const char* someText = "1234567890123456789012345678901234567890";
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Open the file to get a HANDLE */
+ hFile = CreateFile("test.tmp",
+ GENERIC_READ|GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Failed to create the file. The error number "
+ "returned was %u.\n",
+ GetLastError());
+ }
+
+ /* Write to the file -- this should change write access and
+ last access
+ */
+ if(!WriteFile(hFile, someText, strlen(someText), &temp, NULL))
+ {
+ Trace("ERROR: Failed to write to file. The file must be "
+ "written to in order to test that the write time is "
+ "updated. GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Flush the buffers */
+ if(!FlushFileBuffers(hFile))
+ {
+ Trace("ERROR: The FlushFileBuffers function failed. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Get the Last Write, Creation and Access File time of that File */
+ if(!GetFileTime(hFile, &Creation, &LastAccess, &LastWrite))
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure."
+ " GetLastError returned %u\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Convert the structures to an ULONG64 */
+ FirstCreationTime = ((((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ FirstWrite = ((((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ FirstAccess = ((((ULONG64)LastAccess.dwHighDateTime)<<32) |
+ ((ULONG64)LastAccess.dwLowDateTime));
+
+ /* Sleep for 3 seconds, this will ensure the time changes */
+ Sleep(3000);
+
+ /* Write to the file again so we have something to flush */
+ if(!WriteFile(hFile, someText, strlen(someText), &temp, NULL))
+ {
+ Trace("ERROR: Failed to write to file. The file must be "
+ "written to in order to test that the write time is "
+ "updated. GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Flush the buffers forcing the access/mod time to change */
+ if(!FlushFileBuffers(hFile))
+ {
+ Trace("ERROR: The FlushFileBuffers function failed. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ /* Call GetFileTime again */
+ if(!GetFileTime(hFile,&Creation,&LastAccess,&LastWrite))
+ {
+ Trace("ERROR: GetFileTime returned 0, indicating failure."
+ "GetLastError returned %u.\n",
+ GetLastError());
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Store the results in a ULONG64 */
+
+ SecondCreationTime = ( (((ULONG64)Creation.dwHighDateTime)<<32) |
+ ((ULONG64)Creation.dwLowDateTime));
+
+ SecondWrite = ( (((ULONG64)LastWrite.dwHighDateTime)<<32) |
+ ((ULONG64)LastWrite.dwLowDateTime));
+
+ SecondAccess = ((((ULONG64)LastAccess.dwHighDateTime)<<32) |
+ ((ULONG64)LastAccess.dwLowDateTime));
+
+
+ /* Now -- to test. We'll ensure that the Second
+ LastWrite and access times are larger than the first.
+ It tells us that time is passing, which is good!
+ */
+
+ if(FirstWrite >= SecondWrite)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The write-file-time (%I64d) after the first flush "
+ "should be less than the write-file-time (%I64d) after the second "
+ "flush.\n",
+ FirstWrite,
+ LastWrite);
+
+ }
+
+
+ if(SecondAccess < FirstAccess)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The access-file-time (%I64d) after the first flush "
+ "should be less than or equal to the access-file-time (%I64d) "
+ "after the second flush.\n",
+ FirstAccess,
+ LastAccess);
+ }
+
+#if WIN32
+ /* Then we can check to make sure that the creation time
+ hasn't changed. This should always stay the same.
+ */
+
+ if(FirstCreationTime != SecondCreationTime)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The creation time after writing should not "
+ "not change from the original. The second value should be "
+ "equal.\n");
+ }
+#else
+ /* Then we can check to make sure that the creation time
+ has changed. Under FreeBSD it changes whenever the file is
+ access or written.
+ */
+
+ if(FirstCreationTime >= SecondCreationTime)
+ {
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Trace("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("ERROR: The creation time after writing should be "
+ "greater than the original. The second value should be "
+ "larger.\n");
+ }
+
+#endif
+
+ /* Close the File */
+ if(!CloseHandle(hFile))
+ {
+ Fail("ERROR: Failed to close the file handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test7/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileTime/test7/testinfo.dat
new file mode 100644
index 0000000000..774f759adc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test7/testinfo.dat
@@ -0,0 +1,15 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = file_io
+Function = GetFileTime
+Name = Positive Test for GetFileTime
+TYPE = DEFAULT
+EXE1 = getfiletime
+Description
+= Test the PAL implementation of GetFileTime. This test
+= creates a file and compares create and write times after
+= the buffers are flushed, but before the close, and verifies
+= the results are as expected