1 /* 2 Copyright 2020, Dirk Krause. All rights reserved. 3 SPDX-License-Identifier: BSD-3-Clause 4 */ 5 6 #ifndef DK4FILEIT_H_INCLUDED 7 /** Protection against multiple inclusions. */ 8 #define DK4FILEIT_H_INCLUDED 1 9 10 /** @file dk4fileit.h File information data type. 11 12 The dk4_file_info_t data type and related functions allow to 13 properly identify a path name as symbolic link on both non-Windows 14 and Windows systems. 15 16 On non-Windows systems calls to stat() and lstat() are used to 17 retrieve the information. 18 19 On Windows systems calls to GetFileAttributes(), 20 CreateFile()/GetFileInformationByHandle() 21 and FindFirstFile() are used. 22 As the involved data types are Windows-specific the windows.h 23 header file is pulled in by this header. 24 25 The Windows functions to retrieve information about files differ: 26 - GetFileAttributes() returns a DWORD containing bits for 27 file attributes only. 28 - From CreateFile()/GetFileInformationByHandle() we can receive 29 very detailed information. 30 - From FindFirstFile() we can retrieve some of the information 31 also provided by CreateFile()/GetFileInformationByHandle(), but 32 number of links, volume serial number, and file index are not 33 available. 34 Unfortunately the functions behave differently: While FindFirstFile() 35 succeeds for c:/pagefile.sys and other files in the root directory, 36 GetFileAttributes() and CreateFile()/GetFileInformationByHandle() 37 fail in non-privileged processes. Some forum messages state that 38 FindFirstFile() is significantly faster than 39 CreateFile()/GetFileInformationByHandle(), at least for files on servers. 40 When called for a symbolic link, FindFirstFile() always returns information 41 about the link. For CreateFile()/GetFileInformationByHandle() one can 42 choose whether to obtain information about the or about the target. 43 44 So the dk4fileinfo() function attempts GetFileAttributes() and 45 CreateFile()/GetFileInformationByHandle() first to obtain detailed 46 information. If these functions fail, the FindFirstFile() function is 47 used. If only FindFirstFile() returned successfully, the resio 48 component is set to a non-zero value to indicate that only restricted 49 information (without number of links, volume serial number, and 50 file index) is available. 51 */ 52 53 #ifndef DK4CONF_H_INCLUDED 54 #if DK4_BUILDING_DKTOOLS4 55 #include "dk4conf.h" 56 #else 57 #include <dktools-4/dk4conf.h> 58 #endif 59 #endif 60 61 #if DK4_ON_WINDOWS 62 #ifndef WINDOWS_H_INCLUDED 63 #include <windows.h> 64 #define WINDOWS_H_INCLUDED 1 65 #endif 66 #endif 67 68 #ifndef DK4STATT_H_INCLUDED 69 #if DK4_BUILDING_DKTOOLS4 70 #include <libdk4c/dk4statt.h> 71 #else 72 #include <dktools-4/dk4statt.h> 73 #endif 74 #endif 75 76 77 /** File information contents found. 78 */ 79 enum { 80 /** Information about the link 81 from lstat(). 82 */ 83 DK4_FILE_INFO_CONTENTS_DATA_LINK = 1, 84 85 /** Information about the link 86 target from stat(). 87 */ 88 DK4_FILE_INFO_CONTENTS_DATA_TARGET = 2 89 }; 90 91 /** Choose timestamp to convert to text. 92 */ 93 enum { 94 /** Creation time. 95 */ 96 DK4_FILE_INFO_TIME_CREATE = 1, 97 98 /** Modification time. 99 */ 100 DK4_FILE_INFO_TIME_MODIFY , 101 102 /** Last access time. 103 */ 104 DK4_FILE_INFO_TIME_ACCESS 105 }; 106 107 /** File information data type. 108 */ 109 typedef struct { 110 int contents; /**< The available contents. */ 111 #if DK4_ON_WINDOWS 112 BY_HANDLE_FILE_INFORMATION linfo; /**< Information about link. */ 113 BY_HANDLE_FILE_INFORMATION tinfo; /**< Information about target. */ 114 DWORD fattr; /**< Link file attributes. */ 115 DWORD rppnt; /**< Link reparse point tag. */ 116 DWORD resio; /**< Flag: Restricted information. */ 117 #else 118 dk4_stat_t lstb; /**< Buffer for lstat(). */ 119 dk4_stat_t tstb; /**< Buffer for stat(). */ 120 #endif 121 } dk4_file_info_t; 122 123 #endif 124 125