710 lines
26 KiB
C#
710 lines
26 KiB
C#
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 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.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.X86;
|
||
|
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);
|
||
|
|
||
|
// haryadi -- this is currently a hack-kind of hook
|
||
|
// if the app to be run is HelloMp then we intercept control
|
||
|
// and run our own MpLoad, the Ap processor will run the HelloMp
|
||
|
if (arguments.Length != 0 && arguments[0] == "hellomp") {
|
||
|
|
||
|
// IoMemory mpImage = Binder.HelloMpLoadImage();
|
||
|
IoMemory mpImage = Binder.LoadRawImage("/init/hellomp", "hellomp.x86");
|
||
|
IoMemory mpLoadedImage;
|
||
|
|
||
|
// mpLoadedImage should have physical address
|
||
|
PEImage mpPeImage =
|
||
|
PEImage.HelloMpLoad(Thread.CurrentProcess,
|
||
|
mpImage, out mpLoadedImage);
|
||
|
UIntPtr mpEntryPoint = mpPeImage.GetEntryPoint(mpLoadedImage);
|
||
|
|
||
|
DebugStub.WriteLine
|
||
|
("HSG: Sending ApImage e.{0:x}",
|
||
|
__arglist(mpEntryPoint));
|
||
|
|
||
|
// send IPI
|
||
|
bool iflag = Processor.DisableInterrupts();
|
||
|
MpExecution.PutIntrApImage(1, mpEntryPoint);
|
||
|
MpExecution.SendApImage(0,1);
|
||
|
Processor.RestoreInterrupts(iflag);
|
||
|
|
||
|
// uncomment this if want to run this on BSP
|
||
|
// Processor.MpCallEntryPoint(mpEntryPoint);
|
||
|
|
||
|
// return failure to Shell
|
||
|
handle = new ProcessHandle();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// haryadi -- intercept TestMpAbi
|
||
|
if (arguments.Length != 0 && arguments[0] == "testmpabi") {
|
||
|
|
||
|
IoMemory mpImage = Binder.LoadRawImage("/init/testmpabi", "testmpabi.x86");
|
||
|
IoMemory mpLoadedImage;
|
||
|
|
||
|
// mpLoadedImage should have physical address
|
||
|
bool isForMp = true;
|
||
|
PEImage mpPeImage =
|
||
|
PEImage.Load(Thread.CurrentProcess,
|
||
|
mpImage, out mpLoadedImage, isForMp);
|
||
|
UIntPtr mpEntryPoint = mpPeImage.GetEntryPoint(mpLoadedImage);
|
||
|
|
||
|
// prepare IPI
|
||
|
// MpExecution.ApImage apImage = new MpExecution.ApImage();
|
||
|
// apImage.virtAddr = mpLoadedImage.VirtualAddress;
|
||
|
// apImage.phyAddr = mpLoadedImage.PhysicalAddress.Value;
|
||
|
// apImage.length = (UIntPtr)mpLoadedImage.Length;
|
||
|
// apImage.entryPoint = mpEntryPoint;
|
||
|
|
||
|
DebugStub.WriteLine
|
||
|
("HSG: Sending ApImage e.{0:x}",
|
||
|
__arglist(mpEntryPoint));
|
||
|
|
||
|
// send IPI
|
||
|
bool iflag = Processor.DisableInterrupts();
|
||
|
MpExecution.PutIntrApImage(1, mpEntryPoint);
|
||
|
MpExecution.SendApImage(0,1);
|
||
|
Processor.RestoreInterrupts(iflag);
|
||
|
|
||
|
// uncomment this if want to run this on BSP
|
||
|
// Processor.MpCallEntryPoint(mpEntryPoint);
|
||
|
|
||
|
// return failure to Shell
|
||
|
handle = new ProcessHandle();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// 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);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|