//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: IoMemoryNode.sg // // Note: internal node type used to support IoMemory images // using System; using System.Text; using System.Collections; using System.Threading; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Io; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Security; using Microsoft.Singularity.Security.SDS; #if !SINGULARITY_PROCESS namespace Microsoft.Singularity.Directory #else using Microsoft.Singularity; using Microsoft.Singularity.V1.Services; namespace Microsoft.Application.DSP #endif { public class IoMemoryNode : Node { public IoMemory! ioMemory; public IoMemoryNode(IoMemory! ioMem, string! name, Node! parent) { this.ioMemory = ioMem; base(NodeType.IoMemory, name, parent); } /// /// null on success, the service argument if it failed. /// public override ServiceContract.Exp Bind(StringBuilder! p, string! fullPath, Principal pr, int curpos, out int position, out bool success, out bool linkFound, out ErrorCode error, out bool reparse, out string link, out string linkPrefix, [Claims] ServiceContract.Exp! service) { Kernel.Waypoint(3200); reparse = false; link = null; success = false; linkFound = false; linkPrefix = null; position = curpos; if (! (p.Length == 0) ){ error = ErrorCode.NotFound; return service; } // The FileContract needs to be subdivided into Read and Write, then // we can determine which permissions to use here. For now, it must // be the case that all uses (if any) of IoMemory objects in the file system // are read-only. [EPW] if (!CheckAccess(SdsAclPerms.ModeRead, pr, service)) { DebugStub.WriteLine("No access to IoMemoryNode.Bind"); error = ErrorCode.AccessDenied; return service; } #if !SINGULARITY_PROCESS Tracing.Log(Tracing.Debug, "Starting stream IoMemory writer"); //send a bind message to the IoMemory FS with the endpoint and the cookie as args. FileContract.Exp:Start fp = service as FileContract.Exp; if (fp == null) { success = false; error = ErrorCode.ContractNotSupported; return service; } Kernel.Waypoint(3201); IoMemFSContract.Imp:Ready io = Directory.DirectoryService.AcquireIoFS(); if (io != null) { Kernel.Waypoint(3202); io.SendConnect(fp, (UIntPtr)ioMemory.VirtualAddress, ioMemory.Length); Kernel.Waypoint(3203); io.RecvAckConnect(); Kernel.Waypoint(3204); Directory.DirectoryService.ReleaseIoFS(io); success = true; } else { DebugStub.Break(); delete fp; success = false; } Kernel.Waypoint(3205); error = ErrorCode.NoError; return null; #endif error = ErrorCode.NotImplemented; return service; } /// /// null on success, the sp argument if it failed. /// public override ServiceProviderContract.Imp Register(StringBuilder! p, Principal pr, [Claims]ServiceProviderContract.Imp! sp, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { // cannot register over an existing provider reparse = false; linkFound = false; link = null; error = ErrorCode.NotSupported; position = curpos; return sp; } /// /// The endpoint on success, null, if it fails. /// public override ServiceProviderContract.Imp:Start Deregister(StringBuilder! path, Principal pr, DirectoryServiceContract.Exp! ep, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { link = null; linkFound = false; reparse = false; error = ErrorCode.NotSupported; position = curpos; if (! (path.Length == 0) ) { return null; } // we are being removed // the remove will fail! // if we ever allow deregister of IoMemoryNode // do not forget to add an access control check. return null; } /// /// if true returns length and node type, otherwise error /// public override bool GetAttributes(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link, out long length, out NodeType nodeType ) { linkFound = false; reparse = false; link = null; error = ErrorCode.NoError; position = curpos; nodeType = NodeType.IoMemory; length = ioMemory.Length; return true; } /// /// null on success, the imp argument if it failed. /// public override NotifyContract.Imp Notify(StringBuilder! pathSpec, Principal pr, string! pattern, bool sendExisting, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link, [Claims] NotifyContract.Imp! notifyImp) { // this method should never be called error = ErrorCode.NotSupported; reparse = false; link = null; linkFound = false; position = curpos; return notifyImp; } public override FileContract.Imp CreateAndBindFile(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return null; } public override bool CreateDirectory(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { position = curpos; linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; return false; } public override bool CreateFile(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return false; } public override bool CreateLink(StringBuilder! p, Principal pr, string! value, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return false; } public override bool DeleteDirectory(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return false; } public override bool DeleteFile(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return false; } public override bool DeleteLink(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotImplemented; reparse = false; link = null; position = curpos; return false; } public override bool GetLinkValue(StringBuilder! p, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NotLink; reparse = false; link = null; position = curpos; return false; } public override bool QueryACL(StringBuilder! p, bool effective, Principal pr, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link, out Acl acl ) { linkFound = false; error = ErrorCode.NoError; reparse = false; link = null; position = curpos; acl = new Acl(); if (CheckAccess(SdsAclPerms.ModeRead, pr)) { error = ErrorCode.AccessDenied; return false; } if (effective) acl = new Acl(GetAclPattern()); else acl = GetInstanceAcl(); return true; } public override bool StoreACL(StringBuilder! p, Principal pr, Acl acl, int curpos, out int position, out bool linkFound, out ErrorCode error, out bool reparse, out string link ) { linkFound = false; error = ErrorCode.NoError; reparse = false; link = null; position = curpos; if (!CheckAccess(SdsAclPerms.ModeSetAcl, pr)) { error = ErrorCode.AccessDenied; return false; } SetInstanceAcl(acl); return true; } } }