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.
 
 

801 lines
49 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.Collections.Generic;
  23. using System.Diagnostics.CodeAnalysis;
  24. using System.Globalization;
  25. using System.IO;
  26. using System.Runtime.InteropServices;
  27. using System.Security;
  28. using System.Security.AccessControl;
  29. namespace Alphaleonis.Win32.Filesystem
  30. {
  31. partial class Directory
  32. {
  33. #region .NET
  34. /// <summary>Creates all directories and subdirectories in the specified path unless they already exist.</summary>
  35. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  36. /// <exception cref="ArgumentException"/>
  37. /// <exception cref="ArgumentNullException"/>
  38. /// <exception cref="DirectoryNotFoundException"/>
  39. /// <exception cref="IOException"/>
  40. /// <exception cref="NotSupportedException"/>
  41. /// <exception cref="UnauthorizedAccessException"/>
  42. /// <param name="path">The directory to create.</param>
  43. [SecurityCritical]
  44. public static DirectoryInfo CreateDirectory(string path)
  45. {
  46. return CreateDirectoryCore(null, path, null, null, false, PathFormat.RelativePath);
  47. }
  48. #endregion // .NET
  49. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  50. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  51. /// <exception cref="ArgumentException"/>
  52. /// <exception cref="ArgumentNullException"/>
  53. /// <exception cref="DirectoryNotFoundException"/>
  54. /// <exception cref="IOException"/>
  55. /// <exception cref="NotSupportedException"/>
  56. /// <exception cref="UnauthorizedAccessException"/>
  57. /// <param name="path">The directory to create.</param>
  58. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  59. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  60. [SecurityCritical]
  61. public static DirectoryInfo CreateDirectory(string path, PathFormat pathFormat)
  62. {
  63. return CreateDirectoryCore(null, path, null, null, false, pathFormat);
  64. }
  65. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  66. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  67. /// <exception cref="ArgumentException"/>
  68. /// <exception cref="ArgumentNullException"/>
  69. /// <exception cref="DirectoryNotFoundException"/>
  70. /// <exception cref="IOException"/>
  71. /// <exception cref="NotSupportedException"/>
  72. /// <exception cref="UnauthorizedAccessException"/>
  73. /// <param name="path">The directory to create.</param>
  74. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  75. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  76. [SecurityCritical]
  77. public static DirectoryInfo CreateDirectory(string path, bool compress)
  78. {
  79. return CreateDirectoryCore(null, path, null, null, compress, PathFormat.RelativePath);
  80. }
  81. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  82. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  83. /// <exception cref="ArgumentException"/>
  84. /// <exception cref="ArgumentNullException"/>
  85. /// <exception cref="DirectoryNotFoundException"/>
  86. /// <exception cref="IOException"/>
  87. /// <exception cref="NotSupportedException"/>
  88. /// <exception cref="UnauthorizedAccessException"/>
  89. /// <param name="path">The directory to create.</param>
  90. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  91. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  92. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  93. [SecurityCritical]
  94. public static DirectoryInfo CreateDirectory(string path, bool compress, PathFormat pathFormat)
  95. {
  96. return CreateDirectoryCore(null, path, null, null, compress, pathFormat);
  97. }
  98. /// <summary>Creates all the directories in the specified path, unless the already exist, applying the specified Windows security.</summary>
  99. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  100. /// <exception cref="ArgumentException"/>
  101. /// <exception cref="ArgumentNullException"/>
  102. /// <exception cref="DirectoryNotFoundException"/>
  103. /// <exception cref="IOException"/>
  104. /// <exception cref="NotSupportedException"/>
  105. /// <exception cref="UnauthorizedAccessException"/>
  106. /// <param name="path">The directory to create.</param>
  107. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  108. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  109. [SecurityCritical]
  110. public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity)
  111. {
  112. return CreateDirectoryCore(null, path, null, directorySecurity, false, PathFormat.RelativePath);
  113. }
  114. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  115. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  116. /// <exception cref="ArgumentException"/>
  117. /// <exception cref="ArgumentNullException"/>
  118. /// <exception cref="DirectoryNotFoundException"/>
  119. /// <exception cref="IOException"/>
  120. /// <exception cref="NotSupportedException"/>
  121. /// <exception cref="UnauthorizedAccessException"/>
  122. /// <param name="path">The directory to create.</param>
  123. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  124. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  125. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  126. [SecurityCritical]
  127. public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, PathFormat pathFormat)
  128. {
  129. return CreateDirectoryCore(null, path, null, directorySecurity, false, pathFormat);
  130. }
  131. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  132. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  133. /// <exception cref="ArgumentException"/>
  134. /// <exception cref="ArgumentNullException"/>
  135. /// <exception cref="DirectoryNotFoundException"/>
  136. /// <exception cref="IOException"/>
  137. /// <exception cref="NotSupportedException"/>
  138. /// <exception cref="UnauthorizedAccessException"/>
  139. /// <param name="path">The directory to create.</param>
  140. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  141. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  142. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  143. [SecurityCritical]
  144. public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, bool compress)
  145. {
  146. return CreateDirectoryCore(null, path, null, directorySecurity, compress, PathFormat.RelativePath);
  147. }
  148. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  149. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  150. /// <exception cref="ArgumentException"/>
  151. /// <exception cref="ArgumentNullException"/>
  152. /// <exception cref="DirectoryNotFoundException"/>
  153. /// <exception cref="IOException"/>
  154. /// <exception cref="NotSupportedException"/>
  155. /// <exception cref="UnauthorizedAccessException"/>
  156. /// <param name="path">The directory to create.</param>
  157. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  158. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  159. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  160. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  161. [SecurityCritical]
  162. public static DirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat)
  163. {
  164. return CreateDirectoryCore(null, path, null, directorySecurity, compress, pathFormat);
  165. }
  166. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  167. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  168. /// <exception cref="ArgumentException"/>
  169. /// <exception cref="ArgumentNullException"/>
  170. /// <exception cref="DirectoryNotFoundException"/>
  171. /// <exception cref="IOException"/>
  172. /// <exception cref="NotSupportedException"/>
  173. /// <exception cref="UnauthorizedAccessException"/>
  174. /// <param name="path">The directory to create.</param>
  175. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  176. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  177. [SecurityCritical]
  178. public static DirectoryInfo CreateDirectory(string path, string templatePath)
  179. {
  180. return CreateDirectoryCore(null, path, templatePath, null, false, PathFormat.RelativePath);
  181. }
  182. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  183. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  184. /// <exception cref="ArgumentException"/>
  185. /// <exception cref="ArgumentNullException"/>
  186. /// <exception cref="DirectoryNotFoundException"/>
  187. /// <exception cref="IOException"/>
  188. /// <exception cref="NotSupportedException"/>
  189. /// <exception cref="UnauthorizedAccessException"/>
  190. /// <param name="path">The directory to create.</param>
  191. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  192. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  193. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  194. [SecurityCritical]
  195. public static DirectoryInfo CreateDirectory(string path, string templatePath, PathFormat pathFormat)
  196. {
  197. return CreateDirectoryCore(null, path, templatePath, null, false, pathFormat);
  198. }
  199. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  200. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  201. /// <exception cref="ArgumentException"/>
  202. /// <exception cref="ArgumentNullException"/>
  203. /// <exception cref="DirectoryNotFoundException"/>
  204. /// <exception cref="IOException"/>
  205. /// <exception cref="NotSupportedException"/>
  206. /// <exception cref="UnauthorizedAccessException"/>
  207. /// <param name="path">The directory to create.</param>
  208. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  209. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  210. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  211. [SecurityCritical]
  212. public static DirectoryInfo CreateDirectory(string path, string templatePath, bool compress)
  213. {
  214. return CreateDirectoryCore(null, path, templatePath, null, compress, PathFormat.RelativePath);
  215. }
  216. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  217. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  218. /// <exception cref="ArgumentException"/>
  219. /// <exception cref="ArgumentNullException"/>
  220. /// <exception cref="DirectoryNotFoundException"/>
  221. /// <exception cref="IOException"/>
  222. /// <exception cref="NotSupportedException"/>
  223. /// <exception cref="UnauthorizedAccessException"/>
  224. /// <param name="path">The directory to create.</param>
  225. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  226. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  227. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  228. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  229. [SecurityCritical]
  230. public static DirectoryInfo CreateDirectory(string path, string templatePath, bool compress, PathFormat pathFormat)
  231. {
  232. return CreateDirectoryCore(null, path, templatePath, null, compress, pathFormat);
  233. }
  234. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  235. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  236. /// <exception cref="ArgumentException"/>
  237. /// <exception cref="ArgumentNullException"/>
  238. /// <exception cref="DirectoryNotFoundException"/>
  239. /// <exception cref="IOException"/>
  240. /// <exception cref="NotSupportedException"/>
  241. /// <exception cref="UnauthorizedAccessException"/>
  242. /// <param name="path">The directory to create.</param>
  243. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  244. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  245. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  246. [SecurityCritical]
  247. public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity)
  248. {
  249. return CreateDirectoryCore(null, path, templatePath, directorySecurity, false, PathFormat.RelativePath);
  250. }
  251. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  252. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  253. /// <exception cref="ArgumentException"/>
  254. /// <exception cref="ArgumentNullException"/>
  255. /// <exception cref="DirectoryNotFoundException"/>
  256. /// <exception cref="IOException"/>
  257. /// <exception cref="NotSupportedException"/>
  258. /// <exception cref="UnauthorizedAccessException"/>
  259. /// <param name="path">The directory to create.</param>
  260. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  261. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  262. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  263. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  264. [SecurityCritical]
  265. public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, PathFormat pathFormat)
  266. {
  267. return CreateDirectoryCore(null, path, templatePath, directorySecurity, false, pathFormat);
  268. }
  269. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  270. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  271. /// <exception cref="ArgumentException"/>
  272. /// <exception cref="ArgumentNullException"/>
  273. /// <exception cref="DirectoryNotFoundException"/>
  274. /// <exception cref="IOException"/>
  275. /// <exception cref="NotSupportedException"/>
  276. /// <exception cref="UnauthorizedAccessException"/>
  277. /// <param name="path">The directory to create.</param>
  278. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  279. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  280. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  281. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  282. [SecurityCritical]
  283. public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress)
  284. {
  285. return CreateDirectoryCore(null, path, templatePath, directorySecurity, compress, PathFormat.RelativePath);
  286. }
  287. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  288. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  289. /// <exception cref="ArgumentException"/>
  290. /// <exception cref="ArgumentNullException"/>
  291. /// <exception cref="DirectoryNotFoundException"/>
  292. /// <exception cref="IOException"/>
  293. /// <exception cref="NotSupportedException"/>
  294. /// <exception cref="UnauthorizedAccessException"/>
  295. /// <param name="path">The directory to create.</param>
  296. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  297. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  298. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  299. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  300. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  301. [SecurityCritical]
  302. public static DirectoryInfo CreateDirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat)
  303. {
  304. return CreateDirectoryCore(null, path, templatePath, directorySecurity, compress, pathFormat);
  305. }
  306. #region Transactional
  307. /// <summary>Creates all directories and subdirectories in the specified path unless they already exist.</summary>
  308. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  309. /// <exception cref="ArgumentException"/>
  310. /// <exception cref="ArgumentNullException"/>
  311. /// <exception cref="DirectoryNotFoundException"/>
  312. /// <exception cref="IOException"/>
  313. /// <exception cref="NotSupportedException"/>
  314. /// <exception cref="UnauthorizedAccessException"/>
  315. /// <param name="transaction">The transaction.</param>
  316. /// <param name="path">The directory to create.</param>
  317. [SecurityCritical]
  318. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path)
  319. {
  320. return CreateDirectoryCore(transaction, path, null, null, false, PathFormat.RelativePath);
  321. }
  322. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  323. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  324. /// <exception cref="ArgumentException"/>
  325. /// <exception cref="ArgumentNullException"/>
  326. /// <exception cref="DirectoryNotFoundException"/>
  327. /// <exception cref="IOException"/>
  328. /// <exception cref="NotSupportedException"/>
  329. /// <exception cref="UnauthorizedAccessException"/>
  330. /// <param name="transaction">The transaction.</param>
  331. /// <param name="path">The directory to create.</param>
  332. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  333. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  334. [SecurityCritical]
  335. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
  336. {
  337. return CreateDirectoryCore(transaction, path, null, null, false, pathFormat);
  338. }
  339. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  340. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  341. /// <exception cref="ArgumentException"/>
  342. /// <exception cref="ArgumentNullException"/>
  343. /// <exception cref="DirectoryNotFoundException"/>
  344. /// <exception cref="IOException"/>
  345. /// <exception cref="NotSupportedException"/>
  346. /// <exception cref="UnauthorizedAccessException"/>
  347. /// <param name="transaction">The transaction.</param>
  348. /// <param name="path">The directory to create.</param>
  349. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  350. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  351. [SecurityCritical]
  352. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, bool compress)
  353. {
  354. return CreateDirectoryCore(transaction, path, null, null, compress, PathFormat.RelativePath);
  355. }
  356. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  357. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  358. /// <exception cref="ArgumentException"/>
  359. /// <exception cref="ArgumentNullException"/>
  360. /// <exception cref="DirectoryNotFoundException"/>
  361. /// <exception cref="IOException"/>
  362. /// <exception cref="NotSupportedException"/>
  363. /// <exception cref="UnauthorizedAccessException"/>
  364. /// <param name="transaction">The transaction.</param>
  365. /// <param name="path">The directory to create.</param>
  366. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  367. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  368. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  369. [SecurityCritical]
  370. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, bool compress, PathFormat pathFormat)
  371. {
  372. return CreateDirectoryCore(transaction, path, null, null, compress, pathFormat);
  373. }
  374. /// <summary>Creates all the directories in the specified path, unless the already exist, applying the specified Windows security.</summary>
  375. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  376. /// <exception cref="ArgumentException"/>
  377. /// <exception cref="ArgumentNullException"/>
  378. /// <exception cref="DirectoryNotFoundException"/>
  379. /// <exception cref="IOException"/>
  380. /// <exception cref="NotSupportedException"/>
  381. /// <exception cref="UnauthorizedAccessException"/>
  382. /// <param name="transaction">The transaction.</param>
  383. /// <param name="path">The directory to create.</param>
  384. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  385. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  386. [SecurityCritical]
  387. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity)
  388. {
  389. return CreateDirectoryCore(transaction, path, null, directorySecurity, false, PathFormat.RelativePath);
  390. }
  391. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  392. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  393. /// <exception cref="ArgumentException"/>
  394. /// <exception cref="ArgumentNullException"/>
  395. /// <exception cref="DirectoryNotFoundException"/>
  396. /// <exception cref="IOException"/>
  397. /// <exception cref="NotSupportedException"/>
  398. /// <exception cref="UnauthorizedAccessException"/>
  399. /// <param name="transaction">The transaction.</param>
  400. /// <param name="path">The directory to create.</param>
  401. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  402. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  403. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  404. [SecurityCritical]
  405. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, PathFormat pathFormat)
  406. {
  407. return CreateDirectoryCore(transaction, path, null, directorySecurity, false, pathFormat);
  408. }
  409. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  410. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  411. /// <exception cref="ArgumentException"/>
  412. /// <exception cref="ArgumentNullException"/>
  413. /// <exception cref="DirectoryNotFoundException"/>
  414. /// <exception cref="IOException"/>
  415. /// <exception cref="NotSupportedException"/>
  416. /// <exception cref="UnauthorizedAccessException"/>
  417. /// <param name="transaction">The transaction.</param>
  418. /// <param name="path">The directory to create.</param>
  419. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  420. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  421. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  422. [SecurityCritical]
  423. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, bool compress)
  424. {
  425. return CreateDirectoryCore(transaction, path, null, directorySecurity, compress, PathFormat.RelativePath);
  426. }
  427. /// <summary>[AlphaFS] Creates all the directories in the specified path, applying the specified Windows security.</summary>
  428. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  429. /// <exception cref="ArgumentException"/>
  430. /// <exception cref="ArgumentNullException"/>
  431. /// <exception cref="DirectoryNotFoundException"/>
  432. /// <exception cref="IOException"/>
  433. /// <exception cref="NotSupportedException"/>
  434. /// <exception cref="UnauthorizedAccessException"/>
  435. /// <param name="transaction">The transaction.</param>
  436. /// <param name="path">The directory to create.</param>
  437. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  438. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  439. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  440. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  441. [SecurityCritical]
  442. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat)
  443. {
  444. return CreateDirectoryCore(transaction, path, null, directorySecurity, compress, pathFormat);
  445. }
  446. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  447. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  448. /// <exception cref="ArgumentException"/>
  449. /// <exception cref="ArgumentNullException"/>
  450. /// <exception cref="DirectoryNotFoundException"/>
  451. /// <exception cref="IOException"/>
  452. /// <exception cref="NotSupportedException"/>
  453. /// <exception cref="UnauthorizedAccessException"/>
  454. /// <param name="transaction">The transaction.</param>
  455. /// <param name="path">The directory to create.</param>
  456. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  457. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  458. [SecurityCritical]
  459. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath)
  460. {
  461. return CreateDirectoryCore(transaction, path, templatePath, null, false, PathFormat.RelativePath);
  462. }
  463. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  464. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  465. /// <exception cref="ArgumentException"/>
  466. /// <exception cref="ArgumentNullException"/>
  467. /// <exception cref="DirectoryNotFoundException"/>
  468. /// <exception cref="IOException"/>
  469. /// <exception cref="NotSupportedException"/>
  470. /// <exception cref="UnauthorizedAccessException"/>
  471. /// <param name="transaction">The transaction.</param>
  472. /// <param name="path">The directory to create.</param>
  473. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  474. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  475. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  476. [SecurityCritical]
  477. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, PathFormat pathFormat)
  478. {
  479. return CreateDirectoryCore(transaction, path, templatePath, null, false, pathFormat);
  480. }
  481. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  482. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  483. /// <exception cref="ArgumentException"/>
  484. /// <exception cref="ArgumentNullException"/>
  485. /// <exception cref="DirectoryNotFoundException"/>
  486. /// <exception cref="IOException"/>
  487. /// <exception cref="NotSupportedException"/>
  488. /// <exception cref="UnauthorizedAccessException"/>
  489. /// <param name="transaction">The transaction.</param>
  490. /// <param name="path">The directory to create.</param>
  491. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  492. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  493. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  494. [SecurityCritical]
  495. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, bool compress)
  496. {
  497. return CreateDirectoryCore(transaction, path, templatePath, null, compress, PathFormat.RelativePath);
  498. }
  499. /// <summary>[AlphaFS] Creates a new directory, with the attributes of a specified template directory.</summary>
  500. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  501. /// <exception cref="ArgumentException"/>
  502. /// <exception cref="ArgumentNullException"/>
  503. /// <exception cref="DirectoryNotFoundException"/>
  504. /// <exception cref="IOException"/>
  505. /// <exception cref="NotSupportedException"/>
  506. /// <exception cref="UnauthorizedAccessException"/>
  507. /// <param name="transaction">The transaction.</param>
  508. /// <param name="path">The directory to create.</param>
  509. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  510. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  511. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  512. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  513. [SecurityCritical]
  514. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, bool compress, PathFormat pathFormat)
  515. {
  516. return CreateDirectoryCore(transaction, path, templatePath, null, compress, pathFormat);
  517. }
  518. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  519. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  520. /// <exception cref="ArgumentException"/>
  521. /// <exception cref="ArgumentNullException"/>
  522. /// <exception cref="DirectoryNotFoundException"/>
  523. /// <exception cref="IOException"/>
  524. /// <exception cref="NotSupportedException"/>
  525. /// <exception cref="UnauthorizedAccessException"/>
  526. /// <param name="transaction">The transaction.</param>
  527. /// <param name="path">The directory to create.</param>
  528. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  529. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  530. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  531. [SecurityCritical]
  532. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity)
  533. {
  534. return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, false, PathFormat.RelativePath);
  535. }
  536. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  537. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  538. /// <exception cref="ArgumentException"/>
  539. /// <exception cref="ArgumentNullException"/>
  540. /// <exception cref="DirectoryNotFoundException"/>
  541. /// <exception cref="IOException"/>
  542. /// <exception cref="NotSupportedException"/>
  543. /// <exception cref="UnauthorizedAccessException"/>
  544. /// <param name="transaction">The transaction.</param>
  545. /// <param name="path">The directory to create.</param>
  546. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  547. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  548. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  549. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  550. [SecurityCritical]
  551. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, PathFormat pathFormat)
  552. {
  553. return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, false, pathFormat);
  554. }
  555. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  556. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  557. /// <exception cref="ArgumentException"/>
  558. /// <exception cref="ArgumentNullException"/>
  559. /// <exception cref="DirectoryNotFoundException"/>
  560. /// <exception cref="IOException"/>
  561. /// <exception cref="NotSupportedException"/>
  562. /// <exception cref="UnauthorizedAccessException"/>
  563. /// <param name="transaction">The transaction.</param>
  564. /// <param name="path">The directory to create.</param>
  565. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  566. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  567. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  568. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  569. [SecurityCritical]
  570. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, bool compress)
  571. {
  572. return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, compress, PathFormat.RelativePath);
  573. }
  574. /// <summary>[AlphaFS] Creates all the directories in the specified path of a specified template directory and applies the specified Windows security.</summary>
  575. /// <returns>An object that represents the directory at the specified path. This object is returned regardless of whether a directory at the specified path already exists.</returns>
  576. /// <exception cref="ArgumentException"/>
  577. /// <exception cref="ArgumentNullException"/>
  578. /// <exception cref="DirectoryNotFoundException"/>
  579. /// <exception cref="IOException"/>
  580. /// <exception cref="NotSupportedException"/>
  581. /// <exception cref="UnauthorizedAccessException"/>
  582. /// <param name="transaction">The transaction.</param>
  583. /// <param name="path">The directory to create.</param>
  584. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
  585. /// <param name="directorySecurity">The access control to apply to the directory.</param>
  586. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  587. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  588. [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
  589. [SecurityCritical]
  590. public static DirectoryInfo CreateDirectoryTransacted(KernelTransaction transaction, string path, string templatePath, DirectorySecurity directorySecurity, bool compress, PathFormat pathFormat)
  591. {
  592. return CreateDirectoryCore(transaction, path, templatePath, directorySecurity, compress, pathFormat);
  593. }
  594. #endregion // Transactional
  595. #region Internal Methods
  596. /// <summary>Creates a new directory with the attributes of a specified template directory (if one is specified).
  597. /// If the underlying file system supports security on files and directories, the function applies the specified security descriptor to the new directory.
  598. /// The new directory retains the other attributes of the specified template directory.
  599. /// </summary>
  600. /// <returns>
  601. /// <para>Returns an object that represents the directory at the specified path.</para>
  602. /// <para>This object is returned regardless of whether a directory at the specified path already exists.</para>
  603. /// </returns>
  604. /// <exception cref="ArgumentException"/>
  605. /// <exception cref="ArgumentNullException"/>
  606. /// <exception cref="DirectoryNotFoundException"/>
  607. /// <exception cref="IOException"/>
  608. /// <exception cref="NotSupportedException"/>
  609. /// <exception cref="UnauthorizedAccessException"/>
  610. /// <param name="transaction">The transaction.</param>
  611. /// <param name="path">The directory to create.</param>
  612. /// <param name="templatePath">The path of the directory to use as a template when creating the new directory. May be <see langword="null"/> to indicate that no template should be used.</param>
  613. /// <param name="directorySecurity">The <see cref="DirectorySecurity"/> access control to apply to the directory, may be null.</param>
  614. /// <param name="compress">When <see langword="true"/> compresses the directory.</param>
  615. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  616. [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
  617. [SecurityCritical]
  618. internal static DirectoryInfo CreateDirectoryCore(KernelTransaction transaction, string path, string templatePath, ObjectSecurity directorySecurity, bool compress, PathFormat pathFormat)
  619. {
  620. bool fullCheck = pathFormat == PathFormat.RelativePath;
  621. Path.CheckSupportedPathFormat(path, fullCheck, fullCheck);
  622. Path.CheckSupportedPathFormat(templatePath, fullCheck, fullCheck);
  623. string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);
  624. // Return DirectoryInfo instance if the directory specified by path already exists.
  625. if (File.ExistsCore(true, transaction, pathLp, PathFormat.LongFullPath))
  626. return new DirectoryInfo(transaction, pathLp, PathFormat.LongFullPath);
  627. // MSDN: .NET 3.5+: IOException: The directory specified by path is a file or the network name was not found.
  628. if (File.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath))
  629. NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, pathLp);
  630. string templatePathLp = Utils.IsNullOrWhiteSpace(templatePath)
  631. ? null
  632. : Path.GetExtendedLengthPathCore(transaction, templatePath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);
  633. #region Construct Full Path
  634. string longPathPrefix = Path.IsUncPathCore(path, false, false) ? Path.LongPathUncPrefix : Path.LongPathPrefix;
  635. path = Path.GetRegularPathCore(pathLp, GetFullPathOptions.None, false);
  636. int length = path.Length;
  637. if (length >= 2 && Path.IsDVsc(path[length - 1], false))
  638. --length;
  639. int rootLength = Path.GetRootLength(path, false);
  640. if (length == 2 && Path.IsDVsc(path[1], false))
  641. throw new ArgumentException(Resources.Cannot_Create_Directory, path);
  642. // Check if directories are missing.
  643. var list = new Stack<string>(100);
  644. if (length > rootLength)
  645. {
  646. for (int index = length - 1; index >= rootLength; --index)
  647. {
  648. string path1 = path.Substring(0, index + 1);
  649. string path2 = longPathPrefix + path1.TrimStart('\\');
  650. if (!File.ExistsCore(true, transaction, path2, PathFormat.LongFullPath))
  651. list.Push(path2);
  652. while (index > rootLength && !Path.IsDVsc(path[index], false))
  653. --index;
  654. }
  655. }
  656. #endregion // Construct Full Path
  657. // Directory security.
  658. using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(directorySecurity))
  659. {
  660. // Create the directory paths.
  661. while (list.Count > 0)
  662. {
  663. string folderLp = list.Pop();
  664. // In the ANSI version of this function, the name is limited to 248 characters.
  665. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
  666. // 2013-01-13: MSDN confirms LongPath usage.
  667. if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista
  668. ? (templatePathLp == null
  669. ? NativeMethods.CreateDirectory(folderLp, securityAttributes)
  670. : NativeMethods.CreateDirectoryEx(templatePathLp, folderLp, securityAttributes))
  671. : NativeMethods.CreateDirectoryTransacted(templatePathLp, folderLp, securityAttributes, transaction.SafeHandle)))
  672. {
  673. int lastError = Marshal.GetLastWin32Error();
  674. switch ((uint) lastError)
  675. {
  676. // MSDN: .NET 3.5+: If the directory already exists, this method does nothing.
  677. // MSDN: .NET 3.5+: IOException: The directory specified by path is a file.
  678. case Win32Errors.ERROR_ALREADY_EXISTS:
  679. if (File.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath))
  680. NativeError.ThrowException(lastError, pathLp);
  681. if (File.ExistsCore(false, transaction, folderLp, PathFormat.LongFullPath))
  682. NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, folderLp);
  683. break;
  684. case Win32Errors.ERROR_BAD_NET_NAME:
  685. NativeError.ThrowException(lastError, pathLp);
  686. break;
  687. case Win32Errors.ERROR_DIRECTORY:
  688. // MSDN: .NET 3.5+: NotSupportedException: path contains a colon character (:) that is not part of a drive label ("C:\").
  689. throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.Unsupported_Path_Format, path));
  690. default:
  691. NativeError.ThrowException(lastError, folderLp);
  692. break;
  693. }
  694. }
  695. else if (compress)
  696. Device.ToggleCompressionCore(true, transaction, folderLp, true, PathFormat.LongFullPath);
  697. }
  698. return new DirectoryInfo(transaction, pathLp, PathFormat.LongFullPath);
  699. }
  700. }
  701. #endregion // Internal Methods
  702. }
  703. }