PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Kernel/Singularity/V1/Processes/ProcessHandle.cs

#
C# | 637 lines | 451 code | 93 blank | 93 comment | 43 complexity | 9d9de64f174032a57e8deef689a7856f MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity - Singularity ABI
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // File: ProcessHandle.cs
  8. //
  9. // Note:
  10. //
  11. using System;
  12. using System.Collections;
  13. using System.Runtime.CompilerServices;
  14. using System.Threading;
  15. using Microsoft.Singularity;
  16. using Microsoft.Singularity.Hal;
  17. using Microsoft.Singularity.Io;
  18. using Microsoft.Singularity.Loader;
  19. using Microsoft.Singularity.Memory;
  20. using Microsoft.Singularity.V1.Services;
  21. using Microsoft.Singularity.V1.Security;
  22. using Microsoft.Singularity.Security;
  23. using Microsoft.Singularity.V1.Types;
  24. using InternalProcessState = System.Threading.ProcessState;
  25. using ExternalProcessState = Microsoft.Singularity.V1.Processes.ProcessState;
  26. namespace Microsoft.Singularity.V1.Processes
  27. {
  28. public enum ProcessState {
  29. Active,
  30. Suspended,
  31. Stopped,
  32. }
  33. //| <include path='docs/doc[@for="ProcessHandle"]/*' />
  34. [CLSCompliant(false)]
  35. public struct ProcessHandle
  36. {
  37. public readonly UIntPtr id;
  38. public static readonly ProcessHandle Zero = new ProcessHandle();
  39. internal ProcessHandle(UIntPtr id)
  40. {
  41. this.id = id;
  42. }
  43. [ExternalEntryPoint]
  44. public static unsafe bool CreateImpl(
  45. char *cmdName,
  46. int cmdLength,
  47. char *actionName,
  48. int actionLength,
  49. char *role,
  50. int roleLength,
  51. ProcessHandle *handle)
  52. {
  53. return Create(cmdName, cmdLength, actionName, actionLength,
  54. role, roleLength, out *handle);
  55. }
  56. public static unsafe bool Create(char *cmdName,
  57. int cmdLength,
  58. char *actionName,
  59. int actionLength,
  60. char *role,
  61. int roleLength,
  62. out ProcessHandle handle) {
  63. Kernel.Waypoint(550);
  64. string mycmd = null;
  65. if (cmdName != null && cmdLength > 0) {
  66. mycmd = String.StringCTOR(cmdName, 0, cmdLength);
  67. }
  68. else {
  69. //should never happen
  70. DebugStub.Break();
  71. }
  72. string myrole = null;
  73. if (role != null && roleLength > 0) {
  74. myrole = String.StringCTOR(role, 0, roleLength);
  75. }
  76. string myaction = null;
  77. if (actionName != null && actionLength > 0) {
  78. myaction = String.StringCTOR(actionName, 0, actionLength);
  79. }
  80. Kernel.Waypoint(551);
  81. //
  82. // Find image to run.
  83. //
  84. Manifest appManifest;
  85. IoMemory image = Binder.LoadImage(Thread.CurrentProcess,
  86. mycmd,
  87. out appManifest);
  88. Kernel.Waypoint(552);
  89. if (image != null && image.Length > 0 && appManifest != null) {
  90. //
  91. // Check manifest to see what resources are needed
  92. //
  93. //
  94. // Create a Managed process, and a handle in the current
  95. // process to hold it.
  96. //
  97. // REVIEW: create empty args array so that we
  98. // do not need to change the process constructor;
  99. String[] myargs;
  100. if (myaction != null) {
  101. myargs = new String[2];
  102. myargs[1] = myaction;
  103. }
  104. else myargs = new String[1];
  105. myargs[0] = mycmd;
  106. Process process = new Process(Thread.CurrentProcess,
  107. image,
  108. myrole,
  109. myargs,
  110. appManifest);
  111. //
  112. // Check manifest to see what resources are needed
  113. //
  114. int epCount = appManifest.SetEndpoints(process, myaction);
  115. #if VERBOSE
  116. DebugStub.WriteLine("new process create: endpoints from manifest {0}",
  117. __arglist( epCount));
  118. #endif
  119. int boolCount, longCount, stringCount, stringArrayCount;
  120. bool ok = appManifest.GetParameterCounts(myaction,
  121. out boolCount,
  122. out longCount,
  123. out stringCount,
  124. out stringArrayCount);
  125. //DebugStub.WriteLine("ProcessHandle: args strings={0}, longs={1}, bools={2}",
  126. // __arglist(stringCount, longCount, boolCount));
  127. process.SetBoolArgCount(boolCount);
  128. process.SetLongArgCount(longCount);
  129. process.SetStringArgCount(stringCount);
  130. process.SetStringArrayArgCount(stringArrayCount);
  131. handle = new ProcessHandle(
  132. Thread.CurrentProcess.AllocateHandle(process));
  133. Tracing.Log(Tracing.Debug,
  134. "ProcessHandle.Create(out id={0:x8})",
  135. handle.id);
  136. Kernel.Waypoint(553);
  137. IoMemory.Release(image);
  138. appManifest = null;
  139. return true;
  140. }
  141. Tracing.Log(Tracing.Debug, "ProcessHandle.Create() failed");
  142. handle = new ProcessHandle();
  143. Kernel.Waypoint(554);
  144. return false;
  145. }
  146. [ExternalEntryPoint]
  147. public static unsafe bool CreateImpl(
  148. char *args,
  149. int *argLengths,
  150. int argCount,
  151. char *role,
  152. int roleLength,
  153. int endpointCount,
  154. ProcessHandle * handle)
  155. {
  156. return Create(args, argLengths, argCount, role, roleLength,
  157. endpointCount, out *handle);
  158. }
  159. public static unsafe bool Create(char *args,
  160. int *argLengths,
  161. int argCount,
  162. char *role,
  163. int roleLength,
  164. int endpointCount,
  165. out ProcessHandle handle)
  166. {
  167. Kernel.Waypoint(550);
  168. //
  169. // Create a kernel String[] object populated with the argument
  170. // values passed in from userland.
  171. //
  172. String[] arguments = new String[argCount];
  173. int offset = 0;
  174. for (int argument = 0; argument < argCount; argument++) {
  175. arguments[argument] = String.StringCTOR(
  176. args, offset, argLengths[argument]);
  177. offset += argLengths[argument];
  178. }
  179. string myrole = null;
  180. if (role != null && roleLength > 0) {
  181. myrole = String.StringCTOR(role, 0, roleLength);
  182. }
  183. Kernel.Waypoint(551);
  184. //
  185. // Find image to run.
  186. //
  187. Manifest appManifest;
  188. IoMemory image = Binder.LoadImage(Thread.CurrentProcess,
  189. arguments[0],
  190. out appManifest);
  191. Kernel.Waypoint(552);
  192. if (image != null && image.Length > 0 && appManifest != null) {
  193. //
  194. // Check manifest to see what resources are needed
  195. //
  196. //
  197. // Create a Managed process, and a handle in the current
  198. // process to hold it.
  199. //
  200. Process process = new Process(Thread.CurrentProcess,
  201. image,
  202. myrole,
  203. arguments,
  204. appManifest);
  205. //
  206. // Check manifest to see what resources are needed
  207. //
  208. int epCount = appManifest.SetEndpoints(process,null);
  209. #if VERBOSE
  210. DebugStub.WriteLine("endpoints passed in={0}, endpoints from manifest {1}",
  211. __arglist(endpointCount, epCount));
  212. #endif
  213. if (epCount == 0) {
  214. process.SetEndpointCount(endpointCount);
  215. }
  216. int boolCount, longCount, stringCount, stringArrayCount;
  217. bool ok = appManifest.GetParameterCounts(null,
  218. out boolCount,
  219. out longCount,
  220. out stringCount,
  221. out stringArrayCount);
  222. //DebugStub.WriteLine("ProcessHandle: args strings={0}, longs={1}, bools={2}",
  223. // __arglist(stringCount, longCount, boolCount));
  224. process.SetBoolArgCount(boolCount);
  225. process.SetLongArgCount(longCount);
  226. process.SetStringArgCount(stringCount);
  227. process.SetStringArrayArgCount(stringArrayCount);
  228. handle = new ProcessHandle(
  229. Thread.CurrentProcess.AllocateHandle(process));
  230. Tracing.Log(Tracing.Debug,
  231. "ProcessHandle.Create(out id={0:x8})",
  232. handle.id);
  233. Kernel.Waypoint(553);
  234. IoMemory.Release(image);
  235. appManifest = null;
  236. return true;
  237. }
  238. Tracing.Log(Tracing.Debug, "ProcessHandle.Create() failed");
  239. handle = new ProcessHandle();
  240. Kernel.Waypoint(554);
  241. return false;
  242. }
  243. /// <summary>
  244. /// Given 2 system types generate and initialize the two endpoints of
  245. /// a channel. The imp side will be set in the processes startup endpoint array
  246. /// at position "index". The exp side will be bound to a service based on global policy
  247. /// </summary>
  248. [ExternalEntryPoint]
  249. public static unsafe bool BindToService(
  250. ProcessHandle handle,
  251. SystemType impType,
  252. SystemType expType,
  253. char *contractChars,
  254. int contractLen,
  255. int startState,
  256. int index)
  257. {
  258. //convert contract to string
  259. if (contractLen == 0) return false;
  260. Process process = HandleTable.GetHandle(handle.id) as Process;
  261. string contract = String.StringCTOR(contractChars, 0, contractLen);
  262. if (contract == null) return false;
  263. return Binder.BindToService(process,
  264. impType,
  265. expType,
  266. contract,
  267. startState,
  268. index);
  269. }
  270. [ExternalEntryPoint]
  271. public static unsafe bool SetStartupEndpoint(ProcessHandle handle,
  272. int index,
  273. SharedHeapService.Allocation * endpoint)
  274. {
  275. Tracing.Log(Tracing.Debug,
  276. "ProcessHandle.SetStartupEndpoint(id={0:x8}, ndx={1}, ep={2:x8})",
  277. handle.id, (UIntPtr)index, (UIntPtr)endpoint);
  278. //
  279. // Convert the handle to a process; set the endpoint.
  280. //
  281. SharedHeap.Allocation *ep = (SharedHeap.Allocation *)endpoint;
  282. Process process = HandleTable.GetHandle(handle.id) as Process;
  283. return process.SetEndpoint(index, ref ep);
  284. }
  285. [ExternalEntryPoint]
  286. public static void Dispose(ProcessHandle handle)
  287. {
  288. Tracing.Log(Tracing.Debug, "ProcessHandle.Dispose(id={0:x8})",
  289. handle.id);
  290. //
  291. // Releasing the handle will allow the process to be
  292. // garbage-collected.
  293. //
  294. Thread.CurrentProcess.ReleaseHandle(handle.id);
  295. }
  296. [ExternalEntryPoint]
  297. public static bool Start(ProcessHandle handle)
  298. {
  299. Tracing.Log(Tracing.Debug, "ProcessHandle.Start(id={0:x8})",
  300. handle.id);
  301. //
  302. // Convert the handle to a process; call Start method.
  303. //
  304. Process process = HandleTable.GetHandle(handle.id) as Process;
  305. return process.Start();
  306. }
  307. [ExternalEntryPoint]
  308. public static unsafe void JoinImpl(ProcessHandle handle, bool * started)
  309. {
  310. Join(handle, out *started);
  311. }
  312. public static void Join(ProcessHandle handle, out bool started)
  313. {
  314. Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
  315. handle.id);
  316. //
  317. // Convert the handle to a process; call Join method.
  318. //
  319. Process process = HandleTable.GetHandle(handle.id) as Process;
  320. process.Join(out started);
  321. }
  322. [ExternalEntryPoint]
  323. public static unsafe bool JoinImpl(
  324. ProcessHandle handle,
  325. TimeSpan timeout,
  326. bool * started)
  327. {
  328. return Join(handle, timeout, out *started);
  329. }
  330. public static bool Join(ProcessHandle handle,
  331. TimeSpan timeout,
  332. out bool started)
  333. {
  334. Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
  335. handle.id);
  336. //
  337. // Convert the handle to a process; call Join method.
  338. //
  339. Process process = HandleTable.GetHandle(handle.id) as Process;
  340. bool ret = process.Join(timeout, out started);
  341. return ret;
  342. }
  343. [ExternalEntryPoint]
  344. public static unsafe bool JoinImpl(
  345. ProcessHandle handle,
  346. SchedulerTime stop,
  347. bool * started)
  348. {
  349. return Join(handle, stop, out *started);
  350. }
  351. public static bool Join(ProcessHandle handle,
  352. SchedulerTime stop,
  353. out bool started)
  354. {
  355. Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
  356. handle.id);
  357. //
  358. // Convert the handle to a process; call Join method.
  359. //
  360. Process process = HandleTable.GetHandle(handle.id) as Process;
  361. bool ret = process.Join(stop, out started);
  362. return ret;
  363. }
  364. [ExternalEntryPoint]
  365. public static bool Suspend(ProcessHandle handle, bool recursive)
  366. {
  367. Tracing.Log(Tracing.Debug, "ProcessHandle.Suspend(id={0:x8})",
  368. handle.id);
  369. //
  370. // Convert the handle to a process; call Suspend method.
  371. //
  372. Process process = HandleTable.GetHandle(handle.id) as Process;
  373. return process.Suspend(recursive);
  374. }
  375. [ExternalEntryPoint]
  376. public static bool Resume(ProcessHandle handle, bool recursive)
  377. {
  378. Tracing.Log(Tracing.Debug, "ProcessHandle.Resume(id={0:x8})",
  379. handle.id);
  380. //
  381. // Convert the handle to a process; call Resume method.
  382. //
  383. Process process = HandleTable.GetHandle(handle.id) as Process;
  384. return process.Resume(recursive);
  385. }
  386. [ExternalEntryPoint]
  387. public static void Stop(ProcessHandle handle, int exitcode)
  388. {
  389. Tracing.Log(Tracing.Debug, "ProcessHandle.Stop(id={0:x8})",
  390. handle.id);
  391. //
  392. // Convert the handle to a process; call Stop method.
  393. //
  394. Process process = HandleTable.GetHandle(handle.id) as Process;
  395. process.Stop(exitcode);
  396. }
  397. [ExternalEntryPoint]
  398. public static void SuspendBarrier()
  399. {
  400. Process.SuspendBarrier();
  401. }
  402. [ExternalEntryPoint]
  403. public static int GetProcessId(ProcessHandle handle)
  404. {
  405. Tracing.Log(Tracing.Debug, "ProcessHandle.GetProcessId(id={0:x8})",
  406. handle.id);
  407. //
  408. // Convert the handle to a process; retrieve ProcessId.
  409. //
  410. Process process = HandleTable.GetHandle(handle.id) as Process;
  411. return process.ProcessId;
  412. }
  413. [ExternalEntryPoint]
  414. public static int GetExitCode(ProcessHandle handle)
  415. {
  416. Tracing.Log(Tracing.Debug, "ProcessHandle.GetExitCode(id={0:x8})",
  417. handle.id);
  418. //
  419. // Convert the handle to a process; retrieve ExitCode.
  420. //
  421. Process process = HandleTable.GetHandle(handle.id) as Process;
  422. return process.ExitCode;
  423. }
  424. [ExternalEntryPoint]
  425. public static PrincipalHandle GetPrincipalHandle(ProcessHandle handle)
  426. {
  427. Tracing.Log(Tracing.Debug, "ProcessHandle.GetPrincipalHandle(id={0:x8})", handle.id);
  428. Process process = HandleTable.GetHandle(handle.id) as Process;
  429. return new PrincipalHandle(process.Principal.Val);
  430. }
  431. [ExternalEntryPoint]
  432. public static ExternalProcessState GetState(ProcessHandle handle)
  433. {
  434. Process process = HandleTable.GetHandle(handle.id) as Process;
  435. switch (process.State) {
  436. case InternalProcessState.Unstarted:
  437. case InternalProcessState.Running:
  438. return ExternalProcessState.Active;
  439. case InternalProcessState.Suspending:
  440. case InternalProcessState.SuspendingRecursive:
  441. case InternalProcessState.Suspended:
  442. return ExternalProcessState.Suspended;
  443. case InternalProcessState.Stopping:
  444. case InternalProcessState.Stopped:
  445. return ExternalProcessState.Stopped;
  446. default:
  447. // handle new missing case
  448. DebugStub.Break();
  449. return ExternalProcessState.Stopped;
  450. }
  451. }
  452. [ExternalEntryPoint]
  453. public static unsafe ParameterCode SetStartupStringArrayArg (
  454. ProcessHandle handle,
  455. int index,
  456. char *args,
  457. int *argLengths,
  458. int argCount)
  459. {
  460. Process process = HandleTable.GetHandle(handle.id) as Process;
  461. //
  462. // Create a kernel String[] object populated with the argument
  463. // values passed in from userland.
  464. //
  465. String[] arguments = new String[argCount];
  466. int offset = 0;
  467. for (int argument = 0; argument < argCount; argument++) {
  468. arguments[argument] = String.StringCTOR(
  469. args, offset, argLengths[argument]);
  470. offset += argLengths[argument];
  471. }
  472. return (ParameterCode) process.SetStartupStringArrayArg(index, arguments);
  473. }
  474. #if false
  475. [ExternalEntryPoint]
  476. public static int GetStartupStringArgCount(ProcessHandle handle) {
  477. Process process = HandleTable.GetHandle(handle.id) as Process;
  478. return process.GetStartupStringArgCount();
  479. }
  480. [ExternalEntryPoint]
  481. public static unsafe int GetStartupStringArg(ProcessHandle handle, int arg, char * output, int maxput) {
  482. Process process = HandleTable.GetHandle(handle.id) as Process;
  483. string s = process.GetStartupStringArg(arg);
  484. Tracing.Log(Tracing.Debug,
  485. "Process.GetStartupStringArg(arg={0}, out={1:x8}, max={2}) = {3}",
  486. (UIntPtr)unchecked((uint)arg),
  487. (UIntPtr)output,
  488. (UIntPtr)unchecked((uint)maxput),
  489. (UIntPtr)unchecked((uint)(s != null ? s.Length : 0)));
  490. if (s == null) {
  491. return 0;
  492. }
  493. if (output == null) {
  494. return s.Length + 1;
  495. }
  496. return s.InternalGetChars(output, maxput);
  497. }
  498. #endif
  499. [ExternalEntryPoint]
  500. public static unsafe ParameterCode SetStartupStringArg(
  501. ProcessHandle handle, int arg, char * input, int length)
  502. {
  503. string s;
  504. if (length == 0) s = null;
  505. else s = String.StringCTOR(input, 0, length);
  506. Process process = HandleTable.GetHandle(handle.id) as Process;
  507. return (ParameterCode) process.SetStartupStringArg(arg, s);
  508. }
  509. #if false
  510. [ExternalEntryPoint]
  511. public static int GetStartupLongArgCount(ProcessHandle handle) {
  512. Process process = HandleTable.GetHandle(handle.id) as Process;
  513. return process.GetStartupLongArgCount();
  514. }
  515. [ExternalEntryPoint]
  516. public static ParameterCode GetStartupLongArg(ProcessHandle handle, int index, out long value) {
  517. Process process = HandleTable.GetHandle(handle.id) as Process;
  518. return (ParameterCode) process.GetStartupLongArg(index, out value);
  519. }
  520. #endif
  521. [ExternalEntryPoint]
  522. public static ParameterCode SetStartupLongArg(ProcessHandle handle, int index, long value) {
  523. Process process = HandleTable.GetHandle(handle.id) as Process;
  524. return (ParameterCode) process.SetStartupLongArg(index, value);
  525. }
  526. #if false
  527. [ExternalEntryPoint]
  528. public static int GetStartupBoolArgCount(ProcessHandle handle) {
  529. Process process = HandleTable.GetHandle(handle.id) as Process;
  530. return process.GetStartupBoolArgCount();
  531. }
  532. [ExternalEntryPoint]
  533. public static ParameterCode GetStartupBoolArg(ProcessHandle handle, int index, out bool value) {
  534. Process process = HandleTable.GetHandle(handle.id) as Process;
  535. return (ParameterCode)process.GetStartupBoolArg(index, out value);
  536. }
  537. #endif
  538. [ExternalEntryPoint]
  539. public static ParameterCode SetStartupBoolArg(ProcessHandle handle, int index, bool value) {
  540. Process process = HandleTable.GetHandle(handle.id) as Process;
  541. return (ParameterCode) process.SetStartupBoolArg(index, value);
  542. }
  543. }
  544. }