You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1325 lines
88 KiB

  1. /* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. using System;
  22. using System.Diagnostics.CodeAnalysis;
  23. using System.Globalization;
  24. using System.IO;
  25. using System.Runtime.InteropServices;
  26. using System.Security;
  27. namespace Alphaleonis.Win32.Filesystem
  28. {
  29. public static partial class File
  30. {
  31. #region Copy
  32. #region .NET
  33. /// <summary>Copies an existing file to a new file. Overwriting a file of the same name is not allowed.</summary>
  34. /// <remarks>
  35. /// <para>The attributes of the original file are retained in the copied file.</para>
  36. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  37. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  38. /// </remarks>
  39. /// <exception cref="ArgumentException"/>
  40. /// <exception cref="ArgumentNullException"/>
  41. /// <exception cref="DirectoryNotFoundException"/>
  42. /// <exception cref="FileNotFoundException"/>
  43. /// <exception cref="IOException"/>
  44. /// <exception cref="NotSupportedException"/>
  45. /// <exception cref="UnauthorizedAccessException"/>
  46. /// <param name="sourceFileName">The file to copy.</param>
  47. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory or an existing file.</param>
  48. [SecurityCritical]
  49. public static void Copy(string sourceFileName, string destinationFileName)
  50. {
  51. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath);
  52. }
  53. /// <summary>Copies an existing file to a new file. Overwriting a file of the same name is allowed.</summary>
  54. /// <remarks>
  55. /// <para>The attributes of the original file are retained in the copied file.</para>
  56. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  57. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  58. /// </remarks>
  59. /// <exception cref="ArgumentException"/>
  60. /// <exception cref="ArgumentNullException"/>
  61. /// <exception cref="DirectoryNotFoundException"/>
  62. /// <exception cref="FileNotFoundException"/>
  63. /// <exception cref="IOException"/>
  64. /// <exception cref="NotSupportedException"/>
  65. /// <exception cref="UnauthorizedAccessException"/>
  66. /// <param name="sourceFileName">The file to copy. </param>
  67. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  68. /// <param name="overwrite"><see langword="true"/> if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, <see langword="false"/>.</param>
  69. [SecurityCritical]
  70. public static void Copy(string sourceFileName, string destinationFileName, bool overwrite)
  71. {
  72. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath);
  73. }
  74. #endregion // .NET
  75. #region AlphaFS
  76. #region Non-Transactional
  77. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed.</summary>
  78. /// <remarks>
  79. /// <para>The attributes of the original file are retained in the copied file.</para>
  80. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  81. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  82. /// </remarks>
  83. /// <exception cref="ArgumentException"/>
  84. /// <exception cref="ArgumentNullException"/>
  85. /// <exception cref="DirectoryNotFoundException"/>
  86. /// <exception cref="FileNotFoundException"/>
  87. /// <exception cref="IOException"/>
  88. /// <exception cref="NotSupportedException"/>
  89. /// <exception cref="UnauthorizedAccessException"/>
  90. /// <param name="sourceFileName">The file to copy. </param>
  91. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  92. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  93. [SecurityCritical]
  94. public static void Copy(string sourceFileName, string destinationFileName, PathFormat pathFormat)
  95. {
  96. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, pathFormat);
  97. }
  98. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed.</summary>
  99. /// <remarks>
  100. /// <para>The attributes of the original file are retained in the copied file.</para>
  101. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  102. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  103. /// </remarks>
  104. /// <exception cref="ArgumentException"/>
  105. /// <exception cref="ArgumentNullException"/>
  106. /// <exception cref="DirectoryNotFoundException"/>
  107. /// <exception cref="FileNotFoundException"/>
  108. /// <exception cref="IOException"/>
  109. /// <exception cref="NotSupportedException"/>
  110. /// <exception cref="UnauthorizedAccessException"/>
  111. /// <param name="sourceFileName">The file to copy. </param>
  112. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  113. /// <param name="overwrite"><see langword="true"/> if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, <see langword="false"/>.</param>
  114. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  115. [SecurityCritical]
  116. public static void Copy(string sourceFileName, string destinationFileName, bool overwrite, PathFormat pathFormat)
  117. {
  118. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat);
  119. }
  120. #endregion // Non-Transactional
  121. #region Transactional
  122. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed.</summary>
  123. /// <remarks>
  124. /// <para>The attributes of the original file are retained in the copied file.</para>
  125. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  126. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  127. /// </remarks>
  128. /// <exception cref="ArgumentException"/>
  129. /// <exception cref="ArgumentNullException"/>
  130. /// <exception cref="DirectoryNotFoundException"/>
  131. /// <exception cref="FileNotFoundException"/>
  132. /// <exception cref="IOException"/>
  133. /// <exception cref="NotSupportedException"/>
  134. /// <exception cref="UnauthorizedAccessException"/>
  135. /// <param name="transaction">The transaction.</param>
  136. /// <param name="sourceFileName">The file to copy.</param>
  137. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory or an existing file.</param>
  138. [SecurityCritical]
  139. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName)
  140. {
  141. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath);
  142. }
  143. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is not allowed.</summary>
  144. /// <remarks>
  145. /// <para>The attributes of the original file are retained in the copied file.</para>
  146. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  147. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  148. /// </remarks>
  149. /// <exception cref="ArgumentException"/>
  150. /// <exception cref="ArgumentNullException"/>
  151. /// <exception cref="DirectoryNotFoundException"/>
  152. /// <exception cref="FileNotFoundException"/>
  153. /// <exception cref="IOException"/>
  154. /// <exception cref="NotSupportedException"/>
  155. /// <exception cref="UnauthorizedAccessException"/>
  156. /// <param name="transaction">The transaction.</param>
  157. /// <param name="sourceFileName">The file to copy. </param>
  158. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  159. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  160. [SecurityCritical]
  161. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, PathFormat pathFormat)
  162. {
  163. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, CopyOptions.FailIfExists, null, null, null, null, pathFormat);
  164. }
  165. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed.</summary>
  166. /// <remarks>
  167. /// <para>The attributes of the original file are retained in the copied file.</para>
  168. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  169. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  170. /// </remarks>
  171. /// <exception cref="ArgumentException"/>
  172. /// <exception cref="ArgumentNullException"/>
  173. /// <exception cref="DirectoryNotFoundException"/>
  174. /// <exception cref="FileNotFoundException"/>
  175. /// <exception cref="IOException"/>
  176. /// <exception cref="NotSupportedException"/>
  177. /// <exception cref="UnauthorizedAccessException"/>
  178. /// <param name="transaction">The transaction.</param>
  179. /// <param name="sourceFileName">The file to copy. </param>
  180. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  181. /// <param name="overwrite"><see langword="true"/> if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, <see langword="false"/>.</param>
  182. [SecurityCritical]
  183. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, bool overwrite)
  184. {
  185. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, PathFormat.RelativePath);
  186. }
  187. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed.</summary>
  188. /// <remarks>
  189. /// <para>The attributes of the original file are retained in the copied file.</para>
  190. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  191. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  192. /// </remarks>
  193. /// <exception cref="ArgumentException"/>
  194. /// <exception cref="ArgumentNullException"/>
  195. /// <exception cref="DirectoryNotFoundException"/>
  196. /// <exception cref="FileNotFoundException"/>
  197. /// <exception cref="IOException"/>
  198. /// <exception cref="NotSupportedException"/>
  199. /// <exception cref="UnauthorizedAccessException"/>
  200. /// <param name="transaction">The transaction.</param>
  201. /// <param name="sourceFileName">The file to copy. </param>
  202. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  203. /// <param name="overwrite"><see langword="true"/> if the destination file should ignoring the read-only and hidden attributes and overwrite; otherwise, <see langword="false"/>.</param>
  204. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  205. [SecurityCritical]
  206. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, bool overwrite, PathFormat pathFormat)
  207. {
  208. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, overwrite ? CopyOptions.None : CopyOptions.FailIfExists, null, null, null, null, pathFormat);
  209. }
  210. #endregion // Transactional
  211. #endregion // AlphaFS
  212. #endregion // Copy
  213. #region Copy (CopyOptions)
  214. #region Non-Transactional
  215. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  216. /// <remarks>
  217. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  218. /// <para>The attributes of the original file are retained in the copied file.</para>
  219. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  220. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  221. /// </remarks>
  222. /// <exception cref="ArgumentException"/>
  223. /// <exception cref="ArgumentNullException"/>
  224. /// <exception cref="DirectoryNotFoundException"/>
  225. /// <exception cref="FileNotFoundException"/>
  226. /// <exception cref="IOException"/>
  227. /// <exception cref="NotSupportedException"/>
  228. /// <exception cref="UnauthorizedAccessException"/>
  229. /// <param name="sourceFileName">The file to copy.</param>
  230. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  231. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  232. [SecurityCritical]
  233. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions)
  234. {
  235. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, PathFormat.RelativePath);
  236. }
  237. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  238. /// <remarks>
  239. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  240. /// <para>The attributes of the original file are retained in the copied file.</para>
  241. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  242. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  243. /// </remarks>
  244. /// <exception cref="ArgumentException"/>
  245. /// <exception cref="ArgumentNullException"/>
  246. /// <exception cref="DirectoryNotFoundException"/>
  247. /// <exception cref="FileNotFoundException"/>
  248. /// <exception cref="IOException"/>
  249. /// <exception cref="NotSupportedException"/>
  250. /// <exception cref="UnauthorizedAccessException"/>
  251. /// <param name="sourceFileName">The file to copy.</param>
  252. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  253. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  254. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  255. [SecurityCritical]
  256. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, PathFormat pathFormat)
  257. {
  258. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, pathFormat);
  259. }
  260. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  261. /// <remarks>
  262. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  263. /// <para>The attributes of the original file are retained in the copied file.</para>
  264. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  265. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  266. /// </remarks>
  267. /// <exception cref="ArgumentException"/>
  268. /// <exception cref="ArgumentNullException"/>
  269. /// <exception cref="DirectoryNotFoundException"/>
  270. /// <exception cref="FileNotFoundException"/>
  271. /// <exception cref="IOException"/>
  272. /// <exception cref="NotSupportedException"/>
  273. /// <exception cref="UnauthorizedAccessException"/>
  274. /// <param name="sourceFileName">The file to copy.</param>
  275. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  276. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  277. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  278. [SecurityCritical]
  279. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates)
  280. {
  281. CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, PathFormat.RelativePath);
  282. }
  283. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  284. /// <remarks>
  285. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  286. /// <para>The attributes of the original file are retained in the copied file.</para>
  287. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  288. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  289. /// </remarks>
  290. /// <exception cref="ArgumentException"/>
  291. /// <exception cref="ArgumentNullException"/>
  292. /// <exception cref="DirectoryNotFoundException"/>
  293. /// <exception cref="FileNotFoundException"/>
  294. /// <exception cref="IOException"/>
  295. /// <exception cref="NotSupportedException"/>
  296. /// <exception cref="UnauthorizedAccessException"/>
  297. /// <param name="sourceFileName">The file to copy.</param>
  298. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  299. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  300. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  301. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  302. [SecurityCritical]
  303. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, PathFormat pathFormat)
  304. {
  305. CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, pathFormat);
  306. }
  307. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  308. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  309. /// </summary>
  310. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  311. /// <remarks>
  312. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  313. /// <para>The attributes of the original file are retained in the copied file.</para>
  314. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  315. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  316. /// </remarks>
  317. /// <exception cref="ArgumentException"/>
  318. /// <exception cref="ArgumentNullException"/>
  319. /// <exception cref="DirectoryNotFoundException"/>
  320. /// <exception cref="FileNotFoundException"/>
  321. /// <exception cref="IOException"/>
  322. /// <exception cref="NotSupportedException"/>
  323. /// <exception cref="UnauthorizedAccessException"/>
  324. /// <param name="sourceFileName">The file to copy.</param>
  325. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  326. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  327. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  328. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  329. [SecurityCritical]
  330. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  331. {
  332. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
  333. }
  334. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  335. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  336. /// </summary>
  337. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  338. /// <remarks>
  339. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  340. /// <para>The attributes of the original file are retained in the copied file.</para>
  341. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  342. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  343. /// </remarks>
  344. /// <exception cref="ArgumentException"/>
  345. /// <exception cref="ArgumentNullException"/>
  346. /// <exception cref="DirectoryNotFoundException"/>
  347. /// <exception cref="FileNotFoundException"/>
  348. /// <exception cref="IOException"/>
  349. /// <exception cref="NotSupportedException"/>
  350. /// <exception cref="UnauthorizedAccessException"/>
  351. /// <param name="sourceFileName">The file to copy.</param>
  352. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  353. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  354. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  355. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  356. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  357. [SecurityCritical]
  358. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  359. {
  360. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
  361. }
  362. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  363. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  364. /// </summary>
  365. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  366. /// <remarks>
  367. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  368. /// <para>The attributes of the original file are retained in the copied file.</para>
  369. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  370. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  371. /// </remarks>
  372. /// <exception cref="ArgumentException"/>
  373. /// <exception cref="ArgumentNullException"/>
  374. /// <exception cref="DirectoryNotFoundException"/>
  375. /// <exception cref="FileNotFoundException"/>
  376. /// <exception cref="IOException"/>
  377. /// <exception cref="NotSupportedException"/>
  378. /// <exception cref="UnauthorizedAccessException"/>
  379. /// <param name="sourceFileName">The file to copy.</param>
  380. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  381. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  382. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  383. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  384. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  385. [SecurityCritical]
  386. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
  387. {
  388. CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
  389. }
  390. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  391. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  392. /// </summary>
  393. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  394. /// <remarks>
  395. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  396. /// <para>The attributes of the original file are retained in the copied file.</para>
  397. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  398. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  399. /// </remarks>
  400. /// <exception cref="ArgumentException"/>
  401. /// <exception cref="ArgumentNullException"/>
  402. /// <exception cref="DirectoryNotFoundException"/>
  403. /// <exception cref="FileNotFoundException"/>
  404. /// <exception cref="IOException"/>
  405. /// <exception cref="NotSupportedException"/>
  406. /// <exception cref="UnauthorizedAccessException"/>
  407. /// <param name="sourceFileName">The file to copy.</param>
  408. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  409. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  410. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  411. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  412. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  413. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  414. [SecurityCritical]
  415. public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  416. {
  417. CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
  418. }
  419. #endregion // Non-Transactional
  420. #region Transactional
  421. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  422. /// <remarks>
  423. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  424. /// <para>The attributes of the original file are retained in the copied file.</para>
  425. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  426. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  427. /// </remarks>
  428. /// <exception cref="ArgumentException"/>
  429. /// <exception cref="ArgumentNullException"/>
  430. /// <exception cref="DirectoryNotFoundException"/>
  431. /// <exception cref="FileNotFoundException"/>
  432. /// <exception cref="IOException"/>
  433. /// <exception cref="NotSupportedException"/>
  434. /// <exception cref="UnauthorizedAccessException"/>
  435. /// <param name="transaction">The transaction.</param>
  436. /// <param name="sourceFileName">The file to copy.</param>
  437. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  438. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  439. [SecurityCritical]
  440. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions)
  441. {
  442. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, PathFormat.RelativePath);
  443. }
  444. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  445. /// <remarks>
  446. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  447. /// <para>The attributes of the original file are retained in the copied file.</para>
  448. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  449. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  450. /// </remarks>
  451. /// <exception cref="ArgumentException"/>
  452. /// <exception cref="ArgumentNullException"/>
  453. /// <exception cref="DirectoryNotFoundException"/>
  454. /// <exception cref="FileNotFoundException"/>
  455. /// <exception cref="IOException"/>
  456. /// <exception cref="NotSupportedException"/>
  457. /// <exception cref="UnauthorizedAccessException"/>
  458. /// <param name="transaction">The transaction.</param>
  459. /// <param name="sourceFileName">The file to copy.</param>
  460. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  461. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  462. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  463. [SecurityCritical]
  464. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, PathFormat pathFormat)
  465. {
  466. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, null, null, null, pathFormat);
  467. }
  468. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  469. /// <remarks>
  470. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  471. /// <para>The attributes of the original file are retained in the copied file.</para>
  472. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  473. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  474. /// </remarks>
  475. /// <exception cref="ArgumentException"/>
  476. /// <exception cref="ArgumentNullException"/>
  477. /// <exception cref="DirectoryNotFoundException"/>
  478. /// <exception cref="FileNotFoundException"/>
  479. /// <exception cref="IOException"/>
  480. /// <exception cref="NotSupportedException"/>
  481. /// <exception cref="UnauthorizedAccessException"/>
  482. /// <param name="transaction">The transaction.</param>
  483. /// <param name="sourceFileName">The file to copy.</param>
  484. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  485. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  486. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  487. [SecurityCritical]
  488. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates)
  489. {
  490. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, PathFormat.RelativePath);
  491. }
  492. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified.</summary>
  493. /// <remarks>
  494. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  495. /// <para>The attributes of the original file are retained in the copied file.</para>
  496. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  497. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  498. /// </remarks>
  499. /// <exception cref="ArgumentException"/>
  500. /// <exception cref="ArgumentNullException"/>
  501. /// <exception cref="DirectoryNotFoundException"/>
  502. /// <exception cref="FileNotFoundException"/>
  503. /// <exception cref="IOException"/>
  504. /// <exception cref="NotSupportedException"/>
  505. /// <exception cref="UnauthorizedAccessException"/>
  506. /// <param name="transaction">The transaction.</param>
  507. /// <param name="sourceFileName">The file to copy.</param>
  508. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  509. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  510. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  511. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  512. [SecurityCritical]
  513. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, PathFormat pathFormat)
  514. {
  515. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, null, null, null, pathFormat);
  516. }
  517. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  518. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  519. /// </summary>
  520. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  521. /// <remarks>
  522. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  523. /// <para>The attributes of the original file are retained in the copied file.</para>
  524. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  525. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  526. /// </remarks>
  527. /// <exception cref="ArgumentException"/>
  528. /// <exception cref="ArgumentNullException"/>
  529. /// <exception cref="DirectoryNotFoundException"/>
  530. /// <exception cref="FileNotFoundException"/>
  531. /// <exception cref="IOException"/>
  532. /// <exception cref="NotSupportedException"/>
  533. /// <exception cref="UnauthorizedAccessException"/>
  534. /// <param name="transaction">The transaction.</param>
  535. /// <param name="sourceFileName">The file to copy.</param>
  536. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  537. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  538. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  539. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  540. [SecurityCritical]
  541. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  542. {
  543. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
  544. }
  545. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  546. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  547. /// </summary>
  548. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  549. /// <remarks>
  550. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  551. /// <para>The attributes of the original file are retained in the copied file.</para>
  552. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  553. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  554. /// </remarks>
  555. /// <exception cref="ArgumentException"/>
  556. /// <exception cref="ArgumentNullException"/>
  557. /// <exception cref="DirectoryNotFoundException"/>
  558. /// <exception cref="FileNotFoundException"/>
  559. /// <exception cref="IOException"/>
  560. /// <exception cref="NotSupportedException"/>
  561. /// <exception cref="UnauthorizedAccessException"/>
  562. /// <param name="transaction">The transaction.</param>
  563. /// <param name="sourceFileName">The file to copy.</param>
  564. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  565. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  566. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  567. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  568. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  569. [SecurityCritical]
  570. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  571. {
  572. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
  573. }
  574. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  575. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  576. /// </summary>
  577. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  578. /// <remarks>
  579. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  580. /// <para>The attributes of the original file are retained in the copied file.</para>
  581. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  582. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  583. /// </remarks>
  584. /// <exception cref="ArgumentException"/>
  585. /// <exception cref="ArgumentNullException"/>
  586. /// <exception cref="DirectoryNotFoundException"/>
  587. /// <exception cref="FileNotFoundException"/>
  588. /// <exception cref="IOException"/>
  589. /// <exception cref="NotSupportedException"/>
  590. /// <exception cref="UnauthorizedAccessException"/>
  591. /// <param name="transaction">The transaction.</param>
  592. /// <param name="sourceFileName">The file to copy.</param>
  593. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  594. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  595. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  596. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  597. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  598. [SecurityCritical]
  599. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
  600. {
  601. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
  602. }
  603. /// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
  604. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  605. /// </summary>
  606. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  607. /// <remarks>
  608. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  609. /// <para>The attributes of the original file are retained in the copied file.</para>
  610. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  611. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  612. /// </remarks>
  613. /// <param name="transaction">The transaction.</param>
  614. /// <param name="sourceFileName">The file to copy.</param>
  615. /// <param name="destinationFileName">The name of the destination file. This cannot be a directory.</param>
  616. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  617. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise.</param>
  618. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  619. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  620. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  621. /// <exception cref="ArgumentException"/>
  622. /// <exception cref="ArgumentNullException"/>
  623. /// <exception cref="DirectoryNotFoundException"/>
  624. /// <exception cref="FileNotFoundException"/>
  625. /// <exception cref="IOException"/>
  626. /// <exception cref="NotSupportedException"/>
  627. /// <exception cref="UnauthorizedAccessException"/>
  628. [SecurityCritical]
  629. public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  630. {
  631. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
  632. }
  633. #endregion // Transactional
  634. #endregion // Copy (CopyOptions)
  635. #region Move
  636. #region .NET
  637. /// <summary>Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  638. /// <remarks>
  639. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  640. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  641. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  642. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  643. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  644. /// </remarks>
  645. /// <exception cref="ArgumentException"/>
  646. /// <exception cref="ArgumentNullException"/>
  647. /// <exception cref="DirectoryNotFoundException"/>
  648. /// <exception cref="FileNotFoundException"/>
  649. /// <exception cref="IOException"/>
  650. /// <exception cref="NotSupportedException"/>
  651. /// <exception cref="UnauthorizedAccessException"/>
  652. /// <param name="sourceFileName">The name of the file to move.</param>
  653. /// <param name="destinationFileName">The new path for the file.</param>
  654. [SecurityCritical]
  655. public static void Move(string sourceFileName, string destinationFileName)
  656. {
  657. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, PathFormat.RelativePath);
  658. }
  659. #endregion // .NET
  660. #region AlphaFS
  661. #region Non-Transactional
  662. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  663. /// <remarks>
  664. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  665. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  666. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  667. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  668. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  669. /// </remarks>
  670. /// <exception cref="ArgumentException"/>
  671. /// <exception cref="ArgumentNullException"/>
  672. /// <exception cref="DirectoryNotFoundException"/>
  673. /// <exception cref="FileNotFoundException"/>
  674. /// <exception cref="IOException"/>
  675. /// <exception cref="NotSupportedException"/>
  676. /// <exception cref="UnauthorizedAccessException"/>
  677. /// <param name="sourceFileName">The name of the file to move.</param>
  678. /// <param name="destinationFileName">The new path for the file.</param>
  679. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  680. [SecurityCritical]
  681. public static void Move(string sourceFileName, string destinationFileName, PathFormat pathFormat)
  682. {
  683. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, pathFormat);
  684. }
  685. #endregion // Non-Transactional
  686. #region Transactional
  687. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  688. /// <remarks>
  689. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  690. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  691. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  692. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  693. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  694. /// </remarks>
  695. /// <exception cref="ArgumentException"/>
  696. /// <exception cref="ArgumentNullException"/>
  697. /// <exception cref="DirectoryNotFoundException"/>
  698. /// <exception cref="FileNotFoundException"/>
  699. /// <exception cref="IOException"/>
  700. /// <exception cref="NotSupportedException"/>
  701. /// <exception cref="UnauthorizedAccessException"/>
  702. /// <param name="transaction">The transaction.</param>
  703. /// <param name="sourceFileName">The name of the file to move.</param>
  704. /// <param name="destinationFileName">The new path for the file.</param>
  705. [SecurityCritical]
  706. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName)
  707. {
  708. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, PathFormat.RelativePath);
  709. }
  710. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  711. /// <remarks>
  712. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  713. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  714. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  715. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  716. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  717. /// </remarks>
  718. /// <exception cref="ArgumentException"/>
  719. /// <exception cref="ArgumentNullException"/>
  720. /// <exception cref="DirectoryNotFoundException"/>
  721. /// <exception cref="FileNotFoundException"/>
  722. /// <exception cref="IOException"/>
  723. /// <exception cref="NotSupportedException"/>
  724. /// <exception cref="UnauthorizedAccessException"/>
  725. /// <param name="transaction">The transaction.</param>
  726. /// <param name="sourceFileName">The name of the file to move.</param>
  727. /// <param name="destinationFileName">The new path for the file.</param>
  728. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  729. [SecurityCritical]
  730. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, PathFormat pathFormat)
  731. {
  732. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, MoveOptions.CopyAllowed, null, null, null, pathFormat);
  733. }
  734. #endregion // Transactional
  735. #endregion // AlphaFS
  736. #endregion // Move
  737. #region Move (MoveOptions)
  738. #region Non-Transactional
  739. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  740. /// <remarks>
  741. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  742. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  743. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  744. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  745. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  746. /// </remarks>
  747. /// <exception cref="ArgumentException"/>
  748. /// <exception cref="ArgumentNullException"/>
  749. /// <exception cref="DirectoryNotFoundException"/>
  750. /// <exception cref="FileNotFoundException"/>
  751. /// <exception cref="IOException"/>
  752. /// <exception cref="NotSupportedException"/>
  753. /// <exception cref="UnauthorizedAccessException"/>
  754. /// <param name="sourceFileName">The name of the file to move.</param>
  755. /// <param name="destinationFileName">The new path for the file.</param>
  756. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  757. [SecurityCritical]
  758. public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions)
  759. {
  760. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, PathFormat.RelativePath);
  761. }
  762. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  763. /// <remarks>
  764. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  765. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  766. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  767. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  768. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  769. /// </remarks>
  770. /// <exception cref="ArgumentException"/>
  771. /// <exception cref="ArgumentNullException"/>
  772. /// <exception cref="DirectoryNotFoundException"/>
  773. /// <exception cref="FileNotFoundException"/>
  774. /// <exception cref="IOException"/>
  775. /// <exception cref="NotSupportedException"/>
  776. /// <exception cref="UnauthorizedAccessException"/>
  777. /// <param name="sourceFileName">The name of the file to move.</param>
  778. /// <param name="destinationFileName">The new path for the file.</param>
  779. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  780. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  781. [SecurityCritical]
  782. public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, PathFormat pathFormat)
  783. {
  784. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, pathFormat);
  785. }
  786. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  787. /// <returns>A <see cref="CopyMoveResult"/> class with the status of the Move action.</returns>
  788. /// <remarks>
  789. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  790. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  791. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  792. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  793. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  794. /// </remarks>
  795. /// <exception cref="ArgumentException"/>
  796. /// <exception cref="ArgumentNullException"/>
  797. /// <exception cref="DirectoryNotFoundException"/>
  798. /// <exception cref="FileNotFoundException"/>
  799. /// <exception cref="IOException"/>
  800. /// <exception cref="NotSupportedException"/>
  801. /// <exception cref="UnauthorizedAccessException"/>
  802. /// <param name="sourceFileName">The name of the file to move.</param>
  803. /// <param name="destinationFileName">The new path for the file.</param>
  804. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  805. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
  806. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  807. [SecurityCritical]
  808. public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  809. {
  810. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
  811. }
  812. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  813. /// <returns>A <see cref="CopyMoveResult"/> class with the status of the Move action.</returns>
  814. /// <remarks>
  815. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  816. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  817. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  818. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  819. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  820. /// </remarks>
  821. /// <exception cref="ArgumentException"/>
  822. /// <exception cref="ArgumentNullException"/>
  823. /// <exception cref="DirectoryNotFoundException"/>
  824. /// <exception cref="FileNotFoundException"/>
  825. /// <exception cref="IOException"/>
  826. /// <exception cref="NotSupportedException"/>
  827. /// <exception cref="UnauthorizedAccessException"/>
  828. /// <param name="sourceFileName">The name of the file to move.</param>
  829. /// <param name="destinationFileName">The new path for the file.</param>
  830. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  831. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
  832. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  833. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  834. [SecurityCritical]
  835. public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  836. {
  837. CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
  838. }
  839. #endregion // Non-Transactional
  840. #region Transactional
  841. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  842. /// <remarks>
  843. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  844. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  845. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  846. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  847. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  848. /// </remarks>
  849. /// <exception cref="ArgumentException"/>
  850. /// <exception cref="ArgumentNullException"/>
  851. /// <exception cref="DirectoryNotFoundException"/>
  852. /// <exception cref="FileNotFoundException"/>
  853. /// <exception cref="IOException"/>
  854. /// <exception cref="NotSupportedException"/>
  855. /// <exception cref="UnauthorizedAccessException"/>
  856. /// <param name="transaction">The transaction.</param>
  857. /// <param name="sourceFileName">The name of the file to move.</param>
  858. /// <param name="destinationFileName">The new path for the file.</param>
  859. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  860. [SecurityCritical]
  861. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions)
  862. {
  863. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, PathFormat.RelativePath);
  864. }
  865. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  866. /// <remarks>
  867. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  868. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  869. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  870. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  871. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  872. /// </remarks>
  873. /// <exception cref="ArgumentException"/>
  874. /// <exception cref="ArgumentNullException"/>
  875. /// <exception cref="DirectoryNotFoundException"/>
  876. /// <exception cref="FileNotFoundException"/>
  877. /// <exception cref="IOException"/>
  878. /// <exception cref="NotSupportedException"/>
  879. /// <exception cref="UnauthorizedAccessException"/>
  880. /// <param name="transaction">The transaction.</param>
  881. /// <param name="sourceFileName">The name of the file to move.</param>
  882. /// <param name="destinationFileName">The new path for the file.</param>
  883. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  884. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  885. [SecurityCritical]
  886. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, PathFormat pathFormat)
  887. {
  888. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, null, null, null, pathFormat);
  889. }
  890. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  891. /// <returns>A <see cref="CopyMoveResult"/> class with the status of the Move action.</returns>
  892. /// <remarks>
  893. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  894. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  895. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  896. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  897. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  898. /// </remarks>
  899. /// <exception cref="ArgumentException"/>
  900. /// <exception cref="ArgumentNullException"/>
  901. /// <exception cref="DirectoryNotFoundException"/>
  902. /// <exception cref="FileNotFoundException"/>
  903. /// <exception cref="IOException"/>
  904. /// <exception cref="NotSupportedException"/>
  905. /// <exception cref="UnauthorizedAccessException"/>
  906. /// <param name="transaction">The transaction.</param>
  907. /// <param name="sourceFileName">The name of the file to move.</param>
  908. /// <param name="destinationFileName">The new path for the file.</param>
  909. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  910. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
  911. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  912. [SecurityCritical]
  913. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  914. {
  915. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
  916. }
  917. /// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
  918. /// <returns>A <see cref="CopyMoveResult"/> class with the status of the Move action.</returns>
  919. /// <remarks>
  920. /// <para>This method works across disk volumes, and it does not throw an exception if the source and destination are the same.</para>
  921. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an <see cref="IOException"/>.</para>
  922. /// <para>You cannot use the Move method to overwrite an existing file.</para>
  923. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  924. /// <para>If two files have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  925. /// </remarks>
  926. /// <exception cref="ArgumentException"/>
  927. /// <exception cref="ArgumentNullException"/>
  928. /// <exception cref="DirectoryNotFoundException"/>
  929. /// <exception cref="FileNotFoundException"/>
  930. /// <exception cref="IOException"/>
  931. /// <exception cref="NotSupportedException"/>
  932. /// <exception cref="UnauthorizedAccessException"/>
  933. /// <param name="transaction">The transaction.</param>
  934. /// <param name="sourceFileName">The name of the file to move.</param>
  935. /// <param name="destinationFileName">The new path for the file.</param>
  936. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  937. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
  938. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  939. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  940. [SecurityCritical]
  941. public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  942. {
  943. CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
  944. }
  945. #endregion // Transactional
  946. #endregion // Move (MoveOptions)
  947. #region Internal Methods
  948. /// <summary>Determine the Copy or Move action.</summary>
  949. internal static bool DetermineIsCopy(CopyOptions? copyOptions, MoveOptions? moveOptions)
  950. {
  951. // Determine Copy or Move action.
  952. var isCopy = copyOptions != null;
  953. var isMove = !isCopy && moveOptions != null;
  954. if ((!isCopy && !isMove) || (isCopy && isMove))
  955. throw new NotSupportedException(Resources.Cannot_Determine_Copy_Or_Move);
  956. return isCopy;
  957. }
  958. /// <summary>Copy/move a Non-/Transacted file or directory including its children to a new location, <see cref="CopyOptions"/> or <see cref="MoveOptions"/> can be specified,
  959. /// and the possibility of notifying the application of its progress through a callback function.
  960. /// </summary>
  961. /// <returns>A <see cref="CopyMoveResult"/> class with the status of the Copy or Move action.</returns>
  962. /// <remarks>
  963. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  964. /// <para>You cannot use the Move method to overwrite an existing file, unless
  965. /// <paramref name="moveOptions"/> contains <see cref="MoveOptions.ReplaceExisting"/>.</para>
  966. /// <para>This Move method works across disk volumes, and it does not throw an exception if the
  967. /// source and destination are the same. </para>
  968. /// <para>Note that if you attempt to replace a file by moving a file of the same name into
  969. /// that directory, you get an IOException.</para>
  970. /// </remarks>
  971. /// <exception cref="ArgumentException"/>
  972. /// <exception cref="ArgumentNullException"/>
  973. /// <exception cref="DirectoryNotFoundException"/>
  974. /// <exception cref="FileNotFoundException"/>
  975. /// <exception cref="IOException"/>
  976. /// <exception cref="NotSupportedException"/>
  977. /// <exception cref="UnauthorizedAccessException"/>
  978. /// <param name="isFolder">Specifies that <paramref name="sourceFileName"/> and <paramref name="destinationFileName"/> are a file or directory.</param>
  979. /// <param name="transaction">The transaction.</param>
  980. /// <param name="sourceFileName">The source directory path.</param>
  981. /// <param name="destinationFileName">The destination directory path.</param>
  982. /// <param name="preserveDates"><see langword="true"/> if original Timestamps must be preserved, <see langword="false"/> otherwise. This parameter is ignored for move operations.</param>
  983. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  984. /// <param name="moveOptions">Flags that specify how the file or directory is to be moved. This parameter can be <see langword="null"/>.</param>
  985. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied/moved. This parameter can be <see langword="null"/>.</param>
  986. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  987. /// <param name="copyMoveResult"></param>
  988. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  989. [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
  990. [SecurityCritical]
  991. internal static CopyMoveResult CopyMoveCore(bool isFolder, KernelTransaction transaction, string sourceFileName, string destinationFileName, bool preserveDates, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, CopyMoveResult copyMoveResult, PathFormat pathFormat)
  992. {
  993. #region Setup
  994. var sourceFileNameLp = sourceFileName;
  995. var destFileNameLp = destinationFileName;
  996. if (pathFormat != PathFormat.LongFullPath)
  997. {
  998. Path.CheckSupportedPathFormat(sourceFileName, true, true);
  999. Path.CheckSupportedPathFormat(destinationFileName, true, true);
  1000. sourceFileNameLp = Path.GetExtendedLengthPathCore(transaction, sourceFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator);
  1001. destFileNameLp = Path.GetExtendedLengthPathCore(transaction, destinationFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator);
  1002. }
  1003. // Determine Copy or Move action.
  1004. var isCopy = DetermineIsCopy(copyOptions, moveOptions);
  1005. var isMove = !isCopy;
  1006. var cmr = copyMoveResult ?? new CopyMoveResult(sourceFileName, destinationFileName, false, (int) Win32Errors.ERROR_SUCCESS);
  1007. // MSDN: If this flag is set to TRUE during the copy/move operation, the operation is canceled.
  1008. // Otherwise, the copy/move operation will continue to completion.
  1009. bool cancel;
  1010. var raiseException = progressHandler == null;
  1011. // Setup callback function for progress notifications.
  1012. var routine = !raiseException
  1013. ? (totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, lpData) =>
  1014. progressHandler(totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, userProgressData)
  1015. : (NativeMethods.NativeCopyMoveProgressRoutine) null;
  1016. #endregion // Setup
  1017. startCopyMove:
  1018. #region Win32 Copy/Move
  1019. var success = transaction == null || !NativeMethods.IsAtLeastWindowsVista
  1020. ? isMove
  1021. // MoveFileWithProgress() / MoveFileTransacted()
  1022. // In the ANSI version of this function, the name is limited to MAX_PATH characters.
  1023. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
  1024. // 2013-04-15: MSDN confirms LongPath usage.
  1025. // CopyFileEx() / CopyFileTransacted()
  1026. // In the ANSI version of this function, the name is limited to MAX_PATH characters.
  1027. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
  1028. // 2013-04-15: MSDN confirms LongPath usage.
  1029. // Note: The NativeMethod.MoveFileXxx() methods fail if one of the paths is a UNC path, even though both paths refer to the same volume.
  1030. // For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst
  1031. ? NativeMethods.MoveFileWithProgress(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, (MoveOptions) moveOptions)
  1032. : NativeMethods.CopyFileEx(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, out cancel, (CopyOptions) copyOptions)
  1033. : isMove
  1034. ? NativeMethods.MoveFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, (MoveOptions) moveOptions, transaction.SafeHandle)
  1035. : NativeMethods.CopyFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, out cancel, (CopyOptions) copyOptions, transaction.SafeHandle);
  1036. var lastError = (uint) Marshal.GetLastWin32Error();
  1037. if (!success)
  1038. {
  1039. cmr.ErrorCode = (int) lastError;
  1040. if (lastError == Win32Errors.ERROR_REQUEST_ABORTED)
  1041. {
  1042. // MSDN:
  1043. //
  1044. // If lpProgressRoutine returns PROGRESS_CANCEL due to the user canceling the operation,
  1045. // CopyFileEx will return zero and GetLastError will return ERROR_REQUEST_ABORTED.
  1046. // In this case, the partially copied destination file is deleted.
  1047. //
  1048. // If lpProgressRoutine returns PROGRESS_STOP due to the user stopping the operation,
  1049. // CopyFileEx will return zero and GetLastError will return ERROR_REQUEST_ABORTED.
  1050. // In this case, the partially copied destination file is left intact.
  1051. cmr.IsCanceled = true;
  1052. }
  1053. else if (raiseException)
  1054. {
  1055. raiseException:
  1056. #region Win32Errors
  1057. switch (lastError)
  1058. {
  1059. case Win32Errors.ERROR_FILE_NOT_FOUND:
  1060. if (isFolder)
  1061. {
  1062. lastError = Win32Errors.ERROR_PATH_NOT_FOUND;
  1063. goto raiseException;
  1064. }
  1065. // File.Copy()
  1066. // File.Move()
  1067. // MSDN: .NET 3.5+: FileNotFoundException: sourceFileName was not found.
  1068. NativeError.ThrowException(lastError, sourceFileNameLp);
  1069. break;
  1070. case Win32Errors.ERROR_PATH_NOT_FOUND:
  1071. // File.Copy()
  1072. // File.Move()
  1073. // Directory.Move()
  1074. // MSDN: .NET 3.5+: DirectoryNotFoundException: The path specified in sourceFileName or destinationFileName is invalid (for example, it is on an unmapped drive).
  1075. NativeError.ThrowException(lastError, sourceFileNameLp);
  1076. break;
  1077. case Win32Errors.ERROR_FILE_EXISTS:
  1078. // File.Copy()
  1079. // Directory.Copy()
  1080. NativeError.ThrowException(lastError, destFileNameLp);
  1081. break;
  1082. default:
  1083. var destExists = ExistsCore(isFolder, transaction, destFileNameLp, PathFormat.LongFullPath);
  1084. // For a number of error codes (sharing violation, path not found, etc)
  1085. // we don't know if the problem was with the source or destination file.
  1086. // Check if destination directory already exists.
  1087. // Directory.Move()
  1088. // MSDN: .NET 3.5+: IOException: destDirName already exists.
  1089. if (isFolder && destExists)
  1090. NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, destFileNameLp);
  1091. if (isMove)
  1092. {
  1093. // Ensure that the source file or directory exists.
  1094. // Directory.Move()
  1095. // MSDN: .NET 3.5+: DirectoryNotFoundException: The path specified by sourceDirName is invalid (for example, it is on an unmapped drive).
  1096. if (!ExistsCore(isFolder, transaction, sourceFileNameLp, PathFormat.LongFullPath))
  1097. NativeError.ThrowException(isFolder ? Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND, sourceFileNameLp);
  1098. }
  1099. // Try reading the source file.
  1100. var fileNameLp = destFileNameLp;
  1101. if (!isFolder)
  1102. {
  1103. using (var safeHandle = CreateFileCore(transaction, sourceFileNameLp, ExtendedFileAttributes.Normal, null, FileMode.Open, 0, FileShare.Read, false, PathFormat.LongFullPath))
  1104. if (safeHandle != null && safeHandle.IsInvalid)
  1105. fileNameLp = sourceFileNameLp;
  1106. }
  1107. if (lastError == Win32Errors.ERROR_ACCESS_DENIED)
  1108. {
  1109. // File.Copy()
  1110. // File.Move()
  1111. // MSDN: .NET 3.5+: IOException: An I/O error has occurred.
  1112. // Directory exists with the same name as the file.
  1113. if (!isFolder && destExists)
  1114. NativeError.ThrowException(lastError, string.Format(CultureInfo.CurrentCulture, Resources.Target_File_Is_A_Directory, destFileNameLp));
  1115. if (isMove)
  1116. {
  1117. var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA();
  1118. FillAttributeInfoCore(transaction, destFileNameLp, ref data, false, true);
  1119. if (data.dwFileAttributes != (FileAttributes) (-1))
  1120. {
  1121. if ((data.dwFileAttributes & FileAttributes.ReadOnly) != 0)
  1122. {
  1123. // MSDN: .NET 3.5+: IOException: The directory specified by path is read-only.
  1124. if (((MoveOptions) moveOptions & MoveOptions.ReplaceExisting) != 0)
  1125. {
  1126. // Reset file system object attributes.
  1127. SetAttributesCore(isFolder, transaction, destFileNameLp, FileAttributes.Normal, PathFormat.LongFullPath);
  1128. goto startCopyMove;
  1129. }
  1130. // MSDN: .NET 3.5+: UnauthorizedAccessException: destinationFileName is read-only.
  1131. // MSDN: Win32 CopyFileXxx: This function fails with ERROR_ACCESS_DENIED if the destination file already exists
  1132. // and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set.
  1133. throw new FileReadOnlyException(destFileNameLp);
  1134. }
  1135. // MSDN: Win32 CopyFileXxx: This function fails with ERROR_ACCESS_DENIED if the destination file already exists
  1136. // and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set.
  1137. if ((data.dwFileAttributes & FileAttributes.Hidden) != 0)
  1138. NativeError.ThrowException(lastError, string.Format(CultureInfo.CurrentCulture, Resources.File_Is_Hidden, destFileNameLp));
  1139. }
  1140. }
  1141. }
  1142. // MSDN: .NET 3.5+: An I/O error has occurred.
  1143. // File.Copy(): IOException: destinationFileName exists and overwrite is false.
  1144. // File.Move(): The destination file already exists or sourceFileName was not found.
  1145. NativeError.ThrowException(lastError, fileNameLp);
  1146. break;
  1147. }
  1148. #endregion // Win32Errors
  1149. }
  1150. }
  1151. #endregion // Win32 Copy/Move
  1152. #region Transfer Timestamps
  1153. // Apply original Timestamps if requested.
  1154. // MoveFileWithProgress() / MoveFileTransacted() automatically preserve Timestamps.
  1155. // File.Copy()
  1156. if (success && preserveDates && isCopy)
  1157. {
  1158. // Currently preserveDates is only used with files.
  1159. var data = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA();
  1160. var dataInitialised = FillAttributeInfoCore(transaction, sourceFileNameLp, ref data, false, true);
  1161. if (dataInitialised == Win32Errors.ERROR_SUCCESS && data.dwFileAttributes != (FileAttributes) (-1))
  1162. SetFsoDateTimeCore(false, transaction, destFileNameLp, DateTime.FromFileTimeUtc(data.ftCreationTime),
  1163. DateTime.FromFileTimeUtc(data.ftLastAccessTime), DateTime.FromFileTimeUtc(data.ftLastWriteTime), false, PathFormat.LongFullPath);
  1164. }
  1165. #endregion // Transfer Timestamps
  1166. return cmr;
  1167. }
  1168. #endregion // Internal Methods
  1169. }
  1170. }