/fstmerge/examples/Eraser/rev1386-1611-hyp/left-branch-1611/Eraser.Util/StreamInfo.cs

https://github.com/RoDaniel/featurehouse · C# · 282 lines · 282 code · 0 blank · 0 comment · 33 complexity · dbdcce261cf2791152530c62080dea09 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.Win32.SafeHandles;
  5. using System.IO;
  6. using System.ComponentModel;
  7. using System.Runtime.InteropServices;
  8. namespace Eraser.Util
  9. {
  10. public class StreamInfo
  11. {
  12. public StreamInfo(string path)
  13. {
  14. if (path.IndexOf(':') != path.LastIndexOf(':'))
  15. {
  16. int streamNameColon = path.IndexOf(':', path.IndexOf(':') + 1);
  17. fileName = path.Substring(0, streamNameColon);
  18. streamName = path.Substring(streamNameColon + 1);
  19. }
  20. else
  21. {
  22. fileName = path;
  23. }
  24. }
  25. public DirectoryInfo Directory
  26. {
  27. get
  28. {
  29. return new DirectoryInfo(DirectoryName);
  30. }
  31. }
  32. public string DirectoryName
  33. {
  34. get
  35. {
  36. return fileName.Substring(0, fileName.LastIndexOf(Path.DirectorySeparatorChar) + 1);
  37. }
  38. }
  39. public string FullName
  40. {
  41. get
  42. {
  43. if (streamName != null)
  44. return fileName + ':' + streamName;
  45. return fileName;
  46. }
  47. }
  48. public string Name
  49. {
  50. get { return fileName; }
  51. }
  52. public FileInfo File
  53. {
  54. get
  55. {
  56. if (streamName == null)
  57. return new FileInfo(fileName);
  58. return null;
  59. }
  60. }
  61. public FileAttributes Attributes
  62. {
  63. get { return (FileAttributes)NativeMethods.GetFileAttributes(FullName); }
  64. set { NativeMethods.SetFileAttributes(FullName, (uint)value); }
  65. }
  66. public bool Exists
  67. {
  68. get
  69. {
  70. using (SafeFileHandle handle = NativeMethods.CreateFile(
  71. FullName, NativeMethods.GENERIC_READ, NativeMethods.FILE_SHARE_READ,
  72. IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero))
  73. {
  74. if (!handle.IsInvalid)
  75. return true;
  76. int errorCode = Marshal.GetLastWin32Error();
  77. switch (errorCode)
  78. {
  79. case Win32ErrorCode.FileNotFound:
  80. return false;
  81. default:
  82. throw Win32ErrorCode.GetExceptionForWin32Error(errorCode);
  83. }
  84. }
  85. }
  86. }
  87. public bool IsReadOnly
  88. {
  89. get
  90. {
  91. return (Attributes & FileAttributes.ReadOnly) != 0;
  92. }
  93. set
  94. {
  95. if (value)
  96. Attributes |= FileAttributes.ReadOnly;
  97. else
  98. Attributes &= ~FileAttributes.ReadOnly;
  99. }
  100. }
  101. public long Length
  102. {
  103. get
  104. {
  105. long fileSize;
  106. using (SafeFileHandle handle = fileHandle)
  107. if (NativeMethods.GetFileSizeEx(handle, out fileSize))
  108. return fileSize;
  109. return 0;
  110. }
  111. }
  112. public DateTime LastAccessTime
  113. {
  114. get
  115. {
  116. DateTime creationTime, lastAccess, lastWrite;
  117. GetFileTime(out creationTime, out lastAccess, out lastWrite);
  118. return lastAccess;
  119. }
  120. set
  121. {
  122. SetFileTime(DateTime.MinValue, value, DateTime.MinValue);
  123. }
  124. }
  125. public DateTime LastWriteTime
  126. {
  127. get
  128. {
  129. DateTime creationTime, lastAccess, lastWrite;
  130. GetFileTime(out creationTime, out lastAccess, out lastWrite);
  131. return lastWrite;
  132. }
  133. set
  134. {
  135. SetFileTime(DateTime.MinValue, DateTime.MinValue, value);
  136. }
  137. }
  138. public DateTime CreationTime
  139. {
  140. get
  141. {
  142. DateTime creationTime, lastAccess, lastWrite;
  143. GetFileTime(out creationTime, out lastAccess, out lastWrite);
  144. return creationTime;
  145. }
  146. set
  147. {
  148. SetFileTime(value, DateTime.MinValue, DateTime.MinValue);
  149. }
  150. }
  151. private void GetFileTime(out DateTime creationTime, out DateTime lastAccess,
  152. out DateTime lastWrite)
  153. {
  154. SafeFileHandle handle = exclusiveHandle;
  155. bool ownsHandle = false;
  156. try
  157. {
  158. if (handle == null || handle.IsClosed || handle.IsInvalid)
  159. {
  160. handle = fileHandle;
  161. ownsHandle = true;
  162. }
  163. }
  164. catch (ObjectDisposedException)
  165. {
  166. handle = fileHandle;
  167. ownsHandle = true;
  168. }
  169. try
  170. {
  171. Util.File.GetFileTime(handle, out creationTime, out lastAccess, out lastWrite);
  172. }
  173. finally
  174. {
  175. if (ownsHandle)
  176. handle.Close();
  177. }
  178. }
  179. private void SetFileTime(DateTime creationTime, DateTime lastAccess, DateTime lastWrite)
  180. {
  181. SafeFileHandle handle = exclusiveHandle;
  182. bool ownsHandle = false;
  183. try
  184. {
  185. if (handle == null || handle.IsClosed || handle.IsInvalid)
  186. {
  187. handle = fileHandle;
  188. ownsHandle = true;
  189. }
  190. }
  191. catch (ObjectDisposedException)
  192. {
  193. handle = fileHandle;
  194. ownsHandle = true;
  195. }
  196. try
  197. {
  198. Util.File.SetFileTime(handle, creationTime, lastAccess, lastWrite);
  199. }
  200. finally
  201. {
  202. if (ownsHandle)
  203. handle.Close();
  204. }
  205. }
  206. public void Delete()
  207. {
  208. if (streamName == null)
  209. File.Delete();
  210. else
  211. if (!NativeMethods.DeleteFile(FullName))
  212. throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error());
  213. }
  214. public FileStream Open(FileMode mode)
  215. {
  216. return Open(mode, FileAccess.ReadWrite, FileShare.None, FileOptions.None);
  217. }
  218. public FileStream Open(FileMode mode, FileAccess access)
  219. {
  220. return Open(mode, access, FileShare.None, FileOptions.None);
  221. }
  222. public FileStream Open(FileMode mode, FileAccess access, FileShare share)
  223. {
  224. return Open(mode, access, share, FileOptions.None);
  225. }
  226. public FileStream Open(FileMode mode, FileAccess access, FileShare share,
  227. FileOptions options)
  228. {
  229. SafeFileHandle handle = OpenHandle(mode, access, share, options);
  230. if (handle.IsInvalid)
  231. throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
  232. return new FileStream(handle, access);
  233. }
  234. private SafeFileHandle OpenHandle(FileMode mode, FileAccess access, FileShare share,
  235. FileOptions options)
  236. {
  237. uint iAccess = 0;
  238. switch (access)
  239. {
  240. case FileAccess.Read:
  241. iAccess = NativeMethods.GENERIC_READ;
  242. break;
  243. case FileAccess.ReadWrite:
  244. iAccess = NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE;
  245. break;
  246. case FileAccess.Write:
  247. iAccess = NativeMethods.GENERIC_WRITE;
  248. break;
  249. }
  250. if ((share & FileShare.Inheritable) != 0)
  251. throw new NotSupportedException("Inheritable handles are not supported.");
  252. if ((options & FileOptions.Asynchronous) != 0)
  253. throw new NotSupportedException("Asynchronous handles are not implemented.");
  254. SafeFileHandle result = NativeMethods.CreateFile(FullName, iAccess,
  255. (uint)share, IntPtr.Zero, (uint)mode, (uint)options, IntPtr.Zero);
  256. if (result.IsInvalid)
  257. {
  258. int errorCode = Marshal.GetLastWin32Error();
  259. result.Close();
  260. throw Win32ErrorCode.GetExceptionForWin32Error(errorCode);
  261. }
  262. if (share == FileShare.None)
  263. exclusiveHandle = result;
  264. return result;
  265. }
  266. public override string ToString()
  267. {
  268. return FullName;
  269. }
  270. private SafeFileHandle fileHandle
  271. {
  272. get
  273. {
  274. return OpenHandle(FileMode.Open, FileAccess.Read, FileShare.ReadWrite |
  275. FileShare.Delete, FileOptions.None);
  276. }
  277. }
  278. private SafeFileHandle exclusiveHandle;
  279. private string fileName;
  280. private string streamName;
  281. }
  282. }