summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/file_io
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
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')
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c40
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CMakeLists.txt61
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c68
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c159
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c120
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c141
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test3/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c180
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test4/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c155
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/ExpectedResults.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c124
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test2/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c196
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test3/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c296
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c335
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c347
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c345
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c145
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/winoutput1
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c152
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/winoutput1
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp182
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c164
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c83
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c116
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c275
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c206
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c212
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c243
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c107
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c249
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c107
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c130
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c35
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c35
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c97
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c106
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c94
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c65
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt26
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c340
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/testinfo.dat20
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/anchor.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt23
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c227
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c170
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt26
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c345
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_file6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_file1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/keepme1
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/testinfo.dat20
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c173
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c173
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/testinfo.dat13
-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
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c76
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c95
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c72
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c122
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c143
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/testinfo.dat18
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c241
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/testinfo.dat19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c203
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/testinfo.dat19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c157
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c159
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c240
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/testinfo.dat19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c201
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/testinfo.dat19
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c280
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c266
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c132
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c79
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c124
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c86
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c125
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c80
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c159
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c129
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c84
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c161
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c103
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/ExpectedResults.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c469
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/ExpectedResults.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c360
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/ExpectedResults.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c431
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/ExpectedResults.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c478
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/NonReadableFile.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c82
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c198
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c184
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c147
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test4/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp315
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c282
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c144
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c198
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c215
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c142
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c56
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c178
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c147
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c64
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/CMakeLists.txt8
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c85
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c154
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c109
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c138
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test4/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c183
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test5/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c168
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c114
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c48
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c128
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c167
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c121
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c57
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c133
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/test_file1
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/CMakeLists.txt10
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c123
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c356
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c350
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c242
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test4/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c182
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test5/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c213
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c213
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test7/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c129
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c101
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test2/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c66
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c108
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/CMakeLists.txt8
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c114
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/Results.txt1
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c109
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c136
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test3/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test4/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c155
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test5/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c117
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c783
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test1/testinfo.dat31
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c785
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test2/testinfo.dat34
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c244
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test3/testinfo.dat30
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c351
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test4/testinfo.dat34
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c103
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/test1/testinfo.dat15
484 files changed, 26909 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/CMakeLists.txt b/src/pal/tests/palsuite/file_io/AreFileApisANSI/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c
new file mode 100644
index 0000000000..ec61f0cb7d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c
@@ -0,0 +1,40 @@
+// 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: AreFileApisANSI.c
+**
+** Purpose: Tests the PAL implementation of the AreFileApisANSI function.
+** The only possible return is TRUE.
+**
+**
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ bRc = AreFileApisANSI();
+
+
+ if (bRc == FALSE)
+ {
+ Fail("AreFileApisANSI: ERROR: Function returned FALSE whereas only TRUE "
+ "is acceptable.\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt
new file mode 100644
index 0000000000..4f50127cb9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ AreFileApisANSI.c
+)
+
+add_executable(paltest_arefileapisansi_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_arefileapisansi_test1 coreclrpal)
+
+target_link_libraries(paltest_arefileapisansi_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/testinfo.dat
new file mode 100644
index 0000000000..5e6b422ae4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = AreFileApisANSI
+Name = Positive Test for AreFileApisANSI
+Type = DEFAULT
+EXE1 = arefileapisansi
+Description
+=Ensure the return is TRUE because FALSE is not an option in FreeBSD
+
diff --git a/src/pal/tests/palsuite/file_io/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CMakeLists.txt
new file mode 100644
index 0000000000..3d6eff1379
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CMakeLists.txt
@@ -0,0 +1,61 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(AreFileApisANSI)
+add_subdirectory(CompareFileTime)
+add_subdirectory(CopyFileA)
+add_subdirectory(CopyFileW)
+add_subdirectory(CreateDirectoryA)
+add_subdirectory(CreateDirectoryW)
+add_subdirectory(CreateFileA)
+add_subdirectory(CreateFileW)
+add_subdirectory(DeleteFileA)
+add_subdirectory(DeleteFileW)
+add_subdirectory(errorpathnotfound)
+add_subdirectory(FILECanonicalizePath)
+add_subdirectory(FileTimeToDosDateTime)
+add_subdirectory(FindClose)
+add_subdirectory(FindFirstFileA)
+add_subdirectory(FindFirstFileW)
+add_subdirectory(FindNextFileA)
+add_subdirectory(FindNextFileW)
+add_subdirectory(FlushFileBuffers)
+add_subdirectory(GetConsoleCP)
+add_subdirectory(GetConsoleOutputCP)
+add_subdirectory(GetCurrentDirectoryA)
+add_subdirectory(GetCurrentDirectoryW)
+add_subdirectory(GetDiskFreeSpaceW)
+add_subdirectory(GetFileAttributesA)
+add_subdirectory(GetFileAttributesExW)
+add_subdirectory(GetFileAttributesW)
+add_subdirectory(GetFileSize)
+add_subdirectory(GetFileSizeEx)
+add_subdirectory(GetFileTime)
+add_subdirectory(GetFileType)
+add_subdirectory(GetFullPathNameA)
+add_subdirectory(GetFullPathNameW)
+add_subdirectory(GetLongPathNameW)
+add_subdirectory(GetStdHandle)
+add_subdirectory(GetSystemTime)
+add_subdirectory(GetSystemTimeAsFileTime)
+add_subdirectory(GetTempFileNameA)
+add_subdirectory(GetTempFileNameW)
+add_subdirectory(gettemppatha)
+add_subdirectory(GetTempPathW)
+add_subdirectory(MoveFileA)
+add_subdirectory(MoveFileExA)
+add_subdirectory(MoveFileExW)
+add_subdirectory(MoveFileW)
+add_subdirectory(ReadFile)
+add_subdirectory(RemoveDirectoryA)
+add_subdirectory(RemoveDirectoryW)
+add_subdirectory(SearchPathA)
+add_subdirectory(SearchPathW)
+add_subdirectory(SetCurrentDirectoryA)
+add_subdirectory(SetCurrentDirectoryW)
+add_subdirectory(SetEndOfFile)
+add_subdirectory(SetFileAttributesA)
+add_subdirectory(SetFileAttributesW)
+add_subdirectory(SetFilePointer)
+add_subdirectory(SetFileTime)
+add_subdirectory(WriteFile)
+
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CompareFileTime/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..fdcb6559b3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CompareFileTime.c
+)
+
+add_executable(paltest_comparefiletime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_comparefiletime_test1 coreclrpal)
+
+target_link_libraries(paltest_comparefiletime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c
new file mode 100644
index 0000000000..3758f7e4eb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c
@@ -0,0 +1,68 @@
+// 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: CompareFileTime.c
+**
+** Purpose: Tests the PAL implementation of the CompareFileTime function.
+** Defines a large and small file time, and compares them in all fashions
+** to ensure proper return values.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME SmallTime, BigTime;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Set a Big and Small time. These were generated using
+ GetFileTime on a file, with a recent creation time and an old
+ modify time, to get a bigger and smaller value.
+ */
+
+ BigTime.dwLowDateTime = -755748832;
+ BigTime.dwHighDateTime = 29436941;
+
+ SmallTime.dwLowDateTime = -459754240;
+ SmallTime.dwHighDateTime = 29436314;
+
+ /* Check to see that SmallTime is less than Big Time */
+
+ if(CompareFileTime(&SmallTime,&BigTime) != -1)
+ {
+ Fail("ERROR: The first time is less than the second time, so "
+ "-1 should have been returned to indicate this.");
+ }
+
+ /* Check that BigTime is greater than SmallTime */
+
+ if(CompareFileTime(&BigTime,&SmallTime) != 1)
+ {
+ Fail("ERROR: The first time is greater than the second time, so "
+ "1 should have been returned to indicate this.");
+ }
+
+ /* Check that BigTime is equal to BigTime */
+
+ if(CompareFileTime(&BigTime,&BigTime) != 0)
+ {
+ Fail("ERROR: The first time is equal to the second time, so "
+ "0 should have been returned to indicate this.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/testinfo.dat
new file mode 100644
index 0000000000..4ff1b4c980
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/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 = CompareFileTime
+Name = Positive Test for CompareFileTime
+TYPE = DEFAULT
+EXE1 = comparefiletime
+Description
+= Test the CompareFileTime function.
+= Defines a large and small file time, and compares them in all fashions
+= to ensure proper return values.
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b52e5076fa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CopyFileA.c
+)
+
+add_executable(paltest_copyfilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilea_test1 coreclrpal)
+
+target_link_libraries(paltest_copyfilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c
new file mode 100644
index 0000000000..bfea85b7cb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c
@@ -0,0 +1,159 @@
+// 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: CopyFileA.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileA function
+**
+**
+**===================================================================*/
+
+/*
+ 1. copy an existing file to existing with overwrite true
+ 2. copy an existing file to existing with overwrite false
+ 3. copy an existing file to non-existant with overwrite true
+ 4. copy an existing file to non-existant with overwrite false
+ 5. copy non-existant file to existing with overwrite true
+ 6. copy non-existant file to existing with overwrite false
+ 7. copy non-existant file to non-existant with overwrite true
+ 8. copy non-existant file to non-existant with overwrite false
+*/
+
+#include <palsuite.h>
+
+struct TESTS{
+ char* lpSource;
+ char* lpDestination;
+ BOOL bFailIfExists;
+ int nResult;
+ };
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ char szSrcExisting[] = {"src_existing.tmp"};
+ char szSrcNonExistant[] = {"src_non-existant.tmp"};
+ char szDstExisting[] = {"dst_existing.tmp"};
+ char szDstNonExistant[] = {"dst_non-existant.tmp"};
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ FILE* tempFile = NULL;
+ int i;
+ struct TESTS testCase[] =
+ {
+ {szSrcExisting, szDstExisting, FALSE, 1},
+ {szSrcExisting, szDstExisting, TRUE, 0},
+ {szSrcExisting, szDstNonExistant, FALSE, 1},
+ {szSrcExisting, szDstNonExistant, TRUE, 1},
+ {szSrcNonExistant, szDstExisting, FALSE, 0},
+ {szSrcNonExistant, szDstExisting, TRUE, 0},
+ {szSrcNonExistant, szDstNonExistant, FALSE, 0},
+ {szSrcNonExistant, szDstNonExistant, TRUE, 0}
+ };
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the src_existing file */
+ tempFile = fopen(szSrcExisting, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "CopyFileA test file: src_existing.tmp\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Fail("CopyFileA: ERROR-> Couldn't create \"src_existing.tmp\" with "
+ "error %ld\n",
+ GetLastError());
+ }
+
+ /* create the dst_existing file */
+ tempFile = fopen(szDstExisting, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "CopyFileA test file: dst_existing.tmp\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Fail("CopyFileA: ERROR-> Couldn't create \"dst_existing.tmp\" with "
+ "error %ld\n",
+ GetLastError());
+ }
+
+
+
+ for (i = 0; i < (sizeof(testCase) / sizeof(struct TESTS)); i++)
+ {
+ bRc = CopyFileA(testCase[i].lpSource,
+ testCase[i].lpDestination,
+ testCase[i].bFailIfExists);
+ if (!bRc)
+ {
+ if (testCase[i].nResult == 1)
+ {
+ Trace("CopyFileA: FAILED: %s -> %s with bFailIfExists = %d "
+ "with error %ld\n",
+ testCase[i].lpSource,
+ testCase[i].lpDestination,
+ testCase[i].bFailIfExists,
+ GetLastError());
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ if (testCase[i].nResult == 0)
+ {
+ Trace("CopyFileA: FAILED: %s -> %s with bFailIfExists = %d\n",
+ testCase[i].lpSource,
+ testCase[i].lpDestination,
+ testCase[i].bFailIfExists);
+ bSuccess = FALSE;
+ }
+ else
+ {
+ /* verify the file was moved */
+ if (GetFileAttributesA(testCase[i].lpDestination) == -1)
+ {
+ Trace("CopyFileA: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ bSuccess = FALSE;
+ }
+ else if (GetFileAttributesA(testCase[i].lpSource) == -1)
+ {
+ Trace("CopyFileA: GetFileAttributes of source file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ bSuccess = FALSE;
+ }
+ else
+ {
+ /* verify attributes of destination file to source file*/
+ if(GetFileAttributes(testCase[i].lpSource) !=
+ GetFileAttributes(testCase[i].lpDestination))
+ {
+ Trace("CopyFileA : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ bSuccess = FALSE;
+ }
+ }
+ }
+ }
+ /* delete file file but don't worry if it fails */
+ DeleteFileA(szDstNonExistant);
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..88b9c73cb4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = CopyFileA
+Name = Test for CopyFileA (test 1)
+Type = DEFAULT
+EXE1 = copyfilea
+Description
+= Test the CopyFileA function
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..7454f32f51
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_copyfilea_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilea_test2 coreclrpal)
+
+target_link_libraries(paltest_copyfilea_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c b/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c
new file mode 100644
index 0000000000..56618d0a58
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c
@@ -0,0 +1,120 @@
+// 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: test2.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileA function
+** to see if a file can be copied to itself
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ BOOL bRc = TRUE;
+ char* szSrcExisting = "src_existing.tmp";
+ FILE* tempFile = NULL;
+ DWORD temp;
+ int retCode;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the src_existing file */
+ tempFile = fopen(szSrcExisting, "w");
+ if (tempFile != NULL)
+ {
+ retCode = fputs("CopyFileA test file: src_existing.tmp ", tempFile);
+ if(retCode < 0)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't write to %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+ retCode = fclose(tempFile);
+ if(retCode != 0)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't close file: %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+
+ }
+ else
+ {
+ Fail("CopyFileA: ERROR-> Couldn't create %s with "
+ "error %ld\n",szSrcExisting,GetLastError());
+ }
+
+ /* Get file attributes of source */
+ temp = GetFileAttributes(szSrcExisting);
+ if (temp == -1)
+ {
+ Fail("CopyFileA: GetFileAttributes of source file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+
+ /* make sure a file can't copy to itself
+ first testing with IfFileExists flag set to true */
+ bRc = CopyFileA(szSrcExisting,szSrcExisting,TRUE);
+ if(bRc)
+ {
+ Fail("ERROR: Cannot copy a file to itself, %u",GetLastError());
+ }
+
+ /* try to get file attributes of desitnation */
+ if (GetFileAttributesA(szSrcExisting) == -1)
+ {
+ Fail("CopyFileA: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+ else
+ {
+ /* verify attributes of destination file to source file*/
+
+ if(temp != GetFileAttributes(szSrcExisting))
+ {
+ Fail("CopyFileA : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ }
+ }
+
+ /* testing with IfFileExists flags set to false
+ should fail in Windows and pass in UNIX */
+ bRc = CopyFileA(szSrcExisting,szSrcExisting,FALSE);
+ if(bRc && (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Fail("ERROR: Cannot copy a file to itself, %u",GetLastError());
+ }
+
+ if (GetFileAttributesA(szSrcExisting) == -1)
+ {
+ Fail("CopyFileA: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+ else
+ {
+ /* verify attributes of destination file to source file*/
+
+ if(temp != GetFileAttributes(szSrcExisting))
+ {
+ Fail("CopyFileA : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileA/test2/testinfo.dat
new file mode 100644
index 0000000000..31143842e6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test2/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 = CopyFileA
+Name = CopyFileA - checking copying to itself (test2)
+Type = DEFAULT
+EXE1 = test2
+Description
+= Test the CopyFileA function's behaviour
+= for copying a file to itself.
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt
new file mode 100644
index 0000000000..986be9fd22
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_copyfilea_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilea_test3 coreclrpal)
+
+target_link_libraries(paltest_copyfilea_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c b/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c
new file mode 100644
index 0000000000..18c8ce80dc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c
@@ -0,0 +1,141 @@
+// 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: test3.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileA function
+** to see if a file can be copied to itself
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ BOOL bRc = TRUE;
+ char* szSrcExisting = "src_existing.tmp";
+ char* szDest = "src_dest.tmp";
+ FILE* tempFile = NULL;
+ int retCode;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the src_existing file */
+ tempFile = fopen(szSrcExisting, "w");
+ if (tempFile != NULL)
+ {
+ retCode = fputs("CopyFileA test file: src_existing.tmp ", tempFile);
+ if(retCode < 0)
+ {
+ retCode = fclose(tempFile);
+ if(retCode != 0)
+ {
+ Trace("CopyFileA: ERROR-> Couldn't close file: %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+
+ Fail("CopyFileA: ERROR-> Couldn't write to %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+ retCode = fclose(tempFile);
+ if(retCode != 0)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't close file: %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+
+ }
+ else
+ {
+ Fail("CopyFileA: ERROR-> Couldn't create %s with "
+ "error %ld\n",szSrcExisting,GetLastError());
+ }
+
+ /* set the file attributes of the source file to readonly */
+ bRc = SetFileAttributes(szSrcExisting, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't set file attributes for "
+ "file %s with error %u\n", szSrcExisting, GetLastError());
+ }
+
+ // Check the file attributes to make sure SetFileAttributes() above actually succeeded
+ DWORD fileAttributes = GetFileAttributesA(szSrcExisting);
+ if (fileAttributes == INVALID_FILE_ATTRIBUTES)
+ {
+ Fail("CopyFileA: Failed to get file attributes for source file, %u\n", GetLastError());
+ }
+ if ((fileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ {
+ Fail("CopyFileA: SetFileAttributes(read-only) on source file returned success but did not make it read-only.\n");
+ }
+
+ /* copy the file */
+ bRc = CopyFileA(szSrcExisting,szDest,TRUE);
+ if(!bRc)
+ {
+ Fail("CopyFileA: Cannot copy a file with error, %u",GetLastError());
+ }
+
+
+ /* try to get file attributes of destination file */
+ fileAttributes = GetFileAttributesA(szDest);
+ if (fileAttributes == INVALID_FILE_ATTRIBUTES)
+ {
+ Fail("CopyFileA: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+
+ /* verify attributes of destination file to source file*/
+ if((fileAttributes & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ Fail("CopyFileA : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ }
+
+ /* set the attributes of the destination file to normal again */
+ bRc = SetFileAttributesA(szDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't set file attributes for "
+ "file %s with error %u\n", szDest, GetLastError());
+ }
+
+ /* delete the newly copied file */
+ bRc = DeleteFile(szDest);
+ if(!bRc)
+ {
+ Fail("CopyFileA: DeleteFile failed to delete the"
+ "file correctly with error,%u.\n",GetLastError());
+ }
+
+ /* set the attributes of the source file to normal again */
+ bRc = SetFileAttributesA(szSrcExisting, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't set file attributes for "
+ "file %s with error %u\n", szSrcExisting, GetLastError());
+ }
+
+ /* delete the original file */
+ bRc = DeleteFile(szSrcExisting);
+ if(!bRc)
+ {
+ Fail("CopyFileA: DeleteFile failed to delete the"
+ "file correctly with error,%u.\n",GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileA/test3/testinfo.dat
new file mode 100644
index 0000000000..5a9775d14f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test3/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 = CopyFileA
+Name = CopyFileA - checking file attributes maintained (test2)
+Type = DEFAULT
+EXE1 = test3
+Description
+= Test the CopyFileA function's behaviour
+= for copying a file and verifying that
+= the copied file has the same file attributes
+= as the original.
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt
new file mode 100644
index 0000000000..fb48c83741
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.c
+)
+
+add_executable(paltest_copyfilea_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilea_test4 coreclrpal)
+
+target_link_libraries(paltest_copyfilea_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c b/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c
new file mode 100644
index 0000000000..1ae69f5e1f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.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: test4.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileA function
+** to see if a file can through different users belonging to
+** different groups.
+**
+
+=====================================================================*/
+
+/* USECASE
+ Copy a file from a different user, belonging to a different group to
+ the the current user, who is a member of the current group. Then check
+ to see that the current user has the basic access rights to the copied
+ file.
+
+ Thie original file used is the passwd file in the etc directory of a
+ BSD machine. This file should exist on all machines.
+*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+ return PASS;
+
+#else
+
+ BOOL bRc = TRUE;
+ char* szSrcExisting = "/etc/passwd";
+ char* szDest = "temp.tmp";
+ char* szStringTest = "Marry had a little lamb";
+ char szStringRead[30]; /* large enough for string szStringTest */
+
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten=0;
+ DWORD dwBytesRead=0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* copy the file */
+ bRc = CopyFileA(szSrcExisting,szDest,TRUE);
+ if(!bRc)
+ {
+ Fail("CopyFileA: Cannot copy a file with error, %u",GetLastError());
+ }
+
+ /* try to get file attributes of destination file */
+ if (GetFileAttributesA(szDest) == -1)
+ {
+ Fail("CopyFileA: GetFileAttributes of destination file "
+ "failed with error code %u. \n",
+ GetLastError());
+ }
+
+ /* set the attributes of the destination file to normal again */
+ bRc = SetFileAttributes(szDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Fail("CopyFileA: ERROR-> Couldn't set file attributes for "
+ "file %s with error %u\n", szDest, GetLastError());
+ }
+
+ /* open the file for write purposes */
+ hFile = CreateFile(szDest,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("CopyFileA: ERROR -> Unable to create file \"%s\".\n",
+ szDest);
+ }
+
+ /* Attempt to write to the file */
+ bRc = WriteFile(hFile, szStringTest, strlen(szStringTest), &dwBytesWritten, NULL);
+ if (!bRc)
+ {
+ Trace("CopyFileA: ERROR -> Unable to write to copied file with error "
+ "%u.\n", GetLastError());
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileA: ERROR -> Unable to close file \"%s\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+
+ }
+
+ /* Close the file handle */
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileA: ERROR -> Unable to close file \"%s\" with error %u "
+ ".\n",szDest,GetLastError());
+ }
+
+
+ /* open the file for read purposes */
+ hFile = CreateFile(szDest,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("CopyFileA: ERROR -> Unable to create file \"%s\".\n",
+ szDest);
+ }
+
+ /* Attempt to read from the file */
+ bRc = ReadFile(hFile, szStringRead, strlen(szStringTest), &dwBytesRead, NULL);
+ if (!bRc)
+ {
+ Trace("CopyFileA: ERROR -> Unable to read from copied file with "
+ "error %u.\n",GetLastError());
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileA: ERROR -> Unable to close file \"%s\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+
+ }
+
+ if(strncmp(szStringTest,szStringRead, strlen(szStringTest)) != 0)
+ {
+ Trace("CopyFileA: ERROR -> The string which was written '%s' does not "
+ "match the string '%s' which was read from the copied file.\n",
+ szStringTest,szStringRead);
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileA: ERROR -> Unable to close file \"%s\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Close the file handle */
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileA: ERROR -> Unable to close file \"%s\" with error %u "
+ ".\n",szDest,GetLastError());
+ }
+
+ /* Remove the temporary file */
+ bRc = DeleteFile(szDest);
+ if(!bRc)
+ {
+ Fail("CopyFileA: Could not remove copied file with error %u\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileA/test4/testinfo.dat
new file mode 100644
index 0000000000..42187b760f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test4/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 = CopyFileA
+Name = CopyFileA - checking file attributes maintained (test4)
+Type = DEFAULT
+EXE1 = test4
+Description
+= Copy a file from a different user, belonging to a different group to
+= the the current user, who is a member of the current group. Then check
+= to see that the current user has the basic access rights to the copied
+= file.
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..766b120035
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CopyFileW.c
+)
+
+add_executable(paltest_copyfilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilew_test1 coreclrpal)
+
+target_link_libraries(paltest_copyfilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c
new file mode 100644
index 0000000000..6127cc21bd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c
@@ -0,0 +1,155 @@
+// 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: CopyFileW.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileW function
+**
+**
+**===================================================================*/
+
+/*
+1. copy an existing file to non-existant with overwrite true
+2. copy an existing file to non-existant with overwrite false
+3. copy an existing file to existing with overwrite true
+4. copy an existing file to existing with overwrite false
+5. copy non-existant file to non-existant with overwrite true
+6. copy non-existant file to non-existant with overwrite false
+7. copy non-existant file to existing with overwrite true
+8. copy non-existant file to existing with overwrite false
+*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ LPSTR lpSource[2] = {"src_existing.tmp", "src_non-existant.tmp"};
+ LPSTR lpDestination[2] = {"dst_existing.tmp", "dst_non-existant.tmp"};
+ WCHAR* wcSource;
+ WCHAR* wcDest;
+ BOOL bFailIfExists[3] = {FALSE, TRUE};
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ char results[20];
+ FILE* resultsFile = NULL;
+ FILE* tempFile = NULL;
+ int nCounter = 0;
+ int i, j, k;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* load the expected results */
+ resultsFile = fopen("expectedresults.txt", "r");
+ memset (results, 0, 20);
+ fgets(results, 20, resultsFile);
+ fclose(resultsFile);
+
+ nCounter = 0;
+
+ /* create the src_existing file */
+ tempFile = fopen(lpSource[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "CopyFileW test file: src_existing.tmp\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Fail("CopyFileW: ERROR-> Couldn't create \"src_existing.tmp\"\n");
+ }
+
+ /* create the dst_existing file */
+ tempFile = fopen(lpDestination[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "CopyFileW test file: dst_existing.tmp\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Fail("CopyFileW: ERROR-> Couldn't create \"dst_existing.tmp\"\n");
+ }
+
+
+ /* lpSource loop */
+ for (i = 0; i < 2; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 2; j++)
+ {
+ /* bFailIfExists loop */
+ for (k = 0; k < 2; k++)
+ {
+ wcSource = convert(lpSource[i]);
+ wcDest = convert(lpDestination[j]);
+ bRc = CopyFileW(wcSource,
+ wcDest,
+ bFailIfExists[k]);
+ free(wcSource);
+ free(wcDest);
+ if (!bRc)
+ {
+ if (results[nCounter] == '1')
+ {
+ Trace("CopyFileW: FAILED: test[%d][%d][%d]\n", i, j, k);
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ if (results[nCounter] == '0')
+ {
+ Trace("CopyFileW: FAILED: test[%d][%d][%d]\n", i, j, k);
+ bSuccess = FALSE;
+ }
+ else
+ {
+ /* verify the file was moved */
+ if (GetFileAttributesA(lpDestination[j]) == -1)
+ {
+ Trace("CopyFileW: GetFileAttributes of destination"
+ "file failed on test[%d][%d][%d] with error "
+ "code %ld. \n",i,j,k,GetLastError());
+ bSuccess = FALSE;
+ }
+ else if (GetFileAttributesA(lpSource[i]) == -1)
+ {
+ Trace("CopyFileW: GetFileAttributes of source file "
+ "file failed on test[%d][%d][%d] with error "
+ "code %ld. \n",i,j,k,GetLastError());
+ bSuccess = FALSE;
+ }
+ else
+ {
+ /* verify attributes of destination file to
+ source file*/
+ if(GetFileAttributes(lpSource[i]) !=
+ GetFileAttributes(lpDestination[j]))
+ {
+ Trace("CopyFileW : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file on test "
+ "[%d][%d][%d].\n",i,j,k);
+ bSuccess = FALSE;
+ }
+ }
+ }
+
+ }
+ nCounter++;
+ /* delete file file but don't worry if it fails */
+ DeleteFileA(lpDestination[1]);
+ }
+ }
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/ExpectedResults.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test1/ExpectedResults.txt
new file mode 100644
index 0000000000..535a89fe50
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/ExpectedResults.txt
@@ -0,0 +1 @@
+10110000 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..b7ff6de2fd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CopyFileW
+Name = Tests CopyFileW functionality.
+Type = DEFAULT
+EXE1 = copyfilew
+Description
+= Test the CopyFileW function
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..5c0030bc8d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_copyfilew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilew_test2 coreclrpal)
+
+target_link_libraries(paltest_copyfilew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c b/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c
new file mode 100644
index 0000000000..5380a181ca
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c
@@ -0,0 +1,124 @@
+// 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: test2.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileW function
+** Attempt to copy a file to itself
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ LPSTR szSrcExisting = "src_existing.tmp";
+ WCHAR* wcSource;
+ BOOL bRc = TRUE;
+ FILE* tempFile = NULL;
+ DWORD temp;
+ int retCode;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the src_existing file */
+ tempFile = fopen(szSrcExisting, "w");
+ if (tempFile != NULL)
+ {
+ retCode = fputs("CopyFileA test file: src_existing.tmp ", tempFile);
+ if(retCode < 0)
+ {
+ Fail("CopyFileW: ERROR-> Couldn't write to %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+ retCode = fclose(tempFile);
+ if(retCode != 0)
+ {
+ Fail("CopyFileW: ERROR-> Couldn't close file: %s with error "
+ "%u.\n", szSrcExisting, GetLastError());
+ }
+ }
+ else
+ {
+ Fail("CopyFileW: ERROR-> Couldn't create %s.\n", szSrcExisting);
+ }
+
+ /* convert source string to wide character */
+ wcSource = convert(szSrcExisting);
+
+ /* Get file attributes of source */
+ temp = GetFileAttributes(szSrcExisting);
+ if (temp == -1)
+ {
+ free(wcSource);
+ Fail("CopyFileW: GetFileAttributes of source file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+
+ /* make sure a file can't copy to itself
+ first testing with IfFileExists flag set to true */
+ bRc = CopyFileW(wcSource,wcSource,TRUE);
+ if(bRc)
+ {
+ free(wcSource);
+ Fail("ERROR: Cannot copy a file to itself, %u",GetLastError());
+ }
+
+ /* try to get file attributes of desitnation */
+ if (GetFileAttributesA(szSrcExisting) == -1)
+ {
+ free(wcSource);
+ Fail("CopyFileW: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+ else
+ {
+ /* verify attributes of destination file to source file*/
+ if(temp != GetFileAttributes(szSrcExisting))
+ {
+ free(wcSource);
+ Fail("CopyFileW : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ }
+ }
+
+ /* testing with IfFileExists flags set to false
+ should fail in Windows and pass in UNIX */
+ bRc = CopyFileW(wcSource,wcSource,FALSE);
+ free(wcSource);
+ if(bRc && (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Fail("ERROR: Cannot copy a file to itself, %u",GetLastError());
+ }
+
+ if (GetFileAttributesA(szSrcExisting) == -1)
+ {
+ Fail("CopyFileW: GetFileAttributes of destination file "
+ "failed with error code %ld. \n",
+ GetLastError());
+ }
+ else
+ {
+ /* verify attributes of destination file to source file*/
+
+ if(temp != GetFileAttributes(szSrcExisting))
+ {
+ Fail("CopyFileW : The file attributes of the "
+ "destination file do not match the file "
+ "attributes of the source file.\n");
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileW/test2/testinfo.dat
new file mode 100644
index 0000000000..7e1591dd72
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test2/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 = CopyFileW
+Name = Tests CopyFileW to check if file can be copied to itself. (test2)
+Type = DEFAULT
+EXE1 = test2
+Description
+= Test the CopyFileW function
+= to see the effect of copying a
+= file to itself.
+
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt
new file mode 100644
index 0000000000..52d9aad1c0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_copyfilew_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_copyfilew_test3 coreclrpal)
+
+target_link_libraries(paltest_copyfilew_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c b/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c
new file mode 100644
index 0000000000..a2eb04c443
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c
@@ -0,0 +1,196 @@
+// 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: test4.c
+**
+** Purpose: Tests the PAL implementation of the CopyFileW function
+** to see if a file can through different users belonging to
+** different groups.
+**
+
+=====================================================================*/
+
+/* USECASE
+ Copy a file from a different user, belonging to a different group to
+ the the current user, who is a member of the current group. Then check
+ to see that the current user has the basic access rights to the copied
+ file.
+
+ Thie original file used is the passwd file in the etc directory of a
+ BSD machine. This file should exist on all machines.
+*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+ return PASS;
+
+#else
+
+ BOOL bRc = TRUE;
+ WCHAR szSrcExisting[] = {'/','e','t','c','/','p','a','s','s','w','d','\0'};
+ WCHAR szDest[] = {'t','e','m','p','.','t','m','p','\0'};
+ WCHAR szStringTest[] = {'M','a','r','r','y',' ','h','a','d',' ','a',' ',
+ 'l','i','t','t','l','e',' ','l','a','m','b','\0'};
+ WCHAR szStringRead[30]; /* large enough for string szStringTest */
+
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten=0;
+ DWORD dwBytesRead=0;
+ int size=0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* copy the file */
+ bRc = CopyFileW(szSrcExisting,szDest,TRUE);
+ if(!bRc)
+ {
+ Fail("CopyFileW: Cannot copy a file with error, %u",GetLastError());
+ }
+
+ /* try to get file attributes of destination file */
+ if (GetFileAttributesW(szDest) == -1)
+ {
+ Fail("CopyFileW: GetFileAttributes of destination file "
+ "failed with error code %u. \n",
+ GetLastError());
+ }
+
+ /* set the attributes of the destination file to normal again */
+ bRc = SetFileAttributesW(szDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Fail("CopyFileW: ERROR-> Couldn't set file attributes for "
+ "file %S with error %u\n", szDest, GetLastError());
+ }
+
+ /* open the file for write purposes */
+ hFile = CreateFileW((WCHAR *)szDest,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("CopyFileW: ERROR -> Unable to create file \"%S\".\n",
+ szDest);
+ }
+
+ /* To account for the size of a WCHAR is twice that of a char */
+ size = wcslen(szStringTest);
+ size = size*sizeof(WCHAR);
+
+ /* Attempt to write to the file */
+ bRc = WriteFile(hFile,
+ szStringTest,
+ size,
+ &dwBytesWritten,
+ NULL);
+
+ if (!bRc)
+ {
+ Trace("CopyFileW: ERROR -> Unable to write to copied file with error "
+ "%u.\n", GetLastError());
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileW: ERROR -> Unable to close file \"%S\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+
+ }
+
+ /* Close the file handle */
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileW: ERROR -> Unable to close file \"%S\" with error %u "
+ ".\n",szDest,GetLastError());
+ }
+
+
+ /* open the file for read purposes */
+ hFile = CreateFileW((WCHAR *)szDest,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("CopyFileW: ERROR -> Unable to create file \"%S\".\n",
+ szDest);
+ }
+
+ /* Attempt to read from the file */
+ bRc = ReadFile(hFile,
+ szStringRead,
+ size,
+ &dwBytesRead,
+ NULL);
+
+ if (!bRc)
+ {
+ Trace("CopyFileW: ERROR -> Unable to read from copied file with "
+ "error %u.\n",GetLastError());
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileW: ERROR -> Unable to close file \"%S\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+
+ }
+
+ if(wcsncmp(szStringTest,szStringRead, wcslen(szStringTest)) != 0)
+ {
+ Trace("CopyFileW: ERROR -> The string which was written '%S' does not "
+ "match the string '%S' which was read from the copied file.\n",
+ szStringTest,szStringRead);
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileW: ERROR -> Unable to close file \"%S\" with "
+ "error %u.\n",szDest, GetLastError());
+ }
+ Fail("");
+ }
+
+ /* Close the file handle */
+ bRc = CloseHandle(hFile);
+ if (!bRc)
+ {
+ Fail("CopyFileW: ERROR -> Unable to close file \"%S\" with error %u "
+ ".\n",szDest,GetLastError());
+ }
+
+ /* Remove the temporary file */
+ bRc = DeleteFileW(szDest);
+ if(!bRc)
+ {
+ Fail("CopyFileW: Could not remove copied file with error %u.\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+
+}
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/CopyFileW/test3/testinfo.dat
new file mode 100644
index 0000000000..9fd185dad0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test3/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 = CopyFileW
+Name = CopyFileW - checking file attributes maintained (test3)
+Type = DEFAULT
+EXE1 = test3
+Description
+= Copy a file from a different user, belonging to a different group to
+= the the current user, who is a member of the current group. Then check
+= to see that the current user has the basic access rights to the copied
+= file.
+
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryA/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..f8cdf19933
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CreateDirectoryA.c
+)
+
+add_executable(paltest_createdirectorya_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createdirectorya_test1 coreclrpal)
+
+target_link_libraries(paltest_createdirectorya_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c
new file mode 100644
index 0000000000..2bb441e732
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c
@@ -0,0 +1,296 @@
+// 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: CreateDirectoryA.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryA function.
+**
+** Depends on:
+** RemoveDirectoryW (since RemoveDirectoryA is unavailable)
+** GetCurrentDirectoryA
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+/* apparently, under WIN32 the max path size is 248 but under
+ BSD it is _MAX_PATH */
+#if WIN32
+#define CREATE_MAX_PATH_SIZE 248
+#else
+#define CREATE_MAX_PATH_SIZE _MAX_PATH
+#endif
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char* szTestDir = {"test_directory"};
+ const char* szDotDir = {".dotDirectory"};
+ BOOL bRc = FALSE;
+ BOOL bSuccess = FALSE;
+ const int buf_size = CREATE_MAX_PATH_SIZE + 10;
+ char szDirName[CREATE_MAX_PATH_SIZE + 10];
+ char buffer[CREATE_MAX_PATH_SIZE + 10];
+ WCHAR* pTemp = NULL;
+ DWORD curDirLen;
+ DWORD curDirectory = 1024;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* directory does not exist */
+ bRc = CreateDirectoryA(szTestDir, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
+ szTestDir,
+ GetLastError());
+ }
+
+
+ /* directory exists should fail */
+ bRc = CreateDirectoryA(szTestDir, NULL);
+ if (bRc == TRUE)
+ {
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("CreateDirectoryA: Succeeded creating the directory"
+ "\"%s\" when it exists already.\n",
+ szTestDir);
+ }
+ else
+ {
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ }
+
+
+ /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
+ and CREATE_MAX_PATH_SIZE + 1 characters
+ including terminating null char) */
+
+ curDirLen = GetCurrentDirectoryA(0, NULL);
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory"
+ " name %d chars long with the error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* Set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert((LPSTR)szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory"
+ " name %d chars long with error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* Set Directroy back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc != FALSE)
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
+ {
+ Fail("CreateDirectoryA: Failed because it created a directory"
+ " name 1 character longer (%d chars) than the max dir size "
+ "allowed\n",
+ strlen(szDirName));
+ }
+ }
+
+
+ /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
+ (real path length <= CREATE_MAX_PATH_SIZE) */
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
+ szDirName[0] = '.';
+ szDirName[1] = '.';
+ szDirName[2] = '\\';
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory name more "
+ "than %d chars long and its real path name is less "
+ "than %d chars, error %u\n",
+ CREATE_MAX_PATH_SIZE,
+ CREATE_MAX_PATH_SIZE, GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ " \"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+
+ /* directories with dots */
+ memset(szDirName, 0, buf_size);
+ sprintf(szDirName, szDotDir);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
+ szDotDir,
+ GetLastError());
+ }
+ else
+ {
+
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert((LPSTR)szDotDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ " \"%s\" with the error code %ld.\n",
+ szDotDir,
+ GetLastError());
+ }
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/testinfo.dat
new file mode 100644
index 0000000000..562d76d7be
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CreateDirectoryA
+Name = Test for CreateDirectoryA
+Type = DEFAULT
+EXE1 = createdirectorya
+Description
+= Create a directory that exists (should fail) and create
+= a directory that doesn't exist and verify results.
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..a50a986d1a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ createdirectorya.c
+)
+
+add_executable(paltest_createdirectorya_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createdirectorya_test2 coreclrpal)
+
+target_link_libraries(paltest_createdirectorya_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c
new file mode 100644
index 0000000000..fc1bc967b7
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c
@@ -0,0 +1,335 @@
+// 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: createdirectorya.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryA function.
+** Test creating a directory in a directory path that does not exist.
+** Test creating directory with trailing slashes.
+**
+** Depends on:
+** RemoveDirectoryW (since RemoveDirectoryA is unavailable)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+
+int main(int argc, char *argv[])
+{
+
+#if WIN32
+ const char* szTestRootDir = {"/at_root_directory_PALTEST"};
+#endif
+
+ const char* szTestDir = {"test_ directory"};
+ const char* szTestSubDir =
+ {".\\./././../test2/./../../////////createdirectorya"
+ "\\\\/test2/test_ directory\\sub"};
+ const char* szTest2SubDir = {"test_ directory/sub\\sub_sub"};
+ const char* szTest2SubDirWinSlash =
+ {"test_ directory/sub\\sub_sub\\"};
+ const char* szTest2SubDirUnixSlash =
+ {"test_ directory/sub\\sub_sub/////"};
+ BOOL bRc = FALSE;
+ BOOL clean = TRUE;
+ WCHAR* pTemp = NULL;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* platform dependent cases */
+ /* test for WIN32, create directory at the root."
+ * using '/directory_name ' format */
+#if WIN32
+
+ bRc = CreateDirectoryA(szTestRootDir, NULL);
+
+ if (bRc != TRUE)
+ {
+ Fail("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n",
+ szTestRootDir,GetLastError());
+ }
+
+ /* clean szTestRootDir */
+ pTemp = convert((LPSTR) szTestRootDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean=bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestRootDir,
+ GetLastError());
+ }
+
+#endif
+
+
+ /*
+ * create subdirectory "test_directory//sub//sub_sub"
+ * while parent directory does not exist.
+ */
+ bRc = CreateDirectoryA(szTest2SubDir, NULL);
+ if (bRc == TRUE)
+ {
+ pTemp = convert((LPSTR)szTest2SubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDir,
+ GetLastError());
+ }
+ Fail("CreateDirectoryA: Succeeded creating the directory\"%s\" while"
+ " its parent directory does not exists. It should fail.\n",
+ szTest2SubDir);
+
+ }
+
+
+ /* create directory tree one by one
+ * first create "test_dir"
+ */
+ bRc = CreateDirectoryA(szTestDir, NULL);
+
+ if (bRc != TRUE)/*failed creating the path*/
+ {
+ Fail("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n", szTestDir,GetLastError());
+ }
+
+ /* create the sub directory test_directory//sub */
+ bRc = CreateDirectoryA(szTestSubDir, NULL);
+
+ if (bRc != TRUE)/*failed creating the path*/
+ {
+ Trace("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n",
+ szTestSubDir , GetLastError());
+
+ /* cleaning... remove parent directory */
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with an error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub"
+ */
+ bRc = CreateDirectoryA(szTest2SubDir, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDir , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ pTemp = convert((LPSTR)szTestSubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("");
+
+ }
+
+ /* RemoveDirectiryW szTest2SubDir */
+ pTemp = convert((LPSTR)szTest2SubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean=bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDir,
+ GetLastError());
+ }
+
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub\\"
+ */
+ bRc = CreateDirectoryA(szTest2SubDirWinSlash, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDirWinSlash , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ pTemp = convert((LPSTR)szTestSubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("");
+
+ }
+
+ /* RemoveDirectiryW szTest2SubDirWinSlash */
+ pTemp = convert((LPSTR)szTest2SubDirWinSlash);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean=bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDirWinSlash,
+ GetLastError());
+ }
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub/////"
+ */
+ bRc = CreateDirectoryA(szTest2SubDirUnixSlash, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryA: Failed creating the directory "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDirUnixSlash , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ pTemp = convert((LPSTR)szTestSubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("");
+
+ }
+
+ /* RemoveDirectiryW will return false if directory does not exist.
+ * if it returns true then test is completed and the directory path
+ * is clean for running the test again.
+ */
+ pTemp = convert((LPSTR)szTest2SubDirUnixSlash);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean=bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTest2SubDirUnixSlash,
+ GetLastError());
+ }
+
+
+
+
+ /*clean parent szTestSubDir */
+ pTemp = convert((LPSTR)szTestSubDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /*clean parent szTestDir */
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+
+ if(! clean)
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/testinfo.dat
new file mode 100644
index 0000000000..1e2ae774da
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CreateDirectoryA
+Name = Test for CreateDirectoryA
+Type = DEFAULT
+EXE1 = createdirectorya
+Description
+= Call CreateDirectoryA with a path in which more than just
+= the last component doesn't exist.
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryW/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..1981e37082
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CreateDirectoryW.c
+)
+
+add_executable(paltest_createdirectoryw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createdirectoryw_test1 coreclrpal)
+
+target_link_libraries(paltest_createdirectoryw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c
new file mode 100644
index 0000000000..9b020cc19c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c
@@ -0,0 +1,347 @@
+// 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: CreateDirectoryW.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+/* apparently, under WIN32 the max path size is 248 but under
+ BSD it is _MAX_PATH */
+#if WIN32
+#define CREATE_MAX_PATH_SIZE 248
+#else
+#define CREATE_MAX_PATH_SIZE _MAX_PATH
+#endif
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ BOOL bSuccess = FALSE;
+ const int buf_size = CREATE_MAX_PATH_SIZE + 10;
+ char szDirName[CREATE_MAX_PATH_SIZE + 10];
+ char buffer[CREATE_MAX_PATH_SIZE + 10];
+ WCHAR* pTemp = NULL;
+ DWORD curDirLen;
+ DWORD curDirectory = 1024;
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* directory does not exist */
+ pTemp = convert("test_directory");
+ bRc = CreateDirectoryW(pTemp, NULL);
+ free(pTemp);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryW: Failed to create \"test_directory\"\n");
+ }
+
+ /* directory exists */
+ pTemp = convert("test_directory");
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == TRUE)
+ {
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("CreateDirectoryW: Succeeded creating the directory"
+ " \"test_directory\" when it exists already.\n");
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+
+ /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
+ and CREATE_MAX_PATH_SIZE + 1 characters
+ including terminating null char) */
+
+ curDirLen = GetCurrentDirectoryA(0, NULL);
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
+ pTemp = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory"
+ " name (%d) chars long with the error code %ld\n",
+ CREATE_MAX_PATH_SIZE - 1,
+ GetLastError());
+ }
+ else
+ {
+
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory"
+ " name %d chars long with error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+
+ if (bRc != FALSE)
+ {
+ RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed because it created a directory"
+ " name 1 character longer (%d chars) than the max dir size"
+ " allowed\n",
+ strlen(szDirName));
+ }
+ }
+
+ free(pTemp);
+
+ /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
+ (real path length <= CREATE_MAX_PATH_SIZE) */
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
+ szDirName[0] = '.';
+ szDirName[1] = '.';
+ szDirName[2] = '\\';
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory name more "
+ "than %d chars long and its real path name is less "
+ "than %d chars\n",
+ CREATE_MAX_PATH_SIZE,
+ CREATE_MAX_PATH_SIZE);
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ /* directories with dots */
+ memset(szDirName, 0, 252);
+ sprintf(szDirName, ".dotDirectory");
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a dot directory\n");
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/testinfo.dat
new file mode 100644
index 0000000000..bc664892b4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = CreateDirectoryW
+Name = Positive Test for CreateDirectoryW
+Type = DEFAULT
+EXE1 = createdirectoryw
+Description
+= Test the CreateDirctoryW function
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..aae4e7dc54
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ createdirectoryw.c
+)
+
+add_executable(paltest_createdirectoryw_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createdirectoryw_test2 coreclrpal)
+
+target_link_libraries(paltest_createdirectoryw_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c
new file mode 100644
index 0000000000..20fac5a879
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c
@@ -0,0 +1,345 @@
+// 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: createdirectoryw.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryW function.
+** Test creating a directory in a directory path that does not exist.
+** Test creating directory with trailing slashes.
+**
+** Depends on:
+** RemoveDirectoryW.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+#if WIN32
+WCHAR* szTestRootDir = NULL;
+#endif
+
+WCHAR* szTestDir = NULL;
+WCHAR* szTestSubDir = NULL;
+WCHAR* szTest2SubDir = NULL;
+WCHAR* szTest2SubDirWinSlash = NULL;
+WCHAR* szTest2SubDirUnixSlash = NULL;
+
+
+/* Free the memory allocated by convert(...) function*/
+static void CleanMemory(){
+
+#if WIN32
+ free(szTestRootDir);
+#endif
+
+ free( szTestDir);
+ free( szTestSubDir);
+ free( szTest2SubDir);
+ free( szTest2SubDirWinSlash);
+ free( szTest2SubDirUnixSlash);
+
+}
+
+
+int main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ BOOL clean = TRUE;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* initialize strings */
+
+#if WIN32
+ szTestRootDir = convert("/at_root_directory_PALTEST");
+#endif
+
+ szTestDir = convert("test_ directory");
+ szTestSubDir = convert(
+ ".\\./././../test2/./../../////////createdirectoryw"
+ "\\\\/test2/test_ directory\\sub");
+ szTest2SubDir = convert("test_ directory/sub\\sub_sub");
+ szTest2SubDirWinSlash = convert("test_ directory/sub\\sub_sub\\\\");
+ szTest2SubDirUnixSlash = convert("test_ directory/sub\\sub_sub///");
+
+
+ /* Platform dependent cases:-
+ * test for WIN32, create directory at the root.
+ * using /directory_name format
+ */
+#if WIN32
+
+ bRc = CreateDirectoryW(szTestRootDir, NULL);
+
+ if (bRc != TRUE)
+ {
+
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n",
+ szTestRootDir,GetLastError());
+ CleanMemory();
+ Fail("");
+ }
+
+ /*clean szTestRootDir */
+ bRc = RemoveDirectoryW(szTestRootDir);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestRootDir,
+ GetLastError());
+ }
+
+#endif
+
+
+ /*
+ * create subdirectory "test_directory//sub//sub_sub"
+ * while parent directory does not exist.
+ */
+ bRc = CreateDirectoryW(szTest2SubDir, NULL);
+ if (bRc == TRUE)
+ {
+ bRc = RemoveDirectoryW(szTest2SubDir);
+
+ if (! bRc )
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDir,
+ GetLastError());
+ }
+
+ Trace("CreateDirectoryW: Succeeded creating the directory\"%S\" while"
+ " its parent directory does not exists. It should fail.\n",
+ szTest2SubDir);
+ CleanMemory();
+ Fail("");
+
+ }
+
+
+ /* create directory tree one by one
+ * first create "test_dir"
+ */
+ bRc = CreateDirectoryW(szTestDir, NULL);
+
+
+ if (bRc != TRUE)/*failed creating the path*/
+ {
+
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n", szTestDir,GetLastError());
+ CleanMemory();
+ Fail("");
+ }
+
+ /* create the sub directory test_directory//sub */
+ bRc = CreateDirectoryW(szTestSubDir, NULL);
+
+ if (bRc != TRUE)/*failed creating the path*/
+ {
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n",
+ szTestSubDir , GetLastError());
+
+ /* cleaning... remove parent directory */
+ bRc = RemoveDirectoryW(szTestDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with an error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ CleanMemory();
+ Fail("");
+ }
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub"
+ */
+ bRc = CreateDirectoryW(szTest2SubDir, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDir , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ bRc = RemoveDirectoryW(szTestSubDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ bRc = RemoveDirectoryW(szTestDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ CleanMemory();
+ Fail("");
+
+ }
+
+ /* Remove Directiry szTest2SubDir*/
+ bRc = RemoveDirectoryW(szTest2SubDir);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDir,
+ GetLastError());
+ }
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub\\\\"
+ */
+ bRc = CreateDirectoryW(szTest2SubDirWinSlash, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDirWinSlash , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ bRc = RemoveDirectoryW(szTestSubDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ bRc = RemoveDirectoryW(szTestDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ CleanMemory();
+ Fail("");
+
+ }
+
+ /* Remove Directiry szTest2SubDirWinSlash */
+ bRc = RemoveDirectoryW(szTest2SubDirWinSlash);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDirWinSlash,
+ GetLastError());
+ }
+
+ /*
+ * the director structure is test_directory//sub
+ * test creating directory " test_directory//sub//sub_sub///"
+ */
+ bRc = CreateDirectoryW(szTest2SubDirUnixSlash, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("CreateDirectoryW: Failed creating the directory "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDirUnixSlash , GetLastError());
+
+ /* remove parent directory test_directory//sub */
+ bRc = RemoveDirectoryW(szTestSubDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /* remove parent directory test_directory */
+ bRc = RemoveDirectoryW(szTestDir);
+ if (! bRc)
+ {
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ CleanMemory();
+ Fail("");
+
+ }
+
+ /* Remove Directiry szTest2SubDirUnixSlash.*/
+ bRc = RemoveDirectoryW(szTest2SubDirUnixSlash);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTest2SubDirUnixSlash,
+ GetLastError());
+ }
+
+ /*clean parent szTestSubDir */
+ bRc = RemoveDirectoryW(szTestSubDir);
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestSubDir,
+ GetLastError());
+ }
+
+ /*clean parent szTestDir */
+ bRc = RemoveDirectoryW(szTestDir);
+
+
+ if (! bRc)
+ {
+ clean = bRc;
+ Trace("CreateDirectoryW: RemoveDirectoryW failed to remove "
+ "\"%S\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+
+ if(! clean)
+ {
+ CleanMemory();
+ Fail("");
+ }
+
+ CleanMemory();
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/testinfo.dat
new file mode 100644
index 0000000000..0d98a5f3b6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CreateDirectoryW
+Name = Test for CreateDirectoryW
+Type = DEFAULT
+EXE1 = createdirectoryW
+Description
+= Call CreateDirectoryW with a path in which more than just
+= the last component doesn't exist.
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..8814b2281b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CreateFileA.c
+)
+
+add_executable(paltest_createfilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createfilea_test1 coreclrpal)
+
+target_link_libraries(paltest_createfilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c
new file mode 100644
index 0000000000..a70867a5c8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c
@@ -0,0 +1,145 @@
+// 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: CreateFileA.c
+**
+** Purpose: Test the PAL implementation of the CreateFileA function
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+BOOL Cleanup(void)
+{
+ char FileName[20];
+ int i;
+ BOOL bRet = TRUE; // assume success
+
+ // loop through all accesses, modes, dispositions and flags
+ for (i=0; i<4*8*4*5; ++i) {
+ sprintf(FileName, "test%03d.txt", i);
+ if (DeleteFileA(FileName) == FALSE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bSuccess = TRUE;
+ int nCounter = 0;
+ HANDLE hFile;
+ char lpFileName[20];
+ FILE *outFile = NULL;
+ char results[1024];
+ int i, j, k, l;
+ DWORD dwDesiredAccess[4] = {0, // 0
+ GENERIC_READ, // 1
+ GENERIC_WRITE, // 2
+ GENERIC_READ | GENERIC_WRITE}; // 3
+ DWORD dwShareMode[8] = {0, // 0
+ FILE_SHARE_READ, // 1
+ FILE_SHARE_WRITE, // 2
+ FILE_SHARE_DELETE, // 3
+ FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
+ FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
+ FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
+ LPSECURITY_ATTRIBUTES lpAttr = NULL;
+ DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
+ CREATE_ALWAYS, // 1
+ OPEN_EXISTING, // 2
+ OPEN_ALWAYS}; // 3
+ DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
+ FILE_FLAG_SEQUENTIAL_SCAN, // 1
+ FILE_FLAG_WRITE_THROUGH, // 2
+ FILE_FLAG_NO_BUFFERING, // 3
+ FILE_FLAG_RANDOM_ACCESS}; // 4
+ HANDLE hTemplate = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if (!Cleanup()) {
+ Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ /* open the file to read the expected results */
+ outFile = fopen("winoutput", "r");
+ memset (results, 0, 1024);
+
+ fgets(results, 1024, outFile);
+ nCounter = (int)strlen(results);
+ fclose(outFile);
+
+ nCounter = 0;
+
+ // desired access loop
+ for (i = 0; i < 4; i++)
+ {
+ // share mode loop
+ for (j = 0; j < 8; j++)
+ {
+ // security attributes loop
+ for (k = 0; k < 4; k++)
+ {
+ // creation disp loop
+ for (l = 0; l < 5; l++)
+ {
+ sprintf(lpFileName, "test%03d.txt", nCounter);
+ hFile = CreateFile(lpFileName,
+ dwDesiredAccess[i],
+ dwShareMode[j],
+ lpAttr,
+ dwCreationDisp[k],
+ dwFlagsAttrib[l],
+ hTemplate);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ if (results[nCounter] == '1')
+ {
+ Trace("CreateFile: ERROR: Failed when expected "
+ "to pass %s [%d][%d][%d][%d]\n",
+ lpFileName, i, j, k, l);
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ if (results[nCounter] == '0')
+ {
+ Trace("CreateFile: ERROR: Passed when expected "
+ "to fail %s [%d][%d][%d][%d]\n",
+ lpFileName, i, j, k, l);
+ bSuccess = FALSE;
+ }
+ }
+ nCounter ++;
+ }
+ }
+ }
+ }
+
+ if (!Cleanup())
+ {
+ Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..bb872806eb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CreateFileA
+Name = test for CreateFileA
+Type = DEFAULT
+EXE1 = createfilea
+Description
+= Attempts to create files based on all combinations of
+= options of CreateFileA
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/winoutput b/src/pal/tests/palsuite/file_io/CreateFileA/test1/winoutput
new file mode 100644
index 0000000000..3913b99427
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/winoutput
@@ -0,0 +1 @@
+1111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..1ff0b8062f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ CreateFileW.c
+)
+
+add_executable(paltest_createfilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_createfilew_test1 coreclrpal)
+
+target_link_libraries(paltest_createfilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c
new file mode 100644
index 0000000000..4d7d20af29
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c
@@ -0,0 +1,152 @@
+// 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: CreateFileW.c
+**
+** Purpose: Test the PAL implementation of the CreateFileW function
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+BOOL Cleanup(void)
+{
+ char FileName[20];
+ int i;
+ BOOL bRet = TRUE; // assume success
+
+ // loop through all accesses, modes, dispositions and flags
+ for (i=0; i<4*8*4*5; ++i) {
+ sprintf(FileName, "test%03d.txt", i);
+ if (DeleteFileA(FileName) == FALSE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bSuccess = TRUE;
+ int nCounter = 0;
+ HANDLE hFile = NULL;
+ WCHAR *lpFileName = NULL;
+ char* pTemp = NULL;
+ char string[40];
+ FILE *outFile = NULL;
+ char results[1024];
+ int i, j, k, l;
+ DWORD dwDesiredAccess[4] = {0, // 0
+ GENERIC_READ, // 1
+ GENERIC_WRITE, // 2
+ GENERIC_READ | GENERIC_WRITE}; // 3
+ DWORD dwShareMode[8] = {0, // 0
+ FILE_SHARE_READ, // 1
+ FILE_SHARE_WRITE, // 2
+ FILE_SHARE_DELETE, // 3
+ FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
+ FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
+ FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
+ LPSECURITY_ATTRIBUTES lpAttr = NULL;
+ DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
+ CREATE_ALWAYS, // 1
+ OPEN_EXISTING, // 2
+ OPEN_ALWAYS}; // 3
+ DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
+ FILE_FLAG_SEQUENTIAL_SCAN, // 1
+ FILE_FLAG_WRITE_THROUGH, // 2
+ FILE_FLAG_NO_BUFFERING, // 3
+ FILE_FLAG_RANDOM_ACCESS}; // 4
+ HANDLE hTemplate = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if (!Cleanup()) {
+ Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ /* open the file to read the expected results */
+ outFile = fopen("winoutput", "r");
+ memset (results, 0, 1024);
+
+ fgets(results, 1024, outFile);
+ fclose(outFile);
+
+ nCounter = 0;
+
+ // desired access loop
+ for (i = 0; i < 4; i++)
+ {
+ // share mode loop
+ for (j = 0; j < 8; j++)
+ {
+ // security attributes loop
+ for (k = 0; k < 4; k++)
+ {
+ // creation disp loop
+ for (l = 0; l < 5; l++)
+ {
+ sprintf(string, "test%03d.txt", nCounter);
+ lpFileName = convert(string);
+ hFile = CreateFileW(lpFileName,
+ dwDesiredAccess[i],
+ dwShareMode[j],
+ lpAttr,
+ dwCreationDisp[k],
+ dwFlagsAttrib[l],
+ hTemplate);
+ free(lpFileName);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ if (results[nCounter] == '1')
+ {
+ pTemp = convertC(lpFileName);
+ Trace("CreateFile: ERROR: Failed when expected "
+ "to pass %s [%d][%d][%d][%d]\n",
+ pTemp, i, j, k, l);
+ free(pTemp);
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ if (results[nCounter] == '0')
+ {
+ pTemp = convertC(lpFileName);
+ Trace("CreateFile: ERROR: Passed when expected "
+ "to fail %s [%d][%d][%d][%d]\n",
+ pTemp, i, j, k, l);
+ free(pTemp);
+ bSuccess = FALSE;
+ }
+ }
+ nCounter ++;
+ }
+ }
+ }
+ }
+
+ if (!Cleanup())
+ {
+ Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/CreateFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..2dbf159996
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = CreateFileW
+Name = test for CreateFileW
+Type = DEFAULT
+EXE1 = createfilew
+Description
+= Attempts to create files based on all combinations of
+= options of CreateFileW
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/winoutput b/src/pal/tests/palsuite/file_io/CreateFileW/test1/winoutput
new file mode 100644
index 0000000000..3913b99427
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/winoutput
@@ -0,0 +1 @@
+1111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111111111111100000111111111111111000001111111111111110000011111 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b979c206b2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ DeleteFileA.cpp
+)
+
+add_executable(paltest_deletefilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_deletefilea_test1 coreclrpal)
+
+target_link_libraries(paltest_deletefilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp
new file mode 100644
index 0000000000..a8eb71decb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp
@@ -0,0 +1,182 @@
+// 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: DeleteFileA.c
+**
+** Purpose: Tests the PAL implementation of the DeleteFileA function.
+**
+**
+**===================================================================*/
+
+// delete an existing file
+// delete a non-existant file
+// delete an open file
+// delete files using wild cards
+// delete a hidden file
+// delete a file without proper permissions
+//
+
+#define PAL_STDCPP_COMPAT
+#include <palsuite.h>
+#undef PAL_STDCPP_COMPAT
+
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ FILE *tempFile = NULL;
+ BOOL bRc = FALSE;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ //
+ // create a test file
+ //
+ tempFile = fopen("testFile01.txt", "w");
+ if (tempFile == NULL)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't create \"DeleteFileA's"
+ " testFile01.txt\"\n");
+ }
+
+ fprintf(tempFile, "DeleteFileA test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileA's"
+ " testFile01.txt\"\n");
+ }
+
+ //
+ // delete a symlink to an existing file
+ //
+ if (symlink("testFile01.txt", "testFile01_symlink") != 0)
+ {
+ Fail("DeleteFileA: ERROR: Failed to create a symlink to testFile01.txt.\n");
+ }
+
+ bRc = DeleteFileA("testFile01_symlink");
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't delete symlink!\n Error is %d\n", GetLastError());
+ }
+
+ struct stat statBuffer;
+ if (lstat("testFile01.txt", &statBuffer) != 0)
+ {
+ Fail("DeleteFileA: ERROR: Deleting a symlink deleted the file it was pointing to.\n");
+ }
+
+ if (lstat("testFile01_symlink", &statBuffer) == 0)
+ {
+ Fail("DeleteFileA: ERROR: Failed to delete a symlink.\n");
+ }
+
+ //
+ // deleting an existing file
+ //
+ bRc = DeleteFileA("testFile01.txt");
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't delete DeleteFileA's"
+ " \"testFile01.txt\"\n"
+ " Error is %d\n", GetLastError());
+ }
+
+
+ //
+ // deleting a non-existant file : should fail
+ //
+
+ bRc = DeleteFileA("testFile02.txt");
+ if (bRc != FALSE)
+ {
+ Fail ("DeleteFileA: ERROR: Was able to delete the non-existant"
+ " file \"testFile02.txt\"\n");
+ }
+
+
+
+
+ //
+ // deleting an open file
+ //
+ tempFile = fopen("testFile03.txt", "w");
+ if (tempFile == NULL)
+ {
+ Fail("DeleteFileA: ERROR: Couldn't create \"DeleteFileA's"
+ " testFile03.txt\"\n");
+ }
+
+ fprintf(tempFile, "DeleteFileA test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileA's"
+ " testFile03.txt\"\n");
+ }
+
+ bRc = DeleteFileA("testFile03.txt");
+ if (bRc != TRUE)
+ {
+ Fail("DeleteFileA: ERROR: Couldn't delete DeleteFileA's"
+ " \"testFile03.txt\"\n"
+ " Error is %d\n", GetLastError());
+ }
+ bRc = DeleteFileA("testFile03.txt");
+
+
+
+
+ //
+ // delete using wild cards
+ //
+
+ // create the test file
+ tempFile = fopen("testFile04.txt", "w");
+ if (tempFile == NULL)
+ {
+ Fail("DeleteFileA: ERROR: Couldn't create DeleteFileA's"
+ " \"testFile04.txt\"\n");
+ }
+ fprintf(tempFile, "DeleteFileA test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileA's"
+ " testFile04.txt\"\n");
+ }
+
+ // delete using '?'
+ bRc = DeleteFileA("testFile0?.txt");
+ if (bRc == TRUE)
+ {
+ Fail("DeleteFileA: ERROR: Was able to delete using the"
+ " \'?\' wildcard\n");
+ }
+
+ // delete using '*'
+ bRc = DeleteFileA("testFile*.txt");
+ if (bRc == TRUE)
+ {
+ Fail("DeleteFileA: ERROR: Was able to delete using the"
+ " \'*\' wildcard\n");
+ }
+
+ bRc = DeleteFileA("testFile04.txt");
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't delete DeleteFileA's"
+ " \"testFile04.txt\"\n"
+ " Error is %d\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..24283ed932
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = DeleteFileA
+Name = Test for DeleteFileA (test 1)
+Type = DEFAULT
+EXE1 = deletefilea
+Description
+= Attempt to delete various files.
+
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..046fd35148
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ DeleteFileW.c
+)
+
+add_executable(paltest_deletefilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_deletefilew_test1 coreclrpal)
+
+target_link_libraries(paltest_deletefilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c
new file mode 100644
index 0000000000..fca96d1e00
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c
@@ -0,0 +1,164 @@
+// 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: DeleteFileW.c
+**
+** Purpose: Tests the PAL implementation of the DeleteFileW function.
+**
+**
+**===================================================================*/
+
+// delete an existing file
+// delete a non-existant file
+// delete an open file
+// delete files using wild cards
+// delete a hidden file
+// delete a file without proper permissions
+//
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ FILE *tempFile = NULL;
+ BOOL bRc = FALSE;
+ WCHAR* pTemp = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ //
+ // deleting an existing file
+ //
+ tempFile = fopen("testFile01.tmp", "w");
+ if (tempFile == NULL)
+ {
+ Fail ("DeleteFileW: ERROR: Couldn't create \"DeleteFileW's"
+ " testFile01.tmp\"\n");
+ }
+
+ fprintf(tempFile, "DeleteFileW test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileW's"
+ " testFile01.tmp\"\n");
+ }
+
+ pTemp = convert("testFile01.tmp");
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileW: ERROR: Couldn't delete DeleteFileW's"
+ " \"testFile01.tmp\"\n"
+ " Error is %d\n", GetLastError());
+ }
+
+
+ //
+ // deleting a non-existant file : should fail
+ //
+
+ pTemp = convert("testFile02.tmp");
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+ if (bRc != FALSE)
+ {
+ Fail ("DeleteFileW: ERROR: Was able to delete the non-existant"
+ " file \"testFile02.tmp\"\n");
+ }
+
+
+
+
+ //
+ // deleting an open file
+ //
+ tempFile = fopen("testFile03.tmp", "w");
+ if (tempFile == NULL)
+ {
+ Fail("DeleteFileW: ERROR: Couldn't create \"DeleteFileW's"
+ " testFile03.tmp\"\n");
+ }
+
+ fprintf(tempFile, "DeleteFileW test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileW's"
+ " testFile03.tmp\"\n");
+ }
+
+ pTemp = convert("testFile03.tmp");
+ bRc = DeleteFileW(pTemp);
+ if (bRc != TRUE)
+ {
+ Fail("DeleteFileW: ERROR: Couldn't delete DeleteFileW's"
+ " \"testFile03.tmp\"\n"
+ " Error is %d\n", GetLastError());
+ free(pTemp);
+ }
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+
+
+
+
+ //
+ // delete using wild cards
+ //
+
+ // create the test file
+ tempFile = fopen("testFile04.tmp", "w");
+ if (tempFile == NULL)
+ {
+ Fail("DeleteFileW: ERROR: Couldn't create DeleteFileW's"
+ " \"testFile04.tmp\"\n");
+ }
+ fprintf(tempFile, "DeleteFileW test file.\n");
+ if (fclose(tempFile) != 0)
+ {
+ Fail ("DeleteFileA: ERROR: Couldn't close \"DeleteFileW's"
+ " testFile04.tmp\"\n");
+ }
+
+ // delete using '?'
+ pTemp = convert("testFile0?.tmp");
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+ if (bRc == TRUE)
+ {
+ Fail("DeleteFileW: ERROR: Was able to delete using the"
+ " \'?\' wildcard\n");
+ }
+
+ // delete using '*'
+ pTemp = convert("testFile*.tmp");
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+ if (bRc == TRUE)
+ {
+ Fail("DeleteFileW: ERROR: Was able to delete using the"
+ " \'*\' wildcard\n");
+ }
+
+ pTemp = convert("testFile04.tmp");
+ bRc = DeleteFileW(pTemp);
+ free(pTemp);
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileW: ERROR: Couldn't delete DeleteFileW's"
+ " \"testFile04.tmp\"\n"
+ " Error is %d\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..db44f998fc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = DeleteFileW
+Name = Test for DeleteFileW (test 1)
+Type = DEFAULT
+EXE1 = deletefilew
+Description
+= Tests DeleteFileW on various file names
+
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt
new file mode 100644
index 0000000000..0c02c98f15
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FILECanonicalizePath.c
+)
+
+add_executable(paltest_filecanonicalizepath_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_filecanonicalizepath_test1 coreclrpal)
+
+target_link_libraries(paltest_filecanonicalizepath_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c
new file mode 100644
index 0000000000..91bac1f3cb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c
@@ -0,0 +1,83 @@
+// 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: FILECanonicalizePath.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the FILECanonicalizePath function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+extern void FILECanonicalizePath(LPSTR lpUnixPath);
+
+void TestCase(LPSTR input, LPSTR expectedOutput);
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc,argv) != 0)
+ {
+ return FAIL;
+ }
+
+ // Case 01: /<name> should not change
+ TestCase("/Test", "/Test");
+
+ // Case 02: /<name>/<name2> should not change
+ TestCase("/Test/Foo", "/Test/Foo");
+
+ // Case 03: // transforms to /
+ TestCase("//", "/");
+
+ // Case 04: /./ transforms to /
+ TestCase("/./", "/");
+
+ // Case 05: /<name>/../ transforms to /
+ TestCase("/Test/../", "/");
+
+ // Case 06: /Test/Foo/.. transforms to /Test
+ TestCase("/Test/Foo/..", "/Test");
+
+ // Case 07: /Test/.. transforms to /
+ TestCase("/Test/..", "/");
+
+ // Case 08: /. transforms to /
+ TestCase("/.", "/");
+
+ // Case 09: /<name/. transforms to /<name>
+ TestCase("/Test/.", "/Test");
+
+ // Case 10: /<name>/../. transforms to /
+ TestCase("/Test/../.", "/");
+
+ // Case 11: /.. transforms to /
+ TestCase("/..", "/");
+
+ PAL_Terminate();
+ return PASS;
+}
+
+void TestCase(LPSTR input, LPSTR expectedOutput)
+{
+ // Save the input for debug logging since the input is edited in-place
+ char* pOriginalInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
+ strcpy(pOriginalInput, input);
+
+ char* pInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
+ strcpy(pInput, pOriginalInput);
+
+ FILECanonicalizePath(pInput);
+ if (strcmp(pInput, expectedOutput) != 0)
+ {
+ free(pOriginalInput);
+ free(pInput);
+ Fail("FILECanonicalizePath error: input %s did not match expected output %s; got %s instead", pOriginalInput, expectedOutput, pInput);
+ }
+
+ free(pOriginalInput);
+ free(pInput);
+}
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/testinfo.dat b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/testinfo.dat
new file mode 100644
index 0000000000..033ad78b47
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = FILECanonicalizePath
+Name = Test for FILECanonicalizePath (test 1)
+Type = DEFAULT
+EXE1 = filecanonicalizepath
+Description
+= Canonicalizes paths and verifies the results
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..131054266b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_filetimetodosdatetime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_filetimetodosdatetime_test1 coreclrpal)
+
+target_link_libraries(paltest_filetimetodosdatetime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c
new file mode 100644
index 0000000000..5f2c81ff98
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c
@@ -0,0 +1,116 @@
+// 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: test1.c
+**
+** Purpose: Tests that FileTimeToDosDateTime successfully converts values.
+** Makes sure values are rounded up, and the limits of the function
+** pass. Also tests that values outside the valid range fail.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+typedef struct
+{
+ DWORD FileTimeLow;
+ DWORD FileTimeHigh;
+ WORD FatDate;
+ WORD FatTime;
+} testCase;
+
+int __cdecl main(int argc, char **argv)
+{
+ FILETIME FileTime;
+ WORD ResultDate;
+ WORD ResultTime;
+ BOOL ret;
+ int i;
+
+ testCase testCases[] =
+ {
+ /* Test a normal time */
+ {0x9BE00100, 0x1B4A02C, 0x14CF, 0x55AF}, /* 12/15/2000, 10:45:30 AM*/
+ /* Test that 12/15/2000, 10:45:29 Gets rounded up */
+ {0x9B476A80, 0x1B4A02C, 0x14CF, 0x55AF}, /* 12/15/2000, 10:45:30 AM*/
+ /* Test that 12/15/2000, 10:45:31 Gets rounded up */
+ {0x9C789780, 0x1B4A02C, 0x14CF, 0x55B0}, /* 12/15/2000, 10:45:32 AM*/
+
+ /* Test the upper and lower limits of the function */
+ {0xE1D58000, 0x1A8E79F, 0x0021, 0x0000}, /* 1/1/1980, 12:00:00 AM*/
+ {0xb9de1300, 0x1e9eede, 0x739f, 0xbf7d}, /* 12/31/2037, 11:59:58 PM*/
+
+ /* Tests that should fail */
+ {0, 0, 0, 0},
+ {0xE0A45300, 0x1A8E79F, 0, 0},
+ {0x66D29301, 0x23868B8, 0, 0}
+
+ /* All this accomplishes is for the date to overflow.
+ Likely the only reason it fails in Windows is bacause the
+ resulting date falls outside of the legal range. Under BSD,
+ it falls into a legal range. This being that BSD calculates time
+ from 1900 to 2037, not 1980 to 2107.
+ {0xFFFFFFFF, 0xFFFFFFF, 0, 0}
+ */
+ };
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ for (i=0; i<sizeof(testCases) / sizeof(testCase); i++)
+ {
+ ResultDate = 0xFFFF;
+ ResultTime = 0xFFFF;
+
+ FileTime.dwLowDateTime = testCases[i].FileTimeLow;
+ FileTime.dwHighDateTime = testCases[i].FileTimeHigh;
+
+
+ ret = FileTimeToDosDateTime(&FileTime, &ResultDate, &ResultTime);
+ if (testCases[i].FatDate != 0 || testCases[i].FatTime != 0)
+ {
+ /* Expected it to pass */
+ if (!ret)
+ {
+ Fail("FileTimeToDosDateTime failed for %X,%X!\n",
+ testCases[i].FileTimeLow, testCases[i].FileTimeHigh);
+ }
+
+ if (ResultDate != testCases[i].FatDate ||
+ ResultTime != testCases[i].FatTime)
+ {
+ Fail("FileTimeToDosDateTime did not convert %X,%X "
+ "successfully:\nExpected date to be %hX, time %hx.\n"
+ "Got %hX, %hX\n", testCases[i].FileTimeLow,
+ testCases[i].FileTimeHigh, testCases[i].FatDate,
+ testCases[i].FatTime, ResultDate, ResultTime);
+ }
+ }
+ else
+ {
+ /* Expected it to fail. */
+ if (ret)
+ {
+ Fail("FileTimeToDosDateTime passed for %X,%X!\n",
+ testCases[i].FileTimeLow, testCases[i].FileTimeHigh);
+ }
+
+ if (ResultDate != 0xFFFF || ResultTime != 0xFFFF)
+ {
+ Fail("FileTimeToDosDateTime failed, but modified output "
+ "parameters: %X %X\n", ResultDate, ResultTime);
+ }
+ }
+
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/testinfo.dat
new file mode 100644
index 0000000000..b5c7e1ae52
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/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 = FileTimeToDosDateTime
+Name = Positive Test #1 for FileTimeToDosDateTime
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=Tests that FileTimeToDosDateTime successfully converts values.
+=Makes sure values are rounded up, and the limits of the function
+=pass. Also tests that values outside the valid range fail.
+
diff --git a/src/pal/tests/palsuite/file_io/FindClose/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindClose/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindClose/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt
new file mode 100644
index 0000000000..732c9f58d3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FindClose.c
+)
+
+add_executable(paltest_findclose_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findclose_test1 coreclrpal)
+
+target_link_libraries(paltest_findclose_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c b/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c
new file mode 100644
index 0000000000..3d53806e48
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c
@@ -0,0 +1,275 @@
+// 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: FindClose.c
+**
+** Purpose: Tests the PAL implementation of the FindClose function.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+
+const WCHAR szFindName[] = {'t','e', 's', 't', '0', '1', '.', 't', 'x', 't', '\0'};
+const WCHAR szFindName_02[] = {'t','e', 's', 't', '0', '2', '.', 't', 'x', 't', '\0'};
+const WCHAR szFindName_03[] = {'t','e', 's', 't', '0', '3', '.', 't', 'x', 't', '\0'};
+const WCHAR szFindNameWldCard_01[] = {'t','e', 's', 't', '0', '?', '.', 't', 'x', 't', '\0'};
+const WCHAR szFindNameWldCard_02[] = {'*', '.', 't', 'x', 't', '\0'};
+const WCHAR szDirName[] = {'t','e', 's', 't', '_', 'd', 'i', 'r', '\0'};
+const WCHAR szDirName_02[] = {'t','e', 's', 't', '_', 'd', 'i', 'r', '0', '2', '\0'};
+const WCHAR szDirNameWldCard[] = {'t','e', 's', 't', '_', '*', '\0'};
+
+
+
+BOOL createTestFile(const WCHAR* szName)
+{
+ FILE *pFile = NULL;
+ char* pTemp = NULL;
+
+ pTemp = convertC((WCHAR*)szName);
+ pFile = fopen(pTemp, "w");
+ if (pFile == NULL)
+ {
+ Trace("FindClose: ERROR -> Unable to create file \"%s\".\n", pTemp);
+ free(pTemp);
+ return FALSE;
+ }
+ else
+ {
+ fprintf(pFile, "FindClose test file, \"%s\".\n", pTemp);
+ free(pTemp);
+ fclose(pFile);
+ }
+ return TRUE;
+}
+
+
+void removeAll()
+{
+ RemoveDirectoryW(szDirName);
+ RemoveDirectoryW(szDirName_02);
+
+ DeleteFileW(szFindName);
+ DeleteFileW(szFindName_02);
+ DeleteFileW(szFindName_03);
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WIN32_FIND_DATAW findFileData;
+ WIN32_FIND_DATAW findFileData_02;
+ HANDLE hFind = NULL;
+ BOOL bRc = FALSE;
+ char* pTemp = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* do some clean up just to be sure */
+ removeAll();
+
+ /* FindClose a null handle */
+ if(FindClose(NULL)!=0)
+ {
+ Fail("FindClose: ERROR -> Closing a NULL handle succeeded.\n");
+ }
+
+ /* find a file that exists */
+ if(createTestFile(szFindName) == FALSE)
+ {
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ if(createTestFile(szFindName_02) == FALSE)
+ {
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ if(createTestFile(szFindName_03) == FALSE)
+ {
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // close a FindFirstFileW handle
+ hFind = FindFirstFileW(szFindName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ pTemp = convertC((WCHAR*)szFindName);
+ Trace("FindClose: ERROR -> Unable to find \"%s\"\n", pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ bRc = FindClose(hFind);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to close a valid"
+ " FindFirstFileW handle.\n");
+ }
+ }
+ hFind = FindFirstFileW(szFindName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ pTemp = convertC((WCHAR*)szFindName);
+ Trace("FindClose: ERROR -> Unable to find \"%s\"\n", pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData);
+ if (bRc != FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Found a file that doesn't exist.\n");
+ }
+ else
+ {
+ bRc = FindClose(hFind);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to close a valid "
+ "FindNextFileW handle.\n");
+ }
+ }
+ }
+
+ /* find a directory that exists */
+ bRc = CreateDirectoryW(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ pTemp = convertC((WCHAR*)szDirName);
+ Trace("FindClose: ERROR -> Failed to create the directory \"%s\"\n",
+ pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CreateDirectoryW(szDirName_02, NULL);
+ if (bRc == FALSE)
+ {
+ pTemp = convertC((WCHAR*)szDirName_02);
+ Trace("FindClose: ERROR -> Failed to create the directory \"%s\"\n",
+ pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ hFind = FindFirstFileW(szDirName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ pTemp = convertC((WCHAR*)szDirName);
+ Trace("FindClose: ERROR. FindFirstFileW was unable to find \"%s\"\n",
+ pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ bRc = FindClose(hFind);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to close a valid"
+ " FindFirstFileW handle of a directory.\n");
+ }
+ }
+
+ /* find a file using wild cards */
+ hFind = FindFirstFileW(szFindNameWldCard_01, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ pTemp = convertC((WCHAR*)szFindNameWldCard_01);
+ Trace("FindClose: ERROR -> FindFirstFileW was unable to find \"%s\"\n",
+ pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to find another file.\n");
+ }
+ else
+ {
+ bRc = FindClose(hFind);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to close a valid"
+ " FindNextFileW handle.\n");
+ }
+ }
+ }
+
+ /* find a directory using wild cards */
+ hFind = FindFirstFileW(szDirNameWldCard, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ pTemp = convertC((WCHAR*)szDirNameWldCard);
+ Trace("FindClose: ERROR -> Unable to find \"%s\"\n",
+ pTemp);
+ free(pTemp);
+ removeAll();
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to find another directory.\n");
+ }
+ else
+ {
+ bRc = FindClose(hFind);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindClose: ERROR -> Unable to close a valid"
+ " FindNextFileW handle of a directory.\n");
+ }
+ }
+ }
+
+
+ removeAll();
+ PAL_Terminate();
+
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/FindClose/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FindClose/test1/testinfo.dat
new file mode 100644
index 0000000000..b59bcbf578
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindClose/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = FindClose
+Name = Test for FindClose (test 1)
+Type = DEFAULT
+EXE1 = findclose
+Description
+= Test the FindClose on handles opened using the Find functions
+
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..6613c4d444
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FindFirstFileA.c
+)
+
+add_executable(paltest_findfirstfilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findfirstfilea_test1 coreclrpal)
+
+target_link_libraries(paltest_findfirstfilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c
new file mode 100644
index 0000000000..6ceb6a9747
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c
@@ -0,0 +1,206 @@
+// 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: FindFirstFileA.c
+**
+** Purpose: Tests the PAL implementation of the FindFirstFileA function.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+const char* szNoFileName = "333asdf.x77t";
+const char* szFindName = "test01.txt";
+const char* szFindNameWldCard_01 = "test0?.txt";
+const char* szFindNameWldCard_02 = "*.txt";
+const char* szDirName = "test_dir";
+const char* szDirNameSlash = "test_dir\\";
+const char* szDirNameWldCard_01 = "?est_dir";
+const char* szDirNameWldCard_02 = "test_*";
+/* Longer than MAX_LONGPATH characters */
+char szLongFindName[MAX_LONGPATH+1];
+
+BOOL CleanUp()
+{
+ DWORD dwAtt;
+ BOOL result = TRUE;
+
+ dwAtt = GetFileAttributesA(szFindName);
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ if(!SetFileAttributesA (szFindName, FILE_ATTRIBUTE_NORMAL))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", szFindName, FILE_ATTRIBUTE_NORMAL);
+ }
+ if(!DeleteFileA (szFindName))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), szFindName, dwAtt);
+ }
+ }
+
+ dwAtt = GetFileAttributesA(szDirName);
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ if(!RemoveDirectoryA (szDirName))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), szDirName, dwAtt);
+ }
+ }
+
+ return result;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ WIN32_FIND_DATA findFileData;
+ HANDLE hFind = NULL;
+ FILE *pFile = NULL;
+ BOOL bRc = FALSE;
+ WCHAR* szwTemp = NULL;
+
+ memset(szLongFindName, 'a', MAX_LONGPATH+1);
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ if(!CleanUp())
+ {
+ Fail("FindFirstFileW: ERROR : Initial Clean Up failed\n");
+ }
+
+ //
+ // find a file with a NULL pointer
+ //
+ hFind = FindFirstFileA(NULL, &findFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Found invalid NULL file");
+ }
+
+
+ //
+ // find a file that doesn't exist
+ //
+ hFind = FindFirstFileA(szNoFileName, &findFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Found invalid NULL file");
+ }
+
+
+ //
+ // find a file that exists
+ //
+ pFile = fopen(szFindName, "w");
+ if (pFile == NULL)
+ {
+ Fail("FindFirstFileA: ERROR -> Unable to create a test file\n");
+ }
+ else
+ {
+ fclose(pFile);
+ }
+ hFind = FindFirstFileA(szFindName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Unable to find \"%s\"\n", szFindName);
+ }
+ else
+ {
+ // validate we found the correct file
+ if (strcmp(szFindName, findFileData.cFileName) != 0)
+ {
+ Fail ("FindFirstFileA: ERROR -> Found the wrong file\n");
+ }
+ }
+
+
+ //
+ // find a directory that exists
+ //
+ szwTemp = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ free(szwTemp);
+ if (bRc == FALSE)
+ {
+ Fail("FindFirstFileA: ERROR -> Failed to create the directory "
+ "\"%s\"\n",
+ szDirName);
+ }
+
+ hFind = FindFirstFileA(szDirName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR. Unable to find \"%s\"\n", szDirName);
+ }
+ else
+ {
+ // validate we found the correct directory
+ if (strcmp(szDirName, findFileData.cFileName) != 0)
+ {
+ Fail ("FindFirstFileA: ERROR -> Found the wrong directory\n");
+ }
+ }
+
+
+ //
+ // find a directory using a trailing '\' on the directory name: should fail
+ //
+ hFind = FindFirstFileA(szDirNameSlash, &findFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Able to find \"%s\": trailing "
+ "slash should have failed.\n",
+ szDirNameSlash);
+ }
+
+ // find a file using wild cards
+ hFind = FindFirstFileA(szFindNameWldCard_01, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Unable to find \"%s\"\n",
+ szFindNameWldCard_01);
+ }
+
+ hFind = FindFirstFileA(szFindNameWldCard_02, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Unable to find \"%s\"\n", szFindNameWldCard_02);
+ }
+
+
+ //
+ // find a directory using wild cards
+ //
+ hFind = FindFirstFileA(szDirNameWldCard_01, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Unable to find \"%s\"\n", szDirNameWldCard_01);
+ }
+
+ hFind = FindFirstFileA(szDirNameWldCard_02, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileA: ERROR -> Unable to find \"%s\"\n", szDirNameWldCard_02);
+ }
+
+ if(!CleanUp())
+ {
+ Fail("FindFirstFileW: ERROR : Final Clean Up failed\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..5b92f8c642
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = FindFirstFileA
+Name = Test for FindFirstFileA (test 1)
+Type = DEFAULT
+EXE1 = findfirstfilea
+Description
+= Create a number of files and try to find them
+
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..23e95c7dad
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FindFirstFileW.c
+)
+
+add_executable(paltest_findfirstfilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findfirstfilew_test1 coreclrpal)
+
+target_link_libraries(paltest_findfirstfilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c
new file mode 100644
index 0000000000..f69a625976
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c
@@ -0,0 +1,212 @@
+// 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: FindFirstFileW.c
+**
+** Purpose: Tests the PAL implementation of the FindFirstFileW function.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+const char* szNoFileName = "333asdf.x77t";
+const char* szFindName = "test01.txt";
+const char* szFindNameWldCard_01 = "test0?.txt";
+const char* szFindNameWldCard_02 = "*.txt";
+const char* szDirName = "test_dir";
+const char* szDirNameSlash = "test_dir\\";
+const char* szDirNameWldCard_01 = "?est_dir";
+const char* szDirNameWldCard_02 = "test_*";
+
+
+BOOL CleanUp()
+{
+ DWORD dwAtt;
+ BOOL result = TRUE;
+
+ dwAtt = GetFileAttributesA(szFindName);
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ if(!SetFileAttributesA (szFindName, FILE_ATTRIBUTE_NORMAL))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", szFindName, FILE_ATTRIBUTE_NORMAL);
+ }
+ if(!DeleteFileA (szFindName))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), szFindName, dwAtt);
+ }
+ }
+
+ dwAtt = GetFileAttributesA(szDirName);
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ if(!RemoveDirectoryA (szDirName))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), szDirName, dwAtt);
+ }
+ }
+
+ return result;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ WIN32_FIND_DATAW findFileData;
+ HANDLE hFind = NULL;
+ FILE *pFile = NULL;
+ BOOL bRc = FALSE;
+ WCHAR* pTemp = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if(!CleanUp())
+ {
+ Fail("FindFirstFileW: ERROR : Initial Clean Up failed\n");
+ }
+
+ //
+ // find a file that doesn't exist
+ //
+ pTemp = convert((LPSTR)szNoFileName);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail ("FindFirstFileW: ERROR -> Found invalid NULL file\n");
+ }
+
+
+ //
+ // find a file that exists
+ //
+ pFile = fopen(szFindName, "w");
+ if (pFile == NULL)
+ {
+ Fail("FindFirstFileW: ERROR -> Unable to create a test file\n");
+ }
+ else
+ {
+ fclose(pFile);
+ }
+ pTemp = convert((LPSTR)szFindName);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ free(pTemp);
+ Fail ("FindFirstFileW: ERROR -> Unable to find \"%s\"\n", szFindName);
+ }
+ else
+ {
+ // validate we found the correct file
+ if (wcscmp(pTemp, findFileData.cFileName) != 0)
+ {
+ free(pTemp);
+ Fail ("FindFirstFileW: ERROR -> Found the wrong file\n");
+ }
+ }
+ free(pTemp);
+
+ //
+ // find a directory that exists
+ //
+ pTemp = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("FindFirstFileW: ERROR[%u] -> Failed to create the directory \"%s\"\n",
+ GetLastError(), szDirName);
+ }
+
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ free(pTemp);
+ Fail("FindFirstFileW: ERROR. Unable to find \"%s\"\n", szDirName);
+ }
+ else
+ {
+ // validate we found the correct directory
+ if (wcscmp(pTemp, findFileData.cFileName) != 0)
+ {
+ free(pTemp);
+ Fail("FindFirstFileW: ERROR -> Found the wrong directory\n");
+ }
+ }
+ free(pTemp);
+
+ //
+ // find a directory using a trailing '\' on the directory name: should fail
+ //
+ pTemp = convert((LPSTR)szDirNameSlash);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail("FindFirstFileW: ERROR -> Able to find \"%s\": trailing "
+ "slash should have failed.\n",
+ szDirNameSlash);
+ }
+
+ // find a file using wild cards
+ pTemp = convert((LPSTR)szFindNameWldCard_01);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindFirstFileW: ERROR -> Unable to find \"%s\"\n",
+ szFindNameWldCard_01);
+ }
+
+ pTemp = convert((LPSTR)szFindNameWldCard_02);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindFirstFileW: ERROR -> Unable to find \"%s\"\n",
+ szFindNameWldCard_02);
+ }
+
+
+ //
+ // find a directory using wild cards
+ //
+
+ pTemp = convert((LPSTR)szDirNameWldCard_01);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindFirstFileW: ERROR -> Unable to find \"%s\"\n",
+ szDirNameWldCard_01);
+ }
+
+ pTemp = convert((LPSTR)szDirNameWldCard_02);
+ hFind = FindFirstFileW(pTemp, &findFileData);
+ free(pTemp);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindFirstFileW: ERROR -> Unable to find \"%s\"\n",
+ szDirNameWldCard_02);
+ }
+
+ if(!CleanUp())
+ {
+ Fail("FindFirstFileW: ERROR : Final Clean Up failed\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..c088c04cbd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = FindFirstFileW
+Name = Test for FindFirstFileW (test 1)
+Type = DEFAULT
+EXE1 = findfirstfilew
+Description
+= Create a number of files and try to find them
+
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileA/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..efb1655d95
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FindNextFileA.c
+)
+
+add_executable(paltest_findnextfilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findnextfilea_test1 coreclrpal)
+
+target_link_libraries(paltest_findnextfilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c
new file mode 100644
index 0000000000..578fa00542
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c
@@ -0,0 +1,243 @@
+// 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: FindNextFileA.c
+**
+** Purpose: Tests the PAL implementation of the FindNextFileA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szFindName = "test01.txt";
+const char* szFindName_02 = "test02.txt";
+const char* szFindNameWldCard_01 = "test0?.txt";
+const char* szFindNameWldCard_02 = "*.txt";
+const char* szDirName = "test_dir";
+const char* szDirName_02 = "test_dir_02";
+const char* szDirNameWldCard = "test_*";
+
+
+
+void removeAll()
+{
+ WCHAR* wTempPtr = NULL;
+
+ wTempPtr = convert((LPSTR)szDirName);
+ RemoveDirectoryW(wTempPtr);
+ free (wTempPtr);
+ wTempPtr = convert((LPSTR)szDirName_02);
+ RemoveDirectoryW(wTempPtr);
+ free (wTempPtr);
+ DeleteFile(szFindName);
+ DeleteFile(szFindName_02);
+}
+
+
+
+BOOL createTestFile(const char* szName)
+{
+ FILE *pFile = NULL;
+
+ pFile = fopen(szName, "w");
+ if (pFile == NULL)
+ {
+ Trace("FindNextFile: ERROR -> Unable to create file \"%s\".\n",
+ szName);
+ removeAll();
+ return FALSE;
+ }
+ else
+ {
+ fprintf(pFile, "FindNextFile test file, \"%s\".\n", szFindName);
+ fclose(pFile);
+ }
+ return TRUE;
+}
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WIN32_FIND_DATA findFileData;
+ WIN32_FIND_DATA findFileData_02;
+ HANDLE hFind = NULL;
+ BOOL bRc = FALSE;
+ DWORD dwBytesWritten;
+ WCHAR* wTempPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+ removeAll();
+
+
+ //
+ // find a file with a NULL pointer
+ //
+ hFind = FindFirstFileA(NULL, &findFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ Fail("FindNextFile: ERROR -> Found invalid NULL file");
+ }
+
+ bRc = FindNextFile(hFind, &findFileData);
+ if (bRc == TRUE)
+ {
+ Fail("FindNextFile: ERROR -> Found a file based on an invalid handle");
+ }
+
+
+ //
+ // find a file that exists
+ //
+ if(createTestFile(szFindName) == FALSE)
+ {
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ if(createTestFile(szFindName_02) == FALSE)
+ {
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ hFind = FindFirstFileA(szFindName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Unable to find \"%s\"\n", szFindName);
+ }
+ else
+ {
+ bRc = FindNextFile(hFind, &findFileData);
+ if (bRc != FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Found a file that doesn't exist.\n");
+ }
+ }
+
+
+ //
+ // find a directory that exists
+ //
+ wTempPtr = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(wTempPtr, NULL);
+ free (wTempPtr);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Failed to create the directory \"%s\"\n",
+ szDirName);
+ }
+ wTempPtr = convert((LPSTR)szDirName_02);
+ bRc = CreateDirectoryW(wTempPtr, NULL);
+ free (wTempPtr);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Failed to create the directory \"%s\"\n",
+ szDirName_02);
+ }
+
+ hFind = FindFirstFileA(szDirName, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR. FindFirstFileA was unable to find \"%s\"\n",
+ szDirName);
+ }
+ else
+ {
+ bRc = FindNextFile(hFind, &findFileData);
+ if (bRc != FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Found a directory that doesn't exist.\n");
+ }
+ }
+
+
+ //
+ // find a file using wild cards
+ //
+ hFind = FindFirstFileA(szFindNameWldCard_01, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> FindFirstFileA was unable to find \"%s\"\n",
+ szFindNameWldCard_01);
+ }
+ else
+ {
+ bRc = FindNextFile(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Unable to find another file.\n");
+ }
+ else
+ {
+ // validate we found the correct file
+ if (strcmp(findFileData_02.cFileName, findFileData.cFileName) == 0)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Found the same file \"%s\".\n",
+ findFileData.cFileName);
+ }
+ }
+ }
+
+
+ //
+ // find a directory using wild cards
+ //
+ hFind = FindFirstFileA(szDirNameWldCard, &findFileData);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Unable to find \"%s\"\n",
+ szDirNameWldCard);
+ }
+ else
+ {
+ bRc = FindNextFile(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Unable to find another directory.\n");
+ }
+ else
+ {
+ // validate we found the correct directory
+ if (strcmp(findFileData_02.cFileName, findFileData.cFileName) == 0)
+ {
+ removeAll();
+ Fail("FindNextFile: ERROR -> Found the same directory \"%s\".\n",
+ findFileData.cFileName);
+ }
+ }
+ }
+
+ //
+ // attempt to write to the hFind handle (which should fail)
+ //
+ bRc = WriteFile(hFind, "this is a test", 10, &dwBytesWritten, NULL);
+ removeAll();
+ if (bRc == TRUE)
+ {
+ Fail("FindNextFile: ERROR -> Able to write to a FindNextFile handle.\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..e1027eff32
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = FindNextFileA
+Name = Test for FindNextFileA (test 1)
+Type = DEFAULT
+EXE1 = findnextfilea
+Description
+= Create test files and directories to verify FindNextFileA
+
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..96821bdaaa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ findnextfilea.c
+)
+
+add_executable(paltest_findnextfilea_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findnextfilea_test2 coreclrpal)
+
+target_link_libraries(paltest_findnextfilea_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c
new file mode 100644
index 0000000000..c841a4d498
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c
@@ -0,0 +1,107 @@
+// 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: findnextfilea.c
+**
+** Purpose: Tests the PAL implementation of the FindNextFileA function.
+** Tests '*' and '*.*' to ensure that '.' and '..' are
+** returned in the expected order
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szDot = ".";
+const char* szDotDot = "..";
+const char* szStar = "*";
+const char* szStarDotStar = "*.*";
+
+
+static void DoTest(const char* szDir,
+ const char* szResult1,
+ const char* szResult2)
+{
+ HANDLE hFind;
+ WIN32_FIND_DATA findFileData;
+
+ /*
+ ** find the first
+ */
+ if ((hFind = FindFirstFileA(szDir, &findFileData)) == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindNextFileA: ERROR -> FindFirstFileA(\"%s\") failed. "
+ "GetLastError returned %u.\n",
+ szStar,
+ GetLastError());
+ }
+
+ /* did we find the expected */
+ if (strcmp(szResult1, findFileData.cFileName) != 0)
+ {
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileA: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("FindNextFileA: ERROR -> FindFirstFile(\"%s\") didn't find"
+ " the expected \"%s\" but found \"%s\" instead.\n",
+ szDir,
+ szResult1,
+ findFileData.cFileName);
+ }
+
+ /* we found the first expected, let's see if we find the next expected*/
+ if (!FindNextFileA(hFind, &findFileData))
+ {
+ Trace("FindNextFileA: ERROR -> FindNextFileA should have found \"%s\""
+ " but failed. GetLastError returned %u.\n",
+ szResult2,
+ GetLastError());
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileA: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* we found something, but was it '.' */
+ if (strcmp(szResult2, findFileData.cFileName) != 0)
+ {
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileA: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("FindNextFileA: ERROR -> FindNextFileA based on \"%s\" didn't find"
+ " the expected \"%s\" but found \"%s\" instead.\n",
+ szDir,
+ szResult2,
+ findFileData.cFileName);
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ DoTest(szStar, szDot, szDotDot);
+ DoTest(szStarDotStar, szDot, szDotDot);
+
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/testinfo.dat
new file mode 100644
index 0000000000..dd6c1e48b3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/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 = FindNextFileA
+Name = Test for FindNextFileA (test 2)
+Type = DEFAULT
+EXE1 = findnextfilea
+Description
+= Tests the PAL implementation of the FindNextFileA function.
+= Tests '*' and '*.*' to ensure that '.' and '..' are
+= returned in the expected order
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileW/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..4a283dd3a5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FindNextFileW.c
+)
+
+add_executable(paltest_findnextfilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findnextfilew_test1 coreclrpal)
+
+target_link_libraries(paltest_findnextfilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c
new file mode 100644
index 0000000000..42e2e55805
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c
@@ -0,0 +1,249 @@
+// 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: FindNextFileW.c
+**
+** Purpose: Tests the PAL implementation of the FindNextFileW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szFindName = "test01.txt";
+const char* szFindName_02 = "test02.txt";
+const char* szFindNameWldCard_01 = "test0?.txt";
+const char* szFindNameWldCard_02 = "*.txt";
+const char* szDirName = "test_dir";
+const char* szDirName_02 = "test_dir_02";
+const char* szDirNameWldCard = "test_*";
+
+
+
+void removeAll()
+{
+ WCHAR* wTempPtr = NULL;
+
+ wTempPtr = convert((LPSTR)szDirName);
+ RemoveDirectoryW(wTempPtr);
+ free(wTempPtr);
+
+ wTempPtr = convert((LPSTR)szDirName_02);
+ RemoveDirectoryW(wTempPtr);
+ free(wTempPtr);
+
+ wTempPtr = convert((LPSTR)szFindName);
+ DeleteFileW(wTempPtr);
+ free(wTempPtr);
+
+ wTempPtr = convert((LPSTR)szFindName_02);
+ DeleteFileW(wTempPtr);
+ free(wTempPtr);
+}
+
+
+
+BOOL createTestFile(const char* szName)
+{
+ FILE *pFile = NULL;
+
+ pFile = fopen(szName, "w");
+ if (pFile == NULL)
+ {
+ Trace("FindNextFileW: ERROR -> Unable to create file \"%s\".\n", szName);
+ removeAll();
+ return FALSE;
+ }
+ else
+ {
+ fprintf(pFile, "FindNextFileW test file, \"%s\".\n", szFindName);
+ fclose(pFile);
+ }
+
+ return TRUE;
+}
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WIN32_FIND_DATAW findFileData;
+ WIN32_FIND_DATAW findFileData_02;
+ HANDLE hFind = NULL;
+ BOOL bRc = FALSE;
+ DWORD dwBytesWritten;
+ WCHAR* wTempPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+ removeAll();
+
+
+ //
+ // find a file that exists
+ //
+ if(createTestFile(szFindName) == FALSE)
+ {
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ if(createTestFile(szFindName_02) == FALSE)
+ {
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ wTempPtr = convert((LPSTR)szFindName);
+ hFind = FindFirstFileW(wTempPtr, &findFileData);
+ free(wTempPtr);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Unable to find \"%s\"\n", szFindName);
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData);
+ if (bRc != FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Found a file that doesn't exist.\n");
+ }
+ }
+
+
+ //
+ // find a directory that exists
+ //
+ wTempPtr = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(wTempPtr, NULL);
+ free (wTempPtr);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Failed to create the directory \"%s\"\n",
+ szDirName);
+ }
+ wTempPtr = convert((LPSTR)szDirName_02);
+ bRc = CreateDirectoryW(wTempPtr, NULL);
+ free (wTempPtr);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Failed to create the directory "
+ "\"%s\"\n",
+ szDirName_02);
+ }
+
+ wTempPtr = convert((LPSTR)szDirName);
+ hFind = FindFirstFileW(wTempPtr, &findFileData);
+ free (wTempPtr);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR. FindFirstFileW was unable "
+ "to find \"%s\"\n",
+ szDirName);
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData);
+ if (bRc != FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Found a directory that "
+ "doesn't exist.\n");
+ }
+ }
+
+
+ //
+ // find a file using wild cards
+ //
+ wTempPtr = convert((LPSTR)szFindNameWldCard_01);
+ hFind = FindFirstFileW(wTempPtr, &findFileData);
+ free(wTempPtr);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> FindFirstFileW was unable to "
+ "find \"%s\"\n",
+ szFindNameWldCard_01);
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Unable to find another file.\n");
+ }
+ else
+ {
+ // validate we found the correct file
+ if (wcscmp(findFileData_02.cFileName, findFileData.cFileName) == 0)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Found the same file \"%S\".\n",
+ findFileData.cFileName);
+ }
+ }
+ }
+
+
+ //
+ // find a directory using wild cards
+ //
+ wTempPtr = convert((LPSTR)szDirNameWldCard);
+ hFind = FindFirstFileW(wTempPtr, &findFileData);
+ free(wTempPtr);
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Unable to find \"%s\"\n",
+ szDirNameWldCard);
+ }
+ else
+ {
+ bRc = FindNextFileW(hFind, &findFileData_02);
+ if (bRc == FALSE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Unable to find another directory.\n");
+ }
+ else
+ {
+ // validate we found the correct directory
+ if (wcscmp(findFileData_02.cFileName, findFileData.cFileName) == 0)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Found the same directory "
+ "\"%S\".\n",
+ findFileData.cFileName);
+ }
+ }
+ }
+
+ //
+ // attempt to write to the hFind handle (which should fail)
+ //
+ bRc = WriteFile(hFind, "this is a test", 10, &dwBytesWritten, NULL);
+ if (bRc == TRUE)
+ {
+ removeAll();
+ Fail("FindNextFileW: ERROR -> Able to write to a FindNextFileW "
+ "handle.\n");
+ }
+
+ removeAll();
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..3eaebef43e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = FindNextFileW
+Name = Test for FindNextFileW (test 1)
+Type = DEFAULT
+EXE1 = findnextfilew
+Description
+= Create test files and directories to verify FindNextFileW
+
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..2938afb888
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ findnextfilew.c
+)
+
+add_executable(paltest_findnextfilew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_findnextfilew_test2 coreclrpal)
+
+target_link_libraries(paltest_findnextfilew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c
new file mode 100644
index 0000000000..3e806c2576
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c
@@ -0,0 +1,107 @@
+// 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: FindNextFileW.c
+**
+** Purpose: Tests the PAL implementation of the FindNextFileW function.
+** Tests '*' and '*.*' to ensure that '.' and '..' are
+** returned in the expected order
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const WCHAR szwDot[] = {'.','\0'};
+const WCHAR szwDotDot[] = {'.','.','\0'};
+const WCHAR szwStar[] = {'*','\0'};
+const WCHAR szwStarDotStar[] = {'*','.','*','\0'};
+
+
+static void DoTest(const WCHAR* szwDir,
+ const WCHAR* szwResult1,
+ const WCHAR* szwResult2)
+{
+ HANDLE hFind;
+ WIN32_FIND_DATAW findFileData;
+
+ /*
+ ** find the first
+ */
+ if ((hFind = FindFirstFileW(szwDir, &findFileData)) == INVALID_HANDLE_VALUE)
+ {
+ Fail("FindNextFileW: ERROR -> FindFirstFileW(\"%S\") failed. "
+ "GetLastError returned %u.\n",
+ szwStar,
+ GetLastError());
+ }
+
+ /* did we find the expected */
+ if (wcscmp(szwResult1, findFileData.cFileName) != 0)
+ {
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileW: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("FindNextFileW: ERROR -> FindFirstFile(\"%S\") didn't find"
+ " the expected \"%S\" but found \"%S\" instead.\n",
+ szwDir,
+ szwResult1,
+ findFileData.cFileName);
+ }
+
+ /* we found the first expected, let's see if we find the next expected*/
+ if (!FindNextFileW(hFind, &findFileData))
+ {
+ Trace("FindNextFileW: ERROR -> FindNextFileW should have found \"%S\""
+ " but failed. GetLastError returned %u.\n",
+ szwResult2,
+ GetLastError());
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileW: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* we found something, but was it '.' */
+ if (wcscmp(szwResult2, findFileData.cFileName) != 0)
+ {
+ if (!FindClose(hFind))
+ {
+ Trace("FindNextFileW: ERROR -> Failed to close the find handle. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ }
+ Fail("FindNextFileW: ERROR -> FindNextFileW based on \"%S\" didn't find"
+ " the expected \"%S\" but found \"%S\" instead.\n",
+ szwDir,
+ szwResult2,
+ findFileData.cFileName);
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ DoTest(szwStar, szwDot, szwDotDot);
+ DoTest(szwStarDotStar, szwDot, szwDotDot);
+
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/testinfo.dat
new file mode 100644
index 0000000000..98bd5e7793
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/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 = FindNextFileW
+Name = Test for FindNextFileW (test 2)
+Type = DEFAULT
+EXE1 = findnextfilew
+Description
+= Tests the PAL implementation of the FindNextFileW function.
+= Tests '*' and '*.*' to ensure that '.' and '..' are
+= returned in the expected order
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FlushFileBuffers/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt
new file mode 100644
index 0000000000..e3fbccd2ae
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ FlushFileBuffers.c
+)
+
+add_executable(paltest_flushfilebuffers_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_flushfilebuffers_test1 coreclrpal)
+
+target_link_libraries(paltest_flushfilebuffers_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c
new file mode 100644
index 0000000000..246be64847
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c
@@ -0,0 +1,130 @@
+// 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: FlushFileBuffers.c
+**
+** Purpose: Tests the PAL implementation of the FlushFileBuffers function
+** This tests checks the return values of FlushFileBuffers -- once on an
+** open handle and once on a closed handle.
+**
+** Depends:
+** CreateFile
+** WriteFile
+** CloseHandle
+** DeleteFileA
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ int TheReturn;
+ HANDLE TheFileHandle;
+ DWORD temp;
+ DWORD originalSize=10000;
+ DWORD finalSize=10000;
+ const char* fileName="the_file";
+
+ /* 1 2 3 4*/
+ char * SomeText = "1234567890123456789012345678901234567890";
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ fileName,
+ GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(TheFileHandle == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: CreateFile failed. Test depends on this function.");
+ }
+
+ /* get the file size */
+ originalSize = GetFileSize (TheFileHandle, NULL) ;
+ if(originalSize == INVALID_FILE_SIZE)
+ {
+ Fail("ERROR: call to GetFileSize faild with error "
+ "The GetLastError is %d.",GetLastError());
+ }
+
+ /* Write something too the HANDLE. Should be buffered */
+ TheReturn = WriteFile(TheFileHandle,
+ SomeText,
+ strlen(SomeText),
+ &temp,
+ NULL);
+
+ if(TheReturn == 0)
+ {
+ Fail("ERROR: WriteFile failed. Test depends on this function.");
+ }
+
+ /* Test to see that FlushFileBuffers returns a success value */
+ TheReturn = FlushFileBuffers(TheFileHandle);
+ if(TheReturn == 0)
+ {
+ Fail("ERROR: The FlushFileBuffers function returned 0, which "
+ "indicates failure, when trying to flush a valid HANDLE. "
+ "The GetLastError is %d.",GetLastError());
+ }
+
+ /* test if flush modified the file */
+ finalSize = GetFileSize (TheFileHandle, NULL) ;
+ if(finalSize==INVALID_FILE_SIZE)
+ {
+ Fail("ERROR: call to GetFileSize faild with error "
+ "The GetLastError is %d.",GetLastError());
+ }
+ if(finalSize!=(originalSize+strlen(SomeText)))
+ {
+ Fail("ERROR: FlushFileBuffers failed. data was not written to the file");
+ }
+
+
+ /* Close the Handle */
+ TheReturn = CloseHandle(TheFileHandle);
+ if(TheReturn == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This function depends "
+ "upon it.");
+ }
+
+
+ /* Test to see that FlushFileBuffers returns a failure value */
+ TheReturn = FlushFileBuffers(TheFileHandle);
+ if(TheReturn != 0)
+ {
+ Fail("ERROR: The FlushFileBuffers function returned non-zero, "
+ "which indicates success, when trying to flush an invalid "
+ "HANDLE.");
+ }
+
+ /* make sure file does not exist */
+ if(DeleteFileA(fileName)== 0 )
+ {
+ Fail("ERROR: call to DeleteFileA faild with error "
+ "The GetLastError is %d.",GetLastError());
+ }
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/testinfo.dat
new file mode 100644
index 0000000000..3a0da6918d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/testinfo.dat
@@ -0,0 +1,17 @@
+# 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 = FlushFileBuffers
+Name = Positive Test for FlushFileBuffers
+TYPE = DEFAULT
+EXE1 = flushfilebuffers
+Description
+= Test the FlushFileBuffers
+= Test the return values -- ensure that the correct values are
+= returned for success and failure.
+= This test does not prove that flush worked,
+= there is no way of stopping the OS from flushing
+= the file by itself.
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleCP/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt
new file mode 100644
index 0000000000..131f4a5fb7
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetConsoleCP.c
+)
+
+add_executable(paltest_getconsolecp_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getconsolecp_test1 coreclrpal)
+
+target_link_libraries(paltest_getconsolecp_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c
new file mode 100644
index 0000000000..ba17d6c64d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c
@@ -0,0 +1,35 @@
+// 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: GetConsoleCP.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetConsoleCP function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiCP = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ uiCP = GetConsoleCP();
+ if ((uiCP != CP_ACP) && (uiCP != GetACP()) && (uiCP != 437)) /*437 for MSDOS*/
+ {
+ Fail("GetConsoleCP: ERROR -> The invalid code page %d was returned.\n",
+ uiCP);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/testinfo.dat
new file mode 100644
index 0000000000..608a01b2ef
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetConsoleCP
+Name = Positive Test for GetConsoleCP (test 1)
+Type = DEFAULT
+EXE1 = getconsolecp
+Description
+= Test GetConsoleCP. Apparently there are only two possible
+= return values: CP_ACP or 1252
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt
new file mode 100644
index 0000000000..d19ab95a37
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetConsoleOutputCP.c
+)
+
+add_executable(paltest_getconsoleoutputcp_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getconsoleoutputcp_test1 coreclrpal)
+
+target_link_libraries(paltest_getconsoleoutputcp_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c
new file mode 100644
index 0000000000..3deaebf68f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c
@@ -0,0 +1,35 @@
+// 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: GetConsoleOutputCP.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetConsoleOutputCP function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiCP = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ uiCP = GetConsoleOutputCP();
+ if ((uiCP != CP_ACP) && (uiCP != GetACP()) && (uiCP != 437)) /*437 for MSDOS*/
+ {
+ Fail("GetConsoleOutputCP: ERROR -> The invalid code page %d was returned.\n",
+ uiCP);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/testinfo.dat
new file mode 100644
index 0000000000..9ad624eaf2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetConsoleOutputCP
+Name = Positive Test for GetConsoleOutputCP (test 1)
+Type = DEFAULT
+EXE1 = getconsoleoutputcp
+Description
+= Test GetConsoleOutputCP. Apparently there are only two possible
+= return values: CP_ACP or 1252
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..f7382b047d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetCurrentDirectoryA.c
+)
+
+add_executable(paltest_getcurrentdirectorya_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getcurrentdirectorya_test1 coreclrpal)
+
+target_link_libraries(paltest_getcurrentdirectorya_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c
new file mode 100644
index 0000000000..b09e8a104d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c
@@ -0,0 +1,97 @@
+// 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: GetCurrentDirectoryA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetCurrentDirectoryA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szFileName = "blah";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ DWORD dwRc2 = 0;
+ char szReturnedPath[_MAX_PATH+1];
+ char szCurrentDir[_MAX_PATH+1];
+ LPSTR pPathPtr;
+ size_t nCount = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // use GetFullPathName to to get the current path by stripping
+ // the file name off the end
+ memset(szReturnedPath, 0, sizeof(char)*(_MAX_PATH+1));
+ dwRc = GetFullPathNameA(szFileName, _MAX_PATH, szReturnedPath, &pPathPtr);
+ if (dwRc == 0)
+ {
+ // GetFullPathName failed
+ Fail("GetCurrentDirectoryA: ERROR -> GetFullPathNameA failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ else if(dwRc > _MAX_PATH)
+ {
+ Fail("GetCurrentDirectoryA: ERROR -> The path name GetFullPathNameA "
+ "returned is longer than _MAX_PATH characters.\n");
+ }
+
+
+ // strip the file name from the full path to get the current path
+ nCount = strlen(szReturnedPath) - strlen(szFileName) - 1;
+ memset(szCurrentDir, 0, sizeof(char)*(_MAX_PATH+1));
+ strncpy(szCurrentDir, szReturnedPath, nCount);
+
+ // compare the results of GetCurrentDirectoryA with the above
+ memset(szReturnedPath, 0, sizeof(char)*(_MAX_PATH+1));
+ dwRc = GetCurrentDirectoryA((sizeof(char)*(_MAX_PATH+1)), szReturnedPath);
+ if (dwRc == 0)
+ {
+ Fail("GetCurrentDirectoryA: ERROR -> GetCurrentDirectoryA failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ else if(dwRc > _MAX_PATH)
+ {
+ Fail("GetCurrentDirectoryA: ERROR -> The path name "
+ "returned is longer than _MAX_PATH characters.\n");
+ }
+
+
+ /* test case the passed buffer size is not big enough
+ * function should return the size required + 1 a terminating null character
+ */
+
+ /* good buffer size */
+ dwRc = GetCurrentDirectoryA((sizeof(CHAR)*(_MAX_PATH+1)), szReturnedPath);
+
+ /* small buffer (0 size)*/
+ dwRc2 = GetCurrentDirectoryA(0, szReturnedPath);
+ if (dwRc2 != (dwRc+1) )
+ {
+ Fail("GetCurrentDirectoryA: ERROR -> failed to give the correct "
+ "return value when passed a buffer not big enough. "
+ "Expected %u while result is %u \n",(dwRc+1),dwRc2);
+
+ }
+
+ if (strcmp(szReturnedPath, szCurrentDir) != 0)
+ {
+ Fail("GetCurrentDirectoryA: ERROR -> The computed and returned "
+ "directories do not compare.\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/testinfo.dat
new file mode 100644
index 0000000000..c14eb42b22
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/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 = GetCurrentDirectoryA
+Name = Test for GetCurrentDirectoryA (test 1)
+Type = DEFAULT
+EXE1 = getcurrentdirectorya
+Description
+= Calculate the current directory name and compare to that
+= returned by GetCurrentDirectoryA
+
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..ed8419926c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetCurrentDirectoryW.c
+)
+
+add_executable(paltest_getcurrentdirectoryw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getcurrentdirectoryw_test1 coreclrpal)
+
+target_link_libraries(paltest_getcurrentdirectoryw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c
new file mode 100644
index 0000000000..4f4697b0a2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c
@@ -0,0 +1,106 @@
+// 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: GetCurrentDirectoryW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetCurrentDirectoryW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ DWORD dwRc2 = 0;
+ WCHAR szwReturnedPath[_MAX_PATH+1];
+ WCHAR szwCurrentDir[_MAX_PATH+1];
+ WCHAR szwFileName[_MAX_PATH] = {'b','l','a','h','\0'};
+ LPWSTR pPathPtr;
+ size_t nCount = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* use GetFullPathName to to get the current path by stripping
+ * the file name off the end */
+ memset(szwReturnedPath, 0, sizeof(WCHAR)*(_MAX_PATH+1));
+ dwRc = GetFullPathNameW(szwFileName, _MAX_PATH, szwReturnedPath, &pPathPtr);
+ if (dwRc == 0)
+ {
+ /* GetFullPathName failed */
+ Fail("GetCurrentDirectoryW: ERROR -> GetFullPathNameW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ else if(dwRc >_MAX_PATH)
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> The path name GetFullPathNameW "
+ "returned is longer than _MAX_PATH characters.\n");
+ }
+
+ /* strip the file name from the full path to get the current path */
+ nCount = wcslen(szwReturnedPath) - wcslen(szwFileName) - 1;
+ memset(szwCurrentDir, 0, sizeof(WCHAR)*(_MAX_PATH+1));
+ memcpy(szwCurrentDir, szwReturnedPath, nCount*sizeof(WCHAR));
+
+ /* compare the results of GetCurrentDirectoryW with the above */
+ memset(szwReturnedPath, 0, sizeof(WCHAR)*(_MAX_PATH+1));
+ dwRc = GetCurrentDirectoryW((sizeof(WCHAR)*(_MAX_PATH+1)), szwReturnedPath);
+ if (dwRc == 0)
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> GetCurrentDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ else if(dwRc >_MAX_PATH)
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> The path name "
+ "returned is longer than _MAX_PATH characters.\n");
+ }
+
+ /* check to see whether the length of the returned string is equal to
+ * the DWORD returned by GetCurrentDirectoryW.
+ */
+ if(wcslen(szwReturnedPath) != dwRc)
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> The Length of the path name "
+ "returned \"%u\" is not equal to the return value of the "
+ "function \"%u\".\n" , wcslen(szwReturnedPath), dwRc);
+ }
+
+
+
+ /* test case the passed buffer size is not big enough
+ * function should return the size required + 1 for a terminating null character
+ */
+
+ /* good buffer size */
+ dwRc = GetCurrentDirectoryW((sizeof(WCHAR)*(_MAX_PATH+1)), szwReturnedPath);
+
+ /* small buffer (0 size)*/
+ dwRc2 = GetCurrentDirectoryW(0, szwReturnedPath);
+ if (dwRc2 != (dwRc+1) )
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> failed to give the correct "
+ "return value when passed a buffer not big enough. "
+ "Expected %u while result is %u ",(dwRc+1),dwRc2);
+
+ }
+
+ if (wcsncmp(szwReturnedPath, szwCurrentDir, wcslen(szwReturnedPath)) != 0)
+ {
+ Fail("GetCurrentDirectoryW: ERROR -> The computed and returned "
+ "directories do not compare.\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/testinfo.dat
new file mode 100644
index 0000000000..4443a79833
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/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 = GetCurrentDirectoryW
+Name = Test for GetCurrentDirectoryW (test 1)
+Type = DEFAULT
+EXE1 = getcurrentdirectoryw
+Description
+= Compute the current directory and compare with the results
+= from GetCurrentDirectoryW
+
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..6b06376233
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetDiskFreeSpaceW.c
+)
+
+add_executable(paltest_getdiskfreespacew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getdiskfreespacew_test1 coreclrpal)
+
+target_link_libraries(paltest_getdiskfreespacew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c
new file mode 100644
index 0000000000..c1445f654f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c
@@ -0,0 +1,94 @@
+// 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: GetDiskFreeSpaceW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetDiskFreeSpaceW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwSectorsPerCluster; /* sectors per cluster */
+ DWORD dwBytesPerSector; /* bytes per sector */
+ DWORD dwSectorsPerCluster_02; /* sectors per cluster */
+ DWORD dwBytesPerSector_02; /* bytes per sector */
+ DWORD dwNumberOfFreeClusters; /* free clusters */
+ DWORD dwTotalNumberOfClusters; /* total clusters */
+ BOOL bRc = FALSE;
+ WCHAR szwRootPath[10] = {'/','\0'};
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* test the NULL option which translates to the current drive */
+ bRc = GetDiskFreeSpaceW(NULL,
+ &dwSectorsPerCluster,
+ &dwBytesPerSector,
+ &dwNumberOfFreeClusters,
+ &dwTotalNumberOfClusters);
+ if (bRc != TRUE)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> Failed with error code: %ld\n",
+ GetLastError());
+ }
+ else if (dwSectorsPerCluster == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwSectorsPerCluster returned 0\n");
+ }
+ else if (dwBytesPerSector == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwBytesPerSector returned 0\n");
+ }
+
+ /* test the root directory to the current drive */
+ bRc = GetDiskFreeSpaceW(szwRootPath,
+ &dwSectorsPerCluster_02,
+ &dwBytesPerSector_02,
+ &dwNumberOfFreeClusters,
+ &dwTotalNumberOfClusters);
+ if (bRc != TRUE)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> Failed with error code: %ld\n",
+ GetLastError());
+ }
+ else if (dwSectorsPerCluster == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwSectorsPerCluster returned 0\n");
+ }
+ else if (dwBytesPerSector == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwBytesPerSector returned 0\n");
+ }
+ /*
+ ** make sure the values returned for NULL path and root path
+ ** are the same
+ */
+ else if (dwSectorsPerCluster_02 != dwSectorsPerCluster)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwSectorsPerCluster for NULL path "
+ "(%u) should have been the same as the root path (%u).\n",
+ dwSectorsPerCluster,
+ dwSectorsPerCluster_02);
+ }
+ else if (dwBytesPerSector_02 != dwBytesPerSector)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwBytesPerSector for NULL path "
+ "(%u) should have been the same as the root path (%u).\n",
+ dwBytesPerSector,
+ dwBytesPerSector_02);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/testinfo.dat
new file mode 100644
index 0000000000..61b0e55fae
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetDiskFreeSpaceW
+Name = Positive Test for GetDiskFreeSpaceW (test 1)
+Type = DEFAULT
+EXE1 = getdiskfreespacew
+Description
+= Test GetDiskFreeSpaceW. lpNumberOfFreeClusters and
+= lpTotalNumberOfClusters are to be ignored
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..5660b39e1a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getdiskfreespacew.c
+)
+
+add_executable(paltest_getdiskfreespacew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getdiskfreespacew_test2 coreclrpal)
+
+target_link_libraries(paltest_getdiskfreespacew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c
new file mode 100644
index 0000000000..83dcb54b51
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c
@@ -0,0 +1,65 @@
+// 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: GetDiskFreeSpaceW.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the GetDiskFreeSpaceW
+** function on valid non-root paths.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwSectorsPerCluster; /* sectors per cluster */
+ DWORD dwBytesPerSector; /* bytes per sector */
+ DWORD dwNumberOfFreeClusters; /* free clusters */
+ DWORD dwTotalNumberOfClusters; /* total clusters */
+ BOOL bRc = FALSE;
+ WCHAR szwCurrentPath[MAX_LONGPATH];
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* get the current directory so we are sure to have a valid path */
+ if (!GetCurrentDirectoryW(MAX_LONGPATH, szwCurrentPath))
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> GetCurrentDirectoryW failed with "
+ "error code: %u.\n",
+ GetLastError());
+ }
+
+ /* test the current path*/
+ bRc = GetDiskFreeSpaceW(szwCurrentPath,
+ &dwSectorsPerCluster,
+ &dwBytesPerSector,
+ &dwNumberOfFreeClusters,
+ &dwTotalNumberOfClusters);
+ if (bRc != TRUE)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> Failed with error code: %u for "
+ "the path \"%S\".\n",
+ GetLastError(),
+ szwCurrentPath);
+ }
+ else if (dwSectorsPerCluster == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwSectorsPerCluster returned 0\n");
+ }
+ else if (dwBytesPerSector == 0)
+ {
+ Fail("GetDiskFreeSpaceW: ERROR -> dwBytesPerSector returned 0\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/testinfo.dat
new file mode 100644
index 0000000000..0a687240ea
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = GetDiskFreeSpaceW
+Name = Positive Test for GetDiskFreeSpaceW (test 2)
+Type = DEFAULT
+EXE1 = getdiskfreespacew
+Description
+= Test GetDiskFreeSpaceW with valid non-root paths
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_file
new file mode 100644
index 0000000000..0d1ac31cfa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_file
@@ -0,0 +1 @@
+Hidden file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_file
new file mode 100644
index 0000000000..8f78fcb436
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/.hidden_ro_file
@@ -0,0 +1 @@
+.hidden_ro_file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..6bf9818e86
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileAttributesA.c
+)
+
+add_executable(paltest_getfileattributesa_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfileattributesa_test1 coreclrpal)
+
+target_link_libraries(paltest_getfileattributesa_test1
+ pthread
+ m
+ coreclrpal
+)
+add_subdirectory(.hidden_directory)
+add_subdirectory(.hidden_ro_directory)
+add_subdirectory(normal_test_directory)
+add_subdirectory(no_directory)
+add_subdirectory(ro_test_directory)
+add_subdirectory(rw_directory)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c
new file mode 100644
index 0000000000..ff6bd0b8e0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c
@@ -0,0 +1,340 @@
+// 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: GetFileAttributesA.c
+**
+** Purpose: Tests the PAL implementation of the GetFileAttributesA function by
+** checking the attributes of:
+** - a normal directory and file
+** - a read only directory and file
+** - a read write directory and file
+** - a hidden directory and file
+** - a read only hidden directory and file
+** - a directory and a file with no attributes
+** - an invalid file name
+**
+**
+**===========================================================================*/
+#include <palsuite.h>
+
+const int TYPE_DIR = 0;
+const int TYPE_FILE = 1;
+/* Structure defining a test case */
+typedef struct
+{
+ char *name; /* name of the file/directory */
+ DWORD expectedAttribs; /* expected attributes */
+ HANDLE hFile; /* Handle to the file */
+ int isFile; /* is file (1) or dir (0) */
+}TestCaseFile;
+
+typedef struct
+{
+ char *name; /* name of the file/directory */
+ DWORD expectedAttribs; /* expected attributes */
+ HANDLE hFile; /* Handle to the file */
+ int isFile; /* is file (1) or dir (0) */
+}TestCaseDir;
+
+DWORD desiredAccessFile = GENERIC_READ | GENERIC_WRITE;
+DWORD shareModeFile = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
+LPSECURITY_ATTRIBUTES lpAttrFile = NULL;
+DWORD dwCreationDispFile = CREATE_NEW;
+DWORD dwFlagsAttribFile = FILE_ATTRIBUTE_NORMAL;
+HANDLE hTemplateFile = NULL;
+
+int numFileTests = 6;
+TestCaseFile gfaTestsFile[6]; /* GetFileAttributes tests list */
+
+int numDirTests = 6;
+TestCaseDir gfaTestsDir[6]; /* GetFileAttributes tests list */
+
+BOOL CleanUpFiles()
+{
+ DWORD dwAtt;
+ int i;
+ BOOL result = TRUE;
+ for (i = 0; i < numFileTests -1 ; i++ )
+ {
+ dwAtt = GetFileAttributesA(gfaTestsFile[i].name);
+
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ //Trace("Files iteration %d\n", i);
+ if(!SetFileAttributesA (gfaTestsFile[i].name, FILE_ATTRIBUTE_NORMAL))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, FILE_ATTRIBUTE_NORMAL);
+ }
+
+ if(!DeleteFileA (gfaTestsFile[i].name))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, dwAtt);
+ }
+
+ }
+ }
+// Trace("Value of result is %d\n", result);
+ return result;
+}
+BOOL SetUpFiles()
+{
+ int i = 0;
+ BOOL result = TRUE;
+ for (i = 0; i < numFileTests -1; i++ )
+ {
+ gfaTestsFile[i].hFile = CreateFile(gfaTestsFile[i].name,
+ desiredAccessFile,
+ shareModeFile,
+ lpAttrFile,
+ dwCreationDispFile,
+ dwFlagsAttribFile,
+ hTemplateFile);
+
+ if( gfaTestsFile[i].hFile == NULL )
+ {
+ Fail("Error while creating files for iteration %d\n", i);
+ }
+
+ if(!SetFileAttributesA (gfaTestsFile[i].name, gfaTestsFile[i].expectedAttribs))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, gfaTestsFile[i].expectedAttribs);
+ }
+ }
+
+ return result;
+}
+
+BOOL CleanUpDirs()
+{
+ DWORD dwAtt;
+ int i;
+ BOOL result = TRUE;
+ for (i = 0; i < numDirTests -1 ; i++ )
+ {
+ dwAtt = GetFileAttributesA(gfaTestsDir[i].name);
+
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+
+ if(!SetFileAttributesA (gfaTestsDir[i].name, FILE_ATTRIBUTE_DIRECTORY))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, (FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY));
+ }
+
+ if(!RemoveDirectoryA (gfaTestsDir[i].name))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, dwAtt);
+ }
+
+ }
+ }
+
+ return result;
+}
+
+BOOL SetUpDirs()
+{
+ int i = 0;
+ BOOL result = TRUE;
+ DWORD ret = 0;
+ for (i = 0; i < numDirTests - 1 ; i++ )
+ {
+ result = CreateDirectory(gfaTestsDir[i].name,
+ NULL);
+
+ if(!result )
+ {
+ result = FALSE;
+ Fail("Error while creating directory for iteration %d\n", i);
+ }
+
+ if(!SetFileAttributesA (gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs);
+ }
+
+ ret = GetFileAttributesA (gfaTestsDir[i].name);
+ if(ret != gfaTestsDir[i].expectedAttribs)
+ {
+ result = FALSE;
+ Trace("ERROR: Error setting attributes [%s][%d]\n", gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs);
+ }
+ //Trace("Setup Dir setting attr [%d], returned [%d]\n", gfaTestsDir[i].expectedAttribs, ret);
+
+ }
+ //Trace("Setup dirs returning %d\n", result);
+ return result;
+}
+int __cdecl main(int argc, char **argv)
+{
+ int i;
+ BOOL bFailed = FALSE;
+ DWORD result;
+
+ char * NormalDirectoryName = "normal_test_directory";
+ char * ReadOnlyDirectoryName = "ro_test_directory";
+ char * ReadWriteDirectoryName = "rw_directory";
+ char * HiddenDirectoryName = ".hidden_directory";
+ char * HiddenReadOnlyDirectoryName = ".hidden_ro_directory";
+ char * NoDirectoryName = "no_directory";
+
+ char * NormalFileName = "normal_test_file";
+ char * ReadOnlyFileName = "ro_test_file";
+ char * ReadWriteFileName = "rw_file";
+ char * HiddenFileName = ".hidden_file";
+ char * HiddenReadOnlyFileName = ".hidden_ro_file";
+ char * NotReallyAFileName = "not_really_a_file";
+
+ /* Tests on directory */
+ gfaTestsDir[0].name = NormalDirectoryName;
+ gfaTestsDir[0].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY;
+ gfaTestsDir[0].isFile = TYPE_DIR;
+
+ gfaTestsDir[1].name = ReadOnlyDirectoryName;
+ gfaTestsDir[1].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_READONLY;
+ gfaTestsDir[1].isFile = TYPE_DIR;
+
+ gfaTestsDir[2].name = ReadWriteDirectoryName;
+ gfaTestsDir[2].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY;
+ gfaTestsDir[2].isFile = TYPE_DIR;
+
+ gfaTestsDir[3].name = HiddenDirectoryName;
+ gfaTestsDir[3].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsDir[3].isFile = TYPE_DIR;
+
+ gfaTestsDir[4].name = HiddenReadOnlyDirectoryName;
+ gfaTestsDir[4].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_READONLY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsDir[4].isFile = TYPE_DIR;
+
+ gfaTestsDir[5].name = NoDirectoryName;
+ gfaTestsDir[5].expectedAttribs = INVALID_FILE_ATTRIBUTES;
+ gfaTestsDir[5].isFile = TYPE_DIR;
+
+ /* Tests on file */
+ gfaTestsFile[0].name = NormalFileName;
+ gfaTestsFile[0].expectedAttribs = FILE_ATTRIBUTE_NORMAL;
+ gfaTestsFile[0].isFile = TYPE_FILE;
+
+
+ gfaTestsFile[1].name = ReadOnlyFileName;
+ gfaTestsFile[1].expectedAttribs = FILE_ATTRIBUTE_READONLY;
+ gfaTestsFile[1].isFile = TYPE_FILE;
+
+ gfaTestsFile[2].name = ReadWriteFileName;
+ gfaTestsFile[2].expectedAttribs = FILE_ATTRIBUTE_NORMAL;
+ gfaTestsFile[2].isFile = TYPE_FILE;
+
+ gfaTestsFile[3].name = HiddenFileName;
+ gfaTestsFile[3].expectedAttribs = FILE_ATTRIBUTE_NORMAL; //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsFile[3].isFile = TYPE_FILE;
+
+ gfaTestsFile[4].name = HiddenReadOnlyFileName;
+ gfaTestsFile[4].expectedAttribs = FILE_ATTRIBUTE_READONLY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsFile[4].isFile = TYPE_FILE;
+
+
+ gfaTestsFile[5].name = NotReallyAFileName;
+ gfaTestsFile[5].expectedAttribs = INVALID_FILE_ATTRIBUTES;
+ gfaTestsFile[5].isFile = TYPE_FILE;
+
+ /* Initialize PAL environment */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if(!CleanUpFiles())
+ {
+ Fail("GetFileAttributesA: Pre-Clean Up Files Failed\n");
+ }
+
+ if(0 == SetUpFiles())
+ {
+ Fail("GetFileAttributesA: SetUp Files Failed\n");
+ }
+
+ if(!CleanUpDirs())
+ {
+ Fail("GetFileAttributesA: Pre-Clean Up Directories Failed\n");
+ }
+
+ if(!SetUpDirs())
+ {
+ Fail("GetFileAttributesA: SetUp Directories Failed\n");
+ }
+
+ /*
+ * Go through all the test cases above,
+ * call GetFileAttributesA on the name and
+ * make sure the return value is the one expected
+ */
+ for( i = 0; i < numFileTests; i++ )
+ {
+ result = GetFileAttributesA(gfaTestsFile[i].name);
+
+ if( result != gfaTestsFile[i].expectedAttribs )
+ {
+ bFailed = TRUE;
+
+ Trace("ERROR: GetFileAttributesA Test#%u on %s "
+ "returned %u instead of %u. \n",
+ i,
+ gfaTestsFile[i].name,
+ result,
+ gfaTestsFile[i].expectedAttribs);
+
+ }
+ }
+
+
+ for( i = 0; i < numDirTests; i++ )
+ {
+ result = GetFileAttributesA(gfaTestsDir[i].name);
+
+ if( result != gfaTestsDir[i].expectedAttribs )
+ {
+ bFailed = TRUE;
+
+ Trace("ERROR: GetFileAttributesA on Directories Test#%u on %s "
+ "returned %u instead of %u. \n",
+ i,
+ gfaTestsDir[i].name,
+ result,
+ gfaTestsDir[i].expectedAttribs);
+
+ }
+ }
+
+ if(!CleanUpFiles())
+ {
+ Fail("GetFileAttributesA: Post-Clean Up Files Failed\n");
+ }
+
+ if(!CleanUpDirs())
+ {
+ Fail("GetFileAttributesA: Post-Clean Up Directories Failed\n");
+ }
+
+ /* If any errors, just call Fail() */
+ if( bFailed )
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_file
new file mode 100644
index 0000000000..3d631e8103
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/no_file
@@ -0,0 +1 @@
+No attribs file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_file
new file mode 100644
index 0000000000..a6e1e627a8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/normal_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_file
new file mode 100644
index 0000000000..a6e1e627a8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/ro_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_file b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_file
new file mode 100644
index 0000000000..39d66f0365
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/rw_file
@@ -0,0 +1 @@
+Read Write file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/testinfo.dat
new file mode 100644
index 0000000000..2053220bf3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/testinfo.dat
@@ -0,0 +1,20 @@
+# 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 = GetFileAttributesA
+
+Name = Positive Test for GetFileAttributesA
+
+TYPE = DEFAULT
+
+EXE1 = getfileattributesa
+
+Description
+
+= Test the GetFileAttributesA function
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/anchor.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/anchor.txt
new file mode 100644
index 0000000000..9a277fa04e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_directory/anchor.txt
@@ -0,0 +1,2 @@
+This file is here so this directory gets checked out even with the -P
+option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_file b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_file
new file mode 100644
index 0000000000..0d1ac31cfa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/.hidden_file
@@ -0,0 +1 @@
+Hidden file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..2d299d82e5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_getfileattributesexw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfileattributesexw_test1 coreclrpal)
+
+target_link_libraries(paltest_getfileattributesexw_test1
+ pthread
+ m
+ coreclrpal
+)
+add_subdirectory(.hidden_directory)
+add_subdirectory(normal_test_directory)
+add_subdirectory(ro_test_directory)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_file
new file mode 100644
index 0000000000..ab7622ffb1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/normal_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_file
new file mode 100644
index 0000000000..ab7622ffb1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/ro_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c
new file mode 100644
index 0000000000..7a622b628c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c
@@ -0,0 +1,227 @@
+// 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: test1.c
+**
+** Purpose: Tests the PAL implementation of the GetFileAttributesExW function.
+** Call the function on a normal directory and file and a read-only directory
+** and file and a hidden file and directory.
+** Ensure that the attributes returned are correct, and the
+** file times and file sizes.
+**
+**
+**===================================================================*/
+
+#define UNICODE
+#include <palsuite.h>
+
+typedef enum Item
+{
+ IS_DIR,
+ IS_FILE
+}ItemType;
+
+/*
+ This is a helper function which takes two FILETIME structures and
+ checks to see if they contain the exact same time.
+*/
+int IsEqualFileTime(FILETIME FirstTime, FILETIME SecondTime)
+{
+
+ ULONG64 TimeOne, TimeTwo;
+
+ TimeOne = ((((ULONG64)FirstTime.dwHighDateTime)<<32) |
+ ((ULONG64)FirstTime.dwLowDateTime));
+
+ TimeTwo = ((((ULONG64)SecondTime.dwHighDateTime)<<32) |
+ ((ULONG64)SecondTime.dwLowDateTime));
+
+ return(TimeOne == TimeTwo);
+}
+
+/* This function takes a structure and checks that the information
+ within the structure is correct. The 'Attribs' are the expected
+ file attributes, 'TheType' is IS_DIR or IS_FILE and the 'Name' is the
+ name of the file/directory in question.
+*/
+void VerifyInfo(WIN32_FILE_ATTRIBUTE_DATA InfoStruct,
+ DWORD Attribs, ItemType TheType, WCHAR* Name)
+{
+ HANDLE hFile;
+ FILETIME CorrectCreation, CorrectAccess, CorrectModify;
+ WCHAR CopyName[64];
+
+ wcscpy(CopyName,Name);
+ free(Name);
+
+ /* Check to see that the file attributes were recorded */
+ if(InfoStruct.dwFileAttributes != Attribs)
+ {
+ Fail("ERROR: The file attributes on the file/directory were "
+ "recorded as being %d instead of %d.\n",
+ InfoStruct.dwFileAttributes,
+ Attribs);
+ }
+
+ /* Note: We can't open a handle to a directory in windows. This
+ block of tests will only be run on files.
+ */
+ if(TheType == IS_FILE)
+ {
+
+ /* Get a handle to the file */
+ hFile = CreateFile(CopyName,
+ 0,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Could not open a handle to the file "
+ "'%S'. GetLastError() returned %d.",CopyName,
+ GetLastError());
+ }
+
+
+
+ /* Get the FileTime of the file in question */
+ if(GetFileTime(hFile, &CorrectCreation,
+ &CorrectAccess, &CorrectModify) == 0)
+ {
+ Fail("ERROR: GetFileTime failed to get the filetime of the "
+ "file. GetLastError() returned %d.",
+ GetLastError());
+ }
+
+ /* Check that the Creation, Access and Last Modified times are all
+ the same in the structure as what GetFileTime just returned.
+ */
+ if(!IsEqualFileTime(CorrectCreation, InfoStruct.ftCreationTime))
+ {
+ Fail("ERROR: The creation time of the file "
+ "does not match the creation time given from "
+ "GetFileTime.\n");
+ }
+ if(!IsEqualFileTime(CorrectAccess, InfoStruct.ftLastAccessTime))
+ {
+ Fail("ERROR: The access time of the file "
+ "does not match the access time given from "
+ "GetFileTime.\n");
+ }
+ if(!IsEqualFileTime(CorrectModify, InfoStruct.ftLastWriteTime))
+ {
+ Fail("ERROR: The write time of the file "
+ "does not match the last write time given from "
+ "GetFileTime.\n");
+ }
+
+ if(InfoStruct.nFileSizeLow != GetFileSize(hFile,NULL))
+ {
+ Fail("ERROR: The file size reported by GetFileAttributesEx "
+ "did not match the file size given by GetFileSize.\n");
+ }
+
+ if(CloseHandle(hFile) == 0)
+ {
+ Fail("ERROR: Failed to properly close the handle to the "
+ "file we're testing. GetLastError() returned %d.\n",
+ GetLastError());
+
+ }
+
+ }
+
+
+}
+
+/* Given a file/directory name, the expected attribs and whether or not it
+ is a file or directory, call GetFileAttributesEx and verify the
+ results are correct.
+*/
+
+void RunTest(char* Name, DWORD Attribs, ItemType TheType )
+{
+ WCHAR* TheName;
+ WIN32_FILE_ATTRIBUTE_DATA InfoStruct;
+ DWORD TheResult;
+
+ TheName = convert(Name);
+
+ TheResult = GetFileAttributesEx(TheName,
+ GetFileExInfoStandard,
+ &InfoStruct);
+ if(TheResult == 0)
+ {
+ free(TheName);
+ Fail("ERROR: GetFileAttributesEx returned 0, indicating failure. "
+ "GetLastError returned %d.\n",GetLastError());
+ }
+
+ VerifyInfo(InfoStruct, Attribs, TheType, TheName);
+
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ WCHAR* FileName;
+ WIN32_FILE_ATTRIBUTE_DATA InfoStruct;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Test a Directroy */
+ RunTest("normal_test_directory", FILE_ATTRIBUTE_DIRECTORY, IS_DIR);
+
+
+ /* Test a Normal File */
+
+ RunTest("normal_test_file", FILE_ATTRIBUTE_NORMAL, IS_FILE);
+
+ /* Test a Read-Only Directroy */
+
+ RunTest("ro_test_directory",
+ FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_DIRECTORY, IS_DIR);
+
+ /* Test a Read-Only File */
+
+ RunTest("ro_test_file", FILE_ATTRIBUTE_READONLY, IS_FILE);
+
+ /* Test a Hidden File */
+
+ RunTest(".hidden_file", FILE_ATTRIBUTE_HIDDEN, IS_FILE);
+
+ /* Test a Hidden Directroy */
+
+ RunTest(".hidden_directory",
+ FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY, IS_DIR);
+
+ /* Test a Non-Existant File */
+
+ FileName = convert("nonexistent_test_file");
+
+ TheResult = GetFileAttributesEx(FileName,
+ GetFileExInfoStandard,
+ &InfoStruct);
+
+ if(TheResult != 0)
+ {
+ free(FileName);
+ Fail("ERROR: GetFileAttributesEx returned non-zero, indicating "
+ "success when it should have failed. It was called on a "
+ "non-existent file.");
+ }
+
+ free(FileName);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/testinfo.dat
new file mode 100644
index 0000000000..fbc397eac0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/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 = GetFileAttributesExW
+Name = Test with normal file/dir and readonly file/dir and hidden file/dir
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Tests the PAL implementation of the GetFileAttributesExW function.
+= Call the function on a normal directory and file and a read-only directory
+= and file and a hidden file and directory.
+= Ensure that the attributes returned are correct, and the
+= file times and file sizes.
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..70caac2c69
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_getfileattributesexw_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfileattributesexw_test2 coreclrpal)
+
+target_link_libraries(paltest_getfileattributesexw_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c
new file mode 100644
index 0000000000..f244a3bf6a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c
@@ -0,0 +1,170 @@
+// 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: getfileattributesexw.c (getfileattributesexw\test2)
+**
+** Purpose: Tests the PAL implementation of GetFileAttributesExW.
+** First get a file's attributes, modify the file,
+** re-get its attributes
+** and compare the two sets of attributes.
+**
+**
+**===================================================================*/
+#include <palsuite.h>
+
+/**
+ * This is a helper function which takes two FILETIME structures and
+ * checks that the second time isn't before the first.
+ */
+static int IsFileTimeOk(FILETIME FirstTime, FILETIME SecondTime)
+{
+
+ ULONG64 TimeOne, TimeTwo;
+
+ TimeOne = ((((ULONG64)FirstTime.dwHighDateTime)<<32) |
+ ((ULONG64)FirstTime.dwLowDateTime));
+
+ TimeTwo = ((((ULONG64)SecondTime.dwHighDateTime)<<32) |
+ ((ULONG64)SecondTime.dwLowDateTime));
+
+ return(TimeOne <= TimeTwo);
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD res;
+ char fileName[MAX_PATH] = "test_file";
+ WCHAR *wFileName;
+ WIN32_FILE_ATTRIBUTE_DATA beforeAttribs;
+ WIN32_FILE_ATTRIBUTE_DATA afterAttribs;
+ FILE *testFile;
+ ULONG64 beforeFileSize;
+ ULONG64 afterFileSize;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Create the file */
+ testFile = fopen(fileName, "w+");
+ if( NULL == testFile )
+ {
+ Fail("Unexpected error: Unable to open file %S "
+ "with fopen. \n",
+ fileName);
+ }
+
+ if( EOF == fputs( "testing", testFile ) )
+ {
+ Fail("Unexpected error: Unable to write to file %S "
+ "with fputs. \n",
+ fileName);
+ }
+
+ if( 0 != fclose(testFile) )
+ {
+ Fail("Unexpected error: Unable to close file %S "
+ "with fclose. \n",
+ fileName);
+ }
+
+ /* Test the Values returned by GetFileAttributesExW
+ * before and after manipulating a file shouldn't be the same.
+ */
+
+ wFileName = convert(fileName);
+
+ res = GetFileAttributesExW(wFileName,
+ GetFileExInfoStandard,
+ &beforeAttribs);
+
+ if(res == 0)
+ {
+ Fail("ERROR: unable to get initial file attributes with "
+ "GetFileAttributesEx that returned 0 with error %d.\n",
+ GetLastError());
+ }
+
+ /* Make sure the time are different */
+ Sleep(500);
+
+ testFile = fopen(fileName, "w+");
+ if( NULL == testFile )
+ {
+ Fail("Unexpected error: Unable to open file %S "
+ "with fopen. \n",
+ fileName);
+ }
+
+ if( EOF == fputs( "testing GetFileAttributesExW", testFile ) )
+ {
+ Fail("Unexpected error: Unable to write to file %S "
+ "with fputs. \n",
+ fileName);
+ }
+
+ if( 0 != fclose(testFile) )
+ {
+ Fail("Unexpected error: Unable to close file %S "
+ "with fclose. \n",
+ fileName);
+ }
+
+ res = GetFileAttributesExW(wFileName,
+ GetFileExInfoStandard,
+ &afterAttribs);
+
+ if(res == 0)
+ {
+ Fail("ERROR: unable to get file attributes after operations with "
+ "GetFileAttributesEx that returned 0 with error %d.\n",
+ GetLastError());
+ }
+
+ /* Check the creation time */
+ if(!IsFileTimeOk(beforeAttribs.ftCreationTime,
+ afterAttribs.ftCreationTime))
+ {
+ Fail("ERROR: Creation time after the fputs operation "
+ "is earlier than the creation time before the fputs.\n");
+ }
+
+ /* Check the last access time */
+ if(!IsFileTimeOk(beforeAttribs.ftLastAccessTime,
+ afterAttribs.ftLastAccessTime))
+ {
+ Fail("ERROR: Last access time after the fputs operation "
+ "is earlier than the last access time before the fputs.\n");
+ }
+
+ /* Check the last write time */
+ if(!IsFileTimeOk(beforeAttribs.ftLastWriteTime,
+ afterAttribs.ftLastWriteTime))
+ {
+ Fail("ERROR: Last write time after the fputs operation "
+ "is earlier than the last write time before the fputs.\n");
+ }
+
+ beforeFileSize = ((ULONG64)beforeAttribs.nFileSizeHigh)<< 32 |
+ ((ULONG64)beforeAttribs.nFileSizeLow);
+
+ afterFileSize = ((ULONG64)afterAttribs.nFileSizeHigh)<< 32 |
+ ((ULONG64)afterAttribs.nFileSizeLow);
+
+ /* Check the file size */
+ if( afterFileSize <= beforeFileSize )
+ {
+ Fail("ERROR: the file should have had a bigger size "
+ "after(%d) the operations than before(%d)\n",
+ afterAttribs.nFileSizeLow,
+ beforeAttribs.nFileSizeLow);
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/testinfo.dat
new file mode 100644
index 0000000000..560e3f6266
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/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 = GetFileAttributesExW
+Name = Test for GetFileAttributesExW
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Tests the PAL implementation of the GetFileAttributesExW function.
+= First get a file's attributes, modify the file, re-get its attributes
+= and compare the two sets of attributes
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_file
new file mode 100644
index 0000000000..0d1ac31cfa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_file
@@ -0,0 +1 @@
+Hidden file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_file
new file mode 100644
index 0000000000..8f78fcb436
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/.hidden_ro_file
@@ -0,0 +1 @@
+.hidden_ro_file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..7050484607
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileAttributesW.c
+)
+
+add_executable(paltest_getfileattributesw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfileattributesw_test1 coreclrpal)
+
+target_link_libraries(paltest_getfileattributesw_test1
+ pthread
+ m
+ coreclrpal
+)
+add_subdirectory(.hidden_directory)
+add_subdirectory(.hidden_ro_directory)
+add_subdirectory(normal_test_directory)
+add_subdirectory(no_directory)
+add_subdirectory(ro_test_directory)
+add_subdirectory(rw_test_directory)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c
new file mode 100644
index 0000000000..9d00da4bd4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c
@@ -0,0 +1,345 @@
+// 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: GetFileAttributesW.c
+**
+** Purpose: Tests the PAL implementation of the GetFileAttributesW function by
+** checking the attributes of:
+** - a normal directory and file
+** - a read only directory and file
+** - a read write directory and file
+** - a hidden directory and file
+** - a read only hidden directory and file
+** - a directory and a file with no attributes
+** - an invalid file name
+**
+**
+**===========================================================================*/
+#include <palsuite.h>
+
+const int TYPE_DIR = 0;
+const int TYPE_FILE = 1;
+/* Structure defining a test case */
+typedef struct
+{
+ char *name; /* name of the file/directory */
+ DWORD expectedAttribs; /* expected attributes */
+ HANDLE hFile; /* Handle to the file */
+ int isFile; /* is file (1) or dir (0) */
+}TestCaseFile;
+
+typedef struct
+{
+ char *name; /* name of the file/directory */
+ DWORD expectedAttribs; /* expected attributes */
+ HANDLE hFile; /* Handle to the file */
+ int isFile; /* is file (1) or dir (0) */
+}TestCaseDir;
+
+DWORD desiredAccessFile = GENERIC_READ | GENERIC_WRITE;
+DWORD shareModeFile = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
+LPSECURITY_ATTRIBUTES lpAttrFile = NULL;
+DWORD dwCreationDispFile = CREATE_NEW;
+DWORD dwFlagsAttribFile = FILE_ATTRIBUTE_NORMAL;
+HANDLE hTemplateFile = NULL;
+
+int numFileTests = 6;
+TestCaseFile gfaTestsFile[6]; /* GetFileAttributes tests list */
+
+int numDirTests = 6;
+TestCaseDir gfaTestsDir[6]; /* GetFileAttributes tests list */
+
+BOOL CleanUpFiles()
+{
+ DWORD dwAtt;
+ int i;
+ BOOL result = TRUE;
+ for (i = 0; i < numFileTests - 1 ; i++ )
+ {
+ dwAtt = GetFileAttributesA(gfaTestsFile[i].name);
+
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+ //Trace("Files iteration %d\n", i);
+ if(!SetFileAttributesA (gfaTestsFile[i].name, FILE_ATTRIBUTE_NORMAL))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, FILE_ATTRIBUTE_NORMAL);
+ }
+
+ if(!DeleteFileA (gfaTestsFile[i].name))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, dwAtt);
+ }
+
+ }
+ }
+// Trace("Value of result is %d\n", result);
+ return result;
+}
+BOOL SetUpFiles()
+{
+ int i = 0;
+ BOOL result = TRUE;
+ for (i = 0; i < numFileTests - 1 ; i++ )
+ {
+ gfaTestsFile[i].hFile = CreateFile(gfaTestsFile[i].name,
+ desiredAccessFile,
+ shareModeFile,
+ lpAttrFile,
+ dwCreationDispFile,
+ dwFlagsAttribFile,
+ hTemplateFile);
+
+ if( gfaTestsFile[i].hFile == NULL )
+ {
+ Fail("Error while creating files for iteration %d\n", i);
+ }
+
+ if(!SetFileAttributesA (gfaTestsFile[i].name, gfaTestsFile[i].expectedAttribs))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsFile[i].name, gfaTestsFile[i].expectedAttribs);
+ }
+ }
+
+ return result;
+}
+
+BOOL CleanUpDirs()
+{
+ DWORD dwAtt;
+ int i;
+ BOOL result = TRUE;
+ for (i = 0; i < numDirTests - 1; i++ )
+ {
+ dwAtt = GetFileAttributesA(gfaTestsDir[i].name);
+
+ if( dwAtt != INVALID_FILE_ATTRIBUTES )
+ {
+
+ if(!SetFileAttributesA (gfaTestsDir[i].name, FILE_ATTRIBUTE_DIRECTORY))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, (FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY));
+ }
+
+ if(!RemoveDirectoryA (gfaTestsDir[i].name))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error deleting file [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, dwAtt);
+ }
+
+ }
+ }
+
+ return result;
+}
+
+BOOL SetUpDirs()
+{
+ int i = 0;
+ BOOL result = TRUE;
+ DWORD ret = 0;
+ for (i = 0; i < numDirTests - 1; i++ )
+ {
+ result = CreateDirectory(gfaTestsDir[i].name,
+ NULL);
+
+ if(!result )
+ {
+ result = FALSE;
+ Fail("Error while creating directory for iteration %d\n", i);
+ }
+
+ if(!SetFileAttributesA (gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs))
+ {
+ result = FALSE;
+ Trace("ERROR:%d: Error setting attributes [%s][%d]\n", GetLastError(), gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs);
+ }
+
+ ret = GetFileAttributesA (gfaTestsDir[i].name);
+ if(ret != gfaTestsDir[i].expectedAttribs)
+ {
+ result = FALSE;
+ Trace("ERROR: Error setting attributes [%s][%d]\n", gfaTestsDir[i].name, gfaTestsDir[i].expectedAttribs);
+ }
+ // Trace("Setup Dir setting attr [%d], returned [%d]\n", gfaTestsDir[i].expectedAttribs, ret);
+
+ }
+// Trace("Setup dirs returning %d\n", result);
+ return result;
+}
+int __cdecl main(int argc, char **argv)
+{
+ int i;
+ BOOL bFailed = FALSE;
+ DWORD result;
+
+ char * NormalDirectoryName = "normal_test_directory";
+ char * ReadOnlyDirectoryName = "ro_test_directory";
+ char * ReadWriteDirectoryName = "rw_directory";
+ char * HiddenDirectoryName = ".hidden_directory";
+ char * HiddenReadOnlyDirectoryName = ".hidden_ro_directory";
+ char * NoDirectoryName = "no_directory";
+
+ char * NormalFileName = "normal_test_file";
+ char * ReadOnlyFileName = "ro_test_file";
+ char * ReadWriteFileName = "rw_file";
+ char * HiddenFileName = ".hidden_file";
+ char * HiddenReadOnlyFileName = ".hidden_ro_file";
+ char * NotReallyAFileName = "not_really_a_file";
+
+ WCHAR *WStr;
+ /* Tests on directory */
+ gfaTestsDir[0].name = NormalDirectoryName;
+ gfaTestsDir[0].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY;
+ gfaTestsDir[0].isFile = TYPE_DIR;
+
+ gfaTestsDir[1].name = ReadOnlyDirectoryName;
+ gfaTestsDir[1].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_READONLY;
+ gfaTestsDir[1].isFile = TYPE_DIR;
+
+ gfaTestsDir[2].name = ReadWriteDirectoryName;
+ gfaTestsDir[2].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY;
+ gfaTestsDir[2].isFile = TYPE_DIR;
+
+ gfaTestsDir[3].name = HiddenDirectoryName;
+ gfaTestsDir[3].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsDir[3].isFile = TYPE_DIR;
+
+ gfaTestsDir[4].name = HiddenReadOnlyDirectoryName;
+ gfaTestsDir[4].expectedAttribs = FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_READONLY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsDir[4].isFile = TYPE_DIR;
+
+ gfaTestsDir[5].name = NoDirectoryName;
+ gfaTestsDir[5].expectedAttribs = INVALID_FILE_ATTRIBUTES;
+ gfaTestsDir[5].isFile = TYPE_DIR;
+
+ /* Tests on file */
+ gfaTestsFile[0].name = NormalFileName;
+ gfaTestsFile[0].expectedAttribs = FILE_ATTRIBUTE_NORMAL;
+ gfaTestsFile[0].isFile = TYPE_FILE;
+
+
+ gfaTestsFile[1].name = ReadOnlyFileName;
+ gfaTestsFile[1].expectedAttribs = FILE_ATTRIBUTE_READONLY;
+ gfaTestsFile[1].isFile = TYPE_FILE;
+
+ gfaTestsFile[2].name = ReadWriteFileName;
+ gfaTestsFile[2].expectedAttribs = FILE_ATTRIBUTE_NORMAL;
+ gfaTestsFile[2].isFile = TYPE_FILE;
+
+ gfaTestsFile[3].name = HiddenFileName;
+ gfaTestsFile[3].expectedAttribs = FILE_ATTRIBUTE_NORMAL; //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsFile[3].isFile = TYPE_FILE;
+
+ gfaTestsFile[4].name = HiddenReadOnlyFileName;
+ gfaTestsFile[4].expectedAttribs = FILE_ATTRIBUTE_READONLY; //|
+ //FILE_ATTRIBUTE_HIDDEN;
+ gfaTestsFile[4].isFile = TYPE_FILE;
+
+
+ gfaTestsFile[5].name = NotReallyAFileName;
+ gfaTestsFile[5].expectedAttribs = INVALID_FILE_ATTRIBUTES;
+ gfaTestsFile[5].isFile = TYPE_FILE;
+
+ /* Initialize PAL environment */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if(!CleanUpFiles())
+ {
+ Fail("GetFileAttributesW: Pre-Clean Up Files Failed\n");
+ }
+
+ if(0 == SetUpFiles())
+ {
+ Fail("GetFileAttributesW: SetUp Files Failed\n");
+ }
+
+ if(!CleanUpDirs())
+ {
+ Fail("GetFileAttributesW: Pre-Clean Up Directories Failed\n");
+ }
+
+ if(!SetUpDirs())
+ {
+ Fail("GetFileAttributesW: SetUp Directories Failed\n");
+ }
+
+ /*
+ * Go through all the test cases above,
+ * call GetFileAttributesW on the name and
+ * make sure the return value is the one expected
+ */
+ for( i = 0; i < numFileTests; i++ )
+ {
+ WStr = convert(gfaTestsFile[i].name);
+ result = GetFileAttributesW(WStr);
+
+ if( result != gfaTestsFile[i].expectedAttribs )
+ {
+ bFailed = TRUE;
+
+ Trace("ERROR: GetFileAttributesW Test#%u on %s "
+ "returned %u instead of %u. \n",
+ i,
+ gfaTestsFile[i].name,
+ result,
+ gfaTestsFile[i].expectedAttribs);
+
+ }
+ free(WStr);
+ }
+
+
+ for( i = 0; i < numDirTests; i++ )
+ {
+ WStr = convert(gfaTestsDir[i].name);
+ result = GetFileAttributesW(WStr);
+
+ if( result != gfaTestsDir[i].expectedAttribs )
+ {
+ bFailed = TRUE;
+
+ Trace("ERROR: GetFileAttributesW on Directories Test#%u on %s "
+ "returned %u instead of %u. \n",
+ i,
+ gfaTestsDir[i].name,
+ result,
+ gfaTestsDir[i].expectedAttribs);
+
+ }
+ free(WStr);
+ }
+
+ if(!CleanUpFiles())
+ {
+ Fail("GetFileAttributesW: Post-Clean Up Files Failed\n");
+ }
+
+ if(!CleanUpDirs())
+ {
+ Fail("GetFileAttributesW: Post-Clean Up Directories Failed\n");
+ }
+
+ /* If any errors, just call Fail() */
+ if( bFailed )
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_file
new file mode 100644
index 0000000000..3d631e8103
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/no_file
@@ -0,0 +1 @@
+No attribs file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_file
new file mode 100644
index 0000000000..a6e1e627a8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/normal_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_file
new file mode 100644
index 0000000000..a6e1e627a8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/ro_test_file
@@ -0,0 +1,6 @@
+file_io
+CopyFileW
+Positive Test for CopyFileW
+test the CopyFileW function
+DEFAULT
+CopyFileW \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_file b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_file
new file mode 100644
index 0000000000..39d66f0365
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_file
@@ -0,0 +1 @@
+Read Write file \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/CMakeLists.txt
new file mode 100644
index 0000000000..a8fd227402
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/keepme b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/keepme
new file mode 100644
index 0000000000..31eade7217
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/rw_test_directory/keepme
@@ -0,0 +1 @@
+Make CVS checkout this directory even with -p option. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/testinfo.dat
new file mode 100644
index 0000000000..1a8089a0f1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/testinfo.dat
@@ -0,0 +1,20 @@
+# 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 = GetFileAttributesW
+
+Name = Positive Test for GetFileAttributesW
+
+TYPE = DEFAULT
+
+EXE1 = getfileattributesw
+
+Description
+
+= Test the GetFileAttributesW function
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSize/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt
new file mode 100644
index 0000000000..ff20de5905
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileSize.c
+)
+
+add_executable(paltest_getfilesize_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfilesize_test1 coreclrpal)
+
+target_link_libraries(paltest_getfilesize_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c b/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c
new file mode 100644
index 0000000000..fac01c98c9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c
@@ -0,0 +1,173 @@
+// 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: GetFileSize.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetFileSize function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+void CleanUp(HANDLE hFile)
+{
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Fail("GetFileSize: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("GetFileSize: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+}
+
+void CheckFileSize(HANDLE hFile, DWORD dwOffset, DWORD dwHighOrder)
+{
+ DWORD dwRc = 0;
+ DWORD dwReturnedHighOrder = 0;
+ DWORD dwReturnedOffset = 0;
+
+ dwRc = SetFilePointer(hFile, dwOffset, (PLONG)&dwHighOrder, FILE_BEGIN);
+ if (dwRc == INVALID_SET_FILE_POINTER)
+ {
+ Trace("GetFileSize: ERROR -> Call to SetFilePointer failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+ else
+ {
+ if (!SetEndOfFile(hFile))
+ {
+ Trace("GetFileSize: ERROR -> Call to SetEndOfFile failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+ dwReturnedOffset = GetFileSize(hFile, &dwReturnedHighOrder);
+ if ((dwReturnedOffset != dwOffset) ||
+ (dwReturnedHighOrder != dwHighOrder))
+ {
+ CleanUp(hFile);
+ Fail("GetFileSize: ERROR -> File sizes do not match up.\n");
+ }
+ }
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwRc = 0;
+ DWORD dwRc2 = 0;
+ DWORD dwHighOrder = 0;
+ DWORD lpNumberOfBytesWritten;
+ char * data = "1234567890";
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* test on a null file handle */
+ dwRc = GetFileSize(hFile, NULL);
+ if (dwRc != INVALID_FILE_SIZE)
+ {
+ Fail("GetFileSize: ERROR -> A file size was returned for "
+ "a null handle.\n");
+ }
+
+ /* test on a null file handle using the high order option */
+ dwRc = GetFileSize(hFile, &dwHighOrder);
+ if (dwRc != INVALID_FILE_SIZE)
+ {
+ Fail("GetFileSize: ERROR -> A file size was returned for "
+ "a null handle.\n");
+ }
+
+ /* test on an invalid file handle */
+ dwRc = GetFileSize(INVALID_HANDLE_VALUE, NULL);
+ if (dwRc != INVALID_FILE_SIZE)
+ {
+ Fail("GetFileSize: ERROR -> A file size was returned for "
+ "an invalid handle.\n");
+ }
+
+ /* test on an invalid file handle using the high order option */
+ dwRc = GetFileSize(INVALID_HANDLE_VALUE, &dwHighOrder);
+ if (dwRc != INVALID_FILE_SIZE)
+ {
+ Fail("GetFileSize: ERROR -> A file size was returned for "
+ "an invalid handle.\n");
+ }
+
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFileSize: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ /* give the file a size */
+ CheckFileSize(hFile, 256, 0);
+
+ /* make the file large using the high order option */
+ CheckFileSize(hFile, 256, 1);
+
+
+ /* set the file size to zero */
+ CheckFileSize(hFile, 0, 0);
+
+ /* test if file size changes by writing to it. */
+ /* get file size */
+ dwRc = GetFileSize(hFile, NULL);
+
+ /* test writing to the file */
+ if(WriteFile(hFile, data, strlen(data), &lpNumberOfBytesWritten, NULL)==0)
+ {
+ Trace("GetFileSize: ERROR -> Call to WriteFile failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+
+ /* make sure the buffer flushed.*/
+ if(FlushFileBuffers(hFile)==0)
+ {
+ Trace("GetFileSize: ERROR -> Call to FlushFileBuffers failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+
+ /* get file size after writing some chars */
+ dwRc2 = GetFileSize(hFile, NULL);
+ if((dwRc2-dwRc) !=strlen(data))
+ {
+ CleanUp(hFile);
+ Fail("GetFileSize: ERROR -> File size did not increase properly after.\n"
+ "writing %d chars\n", strlen(data));
+ }
+
+ CleanUp(hFile);
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileSize/test1/testinfo.dat
new file mode 100644
index 0000000000..38258572db
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetFileSize
+Name = Positive Test for GetFileSize (test 1)
+Type = DEFAULT
+EXE1 = getfilesize
+Description
+= Test GetFileSize on a NULL handle and valid file handles
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSizeEx/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt
new file mode 100644
index 0000000000..1369a5dc5a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileSizeEx.c
+)
+
+add_executable(paltest_getfilesizeex_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfilesizeex_test1 coreclrpal)
+
+target_link_libraries(paltest_getfilesizeex_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c
new file mode 100644
index 0000000000..ef5afd0e6b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c
@@ -0,0 +1,173 @@
+// 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: GetFileSizeEx.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetFileSizeEx function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+void CleanUp(HANDLE hFile)
+{
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Fail("GetFileSizeEx: ERROR -> Unable to close file \"%s\".\n"
+ " Error is %d\n",
+ szTextFile, GetLastError());
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("GetFileSizeEx: ERROR -> Unable to delete file \"%s\".\n"
+ " Error is %d\n",
+ szTextFile, GetLastError());
+ }
+}
+
+void CheckFileSize(HANDLE hFile, DWORD dwOffset, DWORD dwHighOrder)
+{
+ DWORD dwRc = 0;
+ DWORD dwError = 0;
+ LARGE_INTEGER qwFileSize;
+
+ dwRc = SetFilePointer(hFile, dwOffset, (PLONG)&dwHighOrder, FILE_BEGIN);
+ if (dwRc == INVALID_SET_FILE_POINTER)
+ {
+ Trace("GetFileSizeEx: ERROR -> Call to SetFilePointer failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+ else
+ {
+ if (!SetEndOfFile(hFile))
+ {
+ dwError = GetLastError();
+ CleanUp(hFile);
+ if (dwError == 112)
+ {
+ Fail("GetFileSizeEx: ERROR -> SetEndOfFile failed due to lack of "
+ "disk space\n");
+ }
+ else
+ {
+ Fail("GetFileSizeEx: ERROR -> SetEndOfFile call failed "
+ "with error %ld\n", dwError);
+ }
+ }
+ else
+ {
+ GetFileSizeEx(hFile, &qwFileSize);
+ if ((qwFileSize.u.LowPart != dwOffset) ||
+ (qwFileSize.u.HighPart != dwHighOrder))
+ {
+ CleanUp(hFile);
+ Fail("GetFileSizeEx: ERROR -> File sizes do not match up.\n");
+ }
+ }
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ BOOL bRc = FALSE;
+ DWORD lpNumberOfBytesWritten;
+ LARGE_INTEGER qwFileSize;
+ LARGE_INTEGER qwFileSize2;
+ char * data = "1234567890";
+
+ qwFileSize.QuadPart = 0;
+ qwFileSize2.QuadPart = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* test on a null file */
+ bRc = GetFileSizeEx(NULL, &qwFileSize);
+ if (bRc != FALSE)
+ {
+ Fail("GetFileSizeEx: ERROR -> Returned status as TRUE for "
+ "a null handle.\n");
+ }
+
+
+ /* test on an invalid file */
+ bRc = GetFileSizeEx(INVALID_HANDLE_VALUE, &qwFileSize);
+ if (bRc != FALSE)
+ {
+ Fail("GetFileSizeEx: ERROR -> Returned status as TRUE for "
+ "an invalid handle.\n");
+ }
+
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFileSizeEx: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ /* give the file a size */
+ CheckFileSize(hFile, 256, 0);
+
+ /* make the file large using the high order option */
+ CheckFileSize(hFile, 256, 1);
+
+
+ /* set the file size to zero */
+ CheckFileSize(hFile, 0, 0);
+
+ /* test if file size changes by writing to it. */
+ /* get file size */
+ GetFileSizeEx(hFile, &qwFileSize);
+
+ /* test writing to the file */
+ if(WriteFile(hFile, data, strlen(data), &lpNumberOfBytesWritten, NULL)==0)
+ {
+ Trace("GetFileSizeEx: ERROR -> Call to WriteFile failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+
+ /* make sure the buffer flushed.*/
+ if(FlushFileBuffers(hFile)==0)
+ {
+ Trace("GetFileSizeEx: ERROR -> Call to FlushFileBuffers failed with %ld.\n",
+ GetLastError());
+ CleanUp(hFile);
+ Fail("");
+ }
+
+ /* get file size after writing some chars */
+ GetFileSizeEx(hFile, &qwFileSize2);
+ if((qwFileSize2.QuadPart-qwFileSize.QuadPart) !=strlen(data))
+ {
+ CleanUp(hFile);
+ Fail("GetFileSizeEx: ERROR -> File size did not increase properly after.\n"
+ "writing %d chars\n", strlen(data));
+ }
+
+ CleanUp(hFile);
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/testinfo.dat
new file mode 100644
index 0000000000..5968fe7271
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetFileSizeEx
+Name = Positive Test for GetFileSizeEx (test 1)
+Type = DEFAULT
+EXE1 = getfilesizeex
+Description
+= Test GetFileSizeEx on a NULL handle and valid file handles
+
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
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt
new file mode 100644
index 0000000000..66467e99c5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFileType.c
+)
+
+add_executable(paltest_getfiletype_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletype_test1 coreclrpal)
+
+target_link_libraries(paltest_getfiletype_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c b/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c
new file mode 100644
index 0000000000..6558c00bdd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c
@@ -0,0 +1,76 @@
+// 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: GetFileType.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetFileType function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwRc = 0;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* test FILE_TYPE_UNKNOWN */
+ dwRc = GetFileType(hFile);
+ if (dwRc != FILE_TYPE_UNKNOWN)
+ {
+ Fail("GetFileType: ERROR -> Was expecting a return type of "
+ "FILE_TYPE_UNKNOWN but the function returned %ld.\n",
+ dwRc);
+ }
+
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFileType: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ dwRc = GetFileType(hFile);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Fail("GetFileType: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("GetFileType: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+
+ if (dwRc != FILE_TYPE_DISK)
+ {
+ Fail("GetFileType: ERROR -> Was expecting a return type of "
+ "FILE_TYPE_DISK but the function returned %ld.\n",
+ dwRc);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileType/test1/testinfo.dat
new file mode 100644
index 0000000000..f12a81a20b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetFileType
+Name = Positive Test for GetFileType (test 1)
+Type = DEFAULT
+EXE1 = getfiletype
+Description
+= Test GetFileType on a NULL handle and a valid handle to a file
+
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt
new file mode 100644
index 0000000000..382b27e788
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getfiletype.c
+)
+
+add_executable(paltest_getfiletype_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletype_test2 coreclrpal)
+
+target_link_libraries(paltest_getfiletype_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c b/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c
new file mode 100644
index 0000000000..c9d4eb6572
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c
@@ -0,0 +1,95 @@
+// 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: getfiletype.c
+**
+** Purpose: Test the PAL implementation of GetFileType to ensure it
+** recognizes opened pipes.
+**
+** Depends: CreatePipe
+** CloseHandle
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+ HANDLE hReadPipe = NULL;
+ HANDLE hWritePipe = NULL;
+ BOOL bRetVal = FALSE;
+ DWORD dwFileType;
+ SECURITY_ATTRIBUTES lpPipeAttributes;
+
+ /*Initialize the PAL*/
+ if ((PAL_Initialize(argc, argv)) != 0)
+ {
+ return (FAIL);
+ }
+
+ /*
+ ** create a pipe and make sure GetFileType returns the correct value
+ */
+
+ /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/
+ lpPipeAttributes.nLength = sizeof(lpPipeAttributes);
+ lpPipeAttributes.lpSecurityDescriptor = NULL;
+ lpPipeAttributes.bInheritHandle = TRUE;
+
+ /*Create a Pipe*/
+ bRetVal = CreatePipe(&hReadPipe, /* read handle*/
+ &hWritePipe, /* write handle */
+ &lpPipeAttributes, /* security attributes*/
+ 0); /* pipe size*/
+ if (bRetVal == FALSE)
+ {
+ Fail("ERROR: %u :Unable to create pipe.\n", GetLastError());
+ }
+
+ // Get the file type
+ dwFileType = GetFileType(hReadPipe);
+ if (dwFileType != FILE_TYPE_PIPE)
+ {
+ if (!CloseHandle(hWritePipe))
+ {
+ Trace("ERROR: %u : Unable to close write pipe handle "
+ "hWritePipe=0x%lx\n", GetLastError(), hWritePipe);
+ }
+ if (!CloseHandle(hReadPipe))
+ {
+ Trace("ERROR: %u : Unable to close read pipe handle "
+ "hReadPipe=0x%lx\n", GetLastError(), hReadPipe);
+ }
+ Fail("ERROR: GetFileType returned %u for a pipe instead of the "
+ "expected FILE_TYPE_PIPE (%u).\n",
+ dwFileType,
+ FILE_TYPE_PIPE);
+ }
+
+ /*Close write pipe handle*/
+ if (!CloseHandle(hWritePipe))
+ {
+ if (!CloseHandle(hReadPipe))
+ {
+ Trace("ERROR: %u : Unable to close read pipe handle "
+ "hReadPipe=0x%lx\n", GetLastError(), hReadPipe);
+ }
+ Fail("ERROR: %u : Unable to close write pipe handle "
+ "hWritePipe=0x%lx\n", GetLastError(), hWritePipe);
+ }
+
+ /*Close Read pipe handle*/
+ if (!CloseHandle(hReadPipe))
+ {
+ Fail("ERROR: %u : Unable to close read pipe handle "
+ "hReadPipe=0x%lx\n", GetLastError(), hReadPipe);
+ }
+
+ PAL_Terminate();
+ return (PASS);
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileType/test2/testinfo.dat
new file mode 100644
index 0000000000..eb1361d3f6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetFileType
+Name = Test for GetFileType
+TYPE = DEFAULT
+EXE1 = getfiletype
+Description
+= Test the PAL implementation of GetFileType to ensure it
+= recognizes opened pipes.
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt
new file mode 100644
index 0000000000..52b6077570
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getfiletype.c
+)
+
+add_executable(paltest_getfiletype_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfiletype_test3 coreclrpal)
+
+target_link_libraries(paltest_getfiletype_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c b/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c
new file mode 100644
index 0000000000..6a95585bab
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c
@@ -0,0 +1,72 @@
+// 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: getfiletype.c
+**
+** Purpose: Test the PAL implementation of the GetFileType on a handle
+** to a console.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile;
+#if WIN32
+ char *lpFileName = "CONIN$";
+#else
+ char *lpFileName = "/dev/null";
+#endif
+ DWORD dwFileType;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* get a handle to the console */
+ hFile = CreateFile(lpFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFileType: ERROR: CreateFile failed to open %s with "
+ "error %u.\n",
+ lpFileName,
+ GetLastError());
+ }
+
+ /* Get the file type */
+ if ((dwFileType = GetFileType(hFile)) != FILE_TYPE_CHAR)
+ {
+ if (!CloseHandle(hFile))
+ {
+ Trace("GetFileType: ERROR: %u : Unable to close the handle "
+ "hFile=0x%lx\n", GetLastError(), hFile);
+ }
+ Fail("GetFileType: ERROR: GetFileType returned %u for a device "
+ "instead of the expected FILE_TYPE_CHAR (%u).\n",
+ dwFileType,
+ FILE_TYPE_CHAR);
+ }
+
+ if (!CloseHandle(hFile))
+ {
+ Fail("GetFileType: ERROR: %u : Unable to close the handle "
+ "hFile=0x%lx\n", GetLastError(), hFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFileType/test3/testinfo.dat
new file mode 100644
index 0000000000..9ffd4c2b15
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetFileType
+Name = Test for GetFileTYpe
+TYPE = DEFAULT
+EXE1 = getfiletype
+Description
+= Test the PAL implementation of the GetFileType on a handle
+= to a console.
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..8c10e479fa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFullPathNameA.c
+)
+
+add_executable(paltest_getfullpathnamea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamea_test1 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c
new file mode 100644
index 0000000000..de9a266f5a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c
@@ -0,0 +1,122 @@
+// 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: GetFullPathNameA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szFileName = "testing.tmp";
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ char szShortBuff[2];
+ LPSTR pPathPtr;
+ HANDLE hFile = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* perform a short buffer test */
+ if (GetFullPathNameA(szFileName, 2, szShortBuff, &pPathPtr) <= 2)
+ {
+ /* this test should have failed but didn't */
+ Fail("GetFullPathNameA: ERROR -> The API was passed a buffer that was"
+ " too small for the path name and yet it apparently passed.\n");
+ }
+
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ dwRc = GetFullPathNameA(szFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ // this test should have passed but didn't
+ Fail("GetFullPathNameA: ERROR -> Function failed for the "
+ "file \"%s\" with error code: %ld.\n", szFileName, GetLastError());
+ }
+
+ // the returned value should be the current directory with the
+ // file name appended
+ hFile = CreateFileA(szFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFullPathNameA: ERROR -> CreateFileA failed to create "
+ "file \"%s\" with error code: %ld.\n",
+ szFileName,
+ GetLastError());
+ }
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Fail("GetFullPathNameA: ERROR -> CloseHandle failed with error "
+ "code: %ld.\n", GetLastError());
+ }
+
+ // now try to create the file based on the returned value with the
+ // CREATE_NEW option which should fail since the file should
+ // already exist
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ Fail("GetFullPathNameA: ERROR -> CreateFileA was able to "
+ "CREATE_NEW the returned file \"%s\". The returned file "
+ "name is therefore apparently wrong.\n",
+ szReturnedPath);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Fail("GetFullPathNameA: ERROR -> CloseHandle failed with "
+ "error code: %ld.\n", GetLastError());
+ }
+ if ((DeleteFileA(szReturnedPath) != TRUE) ||
+ (DeleteFileA(szFileName) != TRUE))
+ {
+ Fail("GetFullPathNameA: ERROR -> DeleteFileA failed to "
+ "delete the test files with error code: %ld.\n",
+ GetLastError());
+ }
+ }
+
+ // now make sure the pPathPtr is the same as the file name
+ if (strcmp(pPathPtr, szFileName) != 0)
+ {
+ Fail("GetFullPathNameA: ERROR -> %s != %s\n",
+ pPathPtr, szFileName);
+ }
+ if (DeleteFileA(szFileName) != TRUE)
+ {
+ Fail("GetFullPathNameA: ERROR -> DeleteFileA failed to "
+ "delete \"%s\" with error code: %ld.\n",
+ szFileName,
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/testinfo.dat
new file mode 100644
index 0000000000..a4ccc95348
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/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 = GetFullPathNameA
+Name = Test for GetFullPathNameA (test 1)
+Type = DEFAULT
+EXE1 = getfullpathnamea
+Description
+= Get the full path for a file name and verify the results.
+= Also, attempt to call GetFullPathNameA with a buffer that is
+= too small for the returned path and verify the results.
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..382b8fa4bd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_getfullpathnamea_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamea_test2 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamea_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c
new file mode 100644
index 0000000000..95a1497331
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c
@@ -0,0 +1,143 @@
+// 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: test2.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameA API.
+** GetFullPathA will be passed a directory that contains '..'.
+** To add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+** The test will create a file with in the parent directory
+** to verify that the returned directory is valid.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szDotDot = "..\\";
+const char* szFileName = "testing.tmp";
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ char szFullFileName[_MAX_DIR+1];
+ LPSTR pPathPtr;
+ HANDLE hFile = NULL;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return (FAIL);
+ }
+
+ /* change the directory */
+ if (!SetCurrentDirectoryA(szDotDot))
+ {
+ Fail("ERROR: SetCurrentDirectoryA failed with error code %u"
+ " when passed \"%s\".\n",
+ GetLastError(),
+ szDotDot);
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ memset(szFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * as a pre-fix. */
+ strcat(szFullFileName, szDotDot);
+ strcat(szFullFileName, szFileName);
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameA(szFullFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+ if (dwRc == 0)
+ {
+ Fail("ERROR :%ld: GetFullPathName failed to "
+ "retrieve the path of \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+ /* The returned value should be the parent directory with the
+ * file name appended. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR :%ld: CreateFileA failed to create \"%s\".\n",
+ GetLastError(),
+ szReturnedPath);
+ }
+
+ /* Close the handle to the created file.
+ */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n",
+ GetLastError());
+ goto terminate;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Fail("ERROR :%ld: CreateFileA succeeded to create file "
+ "\"%s\", that already existed.\n",
+ GetLastError(),
+ szFullFileName);
+ }
+
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (strcmp(pPathPtr, szFileName) != 0)
+ {
+ Trace("ERROR : Returned filename \"%s\" is not equal to "
+ "supplied filename \"%s\".\n",
+ pPathPtr,
+ szFileName);
+ goto terminate;
+ }
+
+terminate:
+ /* Delete the create file.
+ */
+ if (DeleteFileA(szReturnedPath) != TRUE)
+ {
+ Fail("ERROR :%ld: DeleteFileA failed to delete \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+ /* Terminate the PAL.*/
+ PAL_Terminate();
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/testinfo.dat
new file mode 100644
index 0000000000..b75f48114b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/testinfo.dat
@@ -0,0 +1,18 @@
+# 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 = GetFullPathNameA
+Name = Test for GetFullPathNameA
+Type = DEFAULT
+EXE1 = test2
+Description
+= Tests the PAL implementation of the GetFullPathNameA API.
+= GetFullPathA will be passed a directory that contains '..'.
+= To add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
+= The test will create a file with in the parent directory
+= to verify that the returned directory is valid.
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt
new file mode 100644
index 0000000000..f0f8929b4a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_getfullpathnamea_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamea_test3 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamea_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c
new file mode 100644
index 0000000000..0cc39e7300
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c
@@ -0,0 +1,241 @@
+// 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: test3.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameA API.
+** GetFullPathA will be passed a directory that contains '..'.
+** Example: test_directory\level1\..\testing.tmp.
+** To add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+** The test will create a file with in the parent directory
+** to verify that the returned directory is valid.
+**
+** Depends: SetCurrentDirectory,
+** CreateDirectory,
+** strcat,
+** memset,
+** CreateFile,
+** CloseHandle,
+** strcmp,
+** DeleteFileA,
+** RemoveDirectory.
+**
+
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+#ifdef WIN32
+ const char* szSeperator = "\\";
+#else
+ const char* szSeperator = "//";
+#endif
+
+const char* szDotDot = "..\\";
+const char* szFileName = "testing.tmp";
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ char szFullFileName[_MAX_DIR+1];
+ char szDirectory[256];
+ char* szCreatedDir = {"test_directory"};
+ char* szCreatedNextDir = {"level1"};
+ WCHAR *szCreatedDirW;
+ LPSTR pPathPtr;
+ HANDLE hFile = NULL;
+ BOOL bRetVal = FAIL;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return (FAIL);
+ }
+
+ /* Initialize the buffer.
+ */
+ memset(szDirectory, '\0', 256);
+
+ /* Change the current working directory.
+ */
+ if (!SetCurrentDirectoryA(szDotDot))
+ {
+ Fail("ERROR: SetCurrentDirectoryA failed with error code %u"
+ " when passed \"%s\".\n",
+ GetLastError(),
+ szDotDot);
+ }
+
+ /* Create the path to the next level of directory to create.
+ */
+ strcat( szDirectory, szCreatedDir );
+
+
+ /* Create a test directory.
+ */
+ if ( !CreateDirectoryA( szDirectory, NULL ) )
+ {
+ Fail("ERROR:%u: Unable to create directories \"%s\".\n",
+ GetLastError(),
+ szDirectory);
+ }
+
+ /* Create the path to the next level of directory to create.
+ */
+ strcat( szDirectory, szSeperator );
+ strcat( szDirectory, szCreatedNextDir );
+
+ /* Create a test directory.
+ */
+ if ( !CreateDirectoryA( szDirectory, NULL ) )
+ {
+ Trace("ERROR:%u: Unable to create directories \"%s\".\n",
+ GetLastError(),
+ szDirectory);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ memset(szFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * in the middle of the path.
+ */
+ strcat(szFullFileName, szCreatedDir);
+ strcat(szFullFileName, szDotDot);
+ strcat(szFullFileName, szFileName);
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameA(szFullFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+ if (dwRc == 0)
+ {
+ Trace("ERROR :%ld: GetFullPathName failed to "
+ "retrieve the path of \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* The returned value should be the parent directory with the
+ * file name appended. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR :%ld: CreateFileA failed to create \"%s\".\n",
+ GetLastError(),
+ szReturnedPath);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Close the handle to the created file.
+ */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n",
+ GetLastError());
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Trace("ERROR :%ld: CreateFileA succeeded to create file "
+ "\"%s\", that already existed.\n",
+ GetLastError(),
+ szFullFileName);
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (strcmp(pPathPtr, szFileName) != 0)
+ {
+ Trace("ERROR : Returned filename \"%s\" is not equal to "
+ "supplied filename \"%s\".\n",
+ pPathPtr,
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Successful test.
+ */
+ bRetVal = PASS;
+
+cleanUpThree:
+
+ /* Delete the create file.
+ */
+ if (DeleteFileA(szReturnedPath) != TRUE)
+ {
+ Fail("ERROR :%ld: DeleteFileA failed to delete \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+cleanUpTwo:
+
+ /* Remove the empty directory.
+ */
+ szCreatedDirW = convert((LPSTR)szDirectory);
+ if (!RemoveDirectoryW(szCreatedDirW))
+ {
+ free (szCreatedDirW);
+ Fail("ERROR:%u: Unable to remove directory \"%s\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+ free (szCreatedDirW);
+
+cleanUpOne:
+
+ /* Remove the empty directory.
+ */
+ szCreatedDirW = convert((LPSTR)szCreatedDir);
+ if (!RemoveDirectoryW(szCreatedDirW))
+ {
+ free (szCreatedDirW);
+ Fail("ERROR:%u: Unable to remove directory \"%s\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+ free (szCreatedDirW);
+
+ /* Terminate the PAL.*/
+ PAL_Terminate();
+ return bRetVal;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/testinfo.dat
new file mode 100644
index 0000000000..3991744d42
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/testinfo.dat
@@ -0,0 +1,19 @@
+# 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 = GetFullPathNameA
+Name = Test for GetFullPathNameA
+Type = DEFAULT
+EXE1 = test3
+Description
+= Tests the PAL implementation of the GetFullPathNameA API.
+= GetFullPathA will be passed a directory that contains '..'.
+= Example: test_directory\level1\..\testing.tmp.
+= To add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
+= The test will create a file with in the parent directory
+= to verify that the returned directory is valid.
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt
new file mode 100644
index 0000000000..cf0d7ff18c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.c
+)
+
+add_executable(paltest_getfullpathnamea_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamea_test4 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamea_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c
new file mode 100644
index 0000000000..fb22c1f07b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c
@@ -0,0 +1,203 @@
+// 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: test4.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameA API.
+** GetFullPathA will be passed a directory that begins with '..'.
+** Example: ..\test_directory\testing.tmp.
+** To add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+** The test will create a file with in the parent directory
+** to verify that the returned directory is valid.
+**
+** Depends: SetCurrentDirectory,
+** CreateDirectory,
+** strcat,
+** memset,
+** CreateFile,
+** CloseHandle,
+** strcmp,
+** DeleteFileA,
+** RemoveDirectory.
+**
+
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+#ifdef WIN32
+ const char* szSeperator = "\\";
+#else
+ const char* szSeperator = "//";
+#endif
+
+const char* szDotDot = "..";
+const char* szFileName = "testing.tmp";
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ char szFullFileName[_MAX_DIR+1];
+ char szDirectory[256];
+ char* szCreatedDir = {"test_directory"};
+ WCHAR *szCreatedDirW;
+ LPSTR pPathPtr;
+ HANDLE hFile = NULL;
+ BOOL bRetVal = FAIL;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return (FAIL);
+ }
+
+ /* Initialize the buffer.
+ */
+ memset(szDirectory, '\0', 256);
+
+ /* Create the path to the next level of directory to create.
+ */
+ strcat( szDirectory, szDotDot ); /* .. */
+ strcat( szDirectory, szSeperator ); /* ../ */
+ strcat( szDirectory, szCreatedDir ); /* ../test_directory */
+
+ /* Create a test directory.
+ */
+ if ( !CreateDirectoryA( szDirectory, NULL ) )
+ {
+ Fail("ERROR:%u: Unable to create directories \"%s\".\n",
+ GetLastError(),
+ szDirectory);
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ memset(szFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * in the middle of the path.
+ */
+ strcat( szFullFileName, szDotDot ); /* .. */
+ strcat( szFullFileName, szSeperator ); /* ../ */
+ strcat( szFullFileName, szCreatedDir ); /* ../test_directory */
+ strcat( szFullFileName, szSeperator ); /* ../test_directory/ */
+ strcat( szFullFileName, szFileName ); /* ../test_directory/testing.tmp */
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameA(szFullFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+ if (dwRc == 0)
+ {
+ Trace("ERROR :%ld: GetFullPathName failed to "
+ "retrieve the path of \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* The returned value should be the parent directory with the
+ * file name appended. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR :%ld: CreateFileA failed to create \"%s\".\n",
+ GetLastError(),
+ szReturnedPath);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* Close the handle to the created file.
+ */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n",
+ GetLastError());
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileA(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Trace("ERROR :%ld: CreateFileA succeeded to create file "
+ "\"%s\", that already existed.\n",
+ GetLastError(),
+ szFullFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (strcmp(pPathPtr, szFileName) != 0)
+ {
+ Trace("ERROR : Returned filename \"%s\" is not equal to "
+ "supplied filename \"%s\".\n",
+ pPathPtr,
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Successful test.
+ */
+ bRetVal = PASS;
+
+cleanUpTwo:
+
+ /* Delete the create file.
+ */
+ if (DeleteFileA(szReturnedPath) != TRUE)
+ {
+ Fail("ERROR :%ld: DeleteFileA failed to delete \"%s\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+cleanUpOne:
+
+ /* Remove the empty directory.
+ */
+ szCreatedDirW = convert((LPSTR)szDirectory);
+ if (!RemoveDirectoryW(szCreatedDirW))
+ {
+ free (szCreatedDirW);
+ Fail("ERROR:%u: Unable to remove directory \"%s\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+ free (szCreatedDirW);
+
+ /* Terminate the PAL.*/
+ PAL_Terminate();
+ return bRetVal;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/testinfo.dat
new file mode 100644
index 0000000000..8a7b3b35da
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/testinfo.dat
@@ -0,0 +1,19 @@
+# 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 = GetFullPathNameA
+Name = Test for GetFullPathNameA
+Type = DEFAULT
+EXE1 = test4
+Description
+= Tests the PAL implementation of the GetFullPathNameA API.
+= GetFullPathA will be passed a directory that begins with '..'.
+= Example: ..\test_directory\level1\testing.tmp.
+= To add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
+= The test will create a file with in the parent directory
+= to verify that the returned directory is valid.
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..a6f354f5a5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetFullPathNameW.c
+)
+
+add_executable(paltest_getfullpathnamew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamew_test1 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c
new file mode 100644
index 0000000000..592d3ad4c5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c
@@ -0,0 +1,157 @@
+// 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: GetFullPathNameW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szFileName = "testing.tmp";
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[_MAX_DIR+1];
+ WCHAR szwShortBuff[2];
+ LPWSTR pPathPtr;
+ HANDLE hFile = NULL;
+ WCHAR* szwFileName = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ szwFileName = convert((char*)szFileName);
+
+ /* perform a short buffer test */
+ if (GetFullPathNameW(szwFileName, 2, szwShortBuff, &pPathPtr) <= 2)
+ {
+ free(szwFileName);
+ /* this test should have failed but didn't */
+ Fail("GetFullPathNameW: ERROR -> The API was passed a buffer that was"
+ " too small for the path name and yet it apparently passed.\n");
+ }
+
+
+ memset(szwReturnedPath, 0, _MAX_DIR+1);
+ dwRc = GetFullPathNameW(szwFileName,
+ _MAX_DIR,
+ szwReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ /* this test should have passed but didn't */
+ free(szwFileName);
+ Fail("GetFullPathNameW: ERROR -> Function failed for the "
+ "file \"%s\" with error code: %ld.\n", szFileName, GetLastError());
+ }
+ /*
+ * the returned value should be the current directory with the
+ * file name appended
+ */
+ hFile = CreateFileW(szwFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ free(szwFileName);
+ Fail("GetFullPathNameW: ERROR -> CreateFileW failed to create "
+ "file \"%s\" with error code: %ld.\n",
+ szFileName,
+ GetLastError());
+ }
+ if (CloseHandle(hFile) != TRUE)
+ {
+ free(szwFileName);
+ Trace("GetFullPathNameW: ERROR -> CloseHandle failed with error "
+ "code: %ld.\n", GetLastError());
+ if (DeleteFileA(szFileName) != TRUE)
+ {
+ Trace("GetFullPathNameW: ERROR -> DeleteFileW failed to "
+ "delete the test file with error code: %ld.\n",
+ GetLastError());
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /*
+ * now try to create the file based on the returned value with the
+ * CREATE_NEW option which should fail since the file should
+ * already exist
+ */
+ hFile = CreateFileW(szwReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ Trace("GetFullPathNameW: ERROR -> CreateFileW was able to "
+ "CREATE_NEW the returned file \"%s\". The returned file "
+ "name is therefore apparently wrong.\n",
+ szwReturnedPath);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("GetFullPathNameW: ERROR -> CloseHandle failed with "
+ "error code: %ld.\n", GetLastError());
+ }
+ if ((DeleteFileW(szwReturnedPath) != TRUE) ||
+ (DeleteFileW(szwFileName) != TRUE))
+ {
+ Trace("GetFullPathNameW: ERROR -> DeleteFileW failed to "
+ "delete the test files with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwFileName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* now make sure the pPathPtr is the same as the file name */
+ if (wcsncmp(pPathPtr, szwFileName, wcslen(szwFileName)) != 0)
+ {
+ Trace("GetFullPathNameW: ERROR -> %s != %s\n",
+ pPathPtr, szFileName);
+ if ((DeleteFileW(szwReturnedPath) != TRUE) ||
+ (DeleteFileW(szwFileName) != TRUE))
+ {
+ Trace("GetFullPathNameW: ERROR -> DeleteFileW failed to "
+ "delete the test files with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwFileName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* clean up */
+ free(szwFileName);
+ if (DeleteFileA(szFileName) != TRUE)
+ {
+ Fail("GetFullPathNameW: ERROR -> DeleteFileW failed to "
+ "delete \"%s\" with error code: %ld.\n",
+ szFileName,
+ GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/testinfo.dat
new file mode 100644
index 0000000000..4f70617d48
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/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 = GetFullPathNameW
+Name = Test for GetFullPathNameW (test 1)
+Type = DEFAULT
+EXE1 = getfullpathnamew
+Description
+= Get the full path for a file name and verify the results.
+= Also, attempt to call GetFullPathNameW with a buffer that is
+= too small for the returned path and verify the results.
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..199aa1efce
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_getfullpathnamew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamew_test2 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c
new file mode 100644
index 0000000000..fae042d229
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c
@@ -0,0 +1,159 @@
+// 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: test2.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameW function.
+** Get the full path for a file name and verify the results.
+** This test will use a relative path, containing '..\'. To
+** add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+WCHAR szwDotDot[] = {'.','.','\\','\0'};
+WCHAR szwFileName[] = {'t','e','s','t','i','n','g','.','t','m','p','\0'};
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[_MAX_DIR+1];
+ WCHAR szwFullFileName[_MAX_DIR+1];
+ char *szReturnedPath;
+ char *szFileName;
+ LPWSTR pPathPtr;
+ HANDLE hFile = NULL;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* change the directory */
+ if (!SetCurrentDirectoryW(szwDotDot))
+ {
+ Fail("ERROR: SetCurrentDirectoryW failed with error code %u"
+ " when passed \"%S\".\n",
+ GetLastError(),
+ szwDotDot);
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szwReturnedPath, 0, _MAX_DIR+1);
+ memset(szwFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * as a pre-fix. */
+ wcscat(szwFullFileName, szwDotDot);
+ wcscat(szwFullFileName, szwFileName);
+
+ /* Convert wide char strings to multibyte, to us
+ * incase of error messages.*/
+ szFileName = convertC(szwFileName);
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameW(szwFullFileName,
+ _MAX_DIR,
+ szwReturnedPath,
+ &pPathPtr);
+
+ szReturnedPath = convertC(szwReturnedPath);
+
+ if (dwRc == 0)
+ {
+ Trace("ERROR :%ld: Failed to get path to \"%s\".\n",
+ GetLastError(),
+ szReturnedPath);
+ free(szReturnedPath);
+ free(szFileName);
+ Fail("");
+ }
+
+ /*
+ * The returned value should be the parent directory with the
+ * file name appended.
+ */
+ hFile = CreateFileW(szwReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR :%ld: CreateFileW failed to create file \"%s\".\n",
+ GetLastError(),
+ szReturnedPath);
+ free(szFileName);
+ free(szReturnedPath);
+ Fail("");
+ }
+
+ /* Close the handle to the create file.*/
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: Failed to close handle hFile=0x%lx.\n",
+ GetLastError(),
+ hFile);
+ goto terminate;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileW(szwReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Trace("ERROR :%ld: CreateFileW succeeded to create file "
+ "\"%s\", that already existed.\n",
+ GetLastError(),
+ szReturnedPath);
+ goto terminate;
+ }
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (wcsncmp(pPathPtr, szwFileName, wcslen(szwFileName)) != 0)
+ {
+ Trace("ERROR : Returned filename is not equal to \"%s\".\n",
+ szFileName);
+ goto terminate;
+ }
+
+terminate:
+ /* Delete the create file.
+ */
+ if (DeleteFileW(szwFullFileName) != TRUE)
+ {
+ Trace("ERROR :%ld: DeleteFileW failed to delete \"%s\".\n",
+ szFileName,
+ GetLastError());
+ free(szFileName);
+ free(szReturnedPath);
+ Fail("");
+ }
+
+ free(szFileName);
+ free(szReturnedPath);
+
+ /* Terminate the PAL.
+ */
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/testinfo.dat
new file mode 100644
index 0000000000..b8460e0b78
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/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 = GetFullPathNameW
+Name = Test for GetFullPathNameW (test 2)
+Type = DEFAULT
+EXE1 = test2
+Description
+= Get the full path for a file name and verify the results.
+= This test will use a relative path, containing '..\'. To
+= add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt
new file mode 100644
index 0000000000..6284958b07
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_getfullpathnamew_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamew_test3 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamew_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c
new file mode 100644
index 0000000000..ba80cf222d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c
@@ -0,0 +1,240 @@
+// 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: test3.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameW API.
+** GetFullPathW will be passed a directory that contains '..'.
+** Example: test_directory\level1\..\testing.tmp.
+** To add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+** The test will create a file with in the parent directory
+** to verify that the returned directory is valid.
+**
+** Depends: SetCurrentDirectory,
+** CreateDirectory,
+** strcat,
+** memset,
+** CreateFile,
+** CloseHandle,
+** strcmp,
+** DeleteFileW,
+** RemoveDirectory.
+**
+
+**
+**===================================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+#ifdef WIN32
+const WCHAR szSeperator[] = {'\\','\\','\0'};
+#else
+const WCHAR szSeperator[] = {'/','/','\0'};
+#endif
+
+const WCHAR szDotDot[] = {'.','.','\0'};
+const WCHAR szFileName[] = {'t','e','s','t','i','n','g','.','t','m','p','\0'};
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+
+ WCHAR szReturnedPath[_MAX_DIR+1];
+ WCHAR szFullFileName[_MAX_DIR+1];
+ WCHAR szDirectory[256];
+ WCHAR szCreatedDir[] = {'t','e','s','t','_','d','i','r','\0'};
+ WCHAR szCreatedNextDir[] = {'l','e','v','e','l','1','\0'};
+
+ LPWSTR pPathPtr;
+ HANDLE hFile = NULL;
+ BOOL bRetVal = FAIL;
+
+ /* Initialize the PAL.
+ */
+ if ( 0 != PAL_Initialize(argc,argv) )
+ {
+ return (FAIL);
+ }
+
+ /* Initialize the buffer.
+ */
+ memset( szDirectory, '\0', 256 );
+
+ /* Change the current working directory.
+ */
+ if ( !SetCurrentDirectoryW(szDotDot) )
+ {
+ Fail("ERROR: SetCurrentDirectoryA failed with error code %u "
+ "when passed \"%S\".\n",
+ GetLastError(),
+ szDotDot);
+ }
+
+ /* Create the path to the next level of directory to create.
+ */
+ wcscat(szDirectory, szCreatedDir); /* test_dir */
+
+
+ /* Create a test directory.
+ */
+ if (!CreateDirectoryW(szDirectory, NULL))
+ {
+ Fail("ERROR:%u: Unable to create directories \"%S\".\n",
+ GetLastError(),
+ szDirectory);
+ }
+
+ /* Create the path to the next level of directory to create.
+ */
+ wcscat(szDirectory, szSeperator); /* / */
+ wcscat(szDirectory, szCreatedNextDir); /* /level1 */
+
+ /* Create a test directory.
+ */
+ if (!CreateDirectoryW(szDirectory, NULL))
+ {
+ Trace("ERROR:%u: Unable to create directories \"%S\".\n",
+ GetLastError(),
+ szDirectory);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ memset(szFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * in the middle of the path.
+ */
+ wcscat(szFullFileName, szCreatedDir); /*test_dir */
+ wcscat(szFullFileName, szSeperator); /*test_dir/ */
+ wcscat(szFullFileName, szCreatedNextDir);/*test_dir/level1 */
+ wcscat(szFullFileName, szSeperator); /*test_dir/level1/ */
+ wcscat(szFullFileName, szDotDot); /*test_dir/level1/.. */
+ wcscat(szFullFileName, szSeperator); /*test_dir/level1/../ */
+ wcscat(szFullFileName, szFileName); /*test_dir/level1/../testing.tmp */
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameW(szFullFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+ if (dwRc == 0)
+ {
+ Trace("ERROR :%ld: GetFullPathNameW failed to "
+ "retrieve the path of \"%S\".\n",
+ GetLastError(),
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* The returned value should be the parent directory with the
+ * file name appended. */
+ hFile = CreateFileW(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR :%ld: CreateFileA failed to create \"%S\".\n",
+ GetLastError(),
+ szReturnedPath);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Close the handle to the created file.
+ */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n",
+ GetLastError());
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileW(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Trace("ERROR :%ld: CreateFileA succeeded to create file "
+ "\"%S\", that already existed.\n",
+ GetLastError(),
+ szFullFileName);
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (wcscmp(pPathPtr, szFileName) != 0)
+ {
+ Trace("ERROR : Returned filename \"%s\" is not equal to "
+ "supplied filename \"%s\".\n",
+ pPathPtr,
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpThree;
+ }
+
+ /* Successful test.
+ */
+ bRetVal = PASS;
+
+cleanUpThree:
+
+ /* Delete the create file.
+ */
+ if (DeleteFileW(szReturnedPath) != TRUE)
+ {
+ Fail("ERROR :%ld: DeleteFileA failed to delete \"%S\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+cleanUpTwo:
+
+ /* Remove the empty directory.
+ */
+ if (!RemoveDirectoryW(szDirectory))
+ {
+ Fail("ERROR:%u: Unable to remove directory \"%S\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+
+cleanUpOne:
+
+ /* Remove the empty directory.
+ */
+ if (!RemoveDirectoryW(szCreatedDir))
+ {
+ Fail("ERROR:%u: Unable to remove directory \"%s\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+
+ /* Terminate the PAL.*/
+ PAL_TerminateEx(bRetVal);
+ return bRetVal;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/testinfo.dat
new file mode 100644
index 0000000000..1eb6a27ada
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/testinfo.dat
@@ -0,0 +1,19 @@
+# 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 = GetFullPathNameW
+Name = Test for GetFullPathNameW
+Type = DEFAULT
+EXE1 = test3
+Description
+= Tests the PAL implementation of the GetFullPathNameW API.
+= GetFullPathW will be passed a directory that contains '..'.
+= Example: test_directory\level1\..\testing.tmp.
+= To add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
+= The test will create a file with in the parent directory
+= to verify that the returned directory is valid.
+
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt
new file mode 100644
index 0000000000..d479b998cc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.c
+)
+
+add_executable(paltest_getfullpathnamew_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getfullpathnamew_test4 coreclrpal)
+
+target_link_libraries(paltest_getfullpathnamew_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c
new file mode 100644
index 0000000000..25eb10d654
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c
@@ -0,0 +1,201 @@
+// 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: test4.c
+**
+** Purpose: Tests the PAL implementation of the GetFullPathNameW API.
+** GetFullPathNameW will be passed a directory that begins with '..'.
+** Example: ..\test_directory\testing.tmp.
+** To add to this test, we will also call SetCurrentDirectory to
+** ensure this is handled properly.
+** The test will create a file with in the parent directory
+** to verify that the returned directory is valid.
+**
+** Depends: SetCurrentDirectory,
+** CreateDirectory,
+** strcat,
+** memset,
+** CreateFile,
+** CloseHandle,
+** strcmp,
+** DeleteFileW,
+** RemoveDirectory.
+**
+
+**
+**===================================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+#ifdef WIN32
+ const WCHAR szSeperator[] = {'\\','\\','\0'};
+#else
+ const WCHAR szSeperator[] = {'/','/','\0'};
+#endif
+
+const WCHAR szDotDot[] = {'.','.','\0'};
+const WCHAR szFileName[] = {'t','e','s','t','i','n','g','.','t','m','p','\0'};
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwRc = 0;
+
+ WCHAR szReturnedPath[_MAX_DIR+1];
+ WCHAR szFullFileName[_MAX_DIR+1];
+ WCHAR szDirectory[256];
+ WCHAR szCreatedDir[] = {'t','e','s','t','_','d','i','r','\0'};
+
+ LPWSTR pPathPtr;
+ HANDLE hFile = NULL;
+ BOOL bRetVal = FAIL;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return (FAIL);
+ }
+
+ /* Initialize the buffer.
+ */
+ memset(szDirectory, '\0', 256);
+
+ /* Create the path to the next level of directory to create.
+ */
+ wcscat(szDirectory, szDotDot); /* .. */
+ wcscat(szDirectory, szSeperator); /* ../ */
+ wcscat(szDirectory, szCreatedDir); /* ../test_directory */
+
+ /* Create a test directory.
+ */
+ if (!CreateDirectoryW(szDirectory, NULL))
+ {
+ Fail("ERROR:%u: Unable to create directories \"%S\".\n",
+ GetLastError(),
+ szDirectory);
+ }
+
+ /* Initialize the receiving char buffers.
+ */
+ memset(szReturnedPath, 0, _MAX_DIR+1);
+ memset(szFullFileName, 0, _MAX_DIR+1);
+
+ /* Create Full filename to pass, will include '..\'
+ * in the middle of the path.
+ */
+ wcscat( szFullFileName, szDotDot ); /* .. */
+ wcscat( szFullFileName, szSeperator ); /* ../ */
+ wcscat( szFullFileName, szCreatedDir ); /* ../test_directory */
+ wcscat( szFullFileName, szSeperator ); /* ../test_directory/ */
+ wcscat( szFullFileName, szFileName ); /* ../test_directory/testing.tmp */
+
+ /* Get the full path to the filename.
+ */
+ dwRc = GetFullPathNameW(szFullFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+ if (dwRc == 0)
+ {
+ Trace("ERROR :%ld: GetFullPathName failed to "
+ "retrieve the path of \"%S\".\n",
+ GetLastError(),
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* The returned value should be the parent directory with the
+ * file name appended. */
+ hFile = CreateFileW(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR :%ld: CreateFileA failed to create \"%S\".\n",
+ GetLastError(),
+ szReturnedPath);
+ bRetVal = FAIL;
+ goto cleanUpOne;
+ }
+
+ /* Close the handle to the created file.
+ */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n",
+ GetLastError());
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Verify that the file was created, attempt to create
+ * the file again. */
+ hFile = CreateFileW(szReturnedPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ((hFile != INVALID_HANDLE_VALUE) &&
+ (GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ Trace("ERROR :%ld: CreateFileA succeeded to create file "
+ "\"%S\", that already existed.\n",
+ GetLastError(),
+ szFullFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Verify that the returned filename is the same as the supplied.
+ */
+ if (wcscmp(pPathPtr, szFileName) != 0)
+ {
+ Trace("ERROR : Returned filename \"%S\" is not equal to "
+ "supplied filename \"%S\".\n",
+ pPathPtr,
+ szFileName);
+ bRetVal = FAIL;
+ goto cleanUpTwo;
+ }
+
+ /* Successful test.
+ */
+ bRetVal = PASS;
+
+cleanUpTwo:
+
+ /* Delete the create file.
+ */
+ if (DeleteFileW(szReturnedPath) != TRUE)
+ {
+ Fail("ERROR :%ld: DeleteFileA failed to delete \"%S\".\n",
+ GetLastError(),
+ szFileName);
+ }
+
+cleanUpOne:
+
+ /* Remove the empty directory.
+ */
+ if (!RemoveDirectoryW(szDirectory))
+ {
+ Fail("ERROR:%u: Unable to remove directory \"%s\".\n",
+ GetLastError(),
+ szCreatedDir);
+ }
+
+ /* Terminate the PAL.*/
+ PAL_TerminateEx(bRetVal);
+ return bRetVal;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/testinfo.dat
new file mode 100644
index 0000000000..8a7b3b35da
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/testinfo.dat
@@ -0,0 +1,19 @@
+# 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 = GetFullPathNameA
+Name = Test for GetFullPathNameA
+Type = DEFAULT
+EXE1 = test4
+Description
+= Tests the PAL implementation of the GetFullPathNameA API.
+= GetFullPathA will be passed a directory that begins with '..'.
+= Example: ..\test_directory\level1\testing.tmp.
+= To add to this test, we will also call SetCurrentDirectory to
+= ensure this is handled properly.
+= The test will create a file with in the parent directory
+= to verify that the returned directory is valid.
+
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetLongPathNameW/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..cf5dcd0bfc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetLongPathNameW.c
+)
+
+add_executable(paltest_getlongpathnamew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getlongpathnamew_test1 coreclrpal)
+
+target_link_libraries(paltest_getlongpathnamew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c
new file mode 100644
index 0000000000..22831dda15
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c
@@ -0,0 +1,280 @@
+// 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: GetLongPathNameW.c Win32 version(test 1)
+**
+** Purpose: Tests the PAL implementation of the GetLongPathNameW function.
+** as expected under Win32
+**
+** Depends on:
+** CreateDirectoryA
+** RemoveDirectoryW
+**
+**
+**===================================================================*/
+/*
+tests:
+ - test invalid path names
+ - test an already short path name
+ - test a long path name
+ - test with buffer size too small
+*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+/* Since GetLongPathNameW operates differently under FreeBSD and Win32 this test
+ is for Win32 only. It runs the same tests as the FreeBSD version but checks for
+ different results
+*/
+
+#if WIN32
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[MAX_LONGPATH];
+ WCHAR szwSmallBuff[3];
+ const char szShortPathName[] = {"testing"};
+ const char szLongPathName[] = {"This_is_a_long_directory_name"};
+ const char szShortenedPathName[] = {"THIS_I~1"};
+ WCHAR* wLongPathPtr = NULL;
+ WCHAR* wShortPathPtr = NULL;
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ memset(szwSmallBuff, 0, 3*sizeof(WCHAR));
+ wLongPathPtr = convert((char*)szLongPathName);
+ wShortPathPtr = convert((char*)szShortenedPathName);
+
+ /* do some clean up just to be safe */
+ RemoveDirectoryW(wLongPathPtr);
+ RemoveDirectoryW(wShortPathPtr);
+
+
+ /* attempt call on an invalid short path name */
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Call made with an invalid short "
+ "path \"%S\" returned \"%S\"\n",
+ wShortPathPtr,
+ szwReturnedPath);
+ free (wLongPathPtr);
+ free (wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* attempt call on an invalid long path name */
+ dwRc = GetLongPathNameW(wLongPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Call made with an invalid long "
+ "path \"%S\" returned \"%S\"\n",
+ wLongPathPtr,
+ szwReturnedPath);
+ free (wLongPathPtr);
+ free (wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* create a long directory name */
+ if (TRUE != CreateDirectoryW(wLongPathPtr, NULL))
+ {
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> CreateDirectoryW failed with an error"
+ " code of %ld when asked to create a directory called \"%s\".\n",
+ GetLastError(),
+ szLongPathName);
+ }
+
+
+ /* get the long path name */
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc == 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> failed with an error"
+ " code of %ld when asked for the long version of \"%s\".\n",
+ GetLastError(),
+ szShortenedPathName);
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ }
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+ /* does the returned match the expected */
+ if (wcsncmp(wLongPathPtr, szwReturnedPath, wcslen(wLongPathPtr)) ||
+ (wcslen(wLongPathPtr) != wcslen(szwReturnedPath)))
+ {
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ }
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> The returned path, \"%S\" doesn't "
+ "match the expected return, \"%s\".\n",
+ szwReturnedPath,
+ szLongPathName);
+ }
+
+ /* does the length returned match the actual length */
+ if (dwRc != wcslen(szwReturnedPath))
+ {
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ }
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> The returned length, %ld, doesn't "
+ "match the string length, %ld.\n",
+ dwRc,
+ wcslen(szwReturnedPath));
+ }
+
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ free(wShortPathPtr);
+ free(wLongPathPtr);
+ Fail("");
+ }
+ free(wShortPathPtr);
+ free(wLongPathPtr);
+
+
+ /* test an actual short name */
+ /* create a long directory name */
+ wShortPathPtr = convert((char*)szShortPathName);
+ RemoveDirectoryW(wShortPathPtr);
+
+ if (TRUE != CreateDirectoryW(wShortPathPtr, NULL))
+ {
+ Trace("GetLongPathNameW: ERROR -> CreateDirectoryW failed with an error"
+ " code of %ld when asked to create a directory called \"%s\".\n",
+ GetLastError(),
+ szShortPathName);
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* get the long path name */
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc == 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> failed with an error"
+ " code of %ld when asked for the long version of \"%s\".\n",
+ GetLastError(),
+ szShortenedPathName);
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+ /* does the returned match the expected */
+ if (wcsncmp(wShortPathPtr, szwReturnedPath, wcslen(wShortPathPtr)) ||
+ (wcslen(wShortPathPtr) != wcslen(szwReturnedPath)))
+ {
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> The returned path, \"%S\" doesn't "
+ "match the expected return, \"%s\".\n",
+ szwReturnedPath,
+ szShortPathName);
+ }
+
+ /* does the length returned match the actual length */
+ if (dwRc != wcslen(szwReturnedPath))
+ {
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> The returned length, %ld, doesn't "
+ "match the string length, %ld.\n",
+ dwRc,
+ wcslen(szwReturnedPath));
+ }
+
+ /* test using a too small return buffer */
+ dwRc = GetLongPathNameW(wShortPathPtr, szwSmallBuff, 3);
+ if ((dwRc != (strlen(szShortPathName)+1)) || /* +1 for the required NULL */
+ szwSmallBuff[0] != '\0')
+ {
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> using a return buffer that was too"
+ " small was not handled properly.\n");
+ }
+
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ free(wShortPathPtr);
+ Fail("");
+ }
+ free(wShortPathPtr);
+
+ PAL_Terminate();
+
+#endif /* WIN32 */
+
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/testinfo.dat
new file mode 100644
index 0000000000..f730300c43
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/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 = GetLongPathNameW
+Name = Test for GetLongPathNameW Win32 (test 1)
+Type = DEFAULT
+EXE1 = getlongpathnamew
+Description
+= Tests invalid path names. Tests conversion of short to long
+= path names as well as passing it a path name that is already short.
+= Under BSD, there isn't a shortened version of directory names so
+= I just use a long path name as the short path name to ensure it returns
+= the same thing.
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..5746ef3e04
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ getlongpathnamew.c
+)
+
+add_executable(paltest_getlongpathnamew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getlongpathnamew_test2 coreclrpal)
+
+target_link_libraries(paltest_getlongpathnamew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c
new file mode 100644
index 0000000000..3b033e9a64
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c
@@ -0,0 +1,266 @@
+// 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: GetLongPathNameW.c FreeBSD version(test 2)
+**
+** Purpose: Tests the PAL implementation of the GetLongPathNameW function
+** as expected under FreeBSD
+**
+** Depends on:
+** CreateDirectoryA
+** RemoveDirectoryW
+**
+**
+**===================================================================*/
+/*
+tests:
+ - test invalid path names
+ - test an already short path name
+ - test a long path name
+ - test with buffer size too small
+*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+/* Since GetLongPathNameW operates differently under FreeBSD and Win32 this test
+ is for freeBSD only. It runs the same tests as the Win32 version but checks for
+ different results
+*/
+#if !(WIN32) /* Only execute if the is Free BSD */
+
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[MAX_LONGPATH];
+ WCHAR szwSmallBuff[3];
+ const char szShortPathName[] = {"testing"};
+ const char szLongPathName[] = {"This_is_a_long_directory_name"};
+ /* since BSD doesn't shorten long dir names, it will only use the long name */
+ const char szShortenedPathName[] = {"This_is_a_long_directory_name"};
+ WCHAR* wLongPathPtr = NULL;
+ WCHAR* wShortPathPtr = NULL;
+ int StringLen = 0;
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ memset(szwSmallBuff, 0, 3*sizeof(WCHAR));
+ wLongPathPtr = convert((char*)szLongPathName);
+ wShortPathPtr = convert((char*)szShortenedPathName);
+
+
+ /* do some clean up just to be safe */
+ RemoveDirectoryW(wLongPathPtr);
+ RemoveDirectoryW(wShortPathPtr);
+
+
+ /* attempt call on an invalid short path name */
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Call made with an invalid short "
+ "path \"%S\" returned \"%S\"\n",
+ wShortPathPtr,
+ szwReturnedPath);
+ free (wLongPathPtr);
+ free (wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* attempt call on an invalid long path name */
+ dwRc = GetLongPathNameW(wLongPathPtr, szwReturnedPath, MAX_LONGPATH);
+ if (dwRc != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Call made with an invalid long "
+ "path \"%S\" returned \"%S\"\n",
+ wLongPathPtr,
+ szwReturnedPath);
+ free (wLongPathPtr);
+ free (wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* create a long directory name */
+ if (TRUE != CreateDirectoryW(wLongPathPtr, NULL))
+ {
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> CreateDirectoryW failed with an error"
+ " code of %ld when asked to create a directory called \"%s\".\n",
+ GetLastError(),
+ szLongPathName);
+ }
+
+
+ /* get the long path name */
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ StringLen = wcslen(wShortPathPtr);
+
+ if (dwRc != StringLen)
+ {
+ Trace("GetLongPathNameW: ERROR -> Under FreeBSD, this test should"
+ " have returned %d but instead returned %d.\n",
+ StringLen, dwRc);
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ }
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("");
+ }
+ if (wcsncmp(wShortPathPtr,szwReturnedPath, StringLen) != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Under Unix,"
+ "the lpszLongPath \"%s\" should have been,"
+ "but was \"%s\".\n",
+ wShortPathPtr, szwReturnedPath);
+
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ }
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+ if (RemoveDirectoryW(wLongPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wLongPathPtr,
+ GetLastError());
+ free(wLongPathPtr);
+ free(wShortPathPtr);
+ Fail("");
+ }
+ free(wShortPathPtr);
+ free(wLongPathPtr);
+
+
+ /* test an actual short name */
+ /* create a long directory name */
+ wShortPathPtr = convert((char*)szShortPathName);
+ RemoveDirectoryW(wShortPathPtr);
+
+ if (TRUE != CreateDirectoryW(wShortPathPtr, NULL))
+ {
+ free(wShortPathPtr);
+ Fail("GetLongPathNameW: ERROR -> CreateDirectoryW failed with an error"
+ " code of %ld when asked to create a directory called \"%s\".\n",
+ GetLastError(),
+ szShortPathName);
+ }
+
+
+ /* get the long path name */
+ memset(szwReturnedPath, 0, MAX_LONGPATH*sizeof(WCHAR));
+ dwRc = GetLongPathNameW(wShortPathPtr, szwReturnedPath, MAX_LONGPATH);
+ StringLen = wcslen (wShortPathPtr);
+
+ if (dwRc != StringLen)
+ {
+ Trace("GetLongPathNameW: ERROR -> Under FreeBSD, this test should"
+ " have returned %d but instead returned %d.\n",
+ StringLen, dwRc);
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("");
+ }
+ if (wcsncmp(wShortPathPtr, szwReturnedPath, StringLen) != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Under Unix, the lpszLongPath"
+ "\"%s\" should have been,"
+ "but was \"%s\".\n",
+ wShortPathPtr, szwReturnedPath);
+
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+
+ /* test using a too small return buffer */
+ dwRc = GetLongPathNameW(wShortPathPtr, szwSmallBuff, 3);
+ StringLen = wcslen (wShortPathPtr);
+
+
+ if (dwRc != (StringLen + 1)) //Return size includes NULL char
+ {
+ Trace("GetLongPathNameW: ERROR -> Under FreeBSD, this test should"
+ " have returned %d but instead returned %d.\n",
+ StringLen, dwRc);
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("");
+ }
+ if (szwSmallBuff[0] != 0)
+ {
+ Trace("GetLongPathNameW: ERROR -> Under FreeBSD, this test should"
+ " not have touched lpszLongPath but instead it returned\"%s\".\n",
+ szwReturnedPath);
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ }
+ free(wShortPathPtr);
+ Fail("");
+ }
+
+ /* clean up */
+ if (RemoveDirectoryW(wShortPathPtr) != TRUE)
+ {
+ Trace("GetLongPathNameW: ERROR -> RemoveDirectoryW failed to "
+ " remove the directory \"%S\" with an error code of %ld.\n",
+ wShortPathPtr,
+ GetLastError());
+ free(wShortPathPtr);
+ Fail("");
+ }
+ free(wShortPathPtr);
+
+ PAL_Terminate();
+
+#endif /* Free BSD */
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/testinfo.dat
new file mode 100644
index 0000000000..5144a35b13
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/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 = GetLongPathNameW
+Name = Test for GetLongPathNameW FreeBSD version (test 2)
+Type = DEFAULT
+EXE1 = getlongpathnamew
+Description
+= Tests invalid path names. Tests conversion of short to long
+= path names as well as passing it a path name that is already short.
+= Under BSD, there isn't a shortened version of directory names so
+= I just use a long path name as the short path name to ensure it returns
+= the same thing.
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetStdHandle/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt
new file mode 100644
index 0000000000..04bcc5fd67
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetStdHandle.c
+)
+
+add_executable(paltest_getstdhandle_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getstdhandle_test1 coreclrpal)
+
+target_link_libraries(paltest_getstdhandle_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c
new file mode 100644
index 0000000000..f4fe03195d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c
@@ -0,0 +1,132 @@
+// 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: GetStdHandle.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetStdHandle function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten = 0;
+ DWORD dwFileType;
+ BOOL bRc = FALSE;
+ const char* szText = "this is a test of GetStdHandle\n";
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /*
+ * attempt to get an invalid handle
+ */
+ hFile = GetStdHandle(-2);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_INPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+
+ /*
+ * test the STD_INPUT_HANDLE handle
+ */
+ hFile = GetStdHandle(STD_INPUT_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_INPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+ /* an attempt to write to the input handle should fail */
+ /* I don't know how to automate a read from the input handle */
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL);
+ if (bRc != FALSE)
+ {
+ Fail("GetStdHandle: ERROR -> WriteFile was able to write to "
+ "STD_INPUT_HANDLE when it should have failed.\n");
+ }
+
+
+ /*
+ * test the STD_OUTPUT_HANDLE handle
+ */
+ hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_OUTPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+ /* try to write to the output handle */
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL);
+ if (bRc != TRUE)
+ {
+ Fail("GetStdHandle: ERROR -> WriteFile failed to write to "
+ "STD_OUTPUT_HANDLE with the error %ld\n",
+ GetLastError());
+ }
+
+
+ /* test the STD_ERROR_HANDLE handle */
+ hFile = GetStdHandle(STD_ERROR_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_ERROR_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+ /* try to write to the error handle */
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL);
+ if (bRc != TRUE)
+ {
+ Fail("GetStdHandle: ERROR -> WriteFile failed to write to "
+ "STD_ERROR_HANDLE with the error %ld\n",
+ GetLastError());
+ }
+
+ /* check if the file type is correct for the handle */
+ if((dwFileType = GetFileType(hFile)) != FILE_TYPE_CHAR)
+ {
+ Fail("GetStdHandle: ERROR -> GetFileType returned %u for "
+ "STD_ERROR_HANDLE instead of the expected FILE_TYPE_CHAR (%u).\n",
+ dwFileType,
+ FILE_TYPE_CHAR);
+ }
+
+ /* check to see if we can CloseHandle works on the STD_ERROR_HANDLE */
+ if (!CloseHandle(hFile))
+ {
+ Fail("GetStdHandle: ERROR -> CloseHandle failed. GetLastError "
+ "returned %u.\n",
+ GetLastError());
+ }
+
+ /* try to write to the closed error handle */
+ bRc = WriteFile(hFile,
+ szText,
+ (DWORD)strlen(szText),
+ &dwBytesWritten,
+ NULL);
+ if (bRc)
+ {
+ Fail("GetStdHandle: ERROR -> WriteFile was able to write to the closed"
+ " STD_ERROR_HANDLE handle.\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/testinfo.dat
new file mode 100644
index 0000000000..3f7dbf5f42
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetStdHandle
+Name = Positive Test for GetStdHandle (test 1)
+Type = DEFAULT
+EXE1 = getstdhandle
+Description
+= Test GetStdHandle on a valid/invalid std handles
+
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt
new file mode 100644
index 0000000000..97816b4319
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetStdHandle.c
+)
+
+add_executable(paltest_getstdhandle_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getstdhandle_test2 coreclrpal)
+
+target_link_libraries(paltest_getstdhandle_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c
new file mode 100644
index 0000000000..45f5ddd243
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c
@@ -0,0 +1,79 @@
+// 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: GetStdHandle.c (test 2)
+**
+** Purpose: Smoke Tests the PAL implementation of the GetStdHandle function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /*
+ * attempt to get an invalid handle
+ */
+ hFile = GetStdHandle(-2);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_INPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+
+ /*
+ * test the STD_INPUT_HANDLE handle
+ */
+ hFile = GetStdHandle(STD_INPUT_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_INPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+
+ /*
+ * test the STD_OUTPUT_HANDLE handle
+ */
+ hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_OUTPUT_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+ /* test the STD_ERROR_HANDLE handle */
+ hFile = GetStdHandle(STD_ERROR_HANDLE);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("GetStdHandle: ERROR -> A request for the STD_ERROR_HANDLE "
+ "returned an invalid handle.\n");
+ }
+
+
+ /* check to see if we can CloseHandle works on the STD_ERROR_HANDLE */
+ if (!CloseHandle(hFile))
+ {
+ Fail("GetStdHandle: ERROR -> CloseHandle failed. GetLastError "
+ "returned %u.\n",
+ GetLastError());
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/testinfo.dat
new file mode 100644
index 0000000000..dcd498c6ef
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetStdHandle
+Name = Positive Test for GetStdHandle (test 2)
+Type = DEFAULT
+EXE1 = getstdhandle
+Description
+= Smoke Test GetStdHandle on a valid/invalid std handles
+
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTime/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..94d5bcded9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test.c
+)
+
+add_executable(paltest_getsystemtime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getsystemtime_test1 coreclrpal)
+
+target_link_libraries(paltest_getsystemtime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c
new file mode 100644
index 0000000000..361dbef33d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c
@@ -0,0 +1,124 @@
+// 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: test.c
+**
+** Purpose: Test for GetSystemTime() function
+**
+**
+**=========================================================*/
+
+/* Note: Some of the range comparisons only check
+ * the high end of the range. Since the structure
+ * contains WORDs, negative values can never be included,
+ * so there is no reason to check and see if the lower
+ * end of the spectrum is <0
+*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ SYSTEMTIME TheTime;
+ SYSTEMTIME firstTime;
+ SYSTEMTIME secondTime;
+
+ WORD avgDeltaFileTime = 0;
+
+ int i=0;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ GetSystemTime(&TheTime);
+
+ /* Go through each item in the structure and ensure it is a valid value.
+ We can't ensure they have the exact values of the current time, but
+ at least that they have been set to a valid range of values for that
+ item.
+ */
+
+ /* Year */
+ if(TheTime.wYear < (WORD)2001)
+ {
+ Fail("ERROR: The year is %d, when it should be at least 2001.",
+ TheTime.wYear);
+ }
+
+ /* Month */
+ if(TheTime.wMonth > (WORD)12 || TheTime.wMonth < (WORD)1)
+ {
+ Fail("ERROR: The month should be between 1 and 12, and it is "
+ "showing up as %d.",TheTime.wMonth);
+ }
+
+ /* Weekday */
+ if(TheTime.wDayOfWeek > 6)
+ {
+ Fail("ERROR: The day of the week should be between 0 and 6, "
+ "and it is showing up as %d.",TheTime.wDayOfWeek);
+ }
+
+ /* Day of the Month */
+ if(TheTime.wDay > 31 || TheTime.wDay < 1)
+ {
+ Fail("ERROR: The day of the month should be between 1 and "
+ "31, and it is showing up as %d.",TheTime.wDay);
+ }
+
+ /* Hour */
+ if(TheTime.wHour > 23)
+ {
+ Fail("ERROR: The hour should be between 0 and 23, and it is "
+ "showing up as %d.",TheTime.wHour);
+ }
+
+ /* Minute */
+ if(TheTime.wMinute > 59)
+ {
+ Fail("ERROR: The minute should be between 0 and 59 and it is "
+ "showing up as %d.",TheTime.wMinute);
+ }
+
+ /* Second */
+ if(TheTime.wSecond > 59)
+ {
+ Fail("ERROR: The second should be between 0 and 59 and it is"
+ " showing up as %d.",TheTime.wSecond);
+ }
+
+ /* Millisecond */
+ if(TheTime.wMilliseconds > 999)
+ {
+ Fail("ERROR: The milliseconds should be between 0 and 999 "
+ "and it is currently showing %d.",TheTime.wMilliseconds);
+ }
+
+ /* check if two consecutive calls to system time return */
+ /* correct time in ms after sleep() call. */
+ for (i = 0; i<5 ;i++)
+ {
+ GetSystemTime(&firstTime);
+ Sleep(1000);
+ GetSystemTime(&secondTime);
+ avgDeltaFileTime += abs(firstTime.wSecond - secondTime.wSecond );
+
+ }
+
+ if( (avgDeltaFileTime/5) < 1.0)
+ {
+ Fail("ERROR: 2 calls for GetSystemTime interrupted"
+ " by a 1000 ms sleep failed Value[%f]", avgDeltaFileTime/5 );
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/testinfo.dat
new file mode 100644
index 0000000000..05169f65c6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = Miscellaneous
+Function = GetSystemTime
+Name = Positive test of GetSystemTime
+Type = DEFAULT
+EXE1 = test
+Description
+= Tests the PAL implementation of the GetSystemTime API
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..977a826e7a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetSystemTimeAsFileTime.c
+)
+
+add_executable(paltest_getsystemtimeasfiletime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_getsystemtimeasfiletime_test1 coreclrpal)
+
+target_link_libraries(paltest_getsystemtimeasfiletime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c
new file mode 100644
index 0000000000..bd7e856abd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c
@@ -0,0 +1,86 @@
+// 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: GetSystemTimeAsFileTime.c
+**
+** Purpose: Tests the PAL implementation of GetSystemTimeAsFileTime
+** Take two times, three seconds apart, and ensure that the time is
+** increasing, and that it has increased at least 3 seconds.
+**
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME TheFirstTime, TheSecondTime;
+ ULONG64 FullFirstTime, FullSecondTime;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Get two times, 3 seconds apart */
+
+ GetSystemTimeAsFileTime( &TheFirstTime );
+
+ Sleep( 3000 );
+
+ GetSystemTimeAsFileTime( &TheSecondTime );
+
+ /* Convert them to ULONG64 to work with */
+
+ FullFirstTime = ((( (ULONG64)TheFirstTime.dwHighDateTime )<<32) |
+ ( (ULONG64)TheFirstTime.dwLowDateTime ));
+
+ FullSecondTime = ((( (ULONG64)TheSecondTime.dwHighDateTime )<<32) |
+ ( (ULONG64)TheSecondTime.dwLowDateTime ));
+
+ /* Test to ensure the second value is larger than the first */
+
+ if( FullSecondTime <= FullFirstTime )
+ {
+ Fail("ERROR: The system time didn't increase in the last "
+ "three seconds. The second time tested was less than "
+ "or equal to the first.");
+ }
+
+ /* Note: The 30000000 magic number is 3 seconds in hundreds of nano
+ seconds. This test checks to ensure at least 3 seconds passed
+ between the readings.
+ */
+
+ if( ( (LONG64)( FullSecondTime - FullFirstTime ) - 30000000 ) < 0 )
+ {
+ ULONG64 TimeError;
+
+ /* Note: This test used to compare the difference between full times
+ in terms of hundreds of nanoseconds. But the x86 clock seems to be
+ precise only to the level of about 10000 nanoseconds, so we would
+ fail the comparison depending on when we took time slices.
+
+ To fix this, we just check that we're within a millisecond of
+ sleeping 3000 milliseconds. We're not currently ensuring that we
+ haven't slept much more than 3000 ms. We may want to do that.
+ */
+ TimeError = 30000000 - ( FullSecondTime - FullFirstTime );
+ if ( TimeError > 10000)
+ {
+ Fail("ERROR: Two system times were tested, with a sleep of 3 "
+ "seconds between. The time passed should have been at least "
+ "3 seconds. But, it was less according to the function.");
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/testinfo.dat
new file mode 100644
index 0000000000..3318d1386a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/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 = GetSystemTimeAsFileTime
+Name = Positive Test for GetSystemTimeAsFileTime
+TYPE = DEFAULT
+EXE1 = getsystemtimeasfiletime
+Description
+= Test the GetSystemTimeAsFileTime function.
+= Take two times, three seconds apart, and ensure that the time is
+= increasing, and that it has increased at least 3 seconds.
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..1b759af2eb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetTempFileNameA.c
+)
+
+add_executable(paltest_gettempfilenamea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamea_test1 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c
new file mode 100644
index 0000000000..8ede8bab04
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c
@@ -0,0 +1,125 @@
+// 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: GetTempFileNameA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameA function.
+**
+** Depends on:
+** GetFileAttributesA
+** DeleteFileA
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiError = 0;
+ const UINT uUnique = 0;
+ const char* szDot = {"."};
+ const char* szValidPrefix = {"cfr"};
+ const char* szLongValidPrefix = {"cfrwxyz"};
+ char szReturnedName[256];
+ char szTempString[256];
+
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* valid path with null prefix */
+ uiError = GetTempFileNameA(szDot, NULL, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path "
+ "with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp file with error code: %ld.\n", GetLastError());
+ }
+ }
+
+
+ /* valid path with valid prefix */
+ uiError = GetTempFileNameA(szDot, szValidPrefix, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp \"%s\" file with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ }
+
+ /* valid path with long prefix */
+ uiError = GetTempFileNameA(szDot, szLongValidPrefix, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+
+ /* now verify that it only used the first 3 characters of the prefix */
+ sprintf(szTempString, "%s\\%s", szDot, szLongValidPrefix);
+ if (strncmp(szTempString, szReturnedName, 6) == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> It appears that an improper prefix "
+ "was used.\n");
+ }
+
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/testinfo.dat
new file mode 100644
index 0000000000..4bf0000b9f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetTempFileNameA
+Name = Test for GetTempFileNameA (test 1)
+Type = DEFAULT
+EXE1 = gettempfilenamea
+Description
+= Tests the PAL implimentation of GetTempFileNameA by testing
+= various combinations of path and prefix names.
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..f4bd9b8797
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetTempFileNameA.c
+)
+
+add_executable(paltest_gettempfilenamea_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamea_test2 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamea_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c
new file mode 100644
index 0000000000..861a8b87e8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c
@@ -0,0 +1,80 @@
+// 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: GetTempFileNameA.c (test 2)
+**
+** Purpose: Tests the number of files GetTempFileNameA can create.
+**
+** Depends on:
+** GetFileAttributesA
+** oodles of free disk space (>4.07GB)
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiError = 0;
+ DWORD dwError = 0;
+ const UINT uUnique = 0;
+ const char* szDot = {"."};
+ const char* szValidPrefix = {"cfr"};
+ char szReturnedName[256];
+ DWORD i;
+
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ /* test the number of temp files that can be created */
+ for (i = 0; i < 0x10005; i++)
+ {
+ uiError = GetTempFileNameA(szDot, szValidPrefix, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ dwError = GetLastError();
+ if (dwError == ERROR_FILE_EXISTS)
+ {
+ /* file already existes so break out of the loop */
+ i--; /* decrement the count because it wasn't successful */
+ break;
+ }
+ else
+ {
+ /* it was something other than the file already existing? */
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid "
+ "path and prefix with the error code: %ld\n", GetLastError());
+ }
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed "
+ "on the returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ }
+ }
+
+ /* did it create more than 0xffff files */
+ if (i > 0xffff)
+ {
+ Fail("GetTempFileNameA: ERROR -> Was able to create more than 0xffff"
+ " temp files.\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/testinfo.dat
new file mode 100644
index 0000000000..ca46f6d842
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/testinfo.dat
@@ -0,0 +1,17 @@
+# 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 = GetTempFileNameA
+Name = Test for GetTempFileNameA (test 2)
+Type = DEFAULT
+EXE1 = gettempfilenamea
+Description
+= Test the number of files that can be created. Since
+= GetTempFileNameA only handles 8.3 file names, the test
+= attempts to create more than the maximum temp files possible
+= with a 3 character prefix. Since this test takes so long, it
+= is not to be included in the standard test harness.
+= This test will also need more than 4.07 GB free disk space.
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt
new file mode 100644
index 0000000000..9c02865575
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ gettempfilenamea.c
+)
+
+add_executable(paltest_gettempfilenamea_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamea_test3 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamea_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c
new file mode 100644
index 0000000000..8eccc3d2e8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c
@@ -0,0 +1,159 @@
+// 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: GetTempFileNameA.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameA function.
+** Checks the file attributes and ensures that getting a file name,
+** deleting the file and getting another doesn't produce the same
+** as the just deleted file. Also checks the file size is 0.
+**
+** Depends on:
+** GetFileAttributesA
+** CloseHandle
+** DeleteFileA
+** CreateFileA
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const UINT uUnique = 0;
+ UINT uiError;
+ const char* szDot = {"."};
+ char szReturnedName[MAX_LONGPATH];
+ char szReturnedName_02[MAX_LONGPATH];
+ DWORD dwFileSize = 0;
+ HANDLE hFile;
+
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ /* valid path with null prefix */
+ uiError = GetTempFileNameA(szDot, NULL, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path "
+ "with the error code: %u.\n",
+ GetLastError());
+ }
+
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %u.\n",
+ szReturnedName,
+ GetLastError());
+ }
+
+ /*
+ ** verify that the file size is 0 bytes
+ */
+
+ hFile = CreateFileA(szReturnedName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("GetTempFileNameA: ERROR -> CreateFileA failed to open"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ if (!DeleteFileA(szReturnedName))
+ {
+ Trace("GetTempFileNameA: ERROR -> DeleteFileA failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ if ((dwFileSize = GetFileSize(hFile, NULL)) != (DWORD)0)
+ {
+ Trace("GetTempFileNameA: ERROR -> GetFileSize returned %u whereas"
+ "it should have returned 0.\n",
+ dwFileSize);
+ if (!CloseHandle(hFile))
+ {
+ Trace("GetTempFileNameA: ERROR -> CloseHandle failed. "
+ "GetLastError returned: %u.\n",
+ GetLastError());
+ }
+ if (!DeleteFileA(szReturnedName))
+ {
+ Trace("GetTempFileNameA: ERROR -> DeleteFileA failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+
+ if (!CloseHandle(hFile))
+ {
+ Fail("GetTempFileNameA: ERROR -> CloseHandle failed. "
+ "GetLastError returned: %u.\n",
+ GetLastError());
+ }
+
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileA failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+
+ /* get another and make sure it's not the same as the last */
+ uiError = GetTempFileNameA(szDot, NULL, uUnique, szReturnedName_02);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path "
+ "with the error code: %u.\n",
+ GetLastError());
+ }
+
+ /* did we get different names? */
+ if (strcmp(szReturnedName, szReturnedName_02) == 0)
+ {
+ Trace("GetTempFileNameA: ERROR -> The first call returned \"%s\". "
+ "The second call returned \"%s\" and the two should not be"
+ " the same.\n",
+ szReturnedName,
+ szReturnedName_02);
+ if (!DeleteFileA(szReturnedName_02))
+ {
+ Trace("GetTempFileNameA: ERROR -> DeleteFileA failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* clean up */
+ if (!DeleteFileA(szReturnedName_02))
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileA failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/testinfo.dat
new file mode 100644
index 0000000000..f1f5bf5764
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/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 = GetTempFileNameA
+Name = Test for GetTempFileNameA (test 3)
+Type = DEFAULT
+EXE1 = gettempfilenamea
+Description
+= Tests the PAL implementation of the GetTempFileNameA function.
+= Checks the file attributes and ensures that getting a file name,
+= deleting the file and getting another doesn't produce the same
+= as the just deleted file. Also checks the file size is 0.
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..1b6c599da4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetTempFileNameW.c
+)
+
+add_executable(paltest_gettempfilenamew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamew_test1 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c
new file mode 100644
index 0000000000..43cda8f447
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c
@@ -0,0 +1,129 @@
+// 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: GetTempFileNameW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiError = 0;
+ const UINT uUnique = 0;
+ WCHAR* wPrefix = NULL;
+ WCHAR* wPath = NULL;
+ WCHAR wReturnedName[256];
+ WCHAR wTempString[256];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ // valid path with null ext
+ wPath = convert(".");
+ uiError = GetTempFileNameW(wPath, wPrefix, uUnique, wReturnedName);
+ free (wPath);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid path "
+ "with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ // verify temp file was created
+ if (GetFileAttributesW(wReturnedName) == -1)
+ {
+ Fail("GetTempFileNameW: ERROR -> GetFileAttributes failed on the "
+ "returned temp file with error code: %ld.\n", GetLastError());
+ }
+ if (DeleteFileW(wReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ "the created temp file with error code: %lld.\n", GetLastError());
+ }
+ }
+
+
+ // valid path with valid prefix
+ wPath = convert(".");
+ wPrefix = convert("cfr");
+ uiError = GetTempFileNameW(wPath, wPrefix, uUnique, wReturnedName);
+ free (wPath);
+ free (wPrefix);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ // verify temp file was created
+ if (GetFileAttributesW(wReturnedName) == -1)
+ {
+ Fail("GetTempFileNameW: ERROR -> GetFileAttributes failed on the "
+ "returned temp file with error code: %ld.\n", GetLastError());
+ }
+ if (DeleteFileW(wReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ "the created temp file with error code: %lld.\n", GetLastError());
+ }
+ }
+
+ // valid path with long prefix
+ wPath = convert(".");
+ wPrefix = convert("cfrwxyz");
+ uiError = GetTempFileNameW(wPath, wPrefix, uUnique, wReturnedName);
+ if (uiError == 0)
+ {
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ // verify temp file was created
+ if (GetFileAttributesW(wReturnedName) == -1)
+ {
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> GetFileAttributes failed on the "
+ "returned temp file with error code: %ld.\n", GetLastError());
+ }
+
+ // now verify that it only used the first 3 characters of the prefix
+ swprintf(wTempString, convert("%s\\%s"), wPath, wPrefix);
+ if (memcmp(wTempString, wReturnedName, wcslen(wTempString)*sizeof(WCHAR)) == 0)
+ {
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> It appears that an improper prefix "
+ "was used.\n");
+ }
+
+ if (DeleteFileW(wReturnedName) != TRUE)
+ {
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ "the created temp file with error code: %lld.\n", GetLastError());
+ }
+ }
+
+ free (wPath);
+ free (wPrefix);
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/testinfo.dat
new file mode 100644
index 0000000000..72af6930d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = GetTempFileNameW
+Name = Test for GetTempFileNameW (test 1)
+Type = DEFAULT
+EXE1 = gettempfilenamew
+Description
+= Test all the different options of GetTempFileNameW
+
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..851030d9ae
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetTempFileNameW.c
+)
+
+add_executable(paltest_gettempfilenamew_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamew_test2 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamew_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c
new file mode 100644
index 0000000000..2c8b19e081
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c
@@ -0,0 +1,84 @@
+// 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: GetTempFileNameW.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiError = 0;
+ DWORD dwError = 0;
+ const UINT uUnique = 0;
+ WCHAR* wPrefix = NULL;
+ WCHAR* wPath = NULL;
+ WCHAR wReturnedName[256];
+ DWORD i;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ // test the number of temp files that can be created
+ wPrefix = convert("cfr");
+ wPath = convert(".");
+ for (i = 0; i < 0x10005; i++)
+ {
+ uiError = GetTempFileNameW(wPath, wPrefix, uUnique, wReturnedName);
+ if (uiError == 0)
+ {
+ dwError = GetLastError();
+ if (dwError == ERROR_FILE_EXISTS)
+ {
+ // file already existes so break out of the loop
+ i--; // decrement the count because it wasn't successful
+ break;
+ }
+ else
+ {
+ // it was something other than the file already existing?
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid "
+ "path and prefix with the error code: %ld\n", GetLastError());
+ }
+ }
+ else
+ {
+ // verify temp file was created
+ if (GetFileAttributesW(wReturnedName) == -1)
+ {
+ free (wPath);
+ free (wPrefix);
+ Fail("GetTempFileNameW: ERROR -> GetFileAttributes failed "
+ "on the returned temp file with error code: %ld.\n",
+ GetLastError());
+ }
+ }
+ }
+
+ free (wPath);
+ free (wPrefix);
+
+ // did it create more than 0xffff files
+ if (i > 0xffff)
+ {
+ Fail("GetTempFileNameW: ERROR -> Was able to create more than 0xffff"
+ " temp files.\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/testinfo.dat
new file mode 100644
index 0000000000..72500111ad
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/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 = GetTempFileNameW
+Name = Test for GetTempFileNameW (test 2)
+Type = DEFAULT
+EXE1 = gettempfilenamew
+Description
+= This test attempts to create over 65000 files and will
+= have to be run manually because it will take longer than
+= the maximum 60 seconds allowed per test
+
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt
new file mode 100644
index 0000000000..82dd0a9f3f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ gettempfilenamew.c
+)
+
+add_executable(paltest_gettempfilenamew_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettempfilenamew_test3 coreclrpal)
+
+target_link_libraries(paltest_gettempfilenamew_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c
new file mode 100644
index 0000000000..96d8e66410
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c
@@ -0,0 +1,161 @@
+// 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: GetTempFileNameW.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameW function.
+** Checks the file attributes and ensures that getting a file name,
+** deleting the file and getting another doesn't produce the same
+** as the just deleted file. Also checks the file size is 0.
+**
+** Depends on:
+** GetFileAttributesW
+** DeleteFileW
+** CreateFileW
+** GetFileSize
+** CloseHandle
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const UINT uUnique = 0;
+ UINT uiError;
+ WCHAR szwReturnedName[MAX_LONGPATH];
+ WCHAR szwReturnedName_02[MAX_LONGPATH];
+ DWORD dwFileSize = 0;
+ HANDLE hFile;
+ const WCHAR szwDot[] = {'.','\0'};
+ const WCHAR szwPre[] = {'c','\0'};
+
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ /* valid path with null prefix */
+ uiError = GetTempFileNameW(szwDot, szwPre, uUnique, szwReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid path "
+ "with the error code: %u.\n",
+ GetLastError());
+ }
+
+ /* verify temp file was created */
+ if (GetFileAttributesW(szwReturnedName) == -1)
+ {
+ Fail("GetTempFileNameW: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%S\" with error code: %u.\n",
+ szwReturnedName,
+ GetLastError());
+ }
+
+ /*
+ ** verify that the file size is 0 bytes
+ */
+
+ hFile = CreateFileW(szwReturnedName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("GetTempFileNameW: ERROR -> CreateFileW failed to open"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ if (!DeleteFileW(szwReturnedName))
+ {
+ Trace("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ if ((dwFileSize = GetFileSize(hFile, NULL)) != (DWORD)0)
+ {
+ Trace("GetTempFileNameW: ERROR -> GetFileSize returned %u whereas"
+ "it should have returned 0.\n",
+ dwFileSize);
+ if (!CloseHandle(hFile))
+ {
+ Trace("GetTempFileNameW: ERROR -> CloseHandle was unable to close the "
+ "opened file. GetLastError returned %u.\n",
+ GetLastError());
+ }
+ if (!DeleteFileW(szwReturnedName))
+ {
+ Trace("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ if (!CloseHandle(hFile))
+ {
+ Fail("GetTempFileNameW: ERROR -> CloseHandle was unable to close the "
+ "opened file. GetLastError returned %u.\n",
+ GetLastError());
+ }
+
+
+ /* delete the file to see if we get the same name next time around */
+ if (DeleteFileW(szwReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+
+ /* get another and make sure it's not the same as the last */
+ uiError = GetTempFileNameW(szwDot, szwPre, uUnique, szwReturnedName_02);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameW: ERROR -> Call failed with a valid path "
+ "with the error code: %u.\n",
+ GetLastError());
+ }
+
+ /* did we get different names? */
+ if (wcsncmp(szwReturnedName, szwReturnedName_02, wcslen(szwReturnedName)) == 0)
+ {
+ Fail("GetTempFileNameW: ERROR -> The first call returned \"%S\". "
+ "The second call returned \"%S\" and the two should not be"
+ " the same.\n",
+ szwReturnedName,
+ szwReturnedName_02);
+ if (!DeleteFileW(szwReturnedName_02))
+ {
+ Trace("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ /* clean up */
+ if (!DeleteFileW(szwReturnedName_02))
+ {
+ Fail("GetTempFileNameW: ERROR -> DeleteFileW failed to delete"
+ " the created temp file with error code: %u.\n",
+ GetLastError());
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/testinfo.dat
new file mode 100644
index 0000000000..dd482dbde5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/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 = GetTempFileNameW
+Name = Test for GetTempFileNameW (test 3)
+Type = DEFAULT
+EXE1 = gettempfilenamew
+Description
+= Tests the PAL implementation of the GetTempFileNameW function.
+= Checks the file attributes and ensures that getting a file name,
+= deleting the file and getting another doesn't produce the same
+= as the just deleted file. Also checks the file size is 0.
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempPathW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..f2979e9536
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ GetTempPathW.c
+)
+
+add_executable(paltest_gettemppathw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettemppathw_test1 coreclrpal)
+
+target_link_libraries(paltest_gettemppathw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c
new file mode 100644
index 0000000000..08c88075ca
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c
@@ -0,0 +1,103 @@
+// 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: GetTempPathW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempPathW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+static void SetTmpDir(WCHAR path[])
+{
+ DWORD result = SetEnvironmentVariableW(W("TMPDIR"), path);
+ if (!result)
+ {
+ Fail("ERROR -> SetEnvironmentVariableW failed with result %d and error code %d.\n",
+ result, GetLastError());
+ }
+}
+
+static void SetAndCompare(WCHAR tmpDirPath[], WCHAR expected[])
+{
+ DWORD dwBufferLength = _MAX_DIR;
+ WCHAR path[dwBufferLength];
+
+ SetTmpDir(tmpDirPath);
+
+ DWORD dwResultLen = GetTempPathW(dwBufferLength, path);
+ if (dwResultLen <= 0)
+ {
+ Fail("ERROR: GetTempPathW returned %d with error code %d.\n", dwResultLen, GetLastError());
+ }
+ if (dwResultLen >= dwBufferLength)
+ {
+ Fail("ERROR: Buffer of length %d passed to GetTempPathA was too small to hold %d chars..\n", dwBufferLength, dwResultLen);
+ }
+ if (wcscmp(expected, path) != 0)
+ {
+ Fail("ERROR: GetTempPathW expected to get '%S' but instead got '%S'.\n", expected, path);
+ }
+ if (expected[dwResultLen - 1] != '/')
+ {
+ Fail("ERROR: GetTempPathW returned '%S', which should have ended in '/'.\n", path);
+ }
+}
+
+static void SetAndCheckLength(WCHAR tmpDirPath [], int bufferLength, int expectedResultLength)
+{
+ WCHAR path[bufferLength];
+
+ SetTmpDir(tmpDirPath);
+ DWORD dwResultLen = GetTempPathW(bufferLength, path);
+
+ if (dwResultLen != expectedResultLength)
+ {
+ Fail("GetTempPathW(%d, %S) expected to return %d but returned %d.\n",
+ bufferLength, tmpDirPath?tmpDirPath:W("NULL"), expectedResultLength, dwResultLen);
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ SetAndCompare(W("/tmp"), W("/tmp/"));
+ SetAndCompare(W("/tmp/"), W("/tmp/"));
+ SetAndCompare(W(""), W("/tmp/"));
+ SetAndCompare(NULL, W("/tmp/"));
+ SetAndCompare(W("/"), W("/"));
+ SetAndCompare(W("/var/tmp"), W("/var/tmp/"));
+ SetAndCompare(W("/var/tmp/"), W("/var/tmp/"));
+ SetAndCompare(W("~"), W("~/"));
+ SetAndCompare(W("~/"), W("~/"));
+ SetAndCompare(W(".tmp"), W(".tmp/"));
+ SetAndCompare(W("./tmp"), W("./tmp/"));
+ SetAndCompare(W("/home/someuser/sometempdir"), W("/home/someuser/sometempdir/"));
+ SetAndCompare(NULL, W("/tmp/"));
+
+ DWORD dwResultLen = GetTempPathA(0, NULL);
+ if (dwResultLen != 0 || GetLastError() != ERROR_INVALID_PARAMETER)
+ {
+ Fail("GetTempPathW(NULL, ...) returned %d with error code %d but "
+ "should have failed with ERROR_INVALID_PARAMETER (%d).\n",
+ dwResultLen, GetLastError(), ERROR_INVALID_PARAMETER);
+ }
+
+ SetAndCheckLength(W("abc/"), 5, 4);
+ SetAndCheckLength(W("abcd"), 5, 6);
+ SetAndCheckLength(W("abcde"), 5, 7);
+ SetAndCheckLength(W("abcdef/"), 5, 9);
+ SetAndCheckLength(NULL, 5, 6);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/testinfo.dat
new file mode 100644
index 0000000000..84dc33832c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/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 = GetTempPathW
+Name = Test for GetTempPathW (test 1)
+Type = DEFAULT
+EXE1 = gettemppathw
+Description
+= Calls GetTempPathW and verifies by passing the returned
+= value to CreateDirectoryW. If the returned path exists,
+= CreateDirectoryW will fail.
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..9a3d0069db
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ MoveFileA.c
+)
+
+add_executable(paltest_movefilea_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_movefilea_test1 coreclrpal)
+
+target_link_libraries(paltest_movefilea_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/ExpectedResults.txt b/src/pal/tests/palsuite/file_io/MoveFileA/test1/ExpectedResults.txt
new file mode 100644
index 0000000000..43b67af6b2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/ExpectedResults.txt
@@ -0,0 +1 @@
+0101000001010000 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c b/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c
new file mode 100644
index 0000000000..8d1bc0eded
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c
@@ -0,0 +1,469 @@
+// 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: MoveFileA.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+LPSTR lpSource[4] = {"src_existing.txt",
+ "src_non-existant.txt",
+ "src_dir_existing",
+ "src_dir_non-existant"};
+LPSTR lpDestination[4] = {"dst_existing.txt",
+ "dst_non-existant.txt",
+ "dst_dir_existing",
+ "dst_dir_non-existant"};
+
+
+/* Create all the required test files */
+int createExisting(void)
+{
+ FILE* tempFile = NULL;
+ DWORD dwError;
+ BOOL bRc = FALSE;
+ char szBuffer[100];
+
+ /* create the src_existing file */
+ tempFile = fopen(lpSource[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: src_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", lpSource[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing directory and files */
+ bRc = CreateDirectoryA(lpSource[2], NULL);
+ if (bRc != TRUE)
+ {
+ Trace("MoveFileA: ERROR: couldn't create \"%s\" because of "
+ "error code %ld\n",
+ lpSource[2],
+ GetLastError());
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf(szBuffer, "%s/test01.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]:MoveFileA couldn't create %s\n", GetLastError(), szBuffer);
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf(szBuffer, "%s/test02.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]: couldn't create %s\n", GetLastError(), szBuffer);
+ return FAIL;
+ }
+
+
+ /* create the dst_existing file */
+ tempFile = fopen(lpDestination[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]:MoveFileA couldn't create \"%s\"\n", GetLastError(), lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the dst_dir_existing directory and files */
+ bRc = CreateDirectoryA(lpDestination[2], NULL);
+ if (bRc != TRUE)
+ {
+ dwError = GetLastError();
+ Trace("Error[%ld]:MoveFileA: couldn't create \"%s\"\n", GetLastError(), lpDestination[2]);
+ return FAIL;
+ }
+
+ tempFile = fopen("dst_dir_existing/test01.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test01.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
+ return FAIL;
+ }
+ tempFile = fopen("dst_dir_existing/test02.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test02.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ul]: couldn't create dst_dir_existing/test02.txt\n", GetLastError());
+ return FAIL;
+ }
+
+ return PASS;
+}
+
+
+
+void removeDirectoryHelper(LPSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesA(dir);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryA(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+
+/* remove all created files in preparation for the next test */
+void removeAll(void)
+{
+ char szTemp[40];
+ DWORD dwAtt;
+
+ /* get rid of source dirs and files */
+ removeFileHelper(lpSource[0], 1);
+ removeFileHelper(lpSource[1], 2);
+
+ dwAtt = GetFileAttributesA(lpSource[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpSource[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpSource[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[2], 17);
+ }
+
+
+ dwAtt = GetFileAttributesA(lpSource[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpSource[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpSource[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[3], 17);
+ }
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesA(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[0], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[1], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 17);
+ }
+
+}
+
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int nCounter = 0;
+ int i, j;
+ char tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ char tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 20);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Fail("MoveFileA ERROR[%ul]: Unable to open \"expectedresults.txt\"\n", GetLastError());
+ }
+
+ fgets(results, 20, resultsFile);
+ fclose(resultsFile);
+
+ /* clean the slate */
+ removeAll();
+
+ if (createExisting() != 0)
+ {
+ removeAll();
+ }
+
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+ bRc = MoveFileA(lpSource[i], lpDestination[j]);
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileA: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
+ i, j, lpSource[i], lpDestination[j]);
+ bSuccess = FALSE;
+ }
+
+ /* undo the last move */
+ removeAll();
+ createExisting();
+
+ nCounter++;
+ }
+ }
+
+ removeAll();
+ if (bSuccess == FALSE)
+ {
+ Fail("MoveFileA: Test Failed");
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileA(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Fail("Error[%ul]:MoveFileA: CreateFile failed to "
+ "create the file correctly.\n", GetLastError());
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileA: CloseHandle failed to close the "
+ "handle correctly. ERROR:%u\n",GetLastError());
+
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+ Fail("");
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesA(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileA: SetFileAttributes failed to set file "
+ "attributes correctly. GetLastError returned %u\n",GetLastError());
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+ Fail("");
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileA(tempSource, tempDest);
+ if(!bRc)
+ {
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA(%S, %S): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ GetLastError(), tempSource, tempDest);
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesA(tempDest);
+ if(result == 0)
+ {
+ /* delete the created file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA: GetFileAttributes failed to get "
+ "the file's attributes.\n", GetLastError());
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]MoveFileA: GetFileAttributes failed to get "
+ "the correct file attributes.\n", GetLastError());
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesA(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA: SetFileAttributes failed to set "
+ "file attributes correctly.\n", GetLastError());
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/MoveFileA/test1/testinfo.dat
new file mode 100644
index 0000000000..685072fcd9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = MoveFileA
+Name = Positive Test for MoveFileA
+TYPE = DEFAULT
+EXE1 = movefilea
+Description
+=Performs a number of MoveFileA tests and uses the
+=file ExpectedResults.txt to determine if the test passed/failed
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..f41dd7fd08
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ MoveFileExA.c
+)
+
+add_executable(paltest_movefileexa_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_movefileexa_test1 coreclrpal)
+
+target_link_libraries(paltest_movefileexa_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/ExpectedResults.txt b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/ExpectedResults.txt
new file mode 100644
index 0000000000..684b8a536f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/ExpectedResults.txt
@@ -0,0 +1 @@
+01110011000000000111001100000000
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c
new file mode 100644
index 0000000000..0bce2b08d1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c
@@ -0,0 +1,360 @@
+// 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: MoveFileExA.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileExA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+LPSTR lpSource[4] = {
+ "src_existing.tmp",
+ "src_non-existant.tmp",
+ "src_dir_existing",
+ "src_dir_non-existant"
+ };
+LPSTR lpDestination[4]={
+ "dst_existing.tmp",
+ "dst_non-existant.tmp",
+ "dst_dir_existing",
+ "dst_dir_non-existant"
+ };
+
+LPSTR lpFiles[14] ={
+ "src_dir_existing\\test01.tmp",
+ "src_dir_existing\\test02.tmp",
+ "dst_dir_existing\\test01.tmp",
+ "dst_dir_existing\\test02.tmp",
+ "src_dir_non-existant\\test01.tmp",
+ "src_dir_non-existant\\test02.tmp",
+ "dst_existing.tmp\\test01.tmp",
+ "dst_existing.tmp\\test02.tmp",
+ "dst_non-existant.tmp\\test01.tmp",
+ "dst_non-existant.tmp\\test02.tmp",
+ "dst_dir_existing\\test01.tmp",
+ "dst_dir_existing\\test02.tmp",
+ "dst_dir_non-existant\\test01.tmp",
+ "dst_dir_non-existant\\test02.tmp"
+ };
+
+DWORD dwFlag[2] = {MOVEFILE_COPY_ALLOWED, MOVEFILE_REPLACE_EXISTING};
+
+
+
+
+int createExisting(void)
+{
+ HANDLE tempFile = NULL;
+ HANDLE tempFile2 = NULL;
+
+ /* create the src_existing file and dst_existing file */
+ tempFile = CreateFileA(lpSource[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileA(lpDestination[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR[%ul]: couldn't create %S or %S\n", GetLastError(), lpSource[0],
+ lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing and dst_dir_existing directory and files */
+ CreateDirectoryA(lpSource[2], NULL);
+
+ tempFile = CreateFileA(lpFiles[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileA(lpFiles[1], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR[%ul]: couldn't create src_dir_existing\\test01.tmp\n", GetLastError());
+ return FAIL;
+ }
+
+ CreateDirectoryA(lpDestination[2], NULL);
+ tempFile = CreateFileA(lpFiles[2], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileA(lpFiles[3], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR[%ul]: couldn't create dst_dir_existing\\test01.tmp\n" , GetLastError());
+ return FAIL;
+ }
+ return PASS;
+
+}
+
+void removeDirectoryHelper(LPSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesA(dir);
+
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryA(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ }
+
+}
+
+void removeAll(void)
+{
+ DWORD dwAtt;
+ /* get rid of destination dirs and files */
+ removeFileHelper(lpSource[0], 11);
+ removeFileHelper(lpSource[1], 12);
+ removeFileHelper(lpFiles[0], 13);
+ removeFileHelper(lpFiles[1], 14);
+
+ removeDirectoryHelper(lpSource[2], 101);
+ removeFileHelper(lpFiles[4], 15);
+ removeFileHelper(lpFiles[5], 16);
+ removeDirectoryHelper(lpSource[3], 102);
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesA(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[6], 18);
+ removeFileHelper(lpFiles[7], 19);
+ removeDirectoryHelper(lpDestination[0], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[8], 21);
+ removeFileHelper(lpFiles[9], 22);
+ removeDirectoryHelper(lpDestination[1], 104);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 19);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[10], 24);
+ removeFileHelper(lpFiles[11], 25);
+ removeDirectoryHelper(lpDestination[2], 105);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 23);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[12], 26);
+ removeFileHelper(lpFiles[13], 27);
+ removeDirectoryHelper(lpDestination[3], 106);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 107);
+ }
+
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int i, j, k, nCounter = 0;
+ int res = FAIL;
+ char tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ char tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 34);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Trace("MoveFileExA ERROR: Unable to open \"expectedresults.txt\"\n");
+ goto EXIT;
+ }
+
+ fgets(results, 34, resultsFile);
+ fclose(resultsFile);
+
+ nCounter = 0;
+
+
+ /* clean the slate */
+ removeAll();
+ if (createExisting() != PASS)
+ {
+ goto EXIT;
+ }
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+ /* dwFlag loop */
+ for (k = 0; k < 2; k++)
+ {
+
+ /* move the file to the new location */
+ bRc = MoveFileExA(lpSource[i], lpDestination[j], dwFlag[k]);
+
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileExA(%s, %s, %s): Values of i[%d], j[%d], k [%d] and results[%d]=%c LastError[%d]Flag[%d]FAILED\n",
+ lpSource[i], lpDestination[j],
+ k == 1 ?
+ "MOVEFILE_REPLACE_EXISTING":"MOVEFILE_COPY_ALLOWED", i, j, k, nCounter, results[nCounter], GetLastError(), bRc);
+ goto EXIT;
+ }
+
+ /* undo the last move */
+ removeAll();
+ if (createExisting() != PASS)
+ {
+ goto EXIT;
+ }
+ nCounter++;
+ }
+ }
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileA(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Trace("MoveFileExA: CreateFile failed to "
+ "create the file correctly.\n");
+ goto EXIT;
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileExA: CloseHandle failed to close the "
+ "handle correctly. yo %u\n",GetLastError());
+ goto EXIT;
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesA(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileExA: SetFileAttributes failed to set file "
+ "attributes correctly. ERROR:%u\n",GetLastError());
+ goto EXIT;
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileExA(tempSource, tempDest, MOVEFILE_COPY_ALLOWED );
+ if(!bRc)
+ {
+ Trace("MoveFileExA(%S, %S, %s): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ tempSource, tempDest, "MOVEFILE_COPY_ALLOWED");
+ goto EXIT;
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesA(tempDest);
+ if(result == 0)
+ {
+ Trace("MoveFileExA: GetFileAttributes failed to get "
+ "the file's attributes.\n");
+ goto EXIT;
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ Trace("MoveFileExA: GetFileAttributes failed to get "
+ "the correct file attributes.\n");
+ goto EXIT;
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesA(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Trace("MoveFileExA: SetFileAttributes "
+ "failed to set file attributes correctly.\n");
+ goto EXIT;
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Trace("MoveFileExA: DeleteFileA failed to delete the"
+ "file correctly.\n");
+ goto EXIT;
+ }
+
+ res = PASS;
+
+EXIT:
+ removeAll();
+
+ PAL_TerminateEx(res);
+ return res;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/testinfo.dat
new file mode 100644
index 0000000000..d8d19af880
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = MoveFileExA
+Name = Test for MoveFileExA (test 1)
+Type = DEFAULT
+EXE1 = movefileexa
+Description
+= Creates a number of files/directories and attempts to move them.
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..4c6a70f050
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ MoveFileExW.c
+)
+
+add_executable(paltest_movefileexw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_movefileexw_test1 coreclrpal)
+
+target_link_libraries(paltest_movefileexw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/ExpectedResults.txt b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/ExpectedResults.txt
new file mode 100644
index 0000000000..684b8a536f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/ExpectedResults.txt
@@ -0,0 +1 @@
+01110011000000000111001100000000
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c
new file mode 100644
index 0000000000..4f5b72dcf7
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c
@@ -0,0 +1,431 @@
+// 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: MoveFileExW.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileExW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+LPWSTR lpSource[4];
+LPWSTR lpDestination[4];
+LPWSTR lpFiles[14];
+
+DWORD dwFlag[2] = {MOVEFILE_COPY_ALLOWED, MOVEFILE_REPLACE_EXISTING};
+
+
+
+int createExisting(void)
+{
+ HANDLE tempFile = NULL;
+ HANDLE tempFile2 = NULL;
+
+ /* create the src_existing file and dst_existing file */
+ tempFile = CreateFileW(lpSource[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileW(lpDestination[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR: couldn't create %S or %S\n", lpSource[0],
+ lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing and dst_dir_existing directory and files */
+ CreateDirectoryW(lpSource[2], NULL);
+
+ tempFile = CreateFileW(lpFiles[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileW(lpFiles[1], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR: couldn't create src_dir_existing\\test01.tmp\n");
+ return FAIL;
+ }
+
+ CreateDirectoryW(lpDestination[2], NULL);
+ tempFile = CreateFileW(lpFiles[2], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ tempFile2 = CreateFileW(lpFiles[3], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ CloseHandle(tempFile2);
+ CloseHandle(tempFile);
+
+ if ((tempFile == NULL) || (tempFile2 == NULL))
+ {
+ Trace("ERROR: couldn't create dst_dir_existing\\test01.tmp\n");
+ return FAIL;
+ }
+ return PASS;
+}
+
+void removeDirectoryHelper(LPWSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesW(dir);
+// Trace(" Value of location[%d], and directorye [%S]\n", location, dir);
+
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryW(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%S], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPWSTR wfile, int location)
+{
+ FILE *fp;
+ char * pfile = convertC(wfile);
+
+// Trace(" Value of location[%d], and file [%s]\n", location, pfile);
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileW(wfile))
+ {
+ Fail("ERROR: Failed to delete file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+ free(pfile);
+}
+
+void removeAll(void)
+{
+ DWORD dwAtt;
+ /* get rid of destination dirs and files */
+ removeFileHelper(lpSource[0], 11);
+// lpSource[0] = convert("src_existing.tmp");
+
+ removeFileHelper(lpSource[1], 12);
+ //lpSource[1] = convert("src_non-existant.tmp");
+
+ removeFileHelper(lpFiles[0], 13);
+// lpFiles[0] = convert("src_dir_existing\\test01.tmp");
+
+ removeFileHelper(lpFiles[1], 14);
+// lpFiles[1] = convert("src_dir_existing\\test02.tmp");
+
+ removeDirectoryHelper(lpSource[2], 101);
+// lpSource[2] = convert("src_dir_existing");
+
+ removeFileHelper(lpFiles[4], 15);
+// lpFiles[4] = convert("src_dir_non-existant\\test01.tmp");
+
+ removeFileHelper(lpFiles[5], 16);
+// lpFiles[5] = convert("src_dir_non-existant\\test02.tmp");
+
+ removeDirectoryHelper(lpSource[3], 102);
+// lpSource[3] = convert("src_dir_non-existant");
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesW(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[6], 18);
+ // lpFiles[6] = convert("dst_existing.tmp\\test01.tmp");
+ removeFileHelper(lpFiles[7], 19);
+ // lpFiles[7] = convert("dst_existing.tmp\\test02.tmp");
+ removeDirectoryHelper(lpDestination[0], 103);
+ // lpDestination[0] = convert("dst_existing.tmp");
+
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ // lpDestination[0] = convert("dst_existing.tmp");
+ }
+
+ dwAtt = GetFileAttributesW(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[8], 21);
+ // lpFiles[8] = convert("dst_non-existant.tmp\\test01.tmp");
+ removeFileHelper(lpFiles[9], 22);
+ // lpFiles[9] = convert("dst_non-existant.tmp\\test02.tmp");
+ removeDirectoryHelper(lpDestination[1], 104);
+ // lpDestination[1] = convert("dst_non-existant.tmp");
+
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 19);
+ //lpDestination[1] = convert("dst_non-existant.tmp");
+ }
+
+ dwAtt = GetFileAttributesW(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[10], 24);
+ // lpFiles[10] = convert("dst_dir_existing\\test01.tmp");
+ removeFileHelper(lpFiles[11], 25);
+ // lpFiles[11] = convert("dst_dir_existing\\test02.tmp");
+ removeDirectoryHelper(lpDestination[2], 105);
+ // lpDestination[2] = convert("dst_dir_existing");
+
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 23);
+ // lpDestination[2] = convert("dst_dir_existing");
+
+ }
+
+ dwAtt = GetFileAttributesW(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ removeFileHelper(lpFiles[12], 26);
+ // lpFiles[12] = convert("dst_dir_non-existant\\test01.tmp");
+ removeFileHelper(lpFiles[13], 27);
+ // lpFiles[13] = convert("dst_dir_non-existant\\test02.tmp");
+ removeDirectoryHelper(lpDestination[3], 106);
+ // lpDestination[3] = convert("dst_dir_non-existant");
+
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 107);
+ // lpDestination[3] = convert("dst_dir_non-existant");
+
+ }
+
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int i, j, k, nCounter = 0;
+ int res = FAIL;
+ WCHAR tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ WCHAR tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ lpSource[0] = convert("src_existing.tmp");
+ lpSource[1] = convert("src_non-existant.tmp");
+ lpSource[2] = convert("src_dir_existing");
+ lpSource[3] = convert("src_dir_non-existant");
+
+ lpDestination[0] = convert("dst_existing.tmp");
+ lpDestination[1] = convert("dst_non-existant.tmp");
+ lpDestination[2] = convert("dst_dir_existing");
+ lpDestination[3] = convert("dst_dir_non-existant");
+
+ lpFiles[0] = convert("src_dir_existing\\test01.tmp");
+ lpFiles[1] = convert("src_dir_existing\\test02.tmp");
+ lpFiles[2] = convert("dst_dir_existing\\test01.tmp");
+ lpFiles[3] = convert("dst_dir_existing\\test02.tmp");
+ lpFiles[4] = convert("src_dir_non-existant\\test01.tmp");
+ lpFiles[5] = convert("src_dir_non-existant\\test02.tmp");
+
+ lpFiles[6] = convert("dst_existing.tmp\\test01.tmp");
+ lpFiles[7] = convert("dst_existing.tmp\\test02.tmp");
+
+ lpFiles[8] = convert("dst_non-existant.tmp\\test01.tmp");
+ lpFiles[9] = convert("dst_non-existant.tmp\\test02.tmp");
+
+ lpFiles[10] = convert("dst_dir_existing\\test01.tmp");
+ lpFiles[11] = convert("dst_dir_existing\\test02.tmp");
+
+ lpFiles[12] = convert("dst_dir_non-existant\\test01.tmp");
+ lpFiles[13] = convert("dst_dir_non-existant\\test02.tmp");
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 34);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Trace("MoveFileExW ERROR: Unable to open \"expectedresults.txt\"\n");
+ goto EXIT;
+ }
+
+ fgets(results, 34, resultsFile);
+ fclose(resultsFile);
+
+// Trace("Value of results[%]=%s\n", i, results);
+ for( i = 0; i < 32; i++)
+ {
+ Trace("Value of results[%d]=%c\n", i, results[i]);
+ }
+ nCounter = 0;
+
+
+ /* clean the slate */
+ removeAll();
+ if (createExisting() != PASS)
+ {
+ goto EXIT;
+ }
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+ /* dwFlag loop */
+ for (k = 0; k < 2; k++)
+ {
+
+ //if(nCounter == 22)
+ //{
+ //exit(1);
+ //}
+ /* move the file to the new location */
+ bRc = MoveFileExW(lpSource[i], lpDestination[j], dwFlag[k]);
+
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileExW(%S, %S, %s): Values of i[%d], j[%d], k [%d] and results[%d]=%c LastError[%d]Flag[%d]FAILED\n",
+ lpSource[i], lpDestination[j],
+ k == 1 ?
+ "MOVEFILE_REPLACE_EXISTING":"MOVEFILE_COPY_ALLOWED", i, j, k, nCounter, results[nCounter], GetLastError(), bRc);
+ goto EXIT;
+ }
+
+ //Trace("MoveFileExW(%S, %S, %s): Values of i[%d], j[%d], k [%d] and results[%d]=%c \n",
+ // lpSource[i], lpDestination[j],
+ // k == 1 ?
+ // "MOVEFILE_REPLACE_EXISTING":"MOVEFILE_COPY_ALLOWED", i, j, k, nCounter, results[nCounter]);
+
+
+ /* undo the last move */
+ removeAll();
+ if (createExisting() != PASS)
+ {
+ goto EXIT;
+ }
+ //Trace("Counter [%d] over \n", nCounter);
+ nCounter++;
+ }
+ }
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileW(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Trace("MoveFileExW: CreateFile failed to "
+ "create the file correctly.\n");
+ goto EXIT;
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileExW: CloseHandle failed to close the "
+ "handle correctly. yo %u\n",GetLastError());
+ goto EXIT;
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesW(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileExW: SetFileAttributes failed to set file "
+ "attributes correctly. ERROR:%u\n",GetLastError());
+ goto EXIT;
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileExW(tempSource, tempDest, MOVEFILE_COPY_ALLOWED );
+ if(!bRc)
+ {
+ Trace("MoveFileExW(%S, %S, %s): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ tempSource, tempDest, "MOVEFILE_COPY_ALLOWED");
+ goto EXIT;
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesW(tempDest);
+ if(result == 0)
+ {
+ Trace("MoveFileExW: GetFileAttributes failed to get "
+ "the file's attributes.\n");
+ goto EXIT;
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ Trace("MoveFileExW: GetFileAttributes failed to get "
+ "the correct file attributes.\n");
+ goto EXIT;
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesW(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ Trace("MoveFileExW: SetFileAttributes "
+ "failed to set file attributes correctly.\n");
+ goto EXIT;
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Trace("MoveFileExW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ goto EXIT;
+ }
+
+ res = PASS;
+
+EXIT:
+ removeAll();
+ for (i=0; i<4; i++)
+ {
+ free(lpSource[i]);
+ free(lpDestination[i]);
+ }
+ for (i=0; i<14; i++)
+ {
+ free(lpFiles[i]);
+ }
+
+ PAL_TerminateEx(res);
+ return res;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/testinfo.dat
new file mode 100644
index 0000000000..9b001b5c38
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = MoveFileExW
+Name = Test for MoveFileExW (test 1)
+Type = DEFAULT
+EXE1 = movefileexw
+Description
+= Creates a number of files/directories and attempts to move them.
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..497f654122
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ MoveFileW.c
+)
+
+add_executable(paltest_movefilew_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_movefilew_test1 coreclrpal)
+
+target_link_libraries(paltest_movefilew_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/ExpectedResults.txt b/src/pal/tests/palsuite/file_io/MoveFileW/test1/ExpectedResults.txt
new file mode 100644
index 0000000000..43b67af6b2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/ExpectedResults.txt
@@ -0,0 +1 @@
+0101000001010000 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c b/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c
new file mode 100644
index 0000000000..58999302d0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c
@@ -0,0 +1,478 @@
+// 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: MoveFileW.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+LPSTR lpSource[4] = {"src_existing.txt",
+ "src_non-existant.txt",
+ "src_dir_existing",
+ "src_dir_non-existant"};
+LPSTR lpDestination[4] = {"dst_existing.txt",
+ "dst_non-existant.txt",
+ "dst_dir_existing",
+ "dst_dir_non-existant"};
+
+
+/* Create all the required test files */
+int createExisting(void)
+{
+ FILE* tempFile = NULL;
+ DWORD dwError;
+ BOOL bRc = FALSE;
+ WCHAR* wPtr = NULL;
+ char szBuffer[100];
+
+ /* create the src_existing file */
+ tempFile = fopen(lpSource[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFile test file: src_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", lpSource[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing directory and files */
+ wPtr = convert(lpSource[2]);
+ bRc = CreateDirectoryW(wPtr, NULL);
+ free(wPtr);
+ if (bRc != TRUE)
+ {
+ Trace("MoveFileW: ERROR: couldn't create \"%s\" because of "
+ "error code %ld\n",
+ lpSource[2],
+ GetLastError());
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf(szBuffer, "%s/test01.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", szBuffer);
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf(szBuffer, "%s/test02.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", szBuffer);
+ return FAIL;
+ }
+
+
+ /* create the dst_existing file */
+ tempFile = fopen(lpDestination[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create \"%s\"\n", lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the dst_dir_existing directory and files */
+ wPtr = convert(lpDestination[2]);
+ bRc = CreateDirectoryW(wPtr, NULL);
+ free(wPtr);
+ if (bRc != TRUE)
+ {
+ dwError = GetLastError();
+ Trace("MoveFileW: ERROR: couldn't create \"%s\"\n", lpDestination[2]);
+ return FAIL;
+ }
+
+ tempFile = fopen("dst_dir_existing/test01.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test01.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
+ return FAIL;
+ }
+ tempFile = fopen("dst_dir_existing/test02.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test02.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test02.txt\n");
+ return FAIL;
+ }
+
+ return PASS;
+}
+
+void removeDirectoryHelper(LPSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesA(dir);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryA(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+/* remove all created files in preparation for the next test */
+void removeAll(void)
+{
+ char szTemp[40];
+ DWORD dwAtt;
+
+ /* get rid of source dirs and files */
+ removeFileHelper(lpSource[0], 1);
+ removeFileHelper(lpSource[1], 2);
+
+ dwAtt = GetFileAttributesA(lpSource[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpSource[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpSource[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[2], 17);
+ }
+
+
+ dwAtt = GetFileAttributesA(lpSource[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpSource[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpSource[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[3], 17);
+ }
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesA(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[0], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[1], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf(szTemp, "%s/test01.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf(szTemp, "%s/test02.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 17);
+ }
+
+}
+
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int nCounter = 0;
+ int i, j;
+ WCHAR* wSource = NULL;
+ WCHAR* wDest = NULL;
+ WCHAR tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ WCHAR tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 20);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Fail("MoveFileW ERROR: Unable to open \"expectedresults.txt\"\n");
+ }
+
+ fgets(results, 20, resultsFile);
+ fclose(resultsFile);
+
+ /* clean the slate */
+ removeAll();
+
+ if (createExisting() != 0)
+ {
+ removeAll();
+ }
+
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+
+ wSource = convert(lpSource[i]);
+ wDest = convert(lpDestination[j]);
+ bRc = MoveFileW(wSource, wDest);
+ free(wSource);
+ free(wDest);
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileW: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
+ i, j, lpSource[i], lpDestination[j]);
+ bSuccess = FALSE;
+ }
+
+ /* undo the last move */
+ removeAll();
+ createExisting();
+
+ nCounter++;
+ }
+ }
+
+ removeAll();
+ if (bSuccess == FALSE)
+ {
+ Fail("MoveFileW: Test Failed");
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileW(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Fail("MoveFileW: CreateFile failed to "
+ "create the file correctly.\n");
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileW: CloseHandle failed to close the "
+ "handle correctly. ERROR:%u\n",GetLastError());
+
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+ Fail("");
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesW(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileW: SetFileAttributes failed to set file "
+ "attributes correctly. GetLastError returned %u\n",GetLastError());
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+ Fail("");
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileW(tempSource, tempDest);
+ if(!bRc)
+ {
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW(%S, %S): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ tempSource, tempDest);
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesW(tempDest);
+ if(result == 0)
+ {
+ /* delete the created file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: GetFileAttributes failed to get "
+ "the file's attributes.\n");
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: GetFileAttributes failed to get "
+ "the correct file attributes.\n");
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesW(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: SetFileAttributes failed to set "
+ "file attributes correctly.\n");
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/MoveFileW/test1/testinfo.dat
new file mode 100644
index 0000000000..8852a03ca2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = MoveFileW
+Name = Positive Test for MoveFileW
+TYPE = DEFAULT
+EXE1 = movefilew
+Description
+=Performs a number of MoveFileW tests and uses the
+=file ExpectedResults.txt to determine if the test passed/failed
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt
new file mode 100644
index 0000000000..7b166e17b0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ReadFile.c
+)
+
+add_executable(paltest_readfile_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_readfile_test1 coreclrpal)
+
+target_link_libraries(paltest_readfile_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/NonReadableFile.txt b/src/pal/tests/palsuite/file_io/ReadFile/test1/NonReadableFile.txt
new file mode 100644
index 0000000000..a8a940627d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/NonReadableFile.txt
@@ -0,0 +1 @@
+this is a test \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c
new file mode 100644
index 0000000000..a59e29212e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c
@@ -0,0 +1,82 @@
+// 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: ReadFile.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the ReadFile function.
+** This test will attempt to read from a NULL handle and from
+** a file without read permissions set.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwBytesRead = 0;
+ BOOL bRc = FALSE;
+ char szBuffer[256];
+ char* szNonReadableFile = {"nonreadablefile.txt"};
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 256);
+
+ /* Read from a NULL handle
+ */
+
+ bRc = ReadFile(hFile, szBuffer, 20, &dwBytesRead, NULL);
+
+ if (bRc == TRUE)
+ {
+ Fail("ReadFile: ERROR -> Able to read from a NULL handle\n");
+ }
+
+
+ /* Read from a file without read permissions
+ */
+
+#if WIN32
+
+#else
+ /* attempt to read from the unreadable file
+ * open a file without read permissions
+ */
+ hFile = CreateFile(szNonReadableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ dwByteCount = GetLastError();
+ Fail("ReadFile: ERROR -> Unable to create file \"%s\".\n",
+ szNonReadableFile);
+ }
+
+ bRc = ReadFile(hFile, szBuffer, 20, &dwBytesRead, NULL);
+
+ if (bRc == TRUE)
+ {
+ Fail("ReadFile: ERROR -> Able to read from a file without read "
+ "permissions\n");
+ }
+#endif
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/ReadFile/test1/testinfo.dat
new file mode 100644
index 0000000000..b0df11a3ab
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = ReadFile
+Name = Positive Test for ReadFile
+Type = DEFAULT
+EXE1 = readfile
+Description
+=Attempt to read from a NULL handle and a file without read permissions
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt
new file mode 100644
index 0000000000..fc4870e73d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ReadFile.c
+)
+
+add_executable(paltest_readfile_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_readfile_test2 coreclrpal)
+
+target_link_libraries(paltest_readfile_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c
new file mode 100644
index 0000000000..f16858e573
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c
@@ -0,0 +1,198 @@
+// 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: ReadFile.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the ReadFile function.
+** Creates a test file and performs an array of read tests.
+**
+** Assumes successful:
+** CreateFile
+** CloseHandle
+** WriteFile
+** GetLastError
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.\0";
+const char* szEmptyString = "";
+const char* szReadableFile = "Readable.txt";
+const char* szResultsFile = "Results.txt";
+
+//Previously number of tests was 6, now 4 refer VSW 312690
+#define NOOFTESTS 4
+
+#ifdef __sparc__
+const int PAGESIZE = 8192;
+#else // __sparc__
+const int PAGESIZE = 4096;
+#endif // __sparc__
+
+char *readBuffer;
+
+BOOL validateResults(const char* szString, // string read
+ DWORD dwByteCount, // amount requested
+ DWORD dwBytesRead) // amount read
+{
+ // were the correct number of bytes read?
+ if (dwBytesRead > dwByteCount)
+ {
+ Trace("bytes read > bytes asked for\n");
+ return FALSE;
+ }
+ if (dwBytesRead != strlen(szString))
+ {
+ Trace("bytes read != length of read string\n");
+ return FALSE;
+ }
+
+ //
+ // compare results
+ //
+
+ if (memcmp(szString, szStringTest, dwBytesRead) != 0)
+ {
+ Trace("read = %s string = %s", szString, szStringTest);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL readTest(DWORD dwByteCount, char cResult)
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesRead;
+ BOOL bRc = FALSE;
+
+ // open the test file
+ hFile = CreateFile(szReadableFile,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ReadFile: ERROR -> Unable to open file \"%s\".\n",
+ szReadableFile);
+ return FALSE;
+ }
+
+ memset(readBuffer, 0, PAGESIZE);
+
+ bRc = ReadFile(hFile, readBuffer, dwByteCount, &dwBytesRead, NULL);
+
+ if (bRc == FALSE)
+ {
+ // if it failed, was it supposed to fail?
+ if (cResult == '1')
+ {
+ Trace("\nbRc = %d\n", bRc);
+ Trace("readBuffer = [%s] dwByteCount = %d dwBytesRead = %d\n", readBuffer, dwByteCount, dwBytesRead);
+ Trace("cresult = 1\n");
+ Trace("getlasterror = %d\n", GetLastError());
+ CloseHandle(hFile);
+ return FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ // if it passed, was it supposed to pass?
+ if (cResult == '0')
+ {
+ Trace("cresult = 0\n");
+ return FALSE;
+ }
+ else
+ {
+ return (validateResults(readBuffer, dwByteCount, dwBytesRead));
+ }
+ }
+
+ CloseHandle(hFile);
+ return TRUE;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ const int BUFFER_SIZE = 2 * PAGESIZE;
+
+ DWORD dwByteCount[] = { 0,
+ 10,
+ strlen(szStringTest),
+ PAGESIZE
+ // Commented out two negative test cases : Refer VSW 312690
+ // 2 * PAGESIZE,
+ // -1
+ };
+
+ DWORD oldProt;
+ char szResults[] = "1111"; // Was "111100": Refer VSW 312690
+ int i;
+ BOOL bRc = FALSE;
+ DWORD dwBytesWritten = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* aloocate read-write memery for readBuffer */
+ if (!(readBuffer = (char*) VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE)))
+ {
+ Fail("VirtualAlloc failed: GetLastError returns %d\n", GetLastError());
+ return FAIL;
+ }
+
+ /* write protect the second page of readBuffer */
+ if (!VirtualProtect(&readBuffer[PAGESIZE], PAGESIZE, PAGE_NOACCESS, &oldProt))
+ {
+ Fail("VirtualProtect failed: GetLastError returns %d\n", GetLastError());
+ return FAIL;
+ }
+
+ // create the test file
+ hFile = CreateFile(szReadableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ReadFile: ERROR -> Unable to create file \"%s\" (%d).\n",
+ szReadableFile, GetLastError());
+ }
+
+ bRc = WriteFile(hFile, szStringTest, strlen(szStringTest), &dwBytesWritten, NULL);
+ CloseHandle(hFile);
+
+
+ for (i = 0; i< NOOFTESTS; i++)
+ {
+ bRc = readTest(dwByteCount[i], szResults[i]);
+ if (bRc != TRUE)
+ {
+ Fail("ReadFile: ERROR -> Failed on test[%d]\n", i);
+ }
+ }
+
+ VirtualFree(readBuffer, BUFFER_SIZE, MEM_RELEASE);
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/ReadFile/test2/testinfo.dat
new file mode 100644
index 0000000000..82b6326170
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = ReadFile
+Name = Positive Test for ReadFile
+Type = DEFAULT
+EXE1 = readfile
+Description
+=Multiple tests of reads of varying sizes with verification
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt
new file mode 100644
index 0000000000..77397743d4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ReadFile.c
+)
+
+add_executable(paltest_readfile_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_readfile_test3 coreclrpal)
+
+target_link_libraries(paltest_readfile_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c
new file mode 100644
index 0000000000..c5d6b1d155
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c
@@ -0,0 +1,184 @@
+// 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: ReadFile.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the ReadFile function.
+** Creates a test file and performs an array of sequential read
+** tests.
+**
+** Assumes successful:
+** CreateFile
+** CloseHandle
+** memset
+** WriteFile
+** CreateFile
+** CloseHandle
+** GetLastError
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.\0";
+const char* szEmptyString = "";
+const char* szReadableFile = "Readable.txt";
+const char* szResultsFile = "Results.txt";
+
+
+BOOL validateResults(const char* szString, // string read
+ DWORD dwByteCount, // amount requested
+ DWORD dwBytesRead) // amount read
+{
+ // were the correct number of bytes read?
+ if (dwBytesRead > dwByteCount)
+ {
+ Trace("bytes read > bytes asked for\n");
+ return FALSE;
+ }
+ if (dwBytesRead != strlen(szString))
+ {
+ Trace("bytes read != length of read string\n");
+ return FALSE;
+ }
+
+
+ //
+ // compare results
+ //
+
+ if (memcmp(szString, szStringTest, dwByteCount) != 0)
+ {
+ Trace("read = %s string = %s", szString, szStringTest);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+
+BOOL readTest(DWORD dwByteCount, char cResult)
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesRead = 0;
+ DWORD dwTotal = 0;
+ DWORD dwRequested = 0;
+ BOOL bRc = FALSE;
+ char szString[100];
+ char* szPtr = szString;
+ int i = 0;
+
+ // open the test file
+ hFile = CreateFile(szReadableFile,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ReadFile: ERROR -> Unable to open file \"%s\".\n",
+ szReadableFile);
+ return FALSE;
+ }
+
+ memset(szString, 0, 100);
+
+ for (i = 0; i < 5; i++)
+ {
+ bRc = ReadFile(hFile, szPtr, dwByteCount, &dwBytesRead, NULL);
+ szPtr += dwByteCount;
+ dwTotal += dwBytesRead;
+ dwRequested += dwByteCount;
+ }
+
+ if (bRc == FALSE)
+ {
+ // if it failed, was it supposed to fail?
+ if (cResult == '1')
+ {
+ Trace("\nbRc = %d\n", bRc);
+ Trace("szString = [%s] dwByteCount = %d dwBytesRead = %d\n",
+ szString,
+ dwByteCount,
+ dwBytesRead);
+ Trace ("cresult = 1\n");
+ Trace ("getlasterror = %d\n", GetLastError());
+ CloseHandle(hFile);
+ return FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ // if it passed, was it supposed to pass?
+ if (cResult == '0')
+ {
+ Trace ("cresult = 0\n");
+ return FALSE;
+ }
+ else
+ {
+ return (validateResults(szString, dwRequested, dwTotal));
+ }
+ }
+
+ CloseHandle(hFile);
+ return TRUE;
+}
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount[4] = {0, 1, 2, 3};
+ char szResults[4] = {'1', '1', '1', '1'};
+ int i;
+ BOOL bRc = FALSE;
+ DWORD dwBytesWritten = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ // create the test file
+ hFile = CreateFile(szReadableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ReadFile: ERROR -> Unable to create file \"%s\".\n",
+ szReadableFile);
+ }
+
+ bRc = WriteFile(hFile, szStringTest, strlen(szStringTest),
+ &dwBytesWritten,
+ NULL);
+ CloseHandle(hFile);
+
+ for (i = 0; i < 4; i++)
+ {
+ bRc = readTest(dwByteCount[i], szResults[i]);
+ if (bRc != TRUE)
+ {
+ Fail("ReadFile: ERROR -> Failed on test[%d]\n", i);
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/ReadFile/test3/testinfo.dat
new file mode 100644
index 0000000000..82b6326170
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = ReadFile
+Name = Positive Test for ReadFile
+Type = DEFAULT
+EXE1 = readfile
+Description
+=Multiple tests of reads of varying sizes with verification
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt
new file mode 100644
index 0000000000..37f227aced
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ readfile.c
+)
+
+add_executable(paltest_readfile_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_readfile_test4 coreclrpal)
+
+target_link_libraries(paltest_readfile_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c b/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c
new file mode 100644
index 0000000000..3ec939f63a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c
@@ -0,0 +1,147 @@
+// 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: ReadFile.c (test 4)
+**
+** Purpose: Tests the PAL implementation of the ReadFile function.
+** Creates a file and writes a small string to it, attempt
+** to read many more characters that exist. The returned
+** number of chars should be the amount written originally
+** not the number requested.
+**
+**
+**===================================================================*/
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ BOOL bRc = FALSE;
+ char szBuffer[256];
+ DWORD dwBytesRead = 0;
+ int szRequestSize = 256;
+ char testFile[] = "testfile.tmp";
+ char testString[] = "people stop and stare";
+ DWORD res = 0;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Initialize the buffer.
+ */
+ memset(szBuffer, 0, 256);
+
+ /* Create a file to test with.
+ */
+ hFile = CreateFile(testFile,
+ GENERIC_WRITE|GENERIC_READ,
+ FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR:%u: Unable to create file \"%s\".\n",
+ GetLastError(),
+ testFile);
+ }
+
+ /* Write to the File handle.
+ */
+ bRc = WriteFile(hFile,
+ testString,
+ strlen(testString),
+ &dwBytesWritten,
+ NULL);
+
+ if (bRc == FALSE)
+ {
+ Trace("ERROR:%u: Unable to write to file handle "
+ "hFile=0x%lx\n",
+ GetLastError(),
+ hFile);
+ if (!CloseHandle(hFile))
+ {
+ Trace("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Set the file pointer to beginning of file.
+ */
+ res = SetFilePointer(hFile, (LONG)NULL, NULL, FILE_BEGIN);
+
+ if( (res == INVALID_SET_FILE_POINTER) &&
+ (GetLastError() != NO_ERROR))
+ {
+ Trace("ERROR:%u: Unable to set file pointer to the beginning of file.",
+ GetLastError());
+
+ if (!CloseHandle(hFile))
+ {
+ Trace("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+
+ /* Attempt to read 256 characters from a file
+ * that does not contain that many.
+ */
+ bRc = ReadFile(hFile,
+ szBuffer,
+ szRequestSize,
+ &dwBytesRead,
+ NULL);
+
+ if (bRc == FALSE)
+ {
+ Trace("ERROR:%u: Unable to read from file handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ if (!CloseHandle(hFile))
+ {
+ Trace("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Confirm the number of bytes read with that requested.
+ */
+ if (dwBytesRead != strlen(testString))
+ {
+ Trace("ERROR: The number of bytes read \"%d\" is not equal to the "
+ "number originally written \"%d\" to the file.\n",
+ dwBytesRead,
+ strlen(testString));
+ if (!CloseHandle(hFile))
+ {
+ Trace("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Terminate the PAL.
+ */
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/ReadFile/test4/testinfo.dat
new file mode 100644
index 0000000000..6f3267d591
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test4/testinfo.dat
@@ -0,0 +1,17 @@
+# 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 = ReadFile
+Name = Positive Test for ReadFile
+Type = DEFAULT
+EXE1 = readfile
+Description
+= Tests the PAL implementation of the ReadFile function.
+= Creates a file and writes a small string to it, attempt
+= to read many more characters that exist. The returned
+= number of chars should be the amount written originally
+= not the number requested.
+
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..7a8d1c9d57
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ RemoveDirectoryA.cpp
+)
+
+add_executable(paltest_removedirectorya_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_removedirectorya_test1 coreclrpal)
+
+target_link_libraries(paltest_removedirectorya_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp
new file mode 100644
index 0000000000..167af58163
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp
@@ -0,0 +1,315 @@
+// 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: RemoveDirectoryA.c
+**
+** Purpose: Tests the PAL implementation of the RemoveDirectoryA function.
+**
+**
+**===================================================================*/
+
+
+#define PAL_STDCPP_COMPAT
+#include <palsuite.h>
+#undef PAL_STDCPP_COMPAT
+
+#include <unistd.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ char szDirName[252];
+ DWORD curDirLen;
+ char *szTemp = NULL;
+ char *szTemp2 = NULL;
+ char szwCurrentDir[MAX_PATH];
+ char szwSubDir[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /*
+ * remove a NULL directory
+ */
+ bRc = RemoveDirectoryA(NULL);
+ if (bRc != FALSE)
+ {
+ Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove a"
+ " NULL directory name\n", GetLastError());
+ }
+
+ /*
+ * remove a directory that does not exist
+ */
+ szTemp = (char *) malloc (sizeof("test_directory"));
+ sprintf(szTemp, "test_directory");
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc != FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove"
+ " the non-existant directory \"test_directory\"\n", GetLastError());
+ }
+
+ /*
+ * remove a symlink to a directory
+ */
+ bRc = CreateDirectoryA(szTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory "
+ "\"test_directory\".\n", GetLastError());
+ }
+
+ char *szSymlinkName = (char *) malloc (sizeof("test_directory_symlink"));
+ sprintf(szSymlinkName, "test_directory_symlink");
+ if (symlink(szTemp, szSymlinkName) != 0)
+ {
+ Fail("Error:RemoveDirectoryA: Failed to create a symlink to the directory \"test_directory\".\n");
+ }
+
+ bRc = RemoveDirectoryA(szSymlinkName);
+ if (bRc != FALSE)
+ {
+ Fail("Error:RemoveDirectoryA: RemoveDirectoryA should return FALSE when passed a symlink.\n");
+ }
+
+ unlink(szSymlinkName);
+
+ /*
+ * remove a directory that exists
+ */
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryW: Failed to remove the directory "
+ "\"test_directory\"\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesA(szTemp) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of "
+ "the removed directory\n" , GetLastError());
+ }
+ free(szTemp);
+
+ /*
+ * remove long directory names (245 characters)
+ */
+ curDirLen = GetCurrentDirectoryA(0, NULL) + 1;
+ memset(szDirName, 0, 252);
+ memset(szDirName, 'a', 245 - curDirLen);
+ szTemp = (char *) malloc (sizeof(szDirName));
+ szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
+
+ bRc = CreateDirectoryA(szTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to create a directory name "
+ "245 chars long\n" , GetLastError());
+ }
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to remove a 245 char "
+ "long directory\n", GetLastError());
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesA(szTemp) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of "
+ "the removed directory\n", GetLastError());
+ }
+ free(szTemp);
+
+ /*
+ * directories with dots
+ */
+ memset(szDirName, 0, 252);
+ sprintf(szDirName, ".dotDirectory");
+ szTemp = (char *) malloc (sizeof(szDirName));
+ szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
+
+ bRc = CreateDirectoryA(szTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to create \"%s\"\n", GetLastError(), szDirName);
+ }
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to remove \"%s\"\n", GetLastError(), szDirName);
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesA(szTemp) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of "
+ "the removed directory\n", GetLastError());
+ }
+ free(szTemp);
+
+ /*
+ * Try calling RemoveDirectory with a file name
+ */
+ memset(szDirName, 0, 252);
+ sprintf(szDirName, "removedirectoryw.c");
+ szTemp = (char *) malloc (sizeof(szDirName));
+ szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
+
+ bRc = RemoveDirectoryA(szTemp);
+ free(szTemp);
+ if (bRc != FALSE)
+ {
+ Fail("Error[%ul]:RemoveDirectoryA: should have failed when "
+ "called with a valid file name", GetLastError() );
+ }
+
+ /*
+ * remove a non empty directory
+ *
+ * To test that, we'll first create non_empty_dir, we'll
+ * set the current dir to non_empty_dir in which we'll
+ * create sub_dir. We'll go back to the root of non_empty_dir
+ * and we'll try to delete it (it shouldn't work).
+ * After that we'll cleanup sub_dir and non_empty_dir
+ */
+
+ /* Get the current directory so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryA(MAX_PATH, szwCurrentDir) )
+ {
+ Fail("RemoveDirectoryA: Failed to get current directory "
+ "with GetCurrentDirectoryA.\n");
+ }
+
+ /* Create non_empty_dir */
+ sprintf( szDirName, "non_empty_dir");
+ szTemp = (char *) malloc (sizeof(szDirName));
+ szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
+ bRc = CreateDirectoryA(szTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory "
+ "\"non_empty_dir\" when it exists already.\n", GetLastError());
+ }
+
+ if( 0 == SetCurrentDirectoryA(szTemp) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError());
+ }
+
+ /* Get the directory full path so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryA(MAX_PATH, szwSubDir) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to get current directory "
+ "with GetCurrentDirectoryA.\n", GetLastError());
+ }
+
+ /* Create sub_dir */
+ sprintf (szDirName, "sub_dir");
+ szTemp2 = (char *) malloc (sizeof(szDirName));
+ szTemp2 = strncpy(szTemp2, szDirName, strlen(szDirName) + 1);
+ bRc = CreateDirectoryA(szTemp2, NULL);
+ if (bRc != TRUE)
+ {
+ free(szTemp);
+ free(szTemp2);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory "
+ "\"sub_dir\" when it exists already.\n", GetLastError());
+ }
+
+ /* Set the current dir to the parent of non_empty_dir/sub_dir */
+ if( 0 == SetCurrentDirectoryA(szwCurrentDir) )
+ {
+ free(szTemp);
+ free(szTemp2);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError());
+ }
+
+ /* Try to remove non_empty_dir (shouldn't work) */
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc == TRUE)
+ {
+ free(szTemp);
+ free(szTemp2);
+ Fail("Error[%ul]:RemoveDirectoryA: shouldn't have been able to remove "
+ "the non empty directory \"non_empty_dir\"\n", GetLastError());
+ }
+
+ /* Go back to non_empty_dir and remove sub_dir */
+ if( 0 == SetCurrentDirectoryA(szwSubDir) )
+ {
+ free(szTemp);
+ free(szTemp2);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError());
+ }
+
+ bRc = RemoveDirectoryA(szTemp2);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ free(szTemp2);
+ Fail("Error[%ul]:RemoveDirectoryA: unable to remove "
+ "directory \"sub_dir\" \n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesA(szTemp2) )
+ {
+ Fail("Error[%ul]RemoveDirectoryA: Able to get the attributes of "
+ "the removed directory\n", GetLastError());
+ }
+ free(szTemp2);
+
+ /* Go back to parent of non_empty_dir and remove non_empty_dir */
+ if( 0 == SetCurrentDirectoryA(szwCurrentDir) )
+ {
+ free(szTemp);
+ Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to "
+ "\"..\non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError());
+ }
+ bRc = RemoveDirectoryA(szTemp);
+ if (bRc == FALSE)
+ {
+ free(szTemp);
+ Fail("Error[%ul]RemoveDirectoryA: unable to remove "
+ "the directory \"non_empty_dir\"\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesA(szTemp) )
+ {
+ Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of "
+ "the removed directory\n", GetLastError());
+ }
+ free(szTemp);
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/testinfo.dat
new file mode 100644
index 0000000000..6d8f72d27e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = RemoveDirectoryA
+Name = Test for RemoveDirectoryA (test 1)
+Type = DEFAULT
+EXE1 = removedirectorya
+Description
+= Create directories and attempt to remove them.
+
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..45b51cec30
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ RemoveDirectoryW.c
+)
+
+add_executable(paltest_removedirectoryw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_removedirectoryw_test1 coreclrpal)
+
+target_link_libraries(paltest_removedirectoryw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c
new file mode 100644
index 0000000000..ae1dd0fb97
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c
@@ -0,0 +1,282 @@
+// 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: RemoveDirectoryW.c
+**
+** Purpose: Tests the PAL implementation of the RemoveDirectoryW function.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ char szDirName[252];
+ DWORD curDirLen;
+ WCHAR *szwTemp = NULL;
+ WCHAR *szwTemp2 = NULL;
+ WCHAR szwCurrentDir[MAX_PATH];
+ WCHAR szwSubDir[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /*
+ * remove a NULL directory
+ */
+ bRc = RemoveDirectoryW(NULL);
+ if (bRc != FALSE)
+ {
+ Fail("RemoveDirectoryW: Failed since it was able to remove a"
+ " NULL directory name\n");
+ }
+
+ /*
+ * remove a directory that does not exist
+ */
+ szwTemp = convert("test_directory");
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc != FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed since it was able to remove"
+ " the non-existant directory \"test_directory\"\n");
+ }
+
+ /*
+ * remove a directory that exists
+ */
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"test_directory\" when it exists already.\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove the directory "
+ "\"test_directory\" (error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * remove long directory names (245 characters)
+ */
+ curDirLen = GetCurrentDirectoryA(0, NULL) + 1;
+ memset(szDirName, 0, 252);
+ memset(szDirName, 'a', 245 - curDirLen);
+ szwTemp = convert(szDirName);
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create a directory name "
+ "245 chars long\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove a 245 char "
+ "long directory\n");
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * directories with dots
+ */
+ memset(szDirName, 0, 252);
+ sprintf(szDirName, ".dotDirectory");
+ szwTemp = convert(szDirName);
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create \"%s\"\n", szDirName);
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove \"%s\"\n", szDirName);
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * Try calling RemoveDirectory with a file name
+ */
+ memset(szDirName, 0, 252);
+ sprintf(szDirName, "removedirectoryw.c");
+ szwTemp = convert(szDirName);
+
+ bRc = RemoveDirectoryW(szwTemp);
+ free(szwTemp);
+ if (bRc != FALSE)
+ {
+ Fail("RemoveDirectoryW: should have failed when "
+ "called with a valid file name" );
+ }
+
+ /*
+ * remove a non empty directory
+ *
+ * To test that, we'll first create non_empty_dir, we'll
+ * set the current dir to non_empty_dir in which we'll
+ * create sub_dir. We'll go back to the root of non_empty_dir
+ * and we'll try to delete it (it shouldn't work).
+ * After that we'll cleanup sub_dir and non_empty_dir
+ */
+
+ /* Get the current directory so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwCurrentDir) )
+ {
+ Fail("RemoveDirectoryW: Failed to get current directory "
+ "with GetCurrentDirectoryW.\n");
+ }
+
+ /* Create non_empty_dir */
+ szwTemp = convert("non_empty_dir");
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"non_empty_dir\" when it exists already.\n");
+ }
+
+ if( 0 == SetCurrentDirectoryW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ /* Get the directory full path so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwSubDir) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to get current directory "
+ "with GetCurrentDirectoryW.\n");
+ }
+
+ /* Create sub_dir */
+ szwTemp2 = convert("sub_dir");
+ bRc = CreateDirectoryW(szwTemp2, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"sub_dir\" when it exists already.\n");
+ }
+
+ /* Set the current dir to the parent of non_empty_dir/sub_dir */
+ if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ /* Try to remove non_empty_dir (shouldn't work) */
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == TRUE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: shouldn't have been able to remove "
+ "the non empty directory \"non_empty_dir\"\n");
+ }
+
+ /* Go back to non_empty_dir and remove sub_dir */
+ if( 0 == SetCurrentDirectoryW(szwSubDir) )
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ bRc = RemoveDirectoryW(szwTemp2);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: unable to remove "
+ "directory \"sub_dir\"(error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp2) )
+ {
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp2);
+
+ /* Go back to parent of non_empty_dir and remove non_empty_dir */
+ if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"..\non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: unable to remove "
+ "the directory \"non_empty_dir\"(error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/testinfo.dat
new file mode 100644
index 0000000000..f94b9b2445
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = RemoveDirectoryW
+Name = Test for RemoveDirectoryW (test 1)
+Type = DEFAULT
+EXE1 = removedirectoryw
+Description
+= Create directories and attempt to remove them.
+
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathA/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..d1ac975d18
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SearchPathA.c
+)
+
+add_executable(paltest_searchpatha_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_searchpatha_test1 coreclrpal)
+
+target_link_libraries(paltest_searchpatha_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c b/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c
new file mode 100644
index 0000000000..ab9eecdebc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c
@@ -0,0 +1,144 @@
+// 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: SearchPathA.c
+**
+** Purpose: Tests the PAL implementation of the SearchFileA function.
+**
+**
+** TODO: Write a test where complete path is passed (say c:\?)
+**===================================================================*/
+//SearchPath
+//
+//The SearchPath function searches for the specified file in the specified path.
+//
+
+
+#include <palsuite.h>
+char* szDir = ".";
+
+char* szNoFileName = "333asdf";
+char* szNoFileNameExt = ".x77t";
+
+char* szFileNameExists = "searchfile";
+char* szFileNameExtExists = ".txt";
+
+char* szFileNameExistsWithExt = "searchfile.txt";
+char fileloc[_MAX_PATH];
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ }
+
+}
+
+
+void RemoveAll()
+{
+ removeFileHelper(fileloc, 1);
+}
+
+int __cdecl main(int argc, char *argv[]) {
+
+ char* lpPath = NULL;
+ char* lpFileName = NULL;
+ char* lpExtension = NULL;
+ DWORD nBufferLength = 0;
+ char lpBuffer[_MAX_PATH];
+ char** lpFilePart = NULL;
+ DWORD error = 0;
+ DWORD result = 0;
+
+ HANDLE hsearchfile;
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ char fullPath[_MAX_DIR];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+
+ /* Initalize the buffer.
+ */
+ memset(fullPath, 0, _MAX_DIR);
+
+ /* Get the full path to the library (DLL).
+ */
+
+ if ( NULL != _fullpath( fullPath, argv[0], _MAX_DIR )) {
+ _splitpath(fullPath,drive,dir,fname,ext);
+ _makepath(fullPath,drive,dir,"","");
+ } else {
+ Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
+ }
+
+ memset(fileloc, 0, _MAX_PATH);
+ sprintf(fileloc, "%s%s", fullPath, szFileNameExistsWithExt);
+
+ RemoveAll();
+
+ hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hsearchfile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
+ return FAIL;
+ }
+
+ CloseHandle(hsearchfile);
+
+ //
+ // find a file that doesn't exist
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = fullPath;
+ lpFileName = szNoFileName;
+ lpExtension = NULL;
+
+ if( SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
+ error = GetLastError();
+ Fail ("SearchPathA: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
+ }
+
+ //
+ // find a file that exists, when path is mentioned explicitly
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = fullPath;
+ lpFileName = szFileNameExistsWithExt;
+ lpExtension = NULL;
+
+ result = SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
+
+ if( result == 0 ){
+ error = GetLastError();
+ Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
+ }
+
+ RemoveAll();
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SearchPathA/test1/testinfo.dat
new file mode 100644
index 0000000000..82401eeeb2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SearchPathA
+Name = Test #1 for SearchPathA
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=Tests the PAL implementation of the SearchFileA function
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathW/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..d0c6252472
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SearchPathW.c
+)
+
+add_executable(paltest_searchpathw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_searchpathw_test1 coreclrpal)
+
+target_link_libraries(paltest_searchpathw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c b/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c
new file mode 100644
index 0000000000..2bc7694dc0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c
@@ -0,0 +1,198 @@
+// 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: SearchPathW.c
+**
+** Purpose: Tests the PAL implementation of the SearchFileW function.
+**
+**
+** TODO: Write a test where complete path is passed (say c:\?)
+**===================================================================*/
+//SearchPath
+//
+//The SearchPath function searches for the specified file in the specified path.
+//
+//
+//DWORD SearchPath(
+// LPCTSTR lpPath,
+// LPCTSTR lpFileName,
+// LPCTSTR lpExtension,
+// DWORD nBufferLength,
+// LPTSTR lpBuffer,
+// LPTSTR* lpFilePart
+//);
+//
+//Parameters
+//lpPath
+//[in] Pointer to a null-terminated string that specifies the path to be searched for the file. If this parameter is NULL, the function searches for a matching file in the following directories in the following sequence:
+//The directory from which the application loaded.
+//The current directory.
+//The system directory. Use the GetSystemDirectory function to get the path of this directory.
+//The 16-bit system directory. There is no function that retrieves the path of this directory, but it is searched.
+//The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
+//The directories that are listed in the PATH environment variable.
+
+//lpFileName
+//[in] Pointer to a null-terminated string that specifies the name of the file to search for.
+
+//lpExtension
+//[in] Pointer to a null-terminated string that specifies an extension to be added to the file name when searching for the file. The first character of the file name extension must be a period (.). The extension is added only if the specified file name does not end with an extension.
+//If a file name extension is not required or if the file name contains an extension, this parameter can be NULL.
+//
+//nBufferLength
+//[in] Size of the buffer that receives the valid path and file name, in TCHARs.
+
+//lpBuffer
+//[out] Pointer to the buffer that receives the path and file name of the file found.
+
+//lpFilePart
+//[out] Pointer to the variable that receives the address (within lpBuffer) of the last component of the valid path and file name, which is the address of the character immediately following the final backslash (\) in the path.
+
+//Return Values
+//If the function succeeds, the value returned is the length, in TCHARs, of the string copied to the buffer, not including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of the buffer required to hold the path.
+//
+//If the function fails, the return value is zero. To get extended error information, call GetLastError.
+
+
+#include <palsuite.h>
+const char* szDir = ".";
+
+const char* szNoFileName = "333asdf";
+const char* szNoFileNameExt = ".x77t";
+
+const char* szFileNameExists = "searchpathw";
+const char* szFileNameExtExists = ".c";
+
+const char* szFileNameExistsWithExt = "searchpathw.c";
+
+char fileloc[_MAX_PATH];
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+void RemoveAll()
+{
+ removeFileHelper(fileloc, 1);
+}
+
+int __cdecl main(int argc, char *argv[]) {
+
+ WCHAR* lpPath = NULL;
+ WCHAR* lpFileName = NULL;
+ WCHAR* lpExtension = NULL;
+ DWORD nBufferLength = 0;
+ WCHAR lpBuffer[_MAX_PATH];
+ WCHAR** lpFilePart = NULL;
+ DWORD error = 0;
+ DWORD result = 0;
+
+ HANDLE hsearchfile;
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ char fullPath[_MAX_DIR];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Initalize the buffer.
+ */
+ memset(fullPath, 0, _MAX_DIR);
+
+ /* Get the full path to the library (DLL).
+ */
+
+ if ( NULL != _fullpath( fullPath, argv[0], _MAX_DIR )) {
+ _splitpath(fullPath,drive,dir,fname,ext);
+ _makepath(fullPath,drive,dir,"","");
+ } else {
+ Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
+ }
+
+ memset(fileloc, 0, _MAX_PATH);
+ sprintf(fileloc, "%s%s", fullPath, szFileNameExistsWithExt);
+
+ RemoveAll();
+
+ hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hsearchfile == NULL)
+ {
+ Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
+ return FAIL;
+ }
+
+ CloseHandle(hsearchfile);
+
+ //
+ // find a file that doesn't exist
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = convert((LPSTR)fullPath);
+ lpFileName = convert((LPSTR)szNoFileName);
+ lpExtension = NULL;
+
+ if( SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
+ error = GetLastError();
+ free(lpPath);
+ free(lpFileName);
+ Fail ("SearchPathW: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
+ }
+
+ free(lpPath);
+ free(lpFileName);
+
+ //
+ // find a file that exists, when path is mentioned explicitly
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = convert((LPSTR)fullPath);
+ lpFileName = convert((LPSTR)szFileNameExistsWithExt);
+ lpExtension = NULL;
+
+ result = SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
+
+ if( result == 0 ){
+ error = GetLastError();
+ free(lpPath);
+ free(lpFileName);
+ Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
+ }
+
+ free(lpPath);
+ free(lpFileName);
+
+ RemoveAll();
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SearchPathW/test1/testinfo.dat
new file mode 100644
index 0000000000..f7a36eb53b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SearchPathW
+Name = Test #1 for SearchPathW
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=Tests the PAL implementation of the SearchFileW function
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..7376b22226
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetCurrentDirectoryA.c
+)
+
+add_executable(paltest_setcurrentdirectorya_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectorya_test1 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectorya_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c
new file mode 100644
index 0000000000..c07a62412b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c
@@ -0,0 +1,215 @@
+// 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: SetCurrentDirectoryA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+/* In order to avoid the "chicken and egg" scenario, this is another
+ method of getting the current directory. GetFullPathNameA is called with
+ a dummy file name and then the file name is stripped off leaving the
+ current working directory
+*/
+
+BOOL GetCurrentDir(char* szCurrentDir)
+{
+ const char* szFileName = "blah";
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ LPSTR pPathPtr;
+ size_t nCount = 0;
+
+ /* use GetFullPathNameA to to get the current path by stripping
+ the file name off the end */
+ memset(szReturnedPath, 0, (_MAX_DIR+1));
+ dwRc = GetFullPathNameA(szFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ /* GetFullPathNameA failed */
+ Trace("SetCurrentDirectoryA: ERROR -> GetFullPathNameA failed "
+ "with error code: %ld.\n", GetLastError());
+ return(FALSE);
+ }
+
+ /* now strip the file name from the full path to get the current path */
+ nCount = strlen(szReturnedPath) - strlen(szFileName);
+ memset(szCurrentDir, 0, (_MAX_DIR+1));
+ strncpy(szCurrentDir, szReturnedPath, nCount);
+
+ return(TRUE);
+}
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char* szDirName = "testing";
+ /* directory name longer than MAX_PATH characters */
+ char szLongDirName[MAX_LONGPATH+1];
+ char szNewDir[_MAX_DIR+1];
+ char szBuiltDir[_MAX_DIR+1];
+ char szHomeDir[_MAX_DIR+1];
+ WCHAR* szwPtr = NULL;
+
+ memset(szLongDirName, 'a', MAX_LONGPATH+1);
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* remove the directory just in case a previous run of the test didn't */
+ szwPtr = convert((LPSTR)szDirName);
+
+ /* clean up. Remove the directory
+ * if it exists */
+ RemoveDirectoryW(szwPtr);
+
+ /* create a temp directory off the current directory */
+ if (CreateDirectoryA(szDirName, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> CreateDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDir, 0, (_MAX_DIR+1));
+ if(GetCurrentDir(szHomeDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* set the current directory to the temp directory */
+
+ if (SetCurrentDirectoryA(szDirName) != TRUE)
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, (_MAX_DIR+1));
+#if WIN32
+ sprintf(szBuiltDir,"%s%s\\", szHomeDir, szDirName);
+#else
+ sprintf(szBuiltDir,"%s%s/", szHomeDir, szDirName);
+#endif
+
+ /* get the new current directory */
+ memset(szNewDir, 0, (_MAX_DIR+1));
+ if(GetCurrentDir(szNewDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (strncmp(szNewDir, szBuiltDir, strlen(szNewDir)) != 0)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> The set directory \"%s\" does not"
+ " compare to the built directory \"%s\".\n",
+ szNewDir,
+ szBuiltDir);
+ }
+
+
+
+ /* set the current dir back to the original */
+ if (SetCurrentDirectoryA(szHomeDir) != TRUE)
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+
+ /* get the new current directory */
+ memset(szNewDir, 0, sizeof(char)*(_MAX_DIR+1));
+ if(GetCurrentDir(szNewDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* ensure it compares to the "home" directory which is where
+ we should be now */
+ if (strncmp(szNewDir, szHomeDir, strlen(szNewDir)) != 0)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/testinfo.dat
new file mode 100644
index 0000000000..743b2ea3db
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SetCurrentDirectoryA
+Name = Test for SetCurrentDirectoryA (test 1)
+Type = DEFAULT
+EXE1 = setcurrentdirectorya
+Description
+= Change the current directory and verify the results.
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..7c9caf8081
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ setcurrentdirectorya.c
+)
+
+add_executable(paltest_setcurrentdirectorya_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectorya_test2 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectorya_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c
new file mode 100644
index 0000000000..415dbbf045
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.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: SetCurrentDirectoryA.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function
+** by setting the current directory with ../
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szDirName[MAX_PATH] = "testing";
+ char szBuiltDir[_MAX_DIR+1];
+ char szHomeDirBefore[_MAX_DIR+1];
+ char szHomeDirAfter[_MAX_DIR+1];
+ WCHAR* szwPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a temp directory off the current directory */
+ szwPtr = convert((LPSTR)szDirName);
+
+ if (CreateDirectoryA(szDirName, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("Unexpected error: CreateDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDirBefore, 0, (_MAX_DIR+1));
+
+ if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirBefore) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryA that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, (_MAX_DIR+1));
+#if WIN32
+ sprintf(szBuiltDir,"%s\\..\\", szDirName);
+#else
+ sprintf(szBuiltDir,"%s/../", szDirName);
+#endif
+
+
+ /* set the current directory to the temp directory */
+ if (SetCurrentDirectoryA(szBuiltDir) != TRUE)
+ {
+ Trace("ERROR: Unable to set current "
+ "directory to %s. Failed with error code: %ld.\n",
+ szBuiltDir,
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDirAfter, 0, (_MAX_DIR+1));
+
+ if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirAfter) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryA that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (strncmp(szHomeDirBefore, szHomeDirAfter, strlen(szHomeDirBefore)) != 0)
+ {
+ Trace("ERROR: The set directory \"%s\" does not "
+ "compare to the built directory \"%s\".\n",
+ szHomeDirAfter,
+ szHomeDirBefore);
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/testinfo.dat
new file mode 100644
index 0000000000..677c484062
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SetCurrentDirectoryA
+Name = Positive test for SetCurrentDirectoryA (test 2)
+Type = DEFAULT
+EXE1 = setcurrentdirectorya
+Description
+= Set the current directory with ../ and verify the results.
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt
new file mode 100644
index 0000000000..57d3577d8f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ setcurrentdirectorya.c
+)
+
+add_executable(paltest_setcurrentdirectorya_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectorya_test3 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectorya_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c
new file mode 100644
index 0000000000..a23a7a6314
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c
@@ -0,0 +1,56 @@
+// 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: SetCurrentDirectoryA.c (test 3)
+**
+** Purpose: Try calling SetCurrentDirectoryA with an invalid path,
+** with a valid filename and with NULL
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szDirName[MAX_PATH] = "testing";
+ const char szFileName[MAX_PATH] = "setcurrentdirectorya.c";
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* set the current directory to an unexistant folder */
+ if (0 != SetCurrentDirectoryA(szDirName))
+ {
+ Fail("ERROR: SetCurrentDirectoryA should have failed "
+ "when trying to set the current directory to "
+ "an invalid folder\n");
+ }
+
+ /* set the current directory to an unexistant folder */
+ if (0 != SetCurrentDirectoryA(szFileName))
+ {
+ Fail("ERROR: SetCurrentDirectoryA should have failed "
+ "when trying to set the current directory to "
+ "a valid file name\n");
+ }
+
+ /* set the current directory to NULL */
+ if (0 != SetCurrentDirectoryA(NULL))
+ {
+ Fail("ERROR: SetCurrentDirectoryA should have failed "
+ "when trying to set the current directory to "
+ "NULL\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/testinfo.dat
new file mode 100644
index 0000000000..d5520f7993
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetCurrentDirectoryA
+Name = Negative test for SetCurrentDirectoryA (test 3)
+Type = DEFAULT
+EXE1 = setcurrentdirectorya
+Description
+= Try calling SetCurrentDirectoryA with an invalid path,
+= with a valid filename and with NULL
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/CMakeLists.txt
new file mode 100644
index 0000000000..1962ade358
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..a0c1dff62a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetCurrentDirectoryW.c
+)
+
+add_executable(paltest_setcurrentdirectoryw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectoryw_test1 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectoryw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c
new file mode 100644
index 0000000000..257d016ffb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c
@@ -0,0 +1,178 @@
+// 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: SetCurrentDirectoryW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szFileName = "blah";
+const char* szDirName = "testing";
+
+
+// In order to avoid the "chicken and egg" scenario, this is another
+// method of getting the current directory. GetFullPathNameW is called with
+// a dummy file name and then the file name is stripped off leaving the
+// current working directory
+BOOL GetCurrentDir(WCHAR* szwCurrentDir)
+{
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[_MAX_DIR+1];
+ LPWSTR pPathPtr;
+ WCHAR* szwFileName = NULL;
+ WCHAR* szwDirName = NULL;
+ int nCount = 0;
+
+ // use GetFullPathName to to get the current path by stripping
+ // the file name off the end
+ memset(szwReturnedPath, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ szwFileName = convert((char*)szFileName);
+ dwRc = GetFullPathNameW(szwFileName,
+ _MAX_DIR,
+ szwReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ // GetFullPathName failed
+ Trace("SetCurrentDirectoryW: ERROR -> GetFullPathNameW failed "
+ "with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwFileName);
+ return(FALSE);
+ }
+
+ // now strip the file name from the full path to get the current path
+ nCount = lstrlenW(szwReturnedPath) - lstrlenW(szwFileName);
+ memset(szwCurrentDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ lstrcpynW(szwCurrentDir, szwReturnedPath, nCount);
+
+ free(szwFileName);
+ return(TRUE);
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR* szwDirName = NULL;
+ WCHAR szwNewDir[_MAX_DIR+1];
+ WCHAR szwBuiltDir[_MAX_DIR+1];
+ WCHAR szwHomeDir[_MAX_DIR+1];
+#if WIN32
+ WCHAR szwSlash[] = {'\\','\0'};
+#else
+ WCHAR szwSlash[] = {'/','\0'};
+#endif
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // remove the directory just in case a previous run of the test didn't
+ szwDirName = convert((char*)szDirName);
+ RemoveDirectoryW(szwDirName);
+
+ // create a temp directory off the current directory
+ if (CreateDirectoryW(szwDirName, NULL) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> CreateDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+ // find out what the current "home" directory is
+ memset(szwHomeDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwHomeDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // set the current directory to the temp directory
+ if (SetCurrentDirectoryW(szwDirName) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+ // append the temp name to the "home" directory
+ memset(szwBuiltDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ wcscpy(szwBuiltDir, szwHomeDir);
+ wcscat(szwBuiltDir, szwSlash);
+ wcscat(szwBuiltDir, szwDirName);
+
+ // get the new current directory
+ memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwNewDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // compare the new current dir to the compiled current dir
+ if (wcsncmp(szwNewDir, szwBuiltDir, wcslen(szwNewDir)) != 0)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+
+ // set the current dir back to the original
+ if (SetCurrentDirectoryW(szwHomeDir) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+
+ // get the new current directory
+ memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwNewDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // ensure it compares to the "home" directory which is where
+ // we should be now
+ if (wcsncmp(szwNewDir, szwHomeDir, wcslen(szwNewDir)) != 0)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/testinfo.dat
new file mode 100644
index 0000000000..3a63887e07
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetCurrentDirectoryW
+Name = Test for SetCurrentDirectoryW (test 1)
+Type = DEFAULT
+EXE1 = setcurrentdirectoryw
+Description
+= Change the current directory and verify the results.
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..a032462d19
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ setcurrentdirectoryw.c
+)
+
+add_executable(paltest_setcurrentdirectoryw_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectoryw_test2 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectoryw_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c
new file mode 100644
index 0000000000..7e3d7b785f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c
@@ -0,0 +1,147 @@
+// 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: SetCurrentDirectoryW.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function
+** by setting the current directory with ../
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szDirName[MAX_PATH] = "testing";
+ char szBuiltDir[MAX_PATH];
+ WCHAR* szwBuiltDir = NULL;
+ WCHAR szwHomeDirBefore[MAX_PATH];
+ WCHAR szwHomeDirAfter[MAX_PATH];
+ WCHAR* szwPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a temp directory off the current directory */
+ szwPtr = convert((LPSTR)szDirName);
+
+ if (CreateDirectoryW(szwPtr, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("Unexpected error: CreateDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szwHomeDirBefore, 0, MAX_PATH * sizeof(WCHAR));
+
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirBefore) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryW that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, MAX_PATH);
+#if WIN32
+ sprintf(szBuiltDir,"%s\\..\\", szDirName);
+#else
+ sprintf(szBuiltDir,"%s/../", szDirName);
+#endif
+
+ szwBuiltDir = convert(szBuiltDir);
+
+ /* set the current directory to the temp directory */
+ if (SetCurrentDirectoryW(szwBuiltDir) != TRUE)
+ {
+ Trace("ERROR: Unable to set current "
+ "directory to %S. Failed with error code: %ld.\n",
+ szwBuiltDir,
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ free(szwBuiltDir);
+ Fail("");
+ }
+
+ free(szwBuiltDir);
+
+ /* find out what the current "home" directory is */
+ memset(szwHomeDirAfter, 0, MAX_PATH * sizeof(WCHAR));
+
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirAfter) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryW that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("ERROR: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (wcsncmp(szwHomeDirBefore, szwHomeDirAfter, wcslen(szwHomeDirBefore)) != 0)
+ {
+ Trace("ERROR:The set directory \"%S\" does not "
+ "compare to the built directory \"%S\".\n",
+ szwHomeDirAfter,
+ szwHomeDirBefore);
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/testinfo.dat
new file mode 100644
index 0000000000..a739688d4d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SetCurrentDirectoryW
+Name = Positive test for SetCurrentDirectoryW (test 2)
+Type = DEFAULT
+EXE1 = setcurrentdirectoryw
+Description
+= Set the current directory with ../ and verify the results.
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt
new file mode 100644
index 0000000000..3b981f9564
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ setcurrentdirectoryw.c
+)
+
+add_executable(paltest_setcurrentdirectoryw_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setcurrentdirectoryw_test3 coreclrpal)
+
+target_link_libraries(paltest_setcurrentdirectoryw_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c
new file mode 100644
index 0000000000..e8c4be2ad4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c
@@ -0,0 +1,64 @@
+// 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: SetCurrentDirectoryW.c (test 3)
+**
+** Purpose: Try calling SetCurrentDirectoryW with an invalid path,
+** with a valid filename and with NULL
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ char szDirName[MAX_PATH] = "testing";
+ WCHAR* szwDirName = NULL;
+ char szFileName[MAX_PATH] = "setcurrentdirectorya.c";
+ WCHAR* szwFileName = NULL;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* set the current directory to an unexistant folder */
+ szwDirName = convert(szDirName);
+ if (0 != SetCurrentDirectoryW(szwDirName))
+ {
+ free(szwDirName);
+ Fail("ERROR: SetCurrentDirectoryW should have failed "
+ "when trying to set the current directory to "
+ "an invalid folder\n");
+ }
+ free(szwDirName);
+
+ /* set the current directory to an unexistant folder */
+ szwFileName = convert(szFileName);
+ if (0 != SetCurrentDirectoryW(szwFileName))
+ {
+ free(szwFileName);
+ Fail("ERROR: SetCurrentDirectoryW should have failed "
+ "when trying to set the current directory to "
+ "a valid file name\n");
+ }
+ free(szwFileName);
+
+ /* set the current directory to NULL */
+ if (0 != SetCurrentDirectoryW(NULL))
+ {
+ Fail("ERROR: SetCurrentDirectoryW should have failed "
+ "when trying to set the current directory to "
+ "NULL\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/testinfo.dat
new file mode 100644
index 0000000000..fc931291ec
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetCurrentDirectoryW
+Name = Negative test for SetCurrentDirectoryW (test 3)
+Type = DEFAULT
+EXE1 = setcurrentdirectoryw
+Description
+= Try calling SetCurrentDirectoryW with an invalid path,
+= with a valid filename and with NULL
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/CMakeLists.txt
new file mode 100644
index 0000000000..8083faf655
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test5)
+
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt
new file mode 100644
index 0000000000..e77ab30b86
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetEndOfFile.c
+)
+
+add_executable(paltest_setendoffile_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setendoffile_test1 coreclrpal)
+
+target_link_libraries(paltest_setendoffile_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c
new file mode 100644
index 0000000000..9078ddc65b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c
@@ -0,0 +1,85 @@
+// 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: SetEndOfFile.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetEndOfFile function.
+** This test will attempt to operate on a NULL file handle and
+** also test truncating a file not opened with GENERIC_WRITE
+**
+** Assumes successful:
+** SetEndOfFile
+** CreateFile
+** CloseHandle
+**
+
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ BOOL bRc = FALSE;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ bRc = SetEndOfFile(NULL);
+ if (bRc == TRUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Operation succeeded on a NULL file "
+ "handle\n");
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ bRc = SetEndOfFile(hFile);
+ if (bRc == TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Operation succeeded on read-only"
+ " file.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/testinfo.dat
new file mode 100644
index 0000000000..72fc5e59e6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetEndOfFile
+Name = Positive Test for SetEndOfFile
+Type = DEFAULT
+EXE1 = setendoffile
+Description
+=Truncate a file
+
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt
new file mode 100644
index 0000000000..b04dea04a6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetEndOfFile.c
+)
+
+add_executable(paltest_setendoffile_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setendoffile_test2 coreclrpal)
+
+target_link_libraries(paltest_setendoffile_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c
new file mode 100644
index 0000000000..6b3c05088e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c
@@ -0,0 +1,154 @@
+// 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: SetEndOfFile.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetEndOfFile function.
+** This test will attempt to truncate a file
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.";
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwBytesWritten;
+ BOOL bRc = FALSE;
+ char szBuffer[100];
+ DWORD dwBytesRead = 0;
+ FILE *pFile = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // create a test file
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ bRc = WriteFile(hFile, szStringTest, 20, &dwBytesWritten, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Uable to write to \"%s\".\n",
+ szTextFile);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+
+ // open the test file
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to open file \"%s\".\n",
+ szTextFile);
+ }
+
+ // read a bit of the file to move the file pointer
+ dwByteCount = 10;
+ bRc = ReadFile(hFile, szBuffer, dwByteCount, &dwBytesRead, NULL);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Uable to read from \"%s\".\n",
+ szTextFile);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = SetEndOfFile(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Uable to set end of file.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+
+ // open and read the test file
+ pFile = fopen(szTextFile, "r");
+ if (pFile == NULL)
+ {
+ Fail("SetEndOfFile: ERROR -> fopen was unable to open file \"%s\".\n",
+ szTextFile);
+ }
+
+ // since we truncated the file at 10 characters,
+ // try reading 20 just to be safe
+ memset(szBuffer, 0, 100);
+ fgets(szBuffer, 20, pFile);
+ fclose(pFile);
+ if (strlen(szBuffer) != dwByteCount)
+ {
+ Fail("SetEndOfFile: ERROR -> file apparently not truncated at "
+ "correct position.\n");
+ }
+ if (strncmp(szBuffer, szStringTest, dwByteCount) != 0)
+ {
+ Fail("SetEndOfFile: ERROR -> truncated file contents doesn't "
+ "compare with what should be there\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/testinfo.dat
new file mode 100644
index 0000000000..555f0d823f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/testinfo.dat
@@ -0,0 +1,12 @@
+# 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 = SetEndOfFile
+Name = Positive Test for SetEndOfFile
+Type = DEFAULT
+EXE1 = setendoffile
+Description
+=Truncate the test file using SetEndOfFile
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt
new file mode 100644
index 0000000000..1ab177d00a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetEndOfFile.c
+)
+
+add_executable(paltest_setendoffile_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setendoffile_test3 coreclrpal)
+
+target_link_libraries(paltest_setendoffile_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c
new file mode 100644
index 0000000000..dfd9194465
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c
@@ -0,0 +1,109 @@
+// 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: SetEndOfFile.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the SetEndOfFile function.
+** This test will attempt to expand a file. Assumes successful
+** SetFilePointer and GetFileSize tests.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwOffset = 25;
+ DWORD dwRc = 0;
+ BOOL bRc = FALSE;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ /* move the file pointer */
+ /* assumes a successful SetFilePointer test */
+ dwRc = SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
+ if (dwRc == INVALID_SET_FILE_POINTER)
+ {
+ Trace("SetEndOfFile: ERROR -> Call to SetFilePointer failed\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_Terminate();
+ return FAIL;
+ }
+
+ bRc = SetEndOfFile(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Uable to set end of file.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ /* call GetFileSize to verify pointer position */
+ /* assumes a successful GetFileSize test */
+
+ dwByteCount = GetFileSize(hFile, NULL);
+ if (dwByteCount != dwOffset)
+ {
+ Trace("SetEndOfFile: ERROR -> file apparently not expanded to the"
+ " correct size.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/testinfo.dat
new file mode 100644
index 0000000000..7f3868d6ca
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/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 = SetEndOfFile
+Name = Positive Test for SetEndOfFile
+Type = DEFAULT
+EXE1 = setendoffile
+Description
+=Set the end of file past the actual end
+=of file thereby, extending it.
+
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt
new file mode 100644
index 0000000000..ff0b6f999c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ setendoffile.c
+)
+
+add_executable(paltest_setendoffile_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setendoffile_test4 coreclrpal)
+
+target_link_libraries(paltest_setendoffile_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c
new file mode 100644
index 0000000000..98a6ec63da
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c
@@ -0,0 +1,138 @@
+// 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: setendoffile.c (test 4)
+**
+** Purpose: Tests the PAL implementation of the SetEndOfFile function.
+** Verify that the file pointer is the same before
+** and after a SetEndOfFile using SetFilePointer with
+** FILE_BEGIN, FILE_CURRENT and FILE_END
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.";
+const char* szTextFile = "test.tmp";
+
+static void Cleanup(HANDLE hFile)
+{
+ if (!CloseHandle(hFile))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to close file \"%s\". ",
+ "GetLastError returned %u.\n",
+ szTextFile,
+ GetLastError());
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to delete file \"%s\". ",
+ "GetLastError returned %u.\n",
+ szTextFile,
+ GetLastError());
+ }
+}
+
+static void DoTest(HANDLE hFile, DWORD dwOffset, DWORD dwMethod)
+{
+ DWORD dwFP1 = 0;
+ DWORD dwFP2 = 0;
+ DWORD dwError;
+
+ /* set the pointer*/
+ dwFP1 = SetFilePointer(hFile, dwOffset, NULL, dwMethod);
+ if ((dwFP1 == INVALID_SET_FILE_POINTER) &&
+ ((dwError = GetLastError()) != ERROR_SUCCESS))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to set the pointer to the "
+ "end of the file. GetLastError returned %u.\n",
+ dwError);
+ Cleanup(hFile);
+ Fail("");
+ }
+
+ /* set EOF */
+ if (!SetEndOfFile(hFile))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to set end of file. "
+ "GetLastError returned %u.\n",
+ GetLastError());
+ Cleanup(hFile);
+ Fail("");
+ }
+
+ /* get current file pointer pointer */
+ dwFP2 = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+ if ((dwFP1 == INVALID_SET_FILE_POINTER) &&
+ ((dwError = GetLastError()) != ERROR_SUCCESS))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to set the pointer to the "
+ "end of the file. GetLastError returned %u.\n",
+ dwError);
+ Cleanup(hFile);
+ Fail("");
+ }
+
+ /* are they the same? */
+ if (dwFP1 != dwFP2)
+ {
+ Trace("SetEndOfFile: ERROR -> File pointer before (%u) the "
+ "SetEndOfFile call was different than after (%u).\n",
+ dwFP1,
+ dwFP2);
+ Cleanup(hFile);
+ Fail("");
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetEndOfFile: ERROR -> Unable to create file \"%s\". "
+ "GetLastError returned %u.\n",
+ szTextFile,
+ GetLastError());
+ }
+
+ if (!WriteFile(hFile, szStringTest, strlen(szStringTest), &dwBytesWritten, NULL))
+ {
+ Trace("SetEndOfFile: ERROR -> Unable to write to \"%s\". ",
+ "GetLastError returned %u.\n",
+ szTextFile,
+ GetLastError());
+ Cleanup(hFile);
+ Fail("");
+ }
+
+ DoTest(hFile, -2, FILE_END); /* test the end */
+ DoTest(hFile, -10, FILE_CURRENT); /* test the middle-ish */
+ DoTest(hFile, 0, FILE_BEGIN); /* test the start */
+
+ Cleanup(hFile);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/testinfo.dat
new file mode 100644
index 0000000000..51d9185343
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/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 = SetEndOfFile
+Name = Positive Test for SetEndOfFile (test 4)
+Type = DEFAULT
+EXE1 = setendoffile
+Description
+= Tests the PAL implementation of the SetEndOfFile function.
+= Verify that the file pointer is the same before
+= and after a SetEndOfFile using SetFilePointer with
+= FILE_BEGIN, FILE_CURRENT and FILE_END
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt
new file mode 100644
index 0000000000..cca7167762
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test5.c
+)
+
+add_executable(paltest_setendoffile_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setendoffile_test5 coreclrpal)
+
+target_link_libraries(paltest_setendoffile_test5
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c
new file mode 100644
index 0000000000..7000d1af15
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c
@@ -0,0 +1,183 @@
+// 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: test5.c
+**
+** Purpose: Tests the PAL implementation of the SetEndOfFile function.
+** Test attempts to read the number of characters up to
+** the EOF pointer, which was specified.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ DWORD retCode;
+ BOOL bRc = FALSE;
+ char szBuffer[256];
+ DWORD dwBytesRead = 0;
+ char testFile[] = "testfile.tmp";
+ char testString[] = "watch what happens";
+ LONG shiftAmount = 10;
+
+ /* Initialize the PAL.
+ */
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Initialize the buffer.
+ */
+ memset(szBuffer, 0, 256);
+
+ /* Create a file to test with.
+ */
+ hFile = CreateFile(testFile,
+ GENERIC_WRITE|GENERIC_READ,
+ FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR:%u: Unable to create file \"%s\".\n",
+ GetLastError(),
+ testFile);
+ }
+
+ /* Write to the File handle.
+ */
+ bRc = WriteFile(hFile,
+ testString,
+ strlen(testString),
+ &dwBytesWritten,
+ NULL);
+
+ if (bRc == FALSE)
+ {
+ Trace("ERROR:%u: Unable to write to file handle "
+ "hFile=0x%lx\n",
+ GetLastError(),
+ hFile);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Set the file pointer to shiftAmount bytes from the front of the file
+ */
+ retCode = SetFilePointer(hFile, shiftAmount, NULL, FILE_BEGIN);
+ if(retCode == INVALID_SET_FILE_POINTER)
+ {
+ Trace("ERROR:%u: Unable to set the file pointer to %d\n",
+ GetLastError(),
+ shiftAmount);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* set the end of file pointer to 'shiftAmount' */
+ bRc = SetEndOfFile(hFile);
+ if (bRc == FALSE)
+ {
+ Trace("ERROR:%u: Unable to set file pointer of file handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Set the file pointer to 10 bytes from the front of the file
+ */
+ retCode = SetFilePointer(hFile, (LONG)NULL, NULL, FILE_BEGIN);
+ if(retCode == INVALID_SET_FILE_POINTER)
+ {
+ Trace("ERROR:%u: Unable to set the file pointer to %d\n",
+ GetLastError(),
+ FILE_BEGIN);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Attempt to read the entire string, 'testString' from a file
+ * that has it's end of pointer set at shiftAmount;
+ */
+ bRc = ReadFile(hFile,
+ szBuffer,
+ strlen(testString),
+ &dwBytesRead,
+ NULL);
+
+ if (bRc == FALSE)
+ {
+ Trace("ERROR:%u: Unable to read from file handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ /* Confirm the number of bytes read with that requested.
+ */
+ if (dwBytesRead != shiftAmount)
+ {
+ Trace("ERROR: The number of bytes read \"%d\" is not equal to the "
+ "number that should have been written \"%d\".\n",
+ dwBytesRead,
+ shiftAmount);
+ if (!CloseHandle(hFile))
+ {
+ Fail("ERROR:%u%: Unable to close handle 0x%lx.\n",
+ GetLastError(),
+ hFile);
+ }
+ Fail("");
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Fail("ERROR:%u CloseHandle failed to close the handle\n",
+ GetLastError());
+ }
+
+ /* Terminate the PAL.
+ */
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/testinfo.dat b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/testinfo.dat
new file mode 100644
index 0000000000..3a226ff8ad
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/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 = SetEndOfFile
+Name = Positive Test for SetEndOfFile
+Type = DEFAULT
+EXE1 = test5
+Description
+= Tests the PAL implementation of the SetEndOfFile function.
+= Test attempts to set the end of file pointer to a position
+= which has data before and after it. Then it attempts to
+= read text beyond the end of file pointer.
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt
new file mode 100644
index 0000000000..81e2dfdea2
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesA.c
+)
+
+add_executable(paltest_setfileattributesa_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesa_test1 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesa_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c
new file mode 100644
index 0000000000..bacab2a0ad
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c
@@ -0,0 +1,168 @@
+// 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: SetFileAttributesA.c
+**
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesA function
+** Test that we can set a file READONLY, and then that we're unable to
+** open that file with WRITE access. Then change it to NORMAL attributes, and
+** try to open it again -- it should work now.
+**
+** Depends:
+** CreateFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+/* According to the spec, only READONLY attribute can be set
+ in FreeBSD.
+*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ HANDLE TheFile;
+ char* FileName = {"test_file"};
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Try to set the file to Read-only */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_READONLY);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_READONLY attribute.");
+ }
+
+ /* Attempt to open this READONLY file with WRITE access,
+ The open should fail and the HANDLE should be invalid.
+ */
+
+ TheFile = CreateFileA(
+ FileName, // 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(TheFile != INVALID_HANDLE_VALUE)
+ {
+ TheResult = CloseHandle(TheFile);
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_WRITE access mode. This should"
+ " cause CreateFile to return an INVALID_HANDLE_VALUE.");
+ }
+
+ /* Try to open the file with READ access, this should be ok.
+ The HANDLE will be valid.
+ */
+
+ TheFile = CreateFileA(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_READ access mode. This should"
+ " cause CreateFile to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+ /* Close that HANDLE */
+
+ TheResult = CloseHandle(TheFile);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+
+ /* Set the file to NORMAL */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_NORMAL);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_NORMAL attribute.");
+ }
+
+ /* To ensure that the set worked correctly, try to open the file
+ with WRITE access again -- this time it should succeed.
+ */
+
+ TheFile = CreateFileA(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "NORMAL with the GENERIC_WRITE access mode. This should"
+ " cause CreateFile to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+ TheResult = CloseHandle(TheFile);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/test_file
new file mode 100644
index 0000000000..1b4bcfe1b5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/test_file
@@ -0,0 +1 @@
+Don't delete me. I'm needed. The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/testinfo.dat
new file mode 100644
index 0000000000..e39eac71b4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/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 = SetFileAttributesA
+Name = Test for SetFileAttributesA which tests READONLY and NORMAL attributes
+TYPE = DEFAULT
+EXE1 = setfileattributesa
+Description
+= Test the SetFileAttributesA function. Set a file as READONLY and
+= attempt to open it with WRITE access, to ensure that this doesn't work.
+= Then switch to NORMAL attributes, and try again -- it should work.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt
new file mode 100644
index 0000000000..03445c1df0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesA.c
+)
+
+add_executable(paltest_setfileattributesa_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesa_test2 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesa_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c
new file mode 100644
index 0000000000..5c04a6b181
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c
@@ -0,0 +1,114 @@
+// 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: SetFileAttributesA.c
+**
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesA function
+** Test that we can set the defined attributes aside from READONLY on a
+** file, and that it doesn't return failure. Note, these attributes won't
+** do anything to the file, however.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+/* this cleanup method tries to revert the file back to its initial attributes */
+void do_cleanup(char* filename, DWORD attributes)
+{
+ DWORD result;
+ result = SetFileAttributesA(filename, attributes);
+ if (result == 0)
+ {
+ Fail("ERROR:SetFileAttributesA returned 0,failure in the do_cleanup "
+ "method when trying to revert the file back to its initial attributes (%u)", GetLastError());
+ }
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ DWORD initialAttr;
+
+ char* FileName = {"test_file"};
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Get the initial attributes of the file */
+
+ initialAttr = GetFileAttributesA(FileName);
+
+ /* Try to set the file to HIDDEN */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_HIDDEN);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_HIDDEN attribute. This should "
+ "not do anything in FreeBSD, but it shouldn't fail.");
+ }
+
+ /* Try to set the file to ARCHIVE */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_ARCHIVE);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_ARCHIVE attribute.");
+ }
+
+ /* Try to set the file to SYSTEM */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_SYSTEM);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_SYSTEM attribute.");
+ }
+
+ /* Try to set the file to DIRECTORY */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_DIRECTORY);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_DIRECTORY attribute.");
+ }
+
+
+ do_cleanup(FileName,initialAttr);
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/test_file
new file mode 100644
index 0000000000..18d630a34d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/test_file
@@ -0,0 +1 @@
+The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/testinfo.dat
new file mode 100644
index 0000000000..778335258d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/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 = SetFileAttributesA
+Name = smoke test for SetFileAttributesA
+TYPE = DEFAULT
+EXE1 = setfileattributesa
+Description
+= Test the SetFileAttributesA function
+= Try to set the attributes that are not valid in FreeBSD. These should
+= return success in either WIN32 or FreeBSD, just have no effect in FreeBSD.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt
new file mode 100644
index 0000000000..3c35172d7c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesA.c
+)
+
+add_executable(paltest_setfileattributesa_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesa_test3 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesa_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c
new file mode 100644
index 0000000000..445b515c7f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c
@@ -0,0 +1,48 @@
+// 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: SetFileAttributesA.c
+**
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesA function
+** Test that the function fails if the file doesn't exist..
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ char* FileName = {"no_file"};
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* Try to set the file to NORMAL on a file that doesn't
+ exist.
+ */
+
+ TheResult = SetFileAttributesA(FileName, FILE_ATTRIBUTE_NORMAL);
+
+ if(TheResult != 0)
+ {
+ Fail("ERROR: SetFileAttributesA returned non-zero0, success, when"
+ " trying to set the FILE_ATTRIBUTE_NORMAL attribute on a non "
+ "existant file. This should fail.");
+ }
+
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/testinfo.dat
new file mode 100644
index 0000000000..33a4b03d64
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFileAttributesA
+Name = Test SetFileAttributesA on an invalid file
+TYPE = DEFAULT
+EXE1 = setfileattributesa
+Description
+= Test the SetFileAttributesA function
+= Try the function on a file that doesn't exist. It should fail.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt
new file mode 100644
index 0000000000..f30969ad04
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesA.c
+)
+
+add_executable(paltest_setfileattributesa_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesa_test4 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesa_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c
new file mode 100644
index 0000000000..240e89ff6f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c
@@ -0,0 +1,128 @@
+// 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: SetFileAttributesA.c
+**
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesA function
+** Check that using two flags (READONLY and NORMAL) only sets the file
+** as READONLY, as MSDN notes that everything else overrides NORMAL.
+**
+** Depends:
+** CreateFileA
+** CloseHandle
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ HANDLE TheFile;
+ char* FileName = {"test_file"};
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Try to set the file to Read-only|Normal ... It should
+ end up as Readonly, since this overrides Normal*/
+
+ TheResult = SetFileAttributesA(FileName,
+ FILE_ATTRIBUTE_NORMAL|
+ FILE_ATTRIBUTE_READONLY);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributesA returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_NORMAL "
+ "attribute.");
+ }
+
+ /* Attempt to open this READONLY file with WRITE access,
+ The open should fail and the HANDLE should be invalid.
+ */
+
+ TheFile = CreateFileA(
+ FileName, // 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(TheFile != INVALID_HANDLE_VALUE)
+ {
+ TheResult = CloseHandle(TheFile);
+ if(TheResult == 0)
+ {
+ Trace("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_WRITE access mode. This should"
+ " cause CreateFileA to return an INVALID_HANDLE_VALUE.");
+ }
+
+ /* Try to open the file with READ access, this should be ok.
+ The HANDLE will be valid.
+ */
+
+ TheFile = CreateFileA(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_READ access mode. This should"
+ " cause CreateFileA to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+ /* Close that HANDLE */
+
+ TheResult = CloseHandle(TheFile);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/test_file
new file mode 100644
index 0000000000..1b4bcfe1b5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/test_file
@@ -0,0 +1 @@
+Don't delete me. I'm needed. The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/testinfo.dat
new file mode 100644
index 0000000000..d8df0625bc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/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 = SetFileAttributesA
+Name = Tests SetFileAttributesA properly overrides NORMAL
+TYPE = DEFAULT
+EXE1 = setfileattributesa
+Description
+= Test the SetFileAttributesA function. Check that using two flags
+= (READONLY and NORMAL) only sets the file as READONLY, as MSDN
+= notes that everything else overrides NORMAL.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt
new file mode 100644
index 0000000000..35927b4b1d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesW.c
+)
+
+add_executable(paltest_setfileattributesw_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesw_test1 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesw_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c
new file mode 100644
index 0000000000..753c396d1f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c
@@ -0,0 +1,167 @@
+// 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: SetFileAttributesW.c
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesW function
+** Test that we can set a file READONLY, and then that we're unable to
+** open that file with WRITE access. Then change it to NORMAL attributes, and
+** try to open it again -- it should work now.
+**
+** Depends:
+** CreateFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+/* According to the spec, only READONLY attribute can be set
+ in FreeBSD.
+*/
+
+#define UNICODE
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ HANDLE TheFile;
+ CHAR *FileName_Multibyte = "test_file";
+ WCHAR FileName[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName_Multibyte, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Make a wide character string for the file name */
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ FileName_Multibyte,
+ -1,
+ FileName,
+ MAX_PATH);
+
+
+ /* Try to set the file to Read-only */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_READONLY);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_READONLY attribute.");
+ }
+
+ /* Attempt to open this READONLY file with WRITE access,
+ The open should fail and the HANDLE should be invalid.
+ */
+
+ TheFile = CreateFile(
+ FileName, // 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(TheFile != INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_WRITE access mode. This should"
+ " cause CreateFile to return an INVALID_HANDLE_VALUE.");
+ }
+
+ /* Try to open the file with READ access, this should be ok.
+ The HANDLE will be valid.
+ */
+
+ TheFile = CreateFile(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_READ access mode. This should"
+ " cause CreateFile to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+ /* Close that HANDLE */
+
+ TheResult = CloseHandle(TheFile);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+
+ /* Set the file to NORMAL */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_NORMAL);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_NORMAL attribute.");
+ }
+
+ /* To ensure that the set worked correctly, try to open the file
+ with WRITE access again -- this time it should succeed.
+ */
+
+ TheFile = CreateFile(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "NORMAL with the GENERIC_WRITE access mode. This should"
+ " cause CreateFile to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/test_file
new file mode 100644
index 0000000000..1b4bcfe1b5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/test_file
@@ -0,0 +1 @@
+Don't delete me. I'm needed. The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/testinfo.dat
new file mode 100644
index 0000000000..75cdc3b719
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/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 = SetFileAttributesW
+Name = Positive Test for SetFileAttributesW
+TYPE = DEFAULT
+EXE1 = setfileattributesw
+Description
+= Test the SetFileAttributesW function. Set a file as READONLY and
+= attempt to open it with WRITE access, to ensure that this doesn't work.
+= Then switch to NORMAL attributes, and try again -- it should work.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt
new file mode 100644
index 0000000000..81fa02c1dd
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesW.c
+)
+
+add_executable(paltest_setfileattributesw_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesw_test2 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesw_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c
new file mode 100644
index 0000000000..f657436845
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c
@@ -0,0 +1,121 @@
+// 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: SetFileAttributesW.c
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesW function
+** Test that we can set the defined attributes aside from READONLY on a
+** file, and that it doesn't return failure. Note, these attributes won't
+** do anything to the file, however.
+**
+**
+**===================================================================*/
+
+#define UNICODE
+
+#include <palsuite.h>
+
+/* this cleanup method tries to revert the file back to its initial attributes */
+void do_cleanup(WCHAR* filename, DWORD attributes)
+{
+ DWORD result;
+ result = SetFileAttributes(filename, attributes);
+ if (result == 0)
+ {
+ Fail("ERROR:SetFileAttributesW returned 0,failure in the do_cleanup "
+ "method when trying to revert the file back to its initial attributes (%u)", GetLastError());
+ }
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ DWORD initialAttr;
+ CHAR *FileName_Multibyte = "test_file";
+ WCHAR FileName[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName_Multibyte, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Make a wide character string for the file name */
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ FileName_Multibyte,
+ -1,
+ FileName,
+ MAX_PATH);
+
+ /* Get the initial attributes of the file */
+ initialAttr = GetFileAttributesW(FileName);
+
+ /* Try to set the file to HIDDEN */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_HIDDEN);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_HIDDEN attribute. This should "
+ "not do anything in FreeBSD, but it shouldn't fail.");
+ }
+
+ /* Try to set the file to ARCHIVE */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_ARCHIVE);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_ARCHIVE attribute.");
+ }
+
+ /* Try to set the file to SYSTEM */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_SYSTEM);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_SYSTEM attribute.");
+ }
+
+ /* Try to set the file to DIRECTORY */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_DIRECTORY);
+
+ if(TheResult == 0)
+ {
+ do_cleanup(FileName,initialAttr);
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_DIRECTORY attribute.");
+ }
+
+ do_cleanup(FileName,initialAttr);
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/test_file
new file mode 100644
index 0000000000..18d630a34d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/test_file
@@ -0,0 +1 @@
+The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/testinfo.dat
new file mode 100644
index 0000000000..e3161a9bd6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/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 = SetFileAttributesW
+Name = Positive Test for SetFileAttributesW
+TYPE = DEFAULT
+EXE1 = setfileattributesw
+Description
+= Test the SetFileAttributesW function
+= Try to set the attributes that are not valid in FreeBSD. These should
+= return success in either WIN32 or FreeBSD, just have no effect in FreeBSD.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt
new file mode 100644
index 0000000000..c2cdacb0d0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesW.c
+)
+
+add_executable(paltest_setfileattributesw_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesw_test3 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesw_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c
new file mode 100644
index 0000000000..8a8bafac68
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c
@@ -0,0 +1,57 @@
+// 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: SetFileAttributesW.c
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesW function
+** Test that the function fails if the file doesn't exist..
+**
+**
+**===================================================================*/
+
+#define UNICODE
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ WCHAR FileName[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Make a wide character string for the file name */
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ "no_file",
+ -1,
+ FileName,
+ MAX_PATH);
+
+
+ /* Try to set the file to NORMAL on a file that doesn't
+ exist.
+ */
+
+ TheResult = SetFileAttributes(FileName,FILE_ATTRIBUTE_NORMAL);
+
+ if(TheResult != 0)
+ {
+ Fail("ERROR: SetFileAttributes returned non-zero0, success, when"
+ " trying to set the FILE_ATTRIBUTE_NORMAL attribute on a non "
+ "existant file. This should fail.");
+ }
+
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/testinfo.dat
new file mode 100644
index 0000000000..4b264898df
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFileAttributesW
+Name = Positive Test for SetFileAttributesW
+TYPE = DEFAULT
+EXE1 = setfileattributesw
+Description
+= Test the SetFileAttributesW function
+= Try the function on a file that doesn't exist. It should fail.
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt
new file mode 100644
index 0000000000..6a4aa8adc3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileAttributesW.c
+)
+
+add_executable(paltest_setfileattributesw_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfileattributesw_test4 coreclrpal)
+
+target_link_libraries(paltest_setfileattributesw_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c
new file mode 100644
index 0000000000..bebadfa264
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c
@@ -0,0 +1,133 @@
+// 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: SetFileAttributesW.c
+**
+** Purpose: Tests the PAL implementation of the SetFileAttributesW function
+** Check that using two flags (READONLY and NORMAL) only sets the file
+** as READONLY, as MSDN notes that everything else overrides NORMAL.
+**
+** Depends:
+** CreateFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+#define UNICODE
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD TheResult;
+ HANDLE TheFile;
+ CHAR *FileName_Multibyte = "test_file";
+ WCHAR FileName[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // Create the test file
+ FILE *testFile = fopen(FileName_Multibyte, "w");
+ if (testFile == NULL)
+ {
+ Fail("Unexpected error: Unable to open file %S with fopen. \n", FileName);
+ }
+ if (fputs("testing", testFile) == EOF)
+ {
+ Fail("Unexpected error: Unable to write to file %S with fputs. \n", FileName);
+ }
+ if (fclose(testFile) != 0)
+ {
+ Fail("Unexpected error: Unable to close file %S with fclose. \n", FileName);
+ }
+ testFile = NULL;
+
+ /* Make a wide character string for the file name */
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ FileName_Multibyte,
+ -1,
+ FileName,
+ MAX_PATH);
+
+
+ /* Try to set the file to Read-only|Normal ... It should
+ end up as Readonly, since this overrides Normal*/
+
+ TheResult = SetFileAttributes(FileName,
+ FILE_ATTRIBUTE_NORMAL|
+ FILE_ATTRIBUTE_READONLY);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: SetFileAttributes returned 0, failure, when trying "
+ "to set the FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_NORMAL "
+ "attribute.");
+ }
+
+ /* Attempt to open this READONLY file with WRITE access,
+ The open should fail and the HANDLE should be invalid.
+ */
+
+ TheFile = CreateFile(
+ FileName, // 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(TheFile != INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_WRITE access mode. This should"
+ " cause CreateFile to return an INVALID_HANDLE_VALUE.");
+ }
+
+ /* Try to open the file with READ access, this should be ok.
+ The HANDLE will be valid.
+ */
+
+ TheFile = CreateFile(
+ FileName, // 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(TheFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("ERROR: Tried to open a file that was created as "
+ "READONLY with the GENERIC_READ access mode. This should"
+ " cause CreateFile to return an valid handle, but "
+ "INVALID_HANDLE_VALUE was returned!.");
+ }
+
+ /* Close that HANDLE */
+
+ TheResult = CloseHandle(TheFile);
+
+ if(TheResult == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This tests relies upon it "
+ "working properly.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/test_file b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/test_file
new file mode 100644
index 0000000000..1b4bcfe1b5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/test_file
@@ -0,0 +1 @@
+Don't delete me. I'm needed. The File. \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/testinfo.dat
new file mode 100644
index 0000000000..75cdc3b719
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/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 = SetFileAttributesW
+Name = Positive Test for SetFileAttributesW
+TYPE = DEFAULT
+EXE1 = setfileattributesw
+Description
+= Test the SetFileAttributesW function. Set a file as READONLY and
+= attempt to open it with WRITE access, to ensure that this doesn't work.
+= Then switch to NORMAL attributes, and try again -- it should work.
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/CMakeLists.txt
new file mode 100644
index 0000000000..19ee487a6a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/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/SetFilePointer/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt
new file mode 100644
index 0000000000..e352449981
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test1 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c
new file mode 100644
index 0000000000..14b5f85e69
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c
@@ -0,0 +1,123 @@
+// 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: SetFilePointer.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Set the file pointer using a NULL handle and other invalid
+** options.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwOffset = 25;
+ DWORD dwRc = 0;
+ BOOL bRc = FALSE;
+ char buffer[100];
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* set the file pointer on a NULL file handle */
+ dwRc = SetFilePointer(NULL, dwOffset, NULL, FILE_BEGIN);
+ if (dwRc != INVALID_SET_FILE_POINTER)
+ {
+ Fail("SetFilePointer: ERROR -> Call to SetFilePointer succeeded "
+ "with a NULL pointer\n");
+ }
+
+
+ /* create a test file without proper permission */
+ hFile = CreateFile(szTextFile,
+ 0,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ /* ReadFile fails as expected */
+ bRc = ReadFile(hFile, buffer, 1, &dwByteCount, NULL);
+ if (bRc != FALSE)
+ {
+ Trace("SetFilePointer: ERROR -> ReadFile was successful when it was "
+ "expected to fail\n");
+ if (!CloseHandle(hFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the file pointer before the beginning of the file */
+ dwRc = SetFilePointer(hFile, -1, NULL, FILE_BEGIN);
+ if (dwRc != INVALID_SET_FILE_POINTER)
+ {
+ Trace("SetFilePointer: ERROR -> Was able to move the pointer before "
+ "the beginning of the file.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/testinfo.dat
new file mode 100644
index 0000000000..dfd4b6bd42
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFilePointer
+Name = Test for SetFilePointer (test 1)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Set the file pointer on a NULL file handle and other invalid options
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt
new file mode 100644
index 0000000000..290a01107f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test2 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c
new file mode 100644
index 0000000000..19e99a74b3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c
@@ -0,0 +1,356 @@
+// 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: SetFilePointer.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_BEGIN option
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char * const szText =
+ "The quick brown fox jumped over the lazy dog's back.";
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwRc = 0;
+ BOOL bRc = FALSE;
+ char szBuffer[100];
+ const char *szPtr;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwByteCount, NULL);
+ if (bRc == FALSE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to write to file \"%s\".\n",
+ szTextFile);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ /* move -1 from beginning which should fail */
+ dwRc = SetFilePointer(hFile, -1, NULL, FILE_BEGIN);
+ if ((dwRc != INVALID_SET_FILE_POINTER) ||
+ (GetLastError() == ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Succeeded to move the pointer "
+ "before the beginning of the file.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the file pointer 0 bytes from the beginning and verify */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ if (dwRc != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the pointer ahead in the file and verify */
+ dwRc = SetFilePointer(hFile, 20, NULL, FILE_BEGIN);
+ if (dwRc != 20)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ memset(szBuffer, 0, 100);
+ bRc = ReadFile(hFile, szBuffer, (DWORD)strlen(szText)-20, &dwByteCount,
+ NULL);
+ if ((bRc != TRUE) || (dwByteCount != strlen(szText)-20))
+ {
+ Trace("SetFilePointer: ERROR -> ReadFile failed to read correctly");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ "\"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ "\"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ szPtr = szText + 20;
+ if (strcmp(szPtr, szBuffer) != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Apparently failed to move the "
+ "pointer properly\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ /* move the file pointer back to the beginning and verify */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ if (dwRc != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ memset(szBuffer, 0, 100);
+ bRc = ReadFile(hFile, szBuffer, (DWORD)strlen(szText), &dwByteCount,
+ NULL);
+ if ((bRc != TRUE) || (dwByteCount != strlen(szText)))
+ {
+ Trace("SetFilePointer: ERROR -> ReadFile failed to read correctly");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ if (strcmp(szText, szBuffer) != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Failed to return the pointer "
+ "properly to the beginning of the file\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ /* return the pointer to the beginning of the file */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ if (dwRc != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* set the pointer past the end of the file and verify */
+ dwRc = SetFilePointer(hFile, (DWORD)strlen(szText)+20, NULL, FILE_BEGIN);
+ if ((dwRc == INVALID_SET_FILE_POINTER) && (GetLastError() != ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past EOF.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify */
+ bRc = SetEndOfFile(hFile);
+ if (bRc != TRUE)
+ {
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (GetFileSize(hFile, NULL) != strlen(szText)+20)
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past"
+ " EOF.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/testinfo.dat
new file mode 100644
index 0000000000..e3a0a861f4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 2)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_BEGIN option
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt
new file mode 100644
index 0000000000..daa7553a1a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test3 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c
new file mode 100644
index 0000000000..dd53829629
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c
@@ -0,0 +1,350 @@
+// 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: SetFilePointer.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_CURRENT option
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* const szText =
+ "The quick brown fox jumped over the lazy dog's back.";
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwRc = 0;
+ BOOL bRc = FALSE;
+ char szBuffer[100];
+ const char* szPtr;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwByteCount, NULL);
+ if (bRc == FALSE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to write to file \"%s\".\n",
+ szTextFile);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* reset the pointer to the beginning */
+ if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ {
+ if (GetLastError() != ERROR_SUCCESS)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to reset the pointer to the "
+ "beginning of the file");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ /* move -1 from beginning which should fail */
+ dwRc = SetFilePointer(hFile, -1, NULL, FILE_CURRENT);
+ if ((dwRc != INVALID_SET_FILE_POINTER) ||
+ (GetLastError() == ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Succeeded to move the pointer "
+ "before the beginning of the file.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ /* move the file pointer 0 bytes from the beginning and verify */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+ if (dwRc != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the pointer ahead in the file and verify */
+ dwRc = SetFilePointer(hFile, 20, NULL, FILE_CURRENT);
+ if (dwRc != 20)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 20 bytes from the "
+ "beginning of the file but moved %ld bytes.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ memset(szBuffer, 0, 100);
+ bRc = ReadFile(hFile, szBuffer, (DWORD)strlen(szText)-20, &dwByteCount,
+ NULL);
+ if ((bRc != TRUE) || (dwByteCount != strlen(szText)-20))
+ {
+ Trace("SetFilePointer: ERROR -> ReadFile failed to read correctly");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ szPtr = szText + 20;;
+ if (strcmp(szPtr, szBuffer) != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Apparently failed to move the"
+ " pointer properly\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /* get the current file pointer position (should be 52) */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+ if (dwRc != 52)
+ {
+ Trace("SetFilePointer: ERROR -> Asked for current position."
+ " Should be 52 but was %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ /* move the pointer backwards in the file and verify */
+ dwRc = SetFilePointer(hFile, -10, NULL, FILE_CURRENT);
+ if (dwRc != 42)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move back 10 bytes from the"
+ "end of the file but moved it to position %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ memset(szBuffer, 0, 100);
+ bRc = ReadFile(hFile, szBuffer, 10, &dwByteCount, NULL);
+ if ((bRc != TRUE) || (dwByteCount != 10))
+ {
+ Trace("SetFilePointer: ERROR -> ReadFile failed to read correctly");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ szPtr = szText + 42;
+ if (strcmp(szPtr, szBuffer) != 0)
+ {
+ Trace("SetFilePointer: ERROR -> Apparently failed to move the"
+ " pointer properly\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ /*
+ * the file pointer is currently at the end of the file so...
+ * set the pointer past the end of the file and verify
+ */
+ dwRc = SetFilePointer(hFile, 20, NULL, FILE_CURRENT);
+ if ((dwRc == INVALID_SET_FILE_POINTER) && (GetLastError() != ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past EOF.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ if (SetFilePointer(hFile, 0, NULL, FILE_CURRENT) != strlen(szText)+20)
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past"
+ " EOF.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/testinfo.dat
new file mode 100644
index 0000000000..7c51fbc384
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 3)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_CURRENT option
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt
new file mode 100644
index 0000000000..1117893350
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test4 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c
new file mode 100644
index 0000000000..2993cfd354
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c
@@ -0,0 +1,242 @@
+// 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: SetFilePointer.c (test 4)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_END option
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szText = "The quick brown fox jumped over the lazy dog's back.";
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwByteCount = 0;
+ DWORD dwOffset = 0;
+ DWORD dwRc = 0;
+ BOOL bRc = FALSE;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+ bRc = WriteFile(hFile, szText, (DWORD)strlen(szText), &dwByteCount, NULL);
+ if (bRc == FALSE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to write to file \"%s\".\n",
+ szTextFile);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ /*
+ * move -1 from the end
+ */
+ dwRc = SetFilePointer(hFile, -1, NULL, FILE_END);
+ if (dwRc == INVALID_SET_FILE_POINTER)
+ {
+ if (GetLastError() != ERROR_SUCCESS)
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move the pointer "
+ "back one character from EOF.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+ else
+ {
+ /* verify */
+ if ((dwRc != strlen(szText)-1))
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move the pointer"
+ " -1 bytes from EOF\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ /*
+ * move the file pointer 0 bytes from the end and verify
+ */
+ dwRc = SetFilePointer(hFile, 0, NULL, FILE_END);
+ if (dwRc != strlen(szText))
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 0 bytes from the "
+ "end of the file. Function returned %ld instead of 52.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /*
+ * move the pointer past the end of the file and verify
+ */
+ dwRc = SetFilePointer(hFile, 20, NULL, FILE_END);
+ if (dwRc != strlen(szText)+20)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 20 bytes past the "
+ "end of the file. Function returned %ld instead of %d.\n",
+ dwRc,
+ strlen(szText)+20);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ bRc = SetEndOfFile(hFile);
+ if ((dwRc = GetFileSize(hFile, NULL)) != strlen(szText)+20)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move back 20 bytes past"
+ " theend of the file. GetFileSize returned %ld whereas it "
+ "should have been %d.\n",
+ dwRc,
+ strlen(szText)+20);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /*
+ * move the pointer backwards to before the start of the file and verify
+ */
+
+ dwOffset = (dwRc + 20) * -1;
+ dwRc = SetFilePointer(hFile, dwOffset, NULL, FILE_END);
+ if ((dwRc != INVALID_SET_FILE_POINTER) ||
+ (GetLastError() == ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Was able to move the pointer "
+ "to before the beginning of the file.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/testinfo.dat
new file mode 100644
index 0000000000..dce6f9eb21
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 4)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_END option
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt
new file mode 100644
index 0000000000..b37bf42ffc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test5 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test5
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c
new file mode 100644
index 0000000000..f1d392da38
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c
@@ -0,0 +1,182 @@
+// 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: SetFilePointer.c (test 5)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_BEGIN option using the high word parameter
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwOffset = 1;
+ LONG dwHighWord = 1;
+ DWORD dwReturnedOffset = 0;
+ DWORD dwReturnedHighWord = 0;
+ DWORD dwRc = 0;
+ DWORD dwError = 0;
+ BOOL bRc = FALSE;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ dwError = GetLastError();
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n with "
+ "error %ld",
+ szTextFile,
+ GetLastError());
+ }
+
+
+
+ /* move -1 from beginning which should fail */
+ dwRc = SetFilePointer(hFile, -1, &dwHighWord, FILE_BEGIN);
+ if (dwRc != INVALID_SET_FILE_POINTER)
+ {
+ Trace("SetFilePointer: ERROR -> Succeeded to move the pointer "
+ "before the beginning of the file using the high word.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* set the pointer past the end of the file and verify */
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighWord, FILE_BEGIN);
+ if ((dwRc == INVALID_SET_FILE_POINTER) &&
+ ((dwError = GetLastError()) != ERROR_SUCCESS))
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past EOF.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify */
+ bRc = SetEndOfFile(hFile);
+ if (bRc != TRUE)
+ {
+ dwError = GetLastError();
+ if (dwError == 112)
+ {
+ Trace("SetFilePointer: ERROR -> SetEndOfFile failed due to "
+ "lack of disk space\n");
+ }
+ else
+ {
+ Trace("SetFilePointer: ERROR -> SetEndOfFile call failed with "
+ "error %ld\n", dwError);
+ }
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ dwReturnedOffset = GetFileSize(hFile, &dwReturnedHighWord);
+ if ((dwOffset != dwReturnedOffset) ||
+ (dwHighWord != dwReturnedHighWord))
+ {
+ Trace("SetFilePointer: ERROR -> Failed to move pointer past"
+ " EOF.\n");
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/testinfo.dat
new file mode 100644
index 0000000000..64745c0e98
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 5)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_BEGIN option with the high word parameter.
+=This test requires about 4 gig free disk space
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt
new file mode 100644
index 0000000000..8f99ed2d76
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test6 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c
new file mode 100644
index 0000000000..b35247ec24
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c
@@ -0,0 +1,213 @@
+// 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: SetFilePointer.c (test 6)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_CURRENT option with high order support
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwOffset = 0;
+ LONG dwHighOrder = 0;
+ DWORD dwReturnedOffset = 0;
+ LONG dwReturnedHighOrder = 0;
+ DWORD dwRc = 0;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+
+ /* move waaaay before the beginning which should fail */
+ dwHighOrder = -1;
+ dwOffset = 0;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_CURRENT);
+ if (dwRc != INVALID_SET_FILE_POINTER)
+ {
+ Trace("SetFilePointer: ERROR -> Succeeded to move the pointer "
+ "before the beginning of the file.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the pointer ahead in the file and verify */
+ dwHighOrder = 1;
+ dwOffset = 10;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_CURRENT);
+ if ((dwRc != 10) || (dwHighOrder != 1))
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 2GB plus 10 bytes from "
+ "the beginning of the file but didn't.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ if (SetEndOfFile(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Call to SetEndOfFile failed with "
+ "error code: %d\n", GetLastError());
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ dwReturnedOffset = GetFileSize(hFile, (DWORD*)&dwReturnedHighOrder);
+ if ((dwReturnedOffset != dwOffset) ||
+ (dwReturnedHighOrder != dwHighOrder))
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move far past the "
+ "current file pointer. "
+ "low order sent: %ld low order returned: %ld "
+ "high order sent: %ld high order returned: %ld",
+ dwOffset, dwReturnedOffset,
+ dwHighOrder, dwReturnedHighOrder);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /*
+ * move the pointer backwards in the file and verify
+ */
+ dwOffset = 0;
+ dwHighOrder = -1;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_CURRENT);
+ if (dwRc != 10)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move back to 10 bytes from the"
+ "beginning of the file but moved it to position %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ dwReturnedHighOrder = 0;
+ dwRc = SetFilePointer(hFile, 0, &dwReturnedHighOrder, FILE_CURRENT);
+ if (dwRc != 10)
+ {
+ Trace("SetFilePointer: ERROR -> Asked for current position. "
+ "Should be 10 but was %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /* clean up, clean up, everybody do their share... */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/testinfo.dat
new file mode 100644
index 0000000000..3138e9bb40
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 6)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_CURRENT option with the high word parameter.
+=This test requires about 4 GB free disk space.
+
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt
new file mode 100644
index 0000000000..c5a46a531a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFilePointer.c
+)
+
+add_executable(paltest_setfilepointer_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfilepointer_test7 coreclrpal)
+
+target_link_libraries(paltest_setfilepointer_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c
new file mode 100644
index 0000000000..33dfd5e711
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c
@@ -0,0 +1,213 @@
+// 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: SetFilePointer.c (test 7)
+**
+** Purpose: Tests the PAL implementation of the SetFilePointer function.
+** Test the FILE_END option with high order support
+**
+** Assumes Successful:
+** CreateFile
+** ReadFile
+** WriteFile
+** strlen
+** CloseHandle
+** strcmp
+** GetFileSize
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szTextFile = "text.txt";
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwOffset = 0;
+ LONG dwHighOrder = 0;
+ DWORD dwReturnedOffset = 0;
+ LONG dwReturnedHighOrder = 0;
+ DWORD dwRc = 0;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a test file */
+ hFile = CreateFile(szTextFile,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("SetFilePointer: ERROR -> Unable to create file \"%s\".\n",
+ szTextFile);
+ }
+
+
+ /* move -1 from beginning which should fail */
+ dwHighOrder = -1;
+ dwOffset = 0;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_END);
+ if (dwRc != INVALID_SET_FILE_POINTER)
+ {
+ Trace("SetFilePointer: ERROR -> Succeeded to move the pointer "
+ "before the beginning of the file.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* move the pointer ahead in the file and verify */
+ dwHighOrder = 1;
+ dwOffset = 10;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_END);
+ if ((dwRc != 10) || (dwHighOrder != 1))
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move 4GB plus 10 bytes from "
+ "the beginning of the file but didn't.\n");
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ if (SetEndOfFile(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Call to SetEndOfFile failed with "
+ "error code: %d\n",
+ GetLastError());
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ dwReturnedOffset = GetFileSize(hFile, (DWORD*)&dwReturnedHighOrder);
+ if ((dwReturnedOffset != dwOffset) || (dwReturnedHighOrder != dwHighOrder))
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move far past the "
+ "end of the file. low order sent: %ld low order returned: %ld "
+ "high order sent: %ld high order returned: %ld",
+ dwOffset, dwReturnedOffset,
+ dwHighOrder, dwReturnedHighOrder);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /*
+ * move the pointer backwards in the file and verify
+ */
+ dwOffset = 0;
+ dwHighOrder = -1;
+ dwRc = SetFilePointer(hFile, dwOffset, &dwHighOrder, FILE_END);
+ if (dwRc != 10)
+ {
+ Trace("SetFilePointer: ERROR -> Asked to move back to 10 bytes from the"
+ "beginning of the file but moved it to position %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ else
+ {
+ /* verify results */
+ dwReturnedHighOrder = 0;
+ dwRc = SetFilePointer(hFile, 0, &dwReturnedHighOrder, FILE_CURRENT);
+ if (dwRc != 10)
+ {
+ Trace("SetFilePointer: ERROR -> Asked for current position. "
+ "Should be 10 but was %ld.\n", dwRc);
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file"
+ " \"%s\".\n", szTextFile);
+ }
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file"
+ " \"%s\".\n", szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+ }
+
+
+ /* clean up, clean up, everybody do their share... */
+ if (CloseHandle(hFile) != TRUE)
+ {
+ Trace("SetFilePointer: ERROR -> Unable to close file \"%s\".\n",
+ szTextFile);
+ if (!DeleteFileA(szTextFile))
+ {
+ Trace("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ if (!DeleteFileA(szTextFile))
+ {
+ Fail("SetFilePointer: ERROR -> Unable to delete file \"%s\".\n",
+ szTextFile);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/testinfo.dat
new file mode 100644
index 0000000000..6e8826291f
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/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 = SetFilePointer
+Name = Positive Test for SetFilePointer (test 7)
+Type = DEFAULT
+EXE1 = setfilepointer
+Description
+=Tests the FILE_END option with the high word parameter
+=This test requires about 4 GB of free disk space.
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt
new file mode 100644
index 0000000000..4c4b5d7611
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileTime.c
+)
+
+add_executable(paltest_setfiletime_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfiletime_test1 coreclrpal)
+
+target_link_libraries(paltest_setfiletime_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c
new file mode 100644
index 0000000000..4711aeba89
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c
@@ -0,0 +1,129 @@
+// 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: SetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the SetFileTime function.
+** This test first sets a valid file time on the file which is opened.
+** Then it calls GetFileTime, and compares the values. They should
+** be the same. Note: Access time isn't checked in this test. It will
+** be dealt with seperatly due to odd behaviour.
+**
+** Depends:
+** CreateFile
+** GetFileTime
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char **argv)
+{
+
+#if WIN32
+ FILETIME Creation;
+ FILETIME SetCreation;
+#endif
+ FILETIME LastWrite;
+ FILETIME SetLastWrite;
+ HANDLE TheFileHandle;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Populate some FILETIME structures with values
+ These values are valid Creation, Access and Write times
+ which I generated, and should work properly.
+ */
+#if WIN32
+ SetCreation.dwLowDateTime = 458108416;
+ SetCreation.dwHighDateTime = 29436904;
+#endif
+
+ SetLastWrite.dwLowDateTime = -1995099136;
+ SetLastWrite.dwHighDateTime = 29436915;
+
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle = CreateFile("the_file",
+ GENERIC_READ|GENERIC_WRITE,
+ 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.\n",GetLastError());
+ }
+
+ /* Set the new file time */
+#if WIN32
+ result = SetFileTime(TheFileHandle,
+ &SetCreation, NULL, &SetLastWrite);
+#else
+ result = SetFileTime(TheFileHandle,
+ NULL, NULL, &SetLastWrite);
+#endif
+ if(result == 0)
+ {
+ Fail("ERROR: SetFileTime failed when trying to set the "
+ "new file time. The GetLastError was %d.\n",GetLastError());
+ }
+
+
+ /* Then get the file time of the file */
+#if WIN32
+ result = GetFileTime(TheFileHandle, &Creation, NULL, &LastWrite);
+#else
+ result = GetFileTime(TheFileHandle, NULL, NULL, &LastWrite);
+#endif
+
+ if(result == 0)
+ {
+ Fail("ERROR: GetFileTime failed, and this tests depends "
+ "upon it working properly, in order to ensure that the "
+ "file time was set with SetFileTime. GetLastError() "
+ "returned %d.\n",GetLastError());
+ }
+
+ /* Compare the write time we Set to the write time aquired with
+ Get. They should be the same.
+ */
+
+ if(LastWrite.dwLowDateTime != SetLastWrite.dwLowDateTime ||
+ LastWrite.dwHighDateTime != SetLastWrite.dwHighDateTime)
+ {
+ Fail("ERROR: After setting the write time, it is not "
+ "equal to what it was set to. Either Set of GetFileTime are "
+ "broken.\n");
+ }
+
+ /* Within FreeBSD, the Creation time is ignored when SetFileTime
+ is called. Since FreeBSD has no equivalent. For that reason,
+ it is not checked with the following test.
+ */
+
+#if WIN32
+ if(Creation.dwHighDateTime != SetCreation.dwHighDateTime ||
+ Creation.dwLowDateTime != SetCreation.dwLowDateTime)
+ {
+ Fail("ERROR: After setting the file time, the Creation "
+ "time is not what it should be. Either Set or GetFileTime "
+ "are broken.");
+ }
+#endif
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileTime/test1/testinfo.dat
new file mode 100644
index 0000000000..09dfa0b623
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test1/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 = SetFileTime
+Name = Positive Test for SetFileTime
+TYPE = DEFAULT
+EXE1 = setfiletime
+Description
+= Test the SetFileTime function.
+= This test calls SetFileTime and sets a file to a given time. It then
+= calls GetFileTime, and compares the values of the two, which should be
+= equal
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt
new file mode 100644
index 0000000000..35c18c8d8d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileTime.c
+)
+
+add_executable(paltest_setfiletime_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfiletime_test2 coreclrpal)
+
+target_link_libraries(paltest_setfiletime_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c
new file mode 100644
index 0000000000..e950153bb0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c
@@ -0,0 +1,101 @@
+// 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: SetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the SetFileTime
+** This test first tries to SetFileTime on a HANDLE which doesn't have
+** GENERIC_WRITE set, which should fail.
+**
+**
+** Depends:
+** CreateFile
+** CloseHandle
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME SetCreation,SetLastAccess,SetLastWrite;
+ HANDLE TheFileHandle;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Populate some FILETIME structures with values
+ These values are valid Creation, Access and Write times
+ which I generated, and should work properly.
+
+ The access times are not seperated into WIN32 and FreeBSD here,
+ but it should be fine, as no comparisons are being done in this
+ test.
+ */
+
+ SetCreation.dwLowDateTime = 458108416;
+ SetCreation.dwHighDateTime = 29436904;
+
+ SetLastAccess.dwLowDateTime = 341368832;
+ SetLastAccess.dwHighDateTime = 29436808;
+
+ SetLastWrite.dwLowDateTime = -1995099136;
+ SetLastWrite.dwHighDateTime = 29436915;
+
+
+/* Open the file to get a HANDLE, without GENERIC WRITE */
+
+ 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());
+ }
+
+ /* This SetFileTime should fail, because the HANDLE isn't set with
+ GENERIC_WRITE
+ */
+ result = SetFileTime(TheFileHandle,
+ &SetCreation,&SetLastAccess,&SetLastWrite);
+
+ if(result != 0)
+ {
+ Fail("ERROR: SetFileTime should have failed, but returned a "
+ "non-zero result. The File HANDLE passed was no set Writable "
+ "which should cause failure.");
+ }
+
+ result = CloseHandle(TheFileHandle);
+
+ if(result == 0)
+ {
+ Fail("ERROR: CloseHandle failed. This test depends upon "
+ "it working.");
+ }
+
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileTime/test2/testinfo.dat
new file mode 100644
index 0000000000..f1699facaf
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test2/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 = SetFileTime
+Name = Negative Test for SetFileTime
+TYPE = DEFAULT
+EXE1 = setfiletime
+Description
+= Test the SetFileTime function.
+= This test first tries to SetFileTime on a HANDLE which doesn't have
+= GENERIC_WRITE set, which should fail. Then it attempts to set the file
+= time with bad FILETIME structures, which should also fail
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt
new file mode 100644
index 0000000000..0a85d30c51
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileTime.c
+)
+
+add_executable(paltest_setfiletime_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfiletime_test3 coreclrpal)
+
+target_link_libraries(paltest_setfiletime_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c
new file mode 100644
index 0000000000..97f49495d7
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c
@@ -0,0 +1,66 @@
+// 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: SetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the SetFileTime function.
+** This test checks to ensure that the function fails when passed an
+** invalid file HANDLE
+**
+**
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILETIME SetCreation, SetLastWrite, SetLastAccess;
+ HANDLE TheFileHandle = NULL;
+ BOOL result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Populate some FILETIME structures with values
+ These values are valid Creation, Access and Write times
+ which I generated, and should work properly.
+ */
+
+ SetCreation.dwLowDateTime = 458108416;
+ SetCreation.dwHighDateTime = 29436904;
+
+ SetLastAccess.dwLowDateTime = 341368832;
+ SetLastAccess.dwHighDateTime = 29436808;
+
+ SetLastWrite.dwLowDateTime = -1995099136;
+ SetLastWrite.dwHighDateTime = 29436915;
+
+
+ /* Pass this function an invalid file HANDLE and it should
+ fail.
+ */
+
+ result = SetFileTime(TheFileHandle,
+ &SetCreation,&SetLastAccess,&SetLastWrite);
+
+ if(result != 0)
+ {
+ Fail("ERROR: Passed an invalid file HANDLE to SetFileTime, but it "
+ "returned non-zero. This should return zero for failure.");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileTime/test3/testinfo.dat
new file mode 100644
index 0000000000..e27280469e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/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 = SetFileTime
+Name = Negative Test for SetFileTime
+TYPE = DEFAULT
+EXE1 = setfiletime
+Description
+= Test the SetFileTime function.
+= This test checks to ensure that the function fails when passed an
+= invalid file HANDLE
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt
new file mode 100644
index 0000000000..086e35e535
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ SetFileTime.c
+)
+
+add_executable(paltest_setfiletime_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_setfiletime_test4 coreclrpal)
+
+target_link_libraries(paltest_setfiletime_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c
new file mode 100644
index 0000000000..3edd2403c4
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c
@@ -0,0 +1,108 @@
+// 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: SetFileTime.c
+**
+** Purpose: Tests the PAL implementation of the SetFileTime function
+** This passes a variety of NULL values as parameters to the function.
+** It should still succeed.
+**
+** Depends:
+** CreateFile
+**
+
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+#if WIN32
+ FILETIME Creation;
+#endif
+ FILETIME LastWrite,LastAccess;
+ HANDLE TheFileHandle;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* Populate some FILETIME structures with values
+ These values are valid Creation, Access and Write times
+ which I generated, and should work properly.
+
+ These values aren't being used for comparison, so they should
+ work ok, even though they weren't generated specifically for
+ FreeBSD or WIN32 ...
+ */
+#if WIN32
+ Creation.dwLowDateTime = 458108416;
+ Creation.dwHighDateTime = 29436904;
+#endif
+ LastAccess.dwLowDateTime = 341368832;
+ LastAccess.dwHighDateTime = 29436808;
+
+ LastWrite.dwLowDateTime = -1995099136;
+ LastWrite.dwHighDateTime = 29436915;
+
+ /* Open the file to get a HANDLE */
+ TheFileHandle =
+ CreateFile(
+ "the_file",
+ GENERIC_READ|GENERIC_WRITE,
+ 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(SetFileTime(TheFileHandle,NULL,NULL,NULL)==0)
+ {
+ Fail("ERROR: SetFileTime returned 0, indicating failure. "
+ "Three of the params were NULL in this case, did they "
+ "cause the problem?");
+ }
+
+#if WIN32
+ /* Set the Creation time of the File */
+ if(SetFileTime(TheFileHandle,&Creation,NULL,NULL)==0)
+ {
+ Fail("ERROR: SetFileTime returned 0, indicating failure. "
+ "Two of the params were NULL in this case, did they "
+ "cause the problem?");
+ }
+#endif
+
+#if WIN32
+ /* Set the Creation, LastWrite time of the File */
+ if(SetFileTime(TheFileHandle,&Creation,&LastWrite,NULL)==0)
+#else
+ /* Set the LastWrite time of the File */
+ if(SetFileTime(TheFileHandle,NULL,&LastWrite,NULL)==0)
+#endif
+ {
+ Fail("ERROR: SetFileTime returned 0, indicating failure. "
+ "One of the params were NULL in this case, did it "
+ "cause the problem?");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/SetFileTime/test4/testinfo.dat
new file mode 100644
index 0000000000..a3dfdd02f0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/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 = SetFileTime
+Name = Positive Test for SetFileTime
+TYPE = DEFAULT
+EXE1 = setfiletime
+Description
+= Test the SetFileTime function.
+= This passes a variety of NULL values as parameters to the function.
+= It should still succeed
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/CMakeLists.txt
new file mode 100644
index 0000000000..8083faf655
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test5)
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt
new file mode 100644
index 0000000000..0c6760a2ce
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ WriteFile.c
+)
+
+add_executable(paltest_writefile_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_writefile_test1 coreclrpal)
+
+target_link_libraries(paltest_writefile_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c
new file mode 100644
index 0000000000..1ac38ddaf0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c
@@ -0,0 +1,114 @@
+// 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: WriteFile.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the WriteFile function.
+** This test will attempt to write to a NULL handle and a
+** read-only file
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.";
+const char* szReadOnlyFile = "ReadOnly.txt";
+void do_cleanup()
+{
+ BOOL bRc = FALSE;
+ bRc = DeleteFileA(szReadOnlyFile);
+ if (bRc != TRUE)
+ {
+ Fail ("DeleteFileA: ERROR[%ld]: During Cleanup: Couldn't delete WriteFile's"
+ " \"ReadOnly.txt\"\n", GetLastError());
+ }
+
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ BOOL bRc = FALSE;
+ DWORD last_error;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ //
+ // Write to a NULL handle
+ //
+
+ bRc = WriteFile(hFile, szStringTest, 20, &dwBytesWritten, NULL);
+
+ if (bRc == TRUE)
+ {
+ last_error = GetLastError();
+ Fail("WriteFile: ERROR[%ld] -> Able to write to a NULL handle\n", last_error);
+ }
+
+
+ //
+ // Write to a file with read-only permissions
+ //
+
+ // create a file without write permissions
+ hFile = CreateFile(szReadOnlyFile,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ last_error = GetLastError();
+ Fail("WriteFile: ERROR[%ld] -> Unable to create file \"%s\".\n",
+ last_error, szReadOnlyFile);
+ }
+
+ if (!SetFileAttributes(szReadOnlyFile, FILE_ATTRIBUTE_READONLY))
+ {
+ last_error = GetLastError();
+ Trace("WriteFile: ERROR[%ld] -> Unable to make the file read-only.\n", last_error);
+ do_cleanup();
+ Fail("WriteFile: ERROR[%ld] -> Unable to make the file read-only.\n", last_error);
+ }
+
+ bRc = WriteFile(hFile, szStringTest, 20, &dwBytesWritten, NULL);
+ if (bRc == TRUE)
+ { last_error = GetLastError();
+ Trace("WriteFile: ERROR[%ld] -> Able to write to a read-only file.\n", last_error);
+ do_cleanup();
+ Fail("WriteFile: ERROR[%ld] -> Able to write to a read-only file.\n", last_error);
+ }
+
+
+ bRc = CloseHandle(hFile);
+ if (bRc != TRUE)
+ { last_error = GetLastError();
+ Trace("WriteFile: ERROR[%ld] -> Unable to close file \"%s\".\n", last_error, szReadOnlyFile);
+ do_cleanup();
+ Fail("WriteFile: ERROR -> Unable to close file \"%s\".\n",
+ szReadOnlyFile);
+ }
+
+ //To delete file need to make it normal
+ if(!SetFileAttributesA(szReadOnlyFile,FILE_ATTRIBUTE_NORMAL))
+ {
+ last_error = GetLastError();
+ Fail("WriteFile: ERROR[%ld] -> Unable to make the file attribute NORMAL.\n", last_error);
+
+ }
+ do_cleanup();
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/WriteFile/test1/testinfo.dat
new file mode 100644
index 0000000000..148a2678e5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = WriteFile
+Name = test for WriteFile
+Type = DEFAULT
+EXE1 = writefile
+Description
+=Attempt to write to a NULL handle and to a read-only file
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt
new file mode 100644
index 0000000000..a9b51efa3d
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ WriteFile.c
+)
+
+add_executable(paltest_writefile_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_writefile_test2 coreclrpal)
+
+target_link_libraries(paltest_writefile_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/Results.txt b/src/pal/tests/palsuite/file_io/WriteFile/test2/Results.txt
new file mode 100644
index 0000000000..1c4c37885a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/Results.txt
@@ -0,0 +1 @@
+0011100111 \ No newline at end of file
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c
new file mode 100644
index 0000000000..24c148afb8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c
@@ -0,0 +1,109 @@
+// 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: WriteFile.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the WriteFile function.
+** Creates a number of files and writes different amounts of
+** data and verifies the writes.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+char* writeBuffer;
+const char* szWritableFile = "Writeable.txt";
+const char* szResultsFile = "Results.txt";
+#ifdef __sparc__
+const int PAGESIZE = 8192;
+#else // __sparc__
+const int PAGESIZE = 4096;
+#endif // __sparc__
+
+BOOL writeTest(DWORD dwByteCount, DWORD dwBytesWrittenResult, BOOL bResult)
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ BOOL bRc = FALSE;
+
+ /* create the test file */
+ DeleteFile(szWritableFile);
+ hFile = CreateFile(szWritableFile, GENERIC_WRITE, FILE_SHARE_WRITE,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("WriteFile: ERROR -> Unable to create file \"%s\".\n",
+ szWritableFile);
+ return FALSE;
+ }
+
+ bRc = WriteFile(hFile, writeBuffer, dwByteCount, &dwBytesWritten, NULL);
+ CloseHandle(hFile);
+
+ if ((bRc != bResult) || (dwBytesWrittenResult != dwBytesWritten))
+ {
+ Trace("WriteFile returned BOOL:%d and dwWritten:%d what we do expect is"
+ " BOOL:%d and dwWritten:%d\n", bRc, dwBytesWritten, bResult,
+ dwBytesWrittenResult);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char * testString = "The quick fox jumped over the lazy dog's back.";
+ const int testStringLen = strlen(testString);
+
+ DWORD dwByteCount[4] = {-1, 10, testStringLen, 0};
+ DWORD dwByteWritten[4] = {0, 10, testStringLen, 0};
+ BOOL bResults[] = {FALSE, TRUE, TRUE, TRUE};
+
+ const int BUFFER_SIZE = 2 * PAGESIZE;
+ int j;
+ BOOL bRc = FALSE;
+ DWORD oldProt;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* allocate read-write memery for writeBuffer */
+ if (!(writeBuffer = (char*) VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT,
+ PAGE_READWRITE)))
+ {
+ Fail("VirtualAlloc failed: GetLastError returns %d\n", GetLastError());
+ return FAIL;
+ }
+
+ memset((void*) writeBuffer, '.', BUFFER_SIZE);
+ strcpy(writeBuffer, testString);
+
+ /* write protect the second page of writeBuffer */
+ if (!VirtualProtect(&writeBuffer[PAGESIZE], PAGESIZE, PAGE_NOACCESS, &oldProt))
+ {
+ Fail("VirtualProtect failed: GetLastError returns %d\n", GetLastError());
+ return FAIL;
+ }
+
+ for (j = 0; j< 4; j++)
+ {
+ bRc = writeTest(dwByteCount[j], dwByteWritten[j], bResults[j]);
+ if (bRc != TRUE)
+ {
+ Fail("WriteFile: ERROR -> Failed on test[%d]\n", j);
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/WriteFile/test2/testinfo.dat
new file mode 100644
index 0000000000..a09df962f3
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = WriteFile
+Name = Positive Test for WriteFile
+Type = DEFAULT
+EXE1 = writefile
+Description
+=Multiple tests of writes of varying sizes with verification
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt
new file mode 100644
index 0000000000..e16e8a48f6
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ WriteFile.c
+)
+
+add_executable(paltest_writefile_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_writefile_test3 coreclrpal)
+
+target_link_libraries(paltest_writefile_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c
new file mode 100644
index 0000000000..751f89ff2c
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c
@@ -0,0 +1,136 @@
+// 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: WriteFile.c (test 3)
+**
+** Purpose: Tests the PAL implementation of the WriteFile function.
+** Performs multiple writes to a file and verifies the results.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+const char* szStringTest = "The quick fox jumped over the lazy dog's back.\0";
+const char* szWritableFile = "writeable.txt";
+
+
+BOOL validateResults(const char* szString)
+{
+ FILE *pFile = NULL;
+ char szReadString[100];
+ DWORD dwBytesRead;
+ DWORD dwStringLength = strlen(szString);
+
+
+
+ memset(szReadString, 0, 100);
+
+ /* open the file */
+ pFile = fopen(szWritableFile, "r");
+ if (pFile == NULL)
+ {
+ Trace("couldn't open test file\n");
+ return FALSE;
+ }
+
+ dwBytesRead = fread(szReadString, sizeof(char), dwStringLength, pFile);
+ fclose(pFile);
+
+ if(dwBytesRead != dwStringLength)
+ {
+ Trace("dwbyteread != string length\n");
+ return FALSE;
+ }
+
+ if (strcmp(szReadString, szString))
+ {
+ Trace("read = %s string = %s", szReadString, szString);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+
+BOOL writeTest(const char* szString)
+{
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ BOOL bRc = FALSE;
+ BOOL bAllPassed = TRUE;
+ int nStringLength = 0;
+ char* szPtr = NULL;
+ int i = 0;
+
+ // create the test file
+ hFile = CreateFile(szWritableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Trace("WriteFile: ERROR -> Unable to create file \"%s\".\n",
+ szWritableFile);
+ return FALSE;
+ }
+
+ nStringLength = strlen(szString);
+ szPtr = (char*) szString;
+
+ for (i = 0; i < nStringLength; i++)
+ {
+ bRc = WriteFile(hFile, szPtr++, 1, &dwBytesWritten, NULL);
+ if ((bRc == FALSE) || (dwBytesWritten != 1))
+ {
+ bAllPassed = FALSE;
+ }
+ }
+ CloseHandle(hFile);
+
+ if (bAllPassed == FALSE)
+ {
+ Trace ("WriteFile: ERROR: Failed to write data.\n");
+ return FALSE;
+ }
+ else
+ {
+ return (validateResults(szString));
+ }
+
+ return TRUE;
+}
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char *pString = szStringTest;
+ BOOL bRc = FALSE;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ bRc = writeTest(pString);
+ if (bRc != TRUE)
+ {
+ Fail("WriteFile: ERROR -> Failed\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/WriteFile/test3/testinfo.dat
new file mode 100644
index 0000000000..e88e985b44
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test3/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = WriteFile
+Name = Positive Test for WriteFile
+Type = DEFAULT
+EXE1 = writefile
+Description
+=Multiple consecutive writes to a file with verification
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt
new file mode 100644
index 0000000000..fff886b430
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ writefile.c
+)
+
+add_executable(paltest_writefile_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_writefile_test4 coreclrpal)
+
+target_link_libraries(paltest_writefile_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/WriteFile/test4/testinfo.dat
new file mode 100644
index 0000000000..87ddf9d857
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test4/testinfo.dat
@@ -0,0 +1,13 @@
+# 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 = WriteFile
+Name = Positive Test for WriteFile
+Type = DEFAULT
+EXE1 = writefile
+Description
+= writes to a file at different locations with verification
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c b/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c
new file mode 100644
index 0000000000..47a0066ec9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c
@@ -0,0 +1,155 @@
+// 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: WriteFile.c (test 4)
+**
+** Purpose: Tests the PAL implementation of the WriteFile function.
+** Performs multiple writes to a file at different locations
+** then verifies the results with GetFileSize.
+**
+** dependency:
+** CreateFile.
+** GetFileSize.
+** FlushFileBuffers
+** SetFilePointer.
+** CloseHandle.
+** DeleteFile.
+**
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+BOOL CleanUp(HANDLE hFile, const char * fileName)
+{
+ BOOL bRc = TRUE;
+ if (CloseHandle(hFile) != TRUE)
+ {
+ bRc = FALSE;
+ Trace("WriteFile: ERROR -> Unable to close file \"%s\","
+ " error: %ld.\n", fileName, GetLastError());
+ }
+ if (!DeleteFileA(fileName))
+ {
+ bRc = FALSE;
+ Trace("WriteFile: ERROR -> Unable to delete file \"%s\","
+ " error: %ld.\n", fileName, GetLastError());
+ }
+ return bRc;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char* szStringTest = "1234567890";
+ const char* szWritableFile = "writeable.txt";
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the test file */
+ hFile = CreateFile(szWritableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("WriteFile: ERROR -> Unable to create file \"%s\".\n",
+ szWritableFile);
+ }
+
+
+ /* test wtriting to the file */
+ if( WriteFile(hFile, /* HANDLE handle to file */
+ szStringTest, /* data buffer */
+ strlen(szStringTest), /* number of bytes to write */
+ &dwBytesWritten, /* number of bytes written */
+ NULL) /* overlapped buffer */
+ ==0)
+ {
+ Trace("WriteFile: ERROR -> Unable to write to file error: %ld \n",
+ GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ if(!FlushFileBuffers(hFile))
+ { Trace("WriteFile: ERROR -> Call to FlushFile Buffers failed "
+ "error %ld \n",GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ /* check the file size */
+ if(GetFileSize(hFile, NULL)!=strlen(szStringTest))
+ {
+ Trace("WriteFile: ERROR -> writing %u chars to empty file "
+ "caused its size to become %u\n",strlen(szStringTest),
+ GetFileSize(hFile, NULL));
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ /* test writing to the file at position 5. */
+ SetFilePointer(
+ hFile, /* handle to file */
+ 0x5, /* bytes to move pointer */
+ NULL, /* bytes to move pointer */
+ FILE_BEGIN /* starting point */
+ );
+
+
+ if( WriteFile(hFile, /* HANDLE handle to file */
+ szStringTest, /* data buffer */
+ strlen(szStringTest), /* number of bytes to write */
+ &dwBytesWritten, /* number of bytes written */
+ NULL) /* overlapped buffer */
+ ==0)
+ {
+ Trace("WriteFile: ERROR -> Unable to write to file after "
+ " moiving the file poiner to 5 error: %ld \n",
+ GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+
+ if(!FlushFileBuffers(hFile))
+ {
+ Trace("WriteFile: ERROR -> Call to FlushFile Buffers failed "
+ "error %ld \n",GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ /* Check the file size */
+ if(GetFileSize(hFile, NULL)!=(strlen(szStringTest)+5))
+ {
+ Trace("WriteFile: ERROR -> writing %u chars to the file after "
+ "sitting the file pointer to 5 resulted in wrong file size; "
+ "Expected %u resulted %u.",strlen(szStringTest),
+ (strlen(szStringTest)+5),GetFileSize(hFile, NULL));
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ if (!CleanUp(hFile,szWritableFile))
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt
new file mode 100644
index 0000000000..978eb7f1e7
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ writefile.c
+)
+
+add_executable(paltest_writefile_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_writefile_test5 coreclrpal)
+
+target_link_libraries(paltest_writefile_test5
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test5/testinfo.dat b/src/pal/tests/palsuite/file_io/WriteFile/test5/testinfo.dat
new file mode 100644
index 0000000000..ffde30ea23
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/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 = WriteFile
+Name = Positive Test for WriteFile
+Type = DEFAULT
+EXE1 = writefile
+Description
+= write lots of data to a file. then check with
+= GetFileSize
+= This test is disabled due to its time overhead.
+
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c b/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c
new file mode 100644
index 0000000000..46920b3335
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c
@@ -0,0 +1,117 @@
+// 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: WriteFile.c (test 5)
+**
+** Purpose: Tests the PAL implementation of the WriteFile function.
+** Performs writing a huge file.
+**
+** dependency:
+** CreateFile.
+** GetFileSize.
+** FlushFileBuffers
+** CloseHandle
+** DeleteFile
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+BOOL CleanUp(HANDLE hFile, const char * fileName)
+{
+ BOOL bRc = TRUE;
+ if (CloseHandle(hFile) != TRUE)
+ {
+ bRc = FALSE;
+ Trace("WriteFile: ERROR -> Unable to close file \"%s\","
+ " error: %ld.\n", fileName, GetLastError());
+ }
+ if (!DeleteFileA(fileName))
+ {
+ bRc = FALSE;
+ Trace("WriteFile: ERROR -> Unable to delete file \"%s\","
+ " error: %ld.\n", fileName, GetLastError());
+ }
+ return bRc;
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE hFile = NULL;
+ DWORD dwBytesWritten;
+ const char* hugeStringTest =
+ "1234567890123456789012345678901234567890";
+ const char* szWritableFile = "writeable.txt";
+ int i =0;
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the test file */
+ hFile = CreateFile(szWritableFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ Fail("WriteFile: ERROR -> Unable to create file \"%s\".\n",
+ szWritableFile);
+ }
+
+ /* write 4000 000 chars to the file.*/
+ for (i=0; i<100000;i++)
+ {
+ if( WriteFile(hFile, /* HANDLE handle to file */
+ hugeStringTest, /* data buffer */
+ strlen(hugeStringTest), /* number of bytes to write */
+ &dwBytesWritten, /* number of bytes written */
+ NULL) /* overlapped buffer */
+ ==0)
+ {
+ Trace("WriteFile: ERROR -> Unable to write to file error: %ld \n",
+ GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+
+ }
+ }
+
+ if(!FlushFileBuffers(hFile))
+ {
+ Trace("WriteFile: ERROR -> Call to FlushFileBuffers failed"
+ "error %ld \n",GetLastError());
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+ }
+
+ /* test if the size changed properly. */
+ if(GetFileSize(hFile,NULL) != 4000000)
+ {
+ Trace("WriteFile: ERROR -> file size did not change properly"
+ " after writing 4000 000 chars to it ( size= %u )\n",
+ GetFileSize(hFile,NULL));
+ CleanUp(hFile,szWritableFile);
+ Fail("");
+
+ }
+
+ if (!CleanUp(hFile,szWritableFile))
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/CMakeLists.txt
new file mode 100644
index 0000000000..a3847f8ca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt
new file mode 100644
index 0000000000..91b7db1f03
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_errorpathnotfound_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_errorpathnotfound_test1 coreclrpal)
+
+target_link_libraries(paltest_errorpathnotfound_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c
new file mode 100644
index 0000000000..eaf3db3a30
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c
@@ -0,0 +1,783 @@
+// 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: test1.c
+
+**
+
+** Purpose: Test the return value of GetLastError() after calling
+
+** some file_io functions with an invalid path.
+
+**
+
+** Functions covered by this test are:
+
+** CopyFileA, CopyFileW, CreateFileA,CreateFileW,
+
+** DeleteFileA and DeleteFileW.
+
+**
+**
+
+
+
+**
+
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+
+{
+
+
+
+ BOOL testPass = TRUE;
+
+ BOOL bRc = TRUE;
+
+ HANDLE hFile;
+
+
+
+ const char* sBadFilePath = "bad/badPath.tmp";
+
+ const char* sBadFileName = "badName.tmp";
+
+ const char* sDest = "dest.tmp";
+
+ const WCHAR wBadFilePath[] =
+
+ {'w','b','a','d','/','b','a',
+
+ 'd','.','t','m','p','\0'};
+
+ const WCHAR wBadFileName[] =
+
+ {'w','B','a','d','.','t','m','p','\0'};
+
+ const WCHAR wDest[] =
+
+ {'w','d','e','s','t','.','t','m','p','\0'};
+
+
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+
+ {
+
+ return FAIL;
+
+ }
+
+
+
+ /*...................Test CopyFileW.............................*/
+
+
+
+ /* test with an invalid path */
+
+ bRc = CopyFileW(wBadFilePath,wDest,TRUE);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CopyFileW: calling GetLastError() after copying a file"
+
+ " with wrong path returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ bRc = CopyFileW(wBadFileName,wDest,TRUE);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("CopyFileW: calling GetLastError() after copying a file"
+
+ " with wrong name returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("CopyFileW: managed to copy a file with wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+
+
+ /*..................CopyFileA...................................*/
+
+
+
+ /* test with an invalid path */
+
+ bRc = CopyFileA(sBadFilePath,sDest,TRUE);
+
+ if(! bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CopyFileA: calling GetLastError() after copying a file"
+
+ " with wrong path returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("CopyFileA: managed to copy a file with wrong path\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with an invalid file name */
+
+ bRc = CopyFileA(sBadFileName,sDest,TRUE);
+
+ if(! bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("CopyFileA: calling GetLastError() after copying a file"
+
+ " with wrong name returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("CopyFileA: managed to copy a file with wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+
+
+ /*............. Test CreateFileA..................................*/
+
+
+
+ /* test with an invalid file name */
+
+ hFile = CreateFileA(sBadFileName,
+
+ GENERIC_READ, /* open for reading */
+
+ FILE_SHARE_READ, /* share for reading */
+
+ NULL, /* no security */
+
+ OPEN_EXISTING, /* existing file only */
+
+ FILE_ATTRIBUTE_NORMAL, /* normal file */
+
+ NULL); /* no attr. template */
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("CreateFileA: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad File Name\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateFileA: managed to create a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+
+
+ if(!CloseHandle(hFile))
+
+ {
+
+ Trace("CreateFileA: Call to CloseHandle failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+
+
+ }
+
+ if(!DeleteFile(sBadFileName))
+
+ {
+
+ Trace("CreateFileA: Call to DeleteFile failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+ }
+
+ }
+
+
+
+ /* test with an invalid path */
+
+ hFile = CreateFileA(sBadFilePath,
+
+ GENERIC_READ, /* open for reading */
+
+ FILE_SHARE_READ, /* share for reading */
+
+ NULL, /* no security */
+
+ OPEN_EXISTING, /* existing file only */
+
+ FILE_ATTRIBUTE_NORMAL, /* normal file */
+
+ NULL); /* no attr. template */
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CreateFileA: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad file path name\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateFileA: managed to create a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+ /*this should not happen*/
+
+ if(!CloseHandle(hFile))
+
+ {
+
+ Trace("CreateFileA: Call to CloseHandle Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+
+
+ }
+
+ if(!DeleteFile(sBadFilePath))
+
+ {
+
+ Trace("CreateFileA: Call to DeleteFile Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+ }
+
+ }
+
+
+
+
+
+
+
+
+
+ /*............. Test CreateFileW..................................*/
+
+
+
+ /* test with an invalid file name */
+
+ hFile = CreateFileW(wBadFileName,
+
+ GENERIC_READ, /* open for reading */
+
+ FILE_SHARE_READ, /* share for reading */
+
+ NULL, /* no security */
+
+ OPEN_EXISTING, /* existing file only */
+
+ FILE_ATTRIBUTE_NORMAL, /* normal file */
+
+ NULL); /* no attr. template */
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("CreateFileW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad filename\n",
+
+ GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateFileW: managed to create a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+
+
+ if(!CloseHandle(hFile))
+
+ {
+
+ Trace("CreateFileW: Call to CloseHandle Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+
+
+ }
+
+
+
+ if(!DeleteFileW(wBadFileName))
+
+ {
+
+ Trace("CreateFileW: Call to DeleteFile Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+ }
+
+ }
+
+
+
+
+
+
+
+ /* test with an invalid path */
+
+ hFile = CreateFileW(wBadFilePath,
+
+ GENERIC_READ, /* open for reading */
+
+ FILE_SHARE_READ, /* share for reading */
+
+ NULL, /* no security */
+
+ OPEN_EXISTING, /* existing file only */
+
+ FILE_ATTRIBUTE_NORMAL, /* normal file */
+
+ NULL); /* no attr. template */
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CreateFileW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad file path \n",
+
+ GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateFileW: managed to create a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+
+
+ if(!CloseHandle(hFile))
+
+ {
+
+ Trace("CreateFileW: Call to CloseHandle Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+
+
+ }
+
+ if(!DeleteFileW(wBadFilePath))
+
+ {
+
+ Trace("CreateFileW: Call to DeleteFile Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+ }
+
+ }
+
+
+
+
+
+
+
+ /* ............. DeleteFileW..................................*/
+
+
+
+ /* test with an invalid path */
+
+ if(DeleteFileW(wBadFilePath))
+
+ {
+
+ Trace("DeleteFileW: Call to DeleteFileW to delete a file"
+
+ " that does not exist succeeded\n");
+
+ testPass = FALSE;
+
+
+
+ }
+
+ else
+
+ {
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("DeleteFileW: Call GetLastError()returned "
+
+ "[%u] while it should return ERROR_PATH_NOT_FOUND [%u]\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+
+
+ }
+
+
+
+ }
+
+
+
+ /* test with an invalid file name */
+
+ if(DeleteFileW(wBadFileName))
+
+ {
+
+ Trace("DeleteFileW: Call to DeleteFileW to delete a file"
+
+ " that does not exist succeeded\n");
+
+ testPass = FALSE;
+
+
+
+ }
+
+ else
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("DeleteFileW: Call GetLastError()returned [%u]"
+
+ " while it should return ERROR_FILE_NOT_FOUND [%u]\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+
+
+ }
+
+
+
+ }
+
+
+
+
+
+ /* ............. DeleteFileA..................................*/
+
+
+
+ /* test with an invalid path */
+
+ if(DeleteFileA(sBadFilePath))
+
+ {
+
+ Trace("DeleteFileA: Call to DeleteFileA to delete a file"
+
+ " that does not exist succeeded\n");
+
+ testPass = FALSE;
+
+
+
+ }
+
+ else
+
+ {
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("DeleteFileA: Call GetLastError() returned [%u]"
+
+ " while it should return ERROR_PATH_NOT_FOUND [%u]\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+
+
+ }
+
+
+
+ }
+
+
+
+ /* test with an invalid file name */
+
+ if(DeleteFileA(sBadFileName))
+
+ {
+
+ Trace("DeleteFileA: Call to DeleteFileA to delete a file"
+
+ " that does not exist succeeded\n");
+
+ testPass = FALSE;
+
+
+
+ }
+
+ else
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("DeleteFileA: Call GetLastError() returned [%u]"
+
+ " while it should return ERROR_FILE_NOT_FOUND [%u]\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+
+
+ }
+
+
+
+ }
+
+
+
+
+
+
+
+ if(! testPass)
+
+ {
+
+ Fail("");
+
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+
+}
+
+
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/testinfo.dat
new file mode 100644
index 0000000000..dc1ddc96f1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/testinfo.dat
@@ -0,0 +1,31 @@
+# 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 = some File_io functions
+
+Name = errorpathnotfound - checking GetLastError.
+
+Type = DEFAULT
+
+EXE1 = test1
+
+Description
+
+= Test the return value of GetLastError() after calling
+
+= some file_io functions with an invalid path.
+
+= Functions covered by this test are:
+
+= CopyFile, CreateFile and DeleteFile.
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt
new file mode 100644
index 0000000000..7d525c21d5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_errorpathnotfound_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_errorpathnotfound_test2 coreclrpal)
+
+target_link_libraries(paltest_errorpathnotfound_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c
new file mode 100644
index 0000000000..5c2ab86b99
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c
@@ -0,0 +1,785 @@
+// 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: test2.c
+
+**
+
+** Purpose: Test the return value of GetLastError() after calling
+
+** some file_io functions with an invalid path.
+
+**
+
+** Functions covered by this test are:
+
+** MoveFileW, FindFirstFileA, FindFirstFileW,
+
+** GetFileAttributesA, GetFileAttributesW,
+
+** SetFileAttributesA, SetFileAttributesW.
+
+**
+**
+
+**
+
+
+
+**
+
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+
+{
+
+
+
+ BOOL testPass = TRUE;
+
+ BOOL bRc = TRUE;
+
+ HANDLE hFile;
+
+ WIN32_FIND_DATA findFileData;
+
+ WIN32_FIND_DATAW wFindFileData;
+
+ DWORD fileAttrib;
+
+
+
+ const char* sBadFilePath = "bad/badPath.tmp";
+
+ const char* sBadFileName = "badName.tmp";
+
+
+
+ const WCHAR wBadFilePath[] =
+
+ {'w','b','a','d','/','b','a',
+
+ 'd','.','t','m','p','\0'};
+
+ const WCHAR wBadFileName[] =
+
+ {'w','B','a','d','.','t','m','p','\0'};
+
+ const WCHAR wDest[] =
+
+ {'w','d','e','s','t','.','t','m','p','\0'};
+
+
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+
+ {
+
+ return FAIL;
+
+ }
+
+
+
+ /*...................Test MoveFileW.............................*/
+
+
+
+ /* test with an invalid path */
+
+ bRc = MoveFileW(wBadFilePath,wDest);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("MoveFileW: calling GetLastError() after moving a file"
+
+ " with wrong path returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ bRc = MoveFileW(wBadFileName,wDest);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("MoveFileW: calling GetLastError() after moving a file"
+
+ " with wrong name returned [%u] while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("MoveFileW: managed to move a file with wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /*............. Test FindFirstFileA..................................*/
+
+
+
+ /* test with an invalid file name */
+
+ hFile = FindFirstFileA(sBadFileName,&findFileData );
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("FindFirstFileA: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad File Name\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("FindFirstFileA: managed to find a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+
+
+ if(!FindClose(hFile))
+
+ {
+
+ Trace("FindFirstFileA: Call to FindClose failed with ErrorCode"
+
+ " [%u]\n", GetLastError());
+
+
+
+ }
+
+
+
+ }
+
+
+
+ /* test with an invalid path */
+
+ hFile = FindFirstFileA(sBadFilePath,&findFileData);
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("FindFirstFileA: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad file path name\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("FindFirstFileA: managed to find a file with an incorrect"
+
+ " filename\n");
+
+ testPass = FALSE;
+
+ /*this should not happen*/
+
+ if(!FindClose(hFile))
+
+ {
+
+ Trace("FindFirstFileA: Call to FindClose Failed with ErrorCode"
+
+ " [%u]\n", GetLastError());
+
+
+
+ }
+
+
+
+ }
+
+
+
+
+
+
+
+ /*............. Test FindFirstFileW..................................*/
+
+
+
+ /* test with an invalid file name */
+
+ hFile = FindFirstFileW(wBadFileName,&wFindFileData );
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("FindFirstFileW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad File Name\n",
+
+ GetLastError(),ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("FindFirstFileW: managed to find a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+
+
+ if(!FindClose(hFile))
+
+ {
+
+ Trace("FindFirstFileW: Call to FindClose failed with ErrorCode"
+
+ " [%u]\n", GetLastError());
+
+
+
+ }
+
+
+
+ }
+
+
+
+ /* test with an invalid path */
+
+ hFile = FindFirstFileW(wBadFilePath,&wFindFileData);
+
+
+
+ if (hFile == INVALID_HANDLE_VALUE)
+
+ {
+
+ if(GetLastError() != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("FindFirstFileW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad file path name\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("FindFirstFileW: managed to find a file with an incorrect "
+
+ "filename\n");
+
+ testPass = FALSE;
+
+ /*this should not happen*/
+
+ if(!FindClose(hFile))
+
+ {
+
+ Trace("FindFirstFileW: Call to FindClose Failed with ErrorCode "
+
+ "[%u]\n", GetLastError());
+
+
+
+ }
+
+
+
+ }
+
+
+
+
+
+ /*...................Test GetFileAttributesW.............................*/
+
+
+
+ /* test with an invalid path */
+
+ fileAttrib = GetFileAttributesW(wBadFilePath);
+
+ if(fileAttrib == -1)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("GetFileAttributesW: calling GetLastError() after getting"
+
+ " the attributes of a file with wrong path returned [%u]"
+
+ " while it should return [%u]\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetFileAttributesW: managed to get the attrib of a file"
+
+ " with wrong path\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ fileAttrib = GetFileAttributesW(wBadFileName);
+
+ if(fileAttrib == -1)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("GetFileAttributesW: calling GetLastError() after getting"
+
+ " the attributes of a file with wrong name returned [%u] "
+
+ "while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetFileAttributesW: managed to get the attrib of a file"
+
+ " with wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /*...................Test GetFileAttributesA.............................*/
+
+
+
+ /* test with an invalid path */
+
+ fileAttrib = GetFileAttributesA(sBadFilePath);
+
+ if(fileAttrib == -1)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("GetFileAttributesA: calling GetLastError() after getting"
+
+ " the attributes of a file with wrong path returned [%u] while"
+
+ " it should return [%u]\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetFileAttributesA: managed to get the attrib of a file"
+
+ " with wrong path\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ fileAttrib = GetFileAttributesA(sBadFileName);
+
+ if(fileAttrib == -1)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("GetFileAttributesA: calling GetLastError() after getting "
+
+ "the attributes of a file with wrong name returned [%u] "
+
+ "while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("GetFileAttributesA: managed to get the attrib of a file with"
+
+ " wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+
+
+
+
+ /*...................Test SetFileAttributesW.............................*/
+
+
+
+ /* test with an invalid path */
+
+ bRc = SetFileAttributesW(wBadFilePath,FILE_ATTRIBUTE_NORMAL);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("SetFileAttributesW: calling GetLastError() after setting"
+
+ " the attributes of a file with wrong path returned [%u] "
+
+ "while it should return [%u]\n",
+
+ GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("SetFileAttributesW: managed to get the attrib of a file"
+
+ " with wrong path\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ bRc = SetFileAttributesW(wBadFileName,FILE_ATTRIBUTE_NORMAL);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("SetFileAttributesW: calling GetLastError() after setting"
+
+ " the attributes of a file with wrong name returned [%u]"
+
+ " while it should return [%u]\n",
+
+ GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("SetFileAttributesW: managed to get the attrib of a file with"
+
+ " wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+ /*...................Test SetFileAttributesA.............................*/
+
+
+
+ /* test with an invalid path */
+
+ bRc = SetFileAttributesA(sBadFilePath,FILE_ATTRIBUTE_NORMAL);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("SetFileAttributesA: calling GetLastError() after setting "
+
+ "the attributes of a file with wrong path returned [%u] "
+
+ "while it should return [%u]\n"
+
+ ,GetLastError(), ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("SetFileAttributesA: managed to get the attrib of a file "
+
+ "with wrong path\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* test with invalid file name */
+
+ bRc = SetFileAttributesA(sBadFileName,FILE_ATTRIBUTE_NORMAL);
+
+ if(!bRc)
+
+ {
+
+ if(GetLastError()!= ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("SetFileAttributesA: calling GetLastError() after setting"
+
+ " the attributes of a file with wrong name returned [%u]"
+
+ " while it should return [%u]\n",
+
+ GetLastError(), ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+
+
+ }
+
+ else
+
+ {
+
+ Trace("SetFileAttributesA: managed to get the attrib of a file with "
+
+ "wrong name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+ if(! testPass)
+
+ {
+
+ Fail("");
+
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+
+}
+
+
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/testinfo.dat b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/testinfo.dat
new file mode 100644
index 0000000000..c5a61b949a
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/testinfo.dat
@@ -0,0 +1,34 @@
+# 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 = some File_io functions
+
+Name = errorpathnotfound - checking GetLastError.
+
+Type = DEFAULT
+
+EXE1 = test2
+
+Description
+
+= Test the return value of GetLastError() after calling
+
+= some file_io functions with an invalid path.
+
+= Functions covered by this test are:
+
+= MoveFileW, FindFirstFileA, FindFirstFileW,
+
+= GetFileAttributesA, GetFileAttributesW,
+
+= SetFileAttributesA, SetFileAttributesW.
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt
new file mode 100644
index 0000000000..c7434f3dba
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_errorpathnotfound_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_errorpathnotfound_test3 coreclrpal)
+
+target_link_libraries(paltest_errorpathnotfound_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c
new file mode 100644
index 0000000000..414cbab176
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c
@@ -0,0 +1,244 @@
+// 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: test3.c
+
+**
+
+** Purpose: Test the return value of GetLastError() after calling
+
+** some file_io functions with an invalid path.
+
+**
+
+** Functions covered by this test are:
+
+** CreateDirectoryA, CreateDirectoryW, RemoveDirectoryW,
+
+**
+**
+
+
+
+**
+
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+
+{
+
+
+
+ BOOL testPass = TRUE;
+
+ BOOL bRc = TRUE;
+
+ DWORD errCode;
+
+
+
+ const char* sBadSubDirectory = "bad/badDir";
+
+
+
+ /* Needed for RemoveDirectoryW */
+
+ const WCHAR tempName[] = {'b','a','d','/',
+
+ 'b','a','d','D','i','r'};
+
+
+
+ const WCHAR wBadSubDirectory[] =
+
+ {'w','b','a','d','/','b','a',
+
+ 'd','D','i','r','\0'};
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+
+ {
+
+ return FAIL;
+
+ }
+
+
+
+ /* ---------------------CreateDirectoryA------------------------- */
+
+
+
+
+
+ /* Testing of CreateDirectoryA */
+
+ bRc = CreateDirectoryA(sBadSubDirectory,NULL);
+
+ if(!bRc)
+
+ {
+
+ errCode = GetLastError();
+
+ if(errCode != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CreateDirectoryA: calling GetLastError() after creating a "
+
+ "directory with invalid path returned [%u] while it should "
+
+ "return [%u]\n",errCode, ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateDirectoryA: Created a directory with an invalid path.\n");
+
+ bRc = RemoveDirectoryW(tempName);
+
+ if(!bRc)
+
+ {
+
+ Trace("Failed to remove %s with error %u.\n",
+
+ sBadSubDirectory,GetLastError());
+
+ }
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* ---------------------CreateDirectoryW------------------------- */
+
+
+
+ /* Testing of CreateDirectoryW */
+
+ bRc = CreateDirectoryW(wBadSubDirectory,NULL);
+
+ if(!bRc)
+
+ {
+
+ errCode = GetLastError();
+
+ if(errCode != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("CreateDirectoryW: calling GetLastError() after creating a "
+
+ "directory with invalid path returned [%u] while it should "
+
+ "return [%u]\n",errCode, ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("CreateDirectoryW: Created a directory with an invalid path.\n");
+
+ bRc = RemoveDirectoryW(wBadSubDirectory);
+
+ if(!bRc)
+
+ {
+
+ Trace("Failed to remove %S with error %u.\n",
+
+ wBadSubDirectory,GetLastError());
+
+ }
+
+ testPass = FALSE;
+
+ }
+
+
+
+ /* ---------------------RemoveDirectoryW------------------------ */
+
+
+
+ /* Testing of RemoveDirectoryW */
+
+ bRc = RemoveDirectoryW(wBadSubDirectory);
+
+ if(!bRc)
+
+ {
+
+ errCode = GetLastError();
+
+ if(errCode != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("RemoveDirectoryW: calling GetLastError() after removing a "
+
+ "sub directory with invalid path returned [%u] while it should "
+
+ "return [%u]\n",errCode, ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("RemoveDirectoryW: Removed a directory that did not exist.\n");
+
+ }
+
+ int exitCode = testPass ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+
+
+
+
+
+
+
+
+
+
+}
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/testinfo.dat b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/testinfo.dat
new file mode 100644
index 0000000000..7a9019f17b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/testinfo.dat
@@ -0,0 +1,30 @@
+# 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 = some File_io functions
+
+Name = errorpathnotfound - checking GetLastError.
+
+Type = DEFAULT
+
+EXE1 = test3
+
+Description
+
+= Test the return value of GetLastError() after calling
+
+= some file_io functions with an invalid path.
+
+= Functions covered by this test are:
+
+= CreateDirectory, RemoveDirectory
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt
new file mode 100644
index 0000000000..f8062fd127
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.c
+)
+
+add_executable(paltest_errorpathnotfound_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_errorpathnotfound_test4 coreclrpal)
+
+target_link_libraries(paltest_errorpathnotfound_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c
new file mode 100644
index 0000000000..e1b68995b0
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c
@@ -0,0 +1,351 @@
+// 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: test4.c
+
+**
+
+** Purpose: Test the return value of GetLastError() after calling
+
+** some file_io functions with an invalid path.
+
+**
+
+** Functions covered by this test are:
+
+** GetDiskFreeSpaceW, GetTempFileNameA
+
+** and GetTempFileNameW
+
+**
+**
+
+**
+
+
+
+**
+
+**===================================================================*/
+
+
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+
+{
+
+
+
+ BOOL testPass = TRUE;
+
+ BOOL bRc = TRUE;
+
+ DWORD lastErr=-50;
+
+ DWORD dwSectorsPerCluster_02; /* sectors per cluster */
+
+ DWORD dwBytesPerSector_02; /* bytes per sector */
+
+ DWORD dwNumberOfFreeClusters; /* free clusters */
+
+ DWORD dwTotalNumberOfClusters; /* total clusters */
+
+
+
+ UINT uiError = 0;
+
+ char szReturnedName[256];
+
+ const UINT uUnique = 0;
+
+ const char* sDot = {"tmpr"};
+
+ const char* sPrefix = {"cfr"};
+
+
+
+ WCHAR wzReturnedName[256];
+
+ const WCHAR wDot[] = {'t','m','p','r','\0'};
+
+ const WCHAR wPrefix[] = {'c','f','r','\0'};
+
+
+
+
+
+ const WCHAR wBadFilePath[] =
+
+ {'w','b','a','d','/','b','a',
+
+ 'd','.','t','m','p','\0'};
+
+ const WCHAR wBadFileName[] =
+
+ {'w','B','a','d','.','t','m','p','\0'};
+
+
+
+
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+
+ {
+
+ return FAIL;
+
+ }
+
+
+
+ /* test .................. GetDiskFreeSpaceW .................. */
+
+
+
+ /* test with invalid file name */
+
+ bRc = GetDiskFreeSpaceW(wBadFileName,
+
+ &dwSectorsPerCluster_02,
+
+ &dwBytesPerSector_02,
+
+ &dwNumberOfFreeClusters,
+
+ &dwTotalNumberOfClusters);
+
+ if (bRc != TRUE)
+
+
+
+ {
+
+ lastErr=GetLastError();
+
+
+
+ if(lastErr != ERROR_FILE_NOT_FOUND)
+
+ {
+
+ Trace("GetDiskFreeSpaceW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad File Name\n",
+
+ lastErr,ERROR_FILE_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetDiskFreeSpaceW: GetDiskFreeSpaceW succeeded when given "
+
+ "a bad fileName\n");
+
+ testPass = FALSE;
+
+
+
+ }
+
+
+
+
+
+ /* test with invalid path name */
+
+ bRc = GetDiskFreeSpaceW(wBadFilePath,
+
+ &dwSectorsPerCluster_02,
+
+ &dwBytesPerSector_02,
+
+ &dwNumberOfFreeClusters,
+
+ &dwTotalNumberOfClusters);
+
+ if (bRc != TRUE)
+
+
+
+ {
+
+ lastErr=GetLastError();
+
+ if(lastErr != ERROR_PATH_NOT_FOUND)
+
+ {
+
+ Trace("GetDiskFreeSpaceW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for a bad File Name\n",
+
+ lastErr,ERROR_PATH_NOT_FOUND);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetDiskFreeSpaceW: GetDiskFreeSpaceW succeeded when given "
+
+ "a bad fileName\n");
+
+ testPass = FALSE;
+
+
+
+
+
+ }
+
+
+
+
+
+ /* test .................. GetTempFileNameA .................. */
+
+
+
+ /* test with invalid path name */
+
+ uiError = GetTempFileNameA(sDot, sPrefix, uUnique, szReturnedName);
+
+ if (uiError == 0)
+
+ {
+
+ lastErr=GetLastError();
+
+ if(lastErr != ERROR_DIRECTORY)
+
+ {
+
+
+
+ Trace("GetTempFileNameA: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for invalid path name\n",
+
+ lastErr,ERROR_DIRECTORY);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetTempFileNameA: GetTempFileNameA succeeded when given "
+
+ "invalid path name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+
+
+
+
+ /* test .................. GetTempFileNameW .................. */
+
+
+
+ /* test with invalid path name */
+
+ uiError = GetTempFileNameW(wDot, wPrefix, uUnique, wzReturnedName);
+
+ if (uiError == 0)
+
+ {
+
+ lastErr=GetLastError();
+
+ if(lastErr != ERROR_DIRECTORY)
+
+ {
+
+
+
+ Trace("GetTempFileNameW: calling GetLastError() returned [%u] "
+
+ "while it should return [%u] for an invalid path name\n",
+
+ lastErr,ERROR_DIRECTORY);
+
+ testPass = FALSE;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ Trace("GetTempFileNameW: GetTempFileNameW succeeded when given"
+
+ " an invalid path name\n");
+
+ testPass = FALSE;
+
+ }
+
+
+
+ if(! testPass)
+
+ {
+
+ Fail("");
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PAL_Terminate();
+
+ return PASS;
+
+}
+
+
+
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/testinfo.dat b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/testinfo.dat
new file mode 100644
index 0000000000..d7b707fca9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/testinfo.dat
@@ -0,0 +1,34 @@
+# 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 = some File_io functions
+
+Name = errorpathnotfound - checking GetLastError.
+
+Type = DEFAULT
+
+EXE1 = test4
+
+Description
+
+= Test the return value of GetLastError() after calling
+
+= some file_io functions with an invalid path.
+
+= Functions covered by this test are:
+
+= MoveFIlew, FindFirstFileA, FindFirstFileW,
+
+= GetFileAttributesA, GetFileAttributesW,
+
+= SetFileAttributesA, SetFileAttributesW.
+
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/CMakeLists.txt b/src/pal/tests/palsuite/file_io/gettemppatha/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt
new file mode 100644
index 0000000000..2aff599e74
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ gettemppatha.c
+)
+
+add_executable(paltest_gettemppatha_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_gettemppatha_test1 coreclrpal)
+
+target_link_libraries(paltest_gettemppatha_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c b/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c
new file mode 100644
index 0000000000..b0da528af8
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c
@@ -0,0 +1,103 @@
+// 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: gettemppatha.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempPathA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+static void SetTmpDir(CHAR path[])
+{
+ DWORD result = SetEnvironmentVariableA("TMPDIR", path);
+ if (!result)
+ {
+ Fail("ERROR -> SetEnvironmentVariableA failed with result %d and error code %d.\n",
+ result, GetLastError());
+ }
+}
+
+static void SetAndCompare(CHAR tmpDirPath[], CHAR expected[])
+{
+ DWORD dwBufferLength = _MAX_DIR;
+ CHAR path[dwBufferLength];
+
+ SetTmpDir(tmpDirPath);
+
+ DWORD dwResultLen = GetTempPathA(dwBufferLength, path);
+ if (dwResultLen <= 0)
+ {
+ Fail("ERROR: GetTempPathA returned %d with error code %d.\n", dwResultLen, GetLastError());
+ }
+ if (dwResultLen >= dwBufferLength)
+ {
+ Fail("ERROR: Buffer of length %d passed to GetTempPathA was too small to hold %d chars..\n", dwBufferLength, dwResultLen);
+ }
+ if (strcmp(expected, path) != 0)
+ {
+ Fail("ERROR: GetTempPathA expected to get '%s' but instead got '%s'.\n", expected, path);
+ }
+ if (expected[dwResultLen - 1] != '/')
+ {
+ Fail("ERROR: GetTempPathA returned '%s', which should have ended in '/'.\n", path);
+ }
+}
+
+static void SetAndCheckLength(CHAR tmpDirPath[], int bufferLength, int expectedResultLength)
+{
+ CHAR path[bufferLength];
+
+ SetTmpDir(tmpDirPath);
+ DWORD dwResultLen = GetTempPathA(bufferLength, path);
+
+ if (dwResultLen != expectedResultLength)
+ {
+ Fail("GetTempPathA(%d, %s) expected to return %d but returned %d.\n",
+ bufferLength, tmpDirPath?tmpDirPath:"NULL", expectedResultLength, dwResultLen);
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ SetAndCompare("/tmp", "/tmp/");
+ SetAndCompare("/tmp/", "/tmp/");
+ SetAndCompare("", "/tmp/");
+ SetAndCompare(NULL, "/tmp/");
+ SetAndCompare("/", "/");
+ SetAndCompare("/var/tmp", "/var/tmp/");
+ SetAndCompare("/var/tmp/", "/var/tmp/");
+ SetAndCompare("~", "~/");
+ SetAndCompare("~/", "~/");
+ SetAndCompare(".tmp", ".tmp/");
+ SetAndCompare("./tmp", "./tmp/");
+ SetAndCompare("/home/someuser/sometempdir", "/home/someuser/sometempdir/");
+ SetAndCompare(NULL, "/tmp/");
+
+ DWORD dwResultLen = GetTempPathA(0, NULL);
+ if (dwResultLen != 0 || GetLastError() != ERROR_INVALID_PARAMETER)
+ {
+ Fail("GetTempPath(NULL, ...) returned %d with error code %d but "
+ "should have failed with ERROR_INVALID_PARAMETER (%d).\n",
+ dwResultLen, GetLastError(), ERROR_INVALID_PARAMETER);
+ }
+
+ SetAndCheckLength("abc/", 5, 4);
+ SetAndCheckLength("abcd", 5, 6);
+ SetAndCheckLength("abcde", 5, 7);
+ SetAndCheckLength("abcdef/", 5, 9);
+ SetAndCheckLength(NULL, 5, 6);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/test1/testinfo.dat b/src/pal/tests/palsuite/file_io/gettemppatha/test1/testinfo.dat
new file mode 100644
index 0000000000..71f8bef651
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/test1/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 = GetTempPathA
+Name = Test for GetTempPathA (test 1)
+Type = DEFAULT
+EXE1 = gettemppatha
+Description
+= Calls GetTempPathA and verifies by passing the returned
+= value to CreateDirectoryA. If the returned path exists,
+= CreateDirectoryA will fail.
+