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)]
37 #if FEATURE_REMOTING || MONO
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)
91 throw new NotImplementedException ();
93 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
94 _data.PopulateFrom(findData);
99 // Full path of the direcory/file
100 public virtual String FullName {
101 [System.Security.SecuritySafeCritical]
104 #pragma warning disable 219
106 #pragma warning restore
107 if (this is DirectoryInfo)
108 demandDir = Directory.GetDemandDir(FullPath, true);
110 demandDir = FullPath;
113 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir);
114 sourceState.EnsureState();
116 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
123 internal virtual String UnsafeGetFullName
125 [System.Security.SecurityCritical]
128 #pragma warning disable 219
130 #pragma warning restore
131 if (this is DirectoryInfo)
132 demandDir = Directory.GetDemandDir(FullPath, true);
134 demandDir = FullPath;
137 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
144 public String Extension
148 // GetFullPathInternal would have already stripped out the terminating "." if present.
149 int length = FullPath.Length;
150 for (int i = length; --i >= 0;) {
151 char ch = FullPath[i];
153 return FullPath.Substring(i, length - i);
154 if (ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar)
161 // For files name of the file is returned, for directories the last directory in hierarchy is returned if possible,
162 // otherwise the fully qualified name s returned
163 public abstract String Name {
167 // Whether a file/directory exists
168 public abstract bool Exists
173 // Delete a file/directory
174 public abstract void Delete();
176 public DateTime CreationTime
179 // depends on the security check in get_CreationTimeUtc
180 return CreationTimeUtc.ToLocalTime();
184 CreationTimeUtc = value.ToUniversalTime();
189 public DateTime CreationTimeUtc {
190 [System.Security.SecuritySafeCritical]
193 // get_CreationTime also depends on this security check
194 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
195 sourceState.EnsureState();
197 if (_dataInitialised == -1) {
199 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
204 if (_dataInitialised != 0) // Refresh was unable to initialise the data
205 __Error.WinIOError(_dataInitialised, DisplayPath);
208 long fileTime = _data.CreationTime;
210 long fileTime = ((long)_data.ftCreationTimeHigh << 32) | _data.ftCreationTimeLow;
212 return DateTime.FromFileTimeUtc(fileTime);
216 [ResourceExposure(ResourceScope.None)]
217 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
219 if (this is DirectoryInfo)
220 Directory.SetCreationTimeUtc(FullPath,value);
222 File.SetCreationTimeUtc(FullPath,value);
223 _dataInitialised = -1;
228 public DateTime LastAccessTime
231 // depends on the security check in get_LastAccessTimeUtc
232 return LastAccessTimeUtc.ToLocalTime();
235 LastAccessTimeUtc = value.ToUniversalTime();
240 public DateTime LastAccessTimeUtc {
241 [System.Security.SecuritySafeCritical]
244 // get_LastAccessTime also depends on this security check
245 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
246 sourceState.EnsureState();
248 if (_dataInitialised == -1) {
250 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
255 if (_dataInitialised != 0) // Refresh was unable to initialise the data
256 __Error.WinIOError(_dataInitialised, DisplayPath);
259 long fileTime = _data.LastAccessTime;
261 long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow;
263 return DateTime.FromFileTimeUtc(fileTime);
267 [ResourceExposure(ResourceScope.None)]
268 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
270 if (this is DirectoryInfo)
271 Directory.SetLastAccessTimeUtc(FullPath,value);
273 File.SetLastAccessTimeUtc(FullPath,value);
274 _dataInitialised = -1;
278 public DateTime LastWriteTime
281 // depends on the security check in get_LastWriteTimeUtc
282 return LastWriteTimeUtc.ToLocalTime();
286 LastWriteTimeUtc = value.ToUniversalTime();
291 public DateTime LastWriteTimeUtc {
292 [System.Security.SecuritySafeCritical]
295 // get_LastWriteTime also depends on this security check
296 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
297 sourceState.EnsureState();
299 if (_dataInitialised == -1) {
301 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
306 if (_dataInitialised != 0) // Refresh was unable to initialise the data
307 __Error.WinIOError(_dataInitialised, DisplayPath);
310 long fileTime = _data.LastWriteTime;
312 long fileTime = ((long)_data.ftLastWriteTimeHigh << 32) | _data.ftLastWriteTimeLow;
314 return DateTime.FromFileTimeUtc(fileTime);
317 [ResourceExposure(ResourceScope.None)]
318 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
320 if (this is DirectoryInfo)
321 Directory.SetLastWriteTimeUtc(FullPath,value);
323 File.SetLastWriteTimeUtc(FullPath,value);
324 _dataInitialised = -1;
328 [System.Security.SecuritySafeCritical] // auto-generated
329 [ResourceExposure(ResourceScope.None)]
330 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
331 public void Refresh()
333 _dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false);
336 public FileAttributes Attributes {
337 [System.Security.SecuritySafeCritical]
341 FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
342 sourceState.EnsureState();
344 if (_dataInitialised == -1) {
346 _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
348 Refresh(); // Call refresh to intialise the data
351 if (_dataInitialised != 0) // Refresh was unable to initialise the data
352 __Error.WinIOError(_dataInitialised, DisplayPath);
354 return (FileAttributes) _data.fileAttributes;
357 [System.Security.SecurityCritical] // auto-generated
359 [System.Security.SecuritySafeCritical]
364 FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, FullPath);
369 if (!MonoIO.SetFileAttributes (FullPath, value, out error)) {
370 int hr = (int) error;
372 bool r = Win32Native.SetFileAttributes(FullPath, (int) value);
374 int hr = Marshal.GetLastWin32Error();
377 if (hr==ERROR_INVALID_PARAMETER)
378 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs"));
380 // For whatever reason we are turning ERROR_ACCESS_DENIED into
381 // ArgumentException here (probably done for some 9x code path).
382 // We can't change this now but special casing the error message instead.
383 if (hr == ERROR_ACCESS_DENIED)
384 throw new ArgumentException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
385 __Error.WinIOError(hr, DisplayPath);
387 _dataInitialised = -1;
391 [System.Security.SecurityCritical] // auto-generated_required
393 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
397 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
401 info.AddValue("OriginalPath", OriginalPath, typeof(String));
402 info.AddValue("FullPath", FullPath, typeof(String));
405 internal String DisplayPath
413 _displayPath = value;