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