/base/Kernel/Singularity/V1/Processes/ProcessHandle.cs
C# | 637 lines | 451 code | 93 blank | 93 comment | 43 complexity | 9d9de64f174032a57e8deef689a7856f MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity - Singularity ABI
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // File: ProcessHandle.cs
- //
- // Note:
- //
-
- using System;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Threading;
-
- using Microsoft.Singularity;
- using Microsoft.Singularity.Hal;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Loader;
- using Microsoft.Singularity.Memory;
- using Microsoft.Singularity.V1.Services;
- using Microsoft.Singularity.V1.Security;
- using Microsoft.Singularity.Security;
- using Microsoft.Singularity.V1.Types;
-
- using InternalProcessState = System.Threading.ProcessState;
- using ExternalProcessState = Microsoft.Singularity.V1.Processes.ProcessState;
-
- namespace Microsoft.Singularity.V1.Processes
- {
- public enum ProcessState {
- Active,
- Suspended,
- Stopped,
- }
-
- //| <include path='docs/doc[@for="ProcessHandle"]/*' />
- [CLSCompliant(false)]
- public struct ProcessHandle
- {
- public readonly UIntPtr id;
-
- public static readonly ProcessHandle Zero = new ProcessHandle();
-
- internal ProcessHandle(UIntPtr id)
- {
- this.id = id;
- }
-
- [ExternalEntryPoint]
- public static unsafe bool CreateImpl(
- char *cmdName,
- int cmdLength,
- char *actionName,
- int actionLength,
- char *role,
- int roleLength,
- ProcessHandle *handle)
- {
- return Create(cmdName, cmdLength, actionName, actionLength,
- role, roleLength, out *handle);
- }
-
- public static unsafe bool Create(char *cmdName,
- int cmdLength,
- char *actionName,
- int actionLength,
- char *role,
- int roleLength,
- out ProcessHandle handle) {
-
- Kernel.Waypoint(550);
-
- string mycmd = null;
-
- if (cmdName != null && cmdLength > 0) {
- mycmd = String.StringCTOR(cmdName, 0, cmdLength);
- }
- else {
- //should never happen
- DebugStub.Break();
- }
-
- string myrole = null;
-
- if (role != null && roleLength > 0) {
- myrole = String.StringCTOR(role, 0, roleLength);
- }
-
- string myaction = null;
-
- if (actionName != null && actionLength > 0) {
- myaction = String.StringCTOR(actionName, 0, actionLength);
- }
-
- Kernel.Waypoint(551);
-
- //
- // Find image to run.
- //
- Manifest appManifest;
- IoMemory image = Binder.LoadImage(Thread.CurrentProcess,
- mycmd,
- out appManifest);
- Kernel.Waypoint(552);
- if (image != null && image.Length > 0 && appManifest != null) {
- //
- // Check manifest to see what resources are needed
- //
-
- //
- // Create a Managed process, and a handle in the current
- // process to hold it.
- //
-
- // REVIEW: create empty args array so that we
- // do not need to change the process constructor;
- String[] myargs;
- if (myaction != null) {
- myargs = new String[2];
- myargs[1] = myaction;
- }
- else myargs = new String[1];
- myargs[0] = mycmd;
-
- Process process = new Process(Thread.CurrentProcess,
- image,
- myrole,
- myargs,
- appManifest);
- //
- // Check manifest to see what resources are needed
- //
-
- int epCount = appManifest.SetEndpoints(process, myaction);
- #if VERBOSE
- DebugStub.WriteLine("new process create: endpoints from manifest {0}",
- __arglist( epCount));
- #endif
-
- int boolCount, longCount, stringCount, stringArrayCount;
- bool ok = appManifest.GetParameterCounts(myaction,
- out boolCount,
- out longCount,
- out stringCount,
- out stringArrayCount);
-
-
- //DebugStub.WriteLine("ProcessHandle: args strings={0}, longs={1}, bools={2}",
- // __arglist(stringCount, longCount, boolCount));
-
- process.SetBoolArgCount(boolCount);
- process.SetLongArgCount(longCount);
- process.SetStringArgCount(stringCount);
- process.SetStringArrayArgCount(stringArrayCount);
-
- handle = new ProcessHandle(
- Thread.CurrentProcess.AllocateHandle(process));
- Tracing.Log(Tracing.Debug,
- "ProcessHandle.Create(out id={0:x8})",
- handle.id);
- Kernel.Waypoint(553);
- IoMemory.Release(image);
- appManifest = null;
- return true;
- }
-
- Tracing.Log(Tracing.Debug, "ProcessHandle.Create() failed");
- handle = new ProcessHandle();
- Kernel.Waypoint(554);
- return false;
- }
-
- [ExternalEntryPoint]
- public static unsafe bool CreateImpl(
- char *args,
- int *argLengths,
- int argCount,
- char *role,
- int roleLength,
- int endpointCount,
- ProcessHandle * handle)
- {
- return Create(args, argLengths, argCount, role, roleLength,
- endpointCount, out *handle);
- }
-
- public static unsafe bool Create(char *args,
- int *argLengths,
- int argCount,
- char *role,
- int roleLength,
- int endpointCount,
- out ProcessHandle handle)
- {
- Kernel.Waypoint(550);
-
- //
- // Create a kernel String[] object populated with the argument
- // values passed in from userland.
- //
- String[] arguments = new String[argCount];
- int offset = 0;
-
- for (int argument = 0; argument < argCount; argument++) {
- arguments[argument] = String.StringCTOR(
- args, offset, argLengths[argument]);
- offset += argLengths[argument];
- }
-
- string myrole = null;
-
- if (role != null && roleLength > 0) {
- myrole = String.StringCTOR(role, 0, roleLength);
- }
-
- Kernel.Waypoint(551);
-
- //
- // Find image to run.
- //
- Manifest appManifest;
- IoMemory image = Binder.LoadImage(Thread.CurrentProcess,
- arguments[0],
- out appManifest);
- Kernel.Waypoint(552);
- if (image != null && image.Length > 0 && appManifest != null) {
- //
- // Check manifest to see what resources are needed
- //
-
- //
- // Create a Managed process, and a handle in the current
- // process to hold it.
- //
- Process process = new Process(Thread.CurrentProcess,
- image,
- myrole,
- arguments,
- appManifest);
-
- //
- // Check manifest to see what resources are needed
- //
-
- int epCount = appManifest.SetEndpoints(process,null);
- #if VERBOSE
- DebugStub.WriteLine("endpoints passed in={0}, endpoints from manifest {1}",
- __arglist(endpointCount, epCount));
- #endif
- if (epCount == 0) {
- process.SetEndpointCount(endpointCount);
- }
-
- int boolCount, longCount, stringCount, stringArrayCount;
- bool ok = appManifest.GetParameterCounts(null,
- out boolCount,
- out longCount,
- out stringCount,
- out stringArrayCount);
-
-
- //DebugStub.WriteLine("ProcessHandle: args strings={0}, longs={1}, bools={2}",
- // __arglist(stringCount, longCount, boolCount));
-
- process.SetBoolArgCount(boolCount);
- process.SetLongArgCount(longCount);
- process.SetStringArgCount(stringCount);
- process.SetStringArrayArgCount(stringArrayCount);
-
- handle = new ProcessHandle(
- Thread.CurrentProcess.AllocateHandle(process));
- Tracing.Log(Tracing.Debug,
- "ProcessHandle.Create(out id={0:x8})",
- handle.id);
- Kernel.Waypoint(553);
- IoMemory.Release(image);
- appManifest = null;
- return true;
- }
-
- Tracing.Log(Tracing.Debug, "ProcessHandle.Create() failed");
- handle = new ProcessHandle();
- Kernel.Waypoint(554);
- return false;
- }
-
- /// <summary>
- /// Given 2 system types generate and initialize the two endpoints of
- /// a channel. The imp side will be set in the processes startup endpoint array
- /// at position "index". The exp side will be bound to a service based on global policy
- /// </summary>
- [ExternalEntryPoint]
- public static unsafe bool BindToService(
- ProcessHandle handle,
- SystemType impType,
- SystemType expType,
- char *contractChars,
- int contractLen,
- int startState,
- int index)
- {
- //convert contract to string
- if (contractLen == 0) return false;
- Process process = HandleTable.GetHandle(handle.id) as Process;
- string contract = String.StringCTOR(contractChars, 0, contractLen);
- if (contract == null) return false;
-
- return Binder.BindToService(process,
- impType,
- expType,
- contract,
- startState,
- index);
- }
-
- [ExternalEntryPoint]
- public static unsafe bool SetStartupEndpoint(ProcessHandle handle,
- int index,
- SharedHeapService.Allocation * endpoint)
- {
- Tracing.Log(Tracing.Debug,
- "ProcessHandle.SetStartupEndpoint(id={0:x8}, ndx={1}, ep={2:x8})",
- handle.id, (UIntPtr)index, (UIntPtr)endpoint);
-
- //
- // Convert the handle to a process; set the endpoint.
- //
- SharedHeap.Allocation *ep = (SharedHeap.Allocation *)endpoint;
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.SetEndpoint(index, ref ep);
- }
-
- [ExternalEntryPoint]
- public static void Dispose(ProcessHandle handle)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Dispose(id={0:x8})",
- handle.id);
-
- //
- // Releasing the handle will allow the process to be
- // garbage-collected.
- //
- Thread.CurrentProcess.ReleaseHandle(handle.id);
- }
-
- [ExternalEntryPoint]
- public static bool Start(ProcessHandle handle)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Start(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Start method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.Start();
- }
-
- [ExternalEntryPoint]
- public static unsafe void JoinImpl(ProcessHandle handle, bool * started)
- {
- Join(handle, out *started);
- }
-
- public static void Join(ProcessHandle handle, out bool started)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Join method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
-
- process.Join(out started);
- }
-
- [ExternalEntryPoint]
- public static unsafe bool JoinImpl(
- ProcessHandle handle,
- TimeSpan timeout,
- bool * started)
- {
- return Join(handle, timeout, out *started);
- }
-
- public static bool Join(ProcessHandle handle,
- TimeSpan timeout,
- out bool started)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Join method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- bool ret = process.Join(timeout, out started);
-
- return ret;
- }
-
- [ExternalEntryPoint]
- public static unsafe bool JoinImpl(
- ProcessHandle handle,
- SchedulerTime stop,
- bool * started)
- {
- return Join(handle, stop, out *started);
- }
-
- public static bool Join(ProcessHandle handle,
- SchedulerTime stop,
- out bool started)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Join(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Join method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- bool ret = process.Join(stop, out started);
-
- return ret;
- }
-
- [ExternalEntryPoint]
- public static bool Suspend(ProcessHandle handle, bool recursive)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Suspend(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Suspend method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.Suspend(recursive);
- }
-
- [ExternalEntryPoint]
- public static bool Resume(ProcessHandle handle, bool recursive)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Resume(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Resume method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.Resume(recursive);
- }
-
- [ExternalEntryPoint]
- public static void Stop(ProcessHandle handle, int exitcode)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.Stop(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; call Stop method.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
- process.Stop(exitcode);
- }
-
- [ExternalEntryPoint]
- public static void SuspendBarrier()
- {
- Process.SuspendBarrier();
- }
-
- [ExternalEntryPoint]
- public static int GetProcessId(ProcessHandle handle)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.GetProcessId(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; retrieve ProcessId.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
-
- return process.ProcessId;
- }
-
- [ExternalEntryPoint]
- public static int GetExitCode(ProcessHandle handle)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.GetExitCode(id={0:x8})",
- handle.id);
-
- //
- // Convert the handle to a process; retrieve ExitCode.
- //
- Process process = HandleTable.GetHandle(handle.id) as Process;
-
- return process.ExitCode;
- }
-
- [ExternalEntryPoint]
- public static PrincipalHandle GetPrincipalHandle(ProcessHandle handle)
- {
- Tracing.Log(Tracing.Debug, "ProcessHandle.GetPrincipalHandle(id={0:x8})", handle.id);
-
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return new PrincipalHandle(process.Principal.Val);
- }
-
- [ExternalEntryPoint]
- public static ExternalProcessState GetState(ProcessHandle handle)
- {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- switch (process.State) {
- case InternalProcessState.Unstarted:
- case InternalProcessState.Running:
- return ExternalProcessState.Active;
-
- case InternalProcessState.Suspending:
- case InternalProcessState.SuspendingRecursive:
- case InternalProcessState.Suspended:
- return ExternalProcessState.Suspended;
-
- case InternalProcessState.Stopping:
- case InternalProcessState.Stopped:
- return ExternalProcessState.Stopped;
-
- default:
- // handle new missing case
- DebugStub.Break();
- return ExternalProcessState.Stopped;
- }
- }
-
- [ExternalEntryPoint]
- public static unsafe ParameterCode SetStartupStringArrayArg (
- ProcessHandle handle,
- int index,
- char *args,
- int *argLengths,
- int argCount)
- {
- Process process = HandleTable.GetHandle(handle.id) as Process;
-
- //
- // Create a kernel String[] object populated with the argument
- // values passed in from userland.
- //
- String[] arguments = new String[argCount];
- int offset = 0;
-
- for (int argument = 0; argument < argCount; argument++) {
- arguments[argument] = String.StringCTOR(
- args, offset, argLengths[argument]);
- offset += argLengths[argument];
- }
-
- return (ParameterCode) process.SetStartupStringArrayArg(index, arguments);
- }
- #if false
- [ExternalEntryPoint]
- public static int GetStartupStringArgCount(ProcessHandle handle) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.GetStartupStringArgCount();
- }
-
- [ExternalEntryPoint]
- public static unsafe int GetStartupStringArg(ProcessHandle handle, int arg, char * output, int maxput) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- string s = process.GetStartupStringArg(arg);
- Tracing.Log(Tracing.Debug,
- "Process.GetStartupStringArg(arg={0}, out={1:x8}, max={2}) = {3}",
- (UIntPtr)unchecked((uint)arg),
- (UIntPtr)output,
- (UIntPtr)unchecked((uint)maxput),
- (UIntPtr)unchecked((uint)(s != null ? s.Length : 0)));
-
- if (s == null) {
- return 0;
- }
- if (output == null) {
- return s.Length + 1;
- }
- return s.InternalGetChars(output, maxput);
- }
- #endif
- [ExternalEntryPoint]
- public static unsafe ParameterCode SetStartupStringArg(
- ProcessHandle handle, int arg, char * input, int length)
- {
- string s;
- if (length == 0) s = null;
- else s = String.StringCTOR(input, 0, length);
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return (ParameterCode) process.SetStartupStringArg(arg, s);
- }
- #if false
- [ExternalEntryPoint]
- public static int GetStartupLongArgCount(ProcessHandle handle) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.GetStartupLongArgCount();
- }
-
- [ExternalEntryPoint]
- public static ParameterCode GetStartupLongArg(ProcessHandle handle, int index, out long value) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return (ParameterCode) process.GetStartupLongArg(index, out value);
- }
- #endif
- [ExternalEntryPoint]
- public static ParameterCode SetStartupLongArg(ProcessHandle handle, int index, long value) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return (ParameterCode) process.SetStartupLongArg(index, value);
- }
- #if false
- [ExternalEntryPoint]
- public static int GetStartupBoolArgCount(ProcessHandle handle) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return process.GetStartupBoolArgCount();
- }
-
- [ExternalEntryPoint]
- public static ParameterCode GetStartupBoolArg(ProcessHandle handle, int index, out bool value) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return (ParameterCode)process.GetStartupBoolArg(index, out value);
- }
- #endif
- [ExternalEntryPoint]
- public static ParameterCode SetStartupBoolArg(ProcessHandle handle, int index, bool value) {
- Process process = HandleTable.GetHandle(handle.id) as Process;
- return (ParameterCode) process.SetStartupBoolArg(index, value);
- }
-
- }
- }