Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.30 KB | None | 0 0
  1. Add-Type -TypeDefinition @'
  2. using Microsoft.Win32.SafeHandles;
  3. using System;
  4. using System.IO;
  5. using System.Runtime.ConstrainedExecution;
  6. using System.Runtime.InteropServices;
  7.  
  8. namespace FileIO
  9. {
  10. public class NativeHelpers
  11. {
  12. public enum GET_FILEEX_INFO_LEVELS
  13. {
  14. GetFileExInfoStandard,
  15. GetFileExMaxInfoLevel
  16. }
  17.  
  18. [StructLayout(LayoutKind.Sequential)]
  19. public struct FILETIME
  20. {
  21. internal UInt32 dwLowDateTime;
  22. internal UInt32 dwHighDateTime;
  23.  
  24. public static implicit operator Int64(FILETIME v) { return ((Int64)v.dwHighDateTime << 32) + v.dwLowDateTime; }
  25. public static explicit operator DateTimeOffset(FILETIME v) { return DateTimeOffset.FromFileTime(v); }
  26. }
  27.  
  28. [StructLayout(LayoutKind.Sequential)]
  29. public struct WIN32_FILE_ATTRIBUTE_DATA
  30. {
  31. public FileAttributes dwFileAttributes;
  32. public FILETIME ftCreationTime;
  33. public FILETIME ftLastAccessTime;
  34. public FILETIME ftLastWriteTime;
  35. public UInt32 nFileSizeHigh;
  36. public UInt32 nFileSizeLow;
  37. }
  38.  
  39. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  40. public struct WIN32_FIND_DATA
  41. {
  42. public FileAttributes dwFileAttributes;
  43. public FILETIME ftCreationTime;
  44. public FILETIME ftLastAccessTime;
  45. public FILETIME ftLastWriteTime;
  46. public UInt32 nFileSizeHigh;
  47. public UInt32 nFileSizeLow;
  48. public UInt32 dwReserved0;
  49. public UInt32 dwReserved1;
  50. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName;
  51. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName;
  52. }
  53. }
  54.  
  55. public class NativeMethods
  56. {
  57. [DllImport("Kernel32.dll", SetLastError = true)]
  58. public static extern bool DeleteFileW(
  59. [MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
  60.  
  61. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  62. public static extern bool GetFileAttributesExW(
  63. [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
  64. NativeHelpers.GET_FILEEX_INFO_LEVELS fInfoLevelId,
  65. out NativeHelpers.WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
  66.  
  67. [DllImport("kernel32.dll", SetLastError = true)]
  68. public static extern bool FindClose(
  69. IntPtr hFindFile);
  70.  
  71. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  72. public static extern SafeFindHandle FindFirstFileW(
  73. [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
  74. out NativeHelpers.WIN32_FIND_DATA lpFindFileData);
  75.  
  76. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  77. public static extern bool FindNextFileW(
  78. SafeFindHandle hFindFile,
  79. out NativeHelpers.WIN32_FIND_DATA lpFindFileData);
  80.  
  81. [DllImport("Kernel32.dll", SetLastError = true)]
  82. public static extern bool RemoveDirectoryW(
  83. [MarshalAs(UnmanagedType.LPWStr)] string lpPathName);
  84.  
  85. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  86. public static extern bool SetFileAttributesW(
  87. [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
  88. FileAttributes dwFileAttributes);
  89. }
  90.  
  91. public class SafeFindHandle : SafeHandleMinusOneIsInvalid
  92. {
  93. public SafeFindHandle() : base(true) { }
  94. public SafeFindHandle(IntPtr handle) : base(true) { this.handle = handle; }
  95.  
  96. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  97. protected override bool ReleaseHandle()
  98. {
  99. return NativeMethods.FindClose(handle);
  100. }
  101. }
  102. }
  103. '@
  104.  
  105. Function Get-Win32ErrorMessage {
  106. Param (
  107. [Parameter(Mandatory=$true)]
  108. [Int32]
  109. $ErrorCode
  110. )
  111.  
  112. $exp = New-Object -TypeName System.ComponentModel.Win32Exception -ArgumentList $ErrorCode
  113. return ("{0} (Win32 Error Code {1} - 0x{1:X8})" -f $exp.Message, $ErrorCode)
  114. }
  115.  
  116. Function Get-FileAttributes {
  117. Param (
  118. [Parameter(Mandatory=$true)]
  119. [String]
  120. $Path
  121. )
  122.  
  123. $data = New-Object -TypeName FileIO.NativeHelpers+WIN32_FILE_ATTRIBUTE_DATA
  124. $res = [FileIO.NativeMethods]::GetFileAttributesExW(
  125. $Path,
  126. [FileIO.NativeHelpers+GET_FILEEX_INFO_LEVELS]::GetFileExInfoStandard,
  127. [Ref]$data
  128. )
  129. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  130.  
  131. if (-not $res) {
  132. if ($err -eq 32) { # ERROR_SHARING_VIOLATION
  133. # Special system files like pagefile.sys return this error. Use FindFirstFileW instead.
  134. $data = New-Object -TypeName FileIO.NativeHelpers+WIN32_FIND_DATA
  135. $find_handle = [FileIO.NativeMethods]::FindFirstFileW($Path, [Ref]$data)
  136. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  137.  
  138. if ($find_handle.IsInvalid) {
  139. throw "Failed to get file attributes for '$Path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  140. }
  141.  
  142. try {
  143. $attrs = $data.dwFileAttributes
  144. } finally {
  145. $find_handle.Dispose()
  146. }
  147. } else {
  148. throw "Failed to get file attributes for '$Path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  149. }
  150. } else {
  151. $attrs = $data.dwFileAttributes
  152. }
  153.  
  154. return $attrs
  155. }
  156.  
  157. Function Remove-ReadOnlyAndHiddenAttribute {
  158. Param (
  159. [Parameter(Mandatory=$true)]
  160. [String]
  161. $Path
  162. )
  163.  
  164. $attrs = Get-FileAttributes -Path $Path
  165. $changed = $false
  166. 'ReadOnly', 'Hidden' | ForEach-Object -Process {
  167. if ($attrs.HasFlag([System.IO.FileAttributes]$_)) {
  168. $attrs = $attrs -bxor [System.IO.FileAttributes]$_
  169. $changed = $true
  170. }
  171. }
  172.  
  173. if ($changed) {
  174. $res = [FileIO.NativeMethods]::SetFileAttributesW($Path, $attrs)
  175. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  176.  
  177. if (-not $res) {
  178. throw "Failed to remove the ReadOnly or Hidden attribute for deletion on '$Path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  179. }
  180. }
  181. }
  182.  
  183. Function Remove-File {
  184. Param (
  185. [Parameter(Mandatory=$true)]
  186. [String]
  187. $Path
  188. )
  189.  
  190. Remove-ReadOnlyAndHiddenAttribute -Path $Path
  191. $res = [FileIO.NativeMEthods]::DeleteFileW($Path)
  192. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  193. if (-not $res) {
  194. throw "Failed to delete file '$Path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  195. }
  196. }
  197.  
  198. Function Remove-Directory {
  199. Param (
  200. [Parameter(Mandatory=$true)]
  201. [String]
  202. $Path,
  203.  
  204. [Switch]
  205. $Recurse
  206. )
  207.  
  208. if ($Recurse) {
  209. $find_path = [System.IO.Path]::Combine($Path, "*")
  210. $find_data = New-Object -TypeName FileIO.NativeHelpers+WIN32_FIND_DATA
  211. $find_handle = [FileIO.NativeMethods]::FindFirstFileW(
  212. $find_path, [ref]$find_data
  213. )
  214. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  215.  
  216. if ($find_handle.IsInvalid) {
  217. throw "Failed to enumerate directory with search pattern '$find_path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  218. }
  219. try {
  220. do {
  221. if ($find_data.cFileName -in @('.', '..')) {
  222. continue
  223. }
  224.  
  225. $file_path = [System.IO.Path]::Combine($Path, $find_data.cFileName)
  226. if ($find_data.dwFileAttributes.HasFlag([System.IO.FileAttributes]::Directory)) {
  227. $is_link = $find_data.dwFileAttributes.HasFlag([System.IO.FileAttributes]::ReparsePoint)
  228. Remove-Directory -Path $file_path -Recurse:(-not $is_link)
  229. } else {
  230. Remove-File -Path $file_path
  231. }
  232. } while ([FileIO.NativeMethods]::FindNextFileW($find_handle, [ref]$find_data))
  233. } finally {
  234. $find_handle.Dispose()
  235. }
  236. }
  237.  
  238. Remove-ReadOnlyAndHiddenAttribute -Path $Path
  239. $res = [FileIO.NativeMethods]::RemoveDirectoryW($Path)
  240. $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
  241. if (-not $res) {
  242. throw "Failed to delete directory '$Path': $(Get-Win32ErrorMessage -ErrorCode $err)"
  243. }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement