3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
8 ** Class: FileSystemInfo
10 ** <OWNER>[....]</OWNER>
16 ===========================================================*/
19 using System.Collections;
20 using System.Security;
22 using System.Security.Permissions;
24 using Microsoft.Win32;
26 using System.Runtime.InteropServices;
27 using System.Runtime.Serialization;
28 using System.Runtime.Versioning;
29 using System.Diagnostics.Contracts;
33 #if !FEATURE_CORECLR && FEATURE_MONO_CAS
34 [FileIOPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)]
38 public abstract class FileSystemInfo : MarshalByRefObject, ISerializable {
39 #else // FEATURE_REMOTING
40 public abstract class FileSystemInfo : ISerializable {
41 #endif //FEATURE_REMOTING
43 internal MonoIOStat _data;
45 [System.Security.SecurityCritical] // auto-generated
46 internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information
48 internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed
49 // we store a zero, on failure we store the HResult in it so that we can
50 // give back a generic error back.
52 private const int ERROR_INVALID_PARAMETER = 87;
53 internal const int ERROR_ACCESS_DENIED = 0x5;
55 protected String FullPath; // fully qualified path of the directory
56 protected String OriginalPath; // path passed in by the user
57 private String _displayPath = ""; // path that can be displayed to the user
60 #if FEATURE_CORESYSTEM
61 [System.Security.SecurityCritical]
63 [System.Security.SecuritySafeCritical]
64 #endif //FEATURE_CORESYSTEM
66 protected FileSystemInfo()
70 [ResourceExposure(ResourceScope.None)]
71 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
72 protected FileSystemInfo(SerializationInfo info, StreamingContext context)
75 throw new ArgumentNullException("info");
76 Contract.EndContractBlock();
78 // Must use V1 field names here, since V1 didn't implement
80 FullPath = Path.GetFullPathInternal(info.GetString("FullPath"));
81 OriginalPath = info.GetString("OriginalPath");
83 // Lazily initialize the file attributes.
84 _dataInitialised = -1;
87 [System.Security.SecurityCritical]
88 internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData)
90 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
91 _data.PopulateFrom(findData);
95 // Full path of the direcory/file
96 public virtual String FullName {
97 [System.Security.SecuritySafeCritical]
101 if (this is DirectoryInfo)
102 demandDir = Directory.GetDemandDir(FullPath, true);
104 demandDir = FullPath;
107 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir);
108 sourceState.EnsureState();
110 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
117 internal virtual String UnsafeGetFullName
119 [System.Security.SecurityCritical]
123 if (this is DirectoryInfo)
124 demandDir = Directory.GetDemandDir(FullPath, true);
126 demandDir = FullPath;
129 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
136 public String Extension
140 // GetFullPathInternal would have already stripped out the terminating "." if present.
141 int length = FullPath.Length;
142 for (int i = length; --i >= 0;) {
143 char ch = FullPath[i];
145 return FullPath.Substring(i, length - i);
146 if (ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar)
153 // For files name of the file is returned, for directories the last directory in hierarchy is returned if possible,
154 // otherwise the fully qualified name s returned
155 public abstract String Name {
159 // Whether a file/directory exists
160 public abstract bool Exists
165 // Delete a file/directory
166 public abstract void Delete();
168 public DateTime CreationTime
171 // depends on the security check in get_CreationTimeUtc
172 return CreationTimeUtc.ToLocalTime();
176 CreationTimeUtc = value.ToUniversalTime();
181 public DateTime CreationTimeUtc {
182 [System.Security.SecuritySafeCritical]
185 // get_CreationTime also depends on this security check
186 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
187 sourceState.EnsureState();
189 if (_dataInitialised == -1) {
191 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
196 if (_dataInitialised != 0) // Refresh was unable to initialise the data
197 __Error.WinIOError(_dataInitialised, DisplayPath);
200 long fileTime = _data.CreationTime;
202 long fileTime = ((long)_data.ftCreationTimeHigh << 32) | _data.ftCreationTimeLow;
204 return DateTime.FromFileTimeUtc(fileTime);
208 [ResourceExposure(ResourceScope.None)]
209 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
211 if (this is DirectoryInfo)
212 Directory.SetCreationTimeUtc(FullPath,value);
214 File.SetCreationTimeUtc(FullPath,value);
215 _dataInitialised = -1;
220 public DateTime LastAccessTime
223 // depends on the security check in get_LastAccessTimeUtc
224 return LastAccessTimeUtc.ToLocalTime();
227 LastAccessTimeUtc = value.ToUniversalTime();
232 public DateTime LastAccessTimeUtc {
233 [System.Security.SecuritySafeCritical]
236 // get_LastAccessTime also depends on this security check
237 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
238 sourceState.EnsureState();
240 if (_dataInitialised == -1) {
242 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
247 if (_dataInitialised != 0) // Refresh was unable to initialise the data
248 __Error.WinIOError(_dataInitialised, DisplayPath);
251 long fileTime = _data.LastAccessTime;
253 long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow;
255 return DateTime.FromFileTimeUtc(fileTime);
259 [ResourceExposure(ResourceScope.None)]
260 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
262 if (this is DirectoryInfo)
263 Directory.SetLastAccessTimeUtc(FullPath,value);
265 File.SetLastAccessTimeUtc(FullPath,value);
266 _dataInitialised = -1;
270 public DateTime LastWriteTime
273 // depends on the security check in get_LastWriteTimeUtc
274 return LastWriteTimeUtc.ToLocalTime();
278 LastWriteTimeUtc = value.ToUniversalTime();
283 public DateTime LastWriteTimeUtc {
284 [System.Security.SecuritySafeCritical]
287 // get_LastWriteTime also depends on this security check
288 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
289 sourceState.EnsureState();
291 if (_dataInitialised == -1) {
293 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
298 if (_dataInitialised != 0) // Refresh was unable to initialise the data
299 __Error.WinIOError(_dataInitialised, DisplayPath);
302 long fileTime = _data.LastWriteTime;
304 long fileTime = ((long)_data.ftLastWriteTimeHigh << 32) | _data.ftLastWriteTimeLow;
306 return DateTime.FromFileTimeUtc(fileTime);
309 [ResourceExposure(ResourceScope.None)]
310 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
312 if (this is DirectoryInfo)
313 Directory.SetLastWriteTimeUtc(FullPath,value);
315 File.SetLastWriteTimeUtc(FullPath,value);
316 _dataInitialised = -1;
320 [System.Security.SecuritySafeCritical] // auto-generated
321 [ResourceExposure(ResourceScope.None)]
322 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
323 public void Refresh()
325 _dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false);
328 public FileAttributes Attributes {
329 [System.Security.SecuritySafeCritical]
333 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
334 sourceState.EnsureState();
336 if (_dataInitialised == -1) {
338 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
340 Refresh(); // Call refresh to intialise the data
343 if (_dataInitialised != 0) // Refresh was unable to initialise the data
344 __Error.WinIOError(_dataInitialised, DisplayPath);
346 return (FileAttributes) _data.fileAttributes;
349 [System.Security.SecurityCritical] // auto-generated
351 [System.Security.SecuritySafeCritical]
356 FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, FullPath);
361 if (!MonoIO.SetFileAttributes (FullPath, value, out error)) {
362 int hr = (int) error;
364 bool r = Win32Native.SetFileAttributes(FullPath, (int) value);
366 int hr = Marshal.GetLastWin32Error();
369 if (hr==ERROR_INVALID_PARAMETER)
370 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
372 // For whatever reason we are turning ERROR_ACCESS_DENIED into
373 // ArgumentException here (probably done for some 9x code path).
374 // We can't change this now but special casing the error message instead.
375 if (hr == ERROR_ACCESS_DENIED)
376 throw new ArgumentException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
377 __Error.WinIOError(hr, DisplayPath);
379 _dataInitialised = -1;
383 [System.Security.SecurityCritical] // auto-generated_required
385 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
389 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
393 info.AddValue("OriginalPath", OriginalPath, typeof(String));
394 info.AddValue("FullPath", FullPath, typeof(String));
397 internal String DisplayPath
405 _displayPath = value;