summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c')
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c279
1 files changed, 279 insertions, 0 deletions
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;
+}
+