3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
8 ** Class: FileSystemInfo
10 ** <OWNER>Microsoft</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 && MONO_FEATURE_CAS
34 [FileIOPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)]
37 #if FEATURE_REMOTING || MONO
38 public abstract class FileSystemInfo : MarshalByRefObject, ISerializable
40 #else // FEATURE_REMOTING
41 public abstract class FileSystemInfo : ISerializable
43 #endif //FEATURE_REMOTING
45 internal MonoIOStat _data;
47 [System.Security.SecurityCritical] // auto-generated
48 internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information
50 internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed
51 // we store a zero, on failure we store the HResult in it so that we can
52 // give back a generic error back.
54 private const int ERROR_INVALID_PARAMETER = 87;
55 internal const int ERROR_ACCESS_DENIED = 0x5;
57 protected String FullPath; // fully qualified path of the directory
58 protected String OriginalPath; // path passed in by the user
59 private String _displayPath = ""; // path that can be displayed to the user
62 #if FEATURE_CORESYSTEM
63 [System.Security.SecurityCritical]
65 [System.Security.SecuritySafeCritical]
66 #endif //FEATURE_CORESYSTEM
68 protected FileSystemInfo()
72 [ResourceExposure(ResourceScope.None)]
73 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
74 protected FileSystemInfo(SerializationInfo info, StreamingContext context)
77 throw new ArgumentNullException("info");
78 Contract.EndContractBlock();
80 // Must use V1 field names here, since V1 didn't implement
82 FullPath = Path.GetFullPathInternal(info.GetString("FullPath"));
83 OriginalPath = info.GetString("OriginalPath");
85 // Lazily initialize the file attributes.
86 _dataInitialised = -1;
89 [System.Security.SecurityCritical]
90 internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData)
93 throw new NotImplementedException ();
95 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
96 _data.PopulateFrom(findData);
101 // Full path of the direcory/file
102 public virtual string FullName
104 [SecuritySafeCritical]
109 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, FullPath);
110 sourceState.EnsureState();
112 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
119 internal virtual string UnsafeGetFullName
126 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
133 public String Extension
137 // GetFullPathInternal would have already stripped out the terminating "." if present.
138 int length = FullPath.Length;
139 for (int i = length; --i >= 0;) {
140 char ch = FullPath[i];
142 return FullPath.Substring(i, length - i);
143 if (ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar)
150 // For files name of the file is returned, for directories the last directory in hierarchy is returned if possible,
151 // otherwise the fully qualified name s returned
152 public abstract String Name {
156 // Whether a file/directory exists
157 public abstract bool Exists
162 // Delete a file/directory
163 public abstract void Delete();
165 public DateTime CreationTime
168 // depends on the security check in get_CreationTimeUtc
169 return CreationTimeUtc.ToLocalTime();
173 CreationTimeUtc = value.ToUniversalTime();
178 public DateTime CreationTimeUtc {
179 [System.Security.SecuritySafeCritical]
182 // get_CreationTime also depends on this security check
183 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
184 sourceState.EnsureState();
186 if (_dataInitialised == -1) {
188 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
193 if (_dataInitialised != 0) // Refresh was unable to initialise the data
194 __Error.WinIOError(_dataInitialised, DisplayPath);
197 long fileTime = _data.CreationTime;
199 long fileTime = ((long)_data.ftCreationTimeHigh << 32) | _data.ftCreationTimeLow;
201 return DateTime.FromFileTimeUtc(fileTime);
205 [ResourceExposure(ResourceScope.None)]
206 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
208 if (this is DirectoryInfo)
209 Directory.SetCreationTimeUtc(FullPath,value);
211 File.SetCreationTimeUtc(FullPath,value);
212 _dataInitialised = -1;
217 public DateTime LastAccessTime
220 // depends on the security check in get_LastAccessTimeUtc
221 return LastAccessTimeUtc.ToLocalTime();
224 LastAccessTimeUtc = value.ToUniversalTime();
229 public DateTime LastAccessTimeUtc {
230 [System.Security.SecuritySafeCritical]
233 // get_LastAccessTime also depends on this security check
234 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
235 sourceState.EnsureState();
237 if (_dataInitialised == -1) {
239 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
244 if (_dataInitialised != 0) // Refresh was unable to initialise the data
245 __Error.WinIOError(_dataInitialised, DisplayPath);
248 long fileTime = _data.LastAccessTime;
250 long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow;
252 return DateTime.FromFileTimeUtc(fileTime);
256 [ResourceExposure(ResourceScope.None)]
257 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
259 if (this is DirectoryInfo)
260 Directory.SetLastAccessTimeUtc(FullPath,value);
262 File.SetLastAccessTimeUtc(FullPath,value);
263 _dataInitialised = -1;
267 public DateTime LastWriteTime
270 // depends on the security check in get_LastWriteTimeUtc
271 return LastWriteTimeUtc.ToLocalTime();
275 LastWriteTimeUtc = value.ToUniversalTime();
280 public DateTime LastWriteTimeUtc {
281 [System.Security.SecuritySafeCritical]
284 // get_LastWriteTime also depends on this security check
285 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
286 sourceState.EnsureState();
288 if (_dataInitialised == -1) {
290 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
295 if (_dataInitialised != 0) // Refresh was unable to initialise the data
296 __Error.WinIOError(_dataInitialised, DisplayPath);
299 long fileTime = _data.LastWriteTime;
301 long fileTime = ((long)_data.ftLastWriteTimeHigh << 32) | _data.ftLastWriteTimeLow;
303 return DateTime.FromFileTimeUtc(fileTime);
306 [ResourceExposure(ResourceScope.None)]
307 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
309 if (this is DirectoryInfo)
310 Directory.SetLastWriteTimeUtc(FullPath,value);
312 File.SetLastWriteTimeUtc(FullPath,value);
313 _dataInitialised = -1;
317 [System.Security.SecuritySafeCritical] // auto-generated
318 [ResourceExposure(ResourceScope.None)]
319 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
320 public void Refresh()
322 _dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false);
325 public FileAttributes Attributes {
326 [System.Security.SecuritySafeCritical]
330 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
331 sourceState.EnsureState();
333 if (_dataInitialised == -1) {
335 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
337 Refresh(); // Call refresh to intialise the data
340 if (_dataInitialised != 0) // Refresh was unable to initialise the data
341 __Error.WinIOError(_dataInitialised, DisplayPath);
343 return (FileAttributes) _data.fileAttributes;
346 [System.Security.SecurityCritical] // auto-generated
348 [System.Security.SecuritySafeCritical]
353 FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, FullPath);
358 if (!MonoIO.SetFileAttributes (FullPath, value, out error)) {
359 int hr = (int) error;
361 bool r = Win32Native.SetFileAttributes(FullPath, (int) value);
363 int hr = Marshal.GetLastWin32Error();
366 if (hr==ERROR_INVALID_PARAMETER)
367 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
369 // For whatever reason we are turning ERROR_ACCESS_DENIED into
370 // ArgumentException here (probably done for some 9x code path).
371 // We can't change this now but special casing the error message instead.
372 if (hr == ERROR_ACCESS_DENIED)
373 throw new ArgumentException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
374 __Error.WinIOError(hr, DisplayPath);
376 _dataInitialised = -1;
380 [System.Security.SecurityCritical] // auto-generated_required
382 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
386 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
390 info.AddValue("OriginalPath", OriginalPath, typeof(String));
391 info.AddValue("FullPath", FullPath, typeof(String));
394 internal String DisplayPath
402 _displayPath = value;