PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/MSBuild/Microsoft/Build/Shared/NativeMethodsShared.cs

#
C# | 474 lines | 445 code | 29 blank | 0 comment | 32 complexity | 31f27feee00de63fb44b11b41746af7b MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
  1. namespace Microsoft.Build.Shared
  2. {
  3. using Microsoft.Win32.SafeHandles;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.Diagnostics;
  8. using System.Runtime.CompilerServices;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Threading;
  12. internal static class NativeMethodsShared
  13. {
  14. internal const uint E_ABORT = 0x80004004;
  15. internal const uint ERROR_FILE_NOT_FOUND = 0x80070002;
  16. internal const uint ERROR_INSUFFICIENT_BUFFER = 0x8007007a;
  17. internal const int FILE_ATTRIBUTE_DIRECTORY = 0x10;
  18. internal const int FILE_ATTRIBUTE_READONLY = 1;
  19. internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
  20. internal const uint FILE_TYPE_CHAR = 2;
  21. internal const uint FUSION_E_PRIVATE_ASM_DISALLOWED = 0x80131044;
  22. internal const uint INFINITE = uint.MaxValue;
  23. private const string kernel32Dll = "kernel32.dll";
  24. internal static int MAX_PATH = 260;
  25. private const string mscoreeDLL = "mscoree.dll";
  26. internal static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
  27. internal static IntPtr NullIntPtr = new IntPtr(0);
  28. internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
  29. internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
  30. internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
  31. internal const uint RPC_S_CALLPENDING = 0x80010115;
  32. internal const uint RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG = 0x40;
  33. internal const uint S_FALSE = 1;
  34. internal const uint S_OK = 0;
  35. internal const uint STARTUP_LOADER_SAFEMODE = 0x10;
  36. internal const int STD_OUTPUT_HANDLE = -11;
  37. internal const uint WAIT_ABANDONED_0 = 0x80;
  38. internal const uint WAIT_OBJECT_0 = 0;
  39. internal const uint WAIT_TIMEOUT = 0x102;
  40. [DllImport("ole32.dll")]
  41. public static extern int CoWaitForMultipleHandles(COWAIT_FLAGS dwFlags, int dwTimeout, int cHandles, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] pHandles, out int pdwIndex);
  42. [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
  43. internal static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SecurityAttributes lpPipeAttributes, int nSize);
  44. internal static string FindOnPath(string filename)
  45. {
  46. StringBuilder buffer = new StringBuilder(MAX_PATH + 1);
  47. string str = null;
  48. for (int i = 0; i < 2; i++)
  49. {
  50. uint num2 = SearchPath(null, filename, null, buffer.Capacity, buffer, null);
  51. if (num2 > buffer.Capacity)
  52. {
  53. Microsoft.Build.Shared.ErrorUtilities.VerifyThrow(i == 0, "We should not have to resize the buffer twice.");
  54. buffer.Capacity = (int) num2;
  55. }
  56. else
  57. {
  58. if (num2 > 0)
  59. {
  60. str = buffer.ToString();
  61. }
  62. return str;
  63. }
  64. }
  65. return str;
  66. }
  67. [return: MarshalAs(UnmanagedType.Bool)]
  68. [DllImport("kernel32.dll", SetLastError=true)]
  69. internal static extern bool FreeLibrary([In] IntPtr module);
  70. internal static List<Tuple<int, SafeProcessHandle>> GetChildProcessIds(int parentProcessId, DateTime parentStartTime)
  71. {
  72. List<Tuple<int, SafeProcessHandle>> list = new List<Tuple<int, SafeProcessHandle>>();
  73. foreach (Process process in Process.GetProcesses())
  74. {
  75. using (process)
  76. {
  77. SafeProcessHandle handle = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, process.Id);
  78. if (!handle.IsInvalid)
  79. {
  80. bool flag = false;
  81. try
  82. {
  83. if (process.StartTime > parentStartTime)
  84. {
  85. int num = GetParentProcessId(process.Id);
  86. if ((num != 0) && (parentProcessId == num))
  87. {
  88. list.Add(new Tuple<int, SafeProcessHandle>(process.Id, handle));
  89. flag = true;
  90. }
  91. }
  92. }
  93. finally
  94. {
  95. if (!flag)
  96. {
  97. handle.Dispose();
  98. }
  99. }
  100. }
  101. }
  102. }
  103. return list;
  104. }
  105. internal static string GetCurrentDirectory()
  106. {
  107. StringBuilder lpBuffer = new StringBuilder(MAX_PATH);
  108. if (GetCurrentDirectory(MAX_PATH, lpBuffer) > 0)
  109. {
  110. return lpBuffer.ToString();
  111. }
  112. return null;
  113. }
  114. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  115. internal static extern int GetCurrentDirectory(int nBufferLength, StringBuilder lpBuffer);
  116. [return: MarshalAs(UnmanagedType.Bool)]
  117. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  118. internal static extern bool GetFileAttributesEx(string name, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
  119. [DllImport("kernel32.dll")]
  120. internal static extern uint GetFileType(IntPtr hFile);
  121. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  122. internal static extern int GetFullPathName(string target, int bufferLength, StringBuilder buffer, IntPtr mustBeZero);
  123. internal static DateTime GetLastWriteFileUtcTime(string fullPath)
  124. {
  125. DateTime minValue = DateTime.MinValue;
  126. WIN32_FILE_ATTRIBUTE_DATA lpFileInformation = new WIN32_FILE_ATTRIBUTE_DATA();
  127. if (GetFileAttributesEx(fullPath, 0, ref lpFileInformation))
  128. {
  129. long fileTime = (lpFileInformation.ftLastWriteTimeHigh << 0x20) | lpFileInformation.ftLastWriteTimeLow;
  130. minValue = DateTime.FromFileTimeUtc(fileTime);
  131. }
  132. return minValue;
  133. }
  134. internal static string GetLongFilePath(string path)
  135. {
  136. if (path != null)
  137. {
  138. int capacity = GetLongPathName(path, null, 0);
  139. if (capacity > 0)
  140. {
  141. StringBuilder fullpath = new StringBuilder(capacity);
  142. GetLongPathName(path, fullpath, capacity);
  143. path = fullpath.ToString();
  144. }
  145. }
  146. return path;
  147. }
  148. [DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
  149. internal static extern int GetLongPathName([In] string path, [In, Out] StringBuilder fullpath, [In] int length);
  150. internal static MemoryStatus GetMemoryStatus()
  151. {
  152. MemoryStatus lpBuffer = new MemoryStatus();
  153. if (!GlobalMemoryStatusEx(lpBuffer))
  154. {
  155. return null;
  156. }
  157. return lpBuffer;
  158. }
  159. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  160. internal static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
  161. [DllImport("kernel32.dll", SetLastError=true)]
  162. internal static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);
  163. [DllImport("kernel32.dll")]
  164. internal static extern int GetOEMCP();
  165. internal static int GetParentProcessId(int processId)
  166. {
  167. int inheritedFromUniqueProcessId = 0;
  168. SafeProcessHandle hProcess = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, processId);
  169. if (!hProcess.IsInvalid)
  170. {
  171. try
  172. {
  173. PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
  174. int pSize = 0;
  175. if (-1 != NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, pbi.Size, ref pSize))
  176. {
  177. inheritedFromUniqueProcessId = pbi.InheritedFromUniqueProcessId;
  178. }
  179. }
  180. finally
  181. {
  182. hProcess.Dispose();
  183. }
  184. }
  185. return inheritedFromUniqueProcessId;
  186. }
  187. [DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)]
  188. internal static extern IntPtr GetProcAddress(IntPtr module, string procName);
  189. [DllImport("mscoree.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  190. internal static extern uint GetRequestedRuntimeInfo(string pExe, string pwszVersion, string pConfigurationFile, uint startupFlags, uint runtimeInfoFlags, StringBuilder pDirectory, int dwDirectory, out uint dwDirectoryLength, StringBuilder pVersion, int cchBuffer, out uint dwlength);
  191. internal static string GetShortFilePath(string path)
  192. {
  193. if (path != null)
  194. {
  195. int capacity = GetShortPathName(path, null, 0);
  196. if (capacity > 0)
  197. {
  198. StringBuilder fullpath = new StringBuilder(capacity);
  199. GetShortPathName(path, fullpath, capacity);
  200. path = fullpath.ToString();
  201. }
  202. }
  203. return path;
  204. }
  205. [DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
  206. internal static extern int GetShortPathName(string path, [In, Out] StringBuilder fullpath, [In] int length);
  207. [DllImport("kernel32.dll")]
  208. internal static extern IntPtr GetStdHandle(int nStdHandle);
  209. [DllImport("kernel32.dll", SetLastError=true)]
  210. internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
  211. [return: MarshalAs(UnmanagedType.Bool)]
  212. [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
  213. private static extern bool GlobalMemoryStatusEx([In, Out] MemoryStatus lpBuffer);
  214. public static bool HResultFailed(int hr)
  215. {
  216. return (hr < 0);
  217. }
  218. public static bool HResultSucceeded(int hr)
  219. {
  220. return (hr >= 0);
  221. }
  222. private static bool IsExpectedKillException(Exception e)
  223. {
  224. return (((e is Win32Exception) || (e is NotSupportedException)) || (e is InvalidOperationException));
  225. }
  226. internal static void KillTree(int processIdTokill)
  227. {
  228. using (Process process = Process.GetProcessById(processIdTokill))
  229. {
  230. DateTime startTime = process.StartTime;
  231. SafeProcessHandle handle = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, processIdTokill);
  232. if (!handle.IsInvalid)
  233. {
  234. try
  235. {
  236. process.Kill();
  237. List<Tuple<int, SafeProcessHandle>> childProcessIds = GetChildProcessIds(processIdTokill, startTime);
  238. try
  239. {
  240. foreach (Tuple<int, SafeProcessHandle> tuple in childProcessIds)
  241. {
  242. KillTree(tuple.Item1);
  243. }
  244. }
  245. finally
  246. {
  247. foreach (Tuple<int, SafeProcessHandle> tuple2 in childProcessIds)
  248. {
  249. tuple2.Item2.Dispose();
  250. }
  251. }
  252. }
  253. finally
  254. {
  255. handle.Dispose();
  256. }
  257. }
  258. }
  259. }
  260. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  261. internal static extern IntPtr LoadLibrary(string fileName);
  262. internal static bool MsgWaitOne(this WaitHandle handle)
  263. {
  264. return handle.MsgWaitOne(-1);
  265. }
  266. internal static bool MsgWaitOne(this WaitHandle handle, int timeout)
  267. {
  268. int num;
  269. IntPtr[] pHandles = new IntPtr[] { handle.SafeWaitHandle.DangerousGetHandle() };
  270. int num2 = CoWaitForMultipleHandles(COWAIT_FLAGS.COWAIT_NONE, timeout, 1, pHandles, out num);
  271. Microsoft.Build.Shared.ErrorUtilities.VerifyThrow((num2 == 0) || ((num2 == -2147417835) && (timeout != -1)), "Received {0} from CoWaitForMultipleHandles, but expected 0 (S_OK)", num2);
  272. return (num2 == 0);
  273. }
  274. internal static bool MsgWaitOne(this WaitHandle handle, TimeSpan timeout)
  275. {
  276. return handle.MsgWaitOne(((int) timeout.TotalMilliseconds));
  277. }
  278. [DllImport("NTDLL.DLL")]
  279. private static extern int NtQueryInformationProcess(SafeProcessHandle hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
  280. [DllImport("KERNEL32.DLL")]
  281. private static extern SafeProcessHandle OpenProcess(eDesiredAccess dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
  282. [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
  283. internal static extern bool ReadFile(SafeFileHandle hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
  284. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  285. private static extern uint SearchPath(string path, string fileName, string extension, int numBufferChars, StringBuilder buffer, int[] filePart);
  286. [return: MarshalAs(UnmanagedType.Bool)]
  287. [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  288. internal static extern bool SetCurrentDirectory(string path);
  289. [DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
  290. public static extern int WaitForMultipleObjects(uint handle, IntPtr[] handles, bool waitAll, uint milliseconds);
  291. [Flags]
  292. public enum COWAIT_FLAGS
  293. {
  294. COWAIT_NONE,
  295. COWAIT_WAITALL,
  296. COWAIT_ALERTABLE
  297. }
  298. private enum eDesiredAccess
  299. {
  300. DELETE = 0x10000,
  301. PROCESS_ALL_ACCESS = 0x100fff,
  302. PROCESS_CREATE_PROCESS = 0x80,
  303. PROCESS_CREATE_THREAD = 2,
  304. PROCESS_DUP_HANDLE = 0x40,
  305. PROCESS_QUERY_INFORMATION = 0x400,
  306. PROCESS_SET_INFORMATION = 0x200,
  307. PROCESS_SET_QUOTA = 0x100,
  308. PROCESS_SET_SESSIONID = 4,
  309. PROCESS_TERMINATE = 1,
  310. PROCESS_VM_OPERATION = 8,
  311. PROCESS_VM_READ = 0x10,
  312. PROCESS_VM_WRITE = 0x20,
  313. READ_CONTROL = 0x20000,
  314. STANDARD_RIGHTS_ALL = 0x1f0000,
  315. SYNCHRONIZE = 0x100000,
  316. WRITE_DAC = 0x40000,
  317. WRITE_OWNER = 0x80000
  318. }
  319. internal static class InprocTracking
  320. {
  321. [DllImport("FileTracker.dll", PreserveSig=false)]
  322. internal static extern void EndTrackingContext();
  323. [DllImport("FileTracker.dll", PreserveSig=false)]
  324. internal static extern void ResumeTracking();
  325. [DllImport("FileTracker.dll", PreserveSig=false)]
  326. internal static extern void SetThreadCount(int threadCount);
  327. [DllImport("FileTracker.dll", PreserveSig=false)]
  328. internal static extern void StartTrackingContext([In, MarshalAs(UnmanagedType.LPWStr)] string intermediateDirectory, [In, MarshalAs(UnmanagedType.LPWStr)] string taskName);
  329. [DllImport("FileTracker.dll", PreserveSig=false)]
  330. internal static extern void StartTrackingContextWithRoot([In, MarshalAs(UnmanagedType.LPWStr)] string intermediateDirectory, [In, MarshalAs(UnmanagedType.LPWStr)] string taskName, [In, MarshalAs(UnmanagedType.LPWStr)] string rootMarker);
  331. [DllImport("FileTracker.dll", PreserveSig=false)]
  332. internal static extern void StopTrackingAndCleanup();
  333. [DllImport("FileTracker.dll", PreserveSig=false)]
  334. internal static extern void SuspendTracking();
  335. [DllImport("FileTracker.dll", PreserveSig=false)]
  336. internal static extern void WriteAllTLogs([In, MarshalAs(UnmanagedType.LPWStr)] string intermediateDirectory, [In, MarshalAs(UnmanagedType.LPWStr)] string tlogRootName);
  337. [DllImport("FileTracker.dll", PreserveSig=false)]
  338. internal static extern void WriteContextTLogs([In, MarshalAs(UnmanagedType.LPWStr)] string intermediateDirectory, [In, MarshalAs(UnmanagedType.LPWStr)] string tlogRootName);
  339. }
  340. [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
  341. internal class MemoryStatus
  342. {
  343. private uint Length = ((uint) Marshal.SizeOf(typeof(Microsoft.Build.Shared.NativeMethodsShared.MemoryStatus)));
  344. public uint MemoryLoad;
  345. public ulong TotalPhysical;
  346. public ulong AvailablePhysical;
  347. public ulong TotalPageFile;
  348. public ulong AvailablePageFile;
  349. public ulong TotalVirtual;
  350. public ulong AvailableVirtual;
  351. public ulong AvailableExtendedVirtual;
  352. }
  353. [StructLayout(LayoutKind.Sequential)]
  354. private struct PROCESS_BASIC_INFORMATION
  355. {
  356. public int ExitStatus;
  357. public int PebBaseAddress;
  358. public int AffinityMask;
  359. public int BasePriority;
  360. public int UniqueProcessId;
  361. public int InheritedFromUniqueProcessId;
  362. public int Size
  363. {
  364. get
  365. {
  366. return 0x18;
  367. }
  368. }
  369. }
  370. private enum PROCESSINFOCLASS
  371. {
  372. ProcessBasicInformation,
  373. ProcessQuotaLimits,
  374. ProcessIoCounters,
  375. ProcessVmCounters,
  376. ProcessTimes,
  377. ProcessBasePriority,
  378. ProcessRaisePriority,
  379. ProcessDebugPort,
  380. ProcessExceptionPort,
  381. ProcessAccessToken,
  382. ProcessLdtInformation,
  383. ProcessLdtSize,
  384. ProcessDefaultHardErrorMode,
  385. ProcessIoPortHandlers,
  386. ProcessPooledUsageAndLimits,
  387. ProcessWorkingSetWatch,
  388. ProcessUserModeIOPL,
  389. ProcessEnableAlignmentFaultFixup,
  390. ProcessPriorityClass,
  391. ProcessWx86Information,
  392. ProcessHandleCount,
  393. ProcessAffinityMask,
  394. ProcessPriorityBoost,
  395. MaxProcessInfoClass
  396. }
  397. internal class SafeProcessHandle : SafeHandleZeroOrMinusOneIsInvalid
  398. {
  399. private SafeProcessHandle() : base(true)
  400. {
  401. }
  402. [DllImport("KERNEL32.DLL")]
  403. private static extern bool CloseHandle(IntPtr hObject);
  404. protected override bool ReleaseHandle()
  405. {
  406. return CloseHandle(base.handle);
  407. }
  408. }
  409. [StructLayout(LayoutKind.Sequential)]
  410. internal class SecurityAttributes
  411. {
  412. private uint nLength = ((uint) Marshal.SizeOf(typeof(Microsoft.Build.Shared.NativeMethodsShared.SecurityAttributes)));
  413. public IntPtr lpSecurityDescriptor;
  414. public bool bInheritHandle;
  415. }
  416. [StructLayout(LayoutKind.Sequential)]
  417. internal struct SYSTEM_INFO
  418. {
  419. internal ushort wProcessorArchitecture;
  420. internal ushort wReserved;
  421. internal uint dwPageSize;
  422. internal IntPtr lpMinimumApplicationAddress;
  423. internal IntPtr lpMaximumApplicationAddress;
  424. internal IntPtr dwActiveProcessorMask;
  425. internal uint dwNumberOfProcessors;
  426. internal uint dwProcessorType;
  427. internal uint dwAllocationGranularity;
  428. internal ushort wProcessorLevel;
  429. internal ushort wProcessorRevision;
  430. }
  431. [StructLayout(LayoutKind.Sequential)]
  432. public struct WIN32_FILE_ATTRIBUTE_DATA
  433. {
  434. internal int fileAttributes;
  435. internal uint ftCreationTimeLow;
  436. internal uint ftCreationTimeHigh;
  437. internal uint ftLastAccessTimeLow;
  438. internal uint ftLastAccessTimeHigh;
  439. internal uint ftLastWriteTimeLow;
  440. internal uint ftLastWriteTimeHigh;
  441. internal uint fileSizeHigh;
  442. internal uint fileSizeLow;
  443. }
  444. }
  445. }