341 lines
14 KiB
Plaintext
341 lines
14 KiB
Plaintext
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// File: DirectoryServiceContract.sg
|
|
//
|
|
|
|
using Microsoft.SingSharp;
|
|
using Microsoft.Singularity.Channels;
|
|
|
|
namespace Microsoft.Singularity.Directory
|
|
{
|
|
// enumeration of possible errors reported by any operation
|
|
public enum ErrorCode : uint
|
|
{
|
|
NoError = 0,
|
|
AccessDenied = 1,
|
|
AlreadyExists = 2,
|
|
BadArguments = 3,
|
|
ContractNotSupported = 4,
|
|
DirectoryNotEmpty = 5,
|
|
NotFound = 6,
|
|
ChannelClosed = 7,
|
|
Unsatisfiable = 8,
|
|
NotImplemented = 9,
|
|
NotSupported = 10,
|
|
CapacityReached = 11,
|
|
InsufficientResources = 12,
|
|
DirectoryFull = 13,
|
|
NotDirectory = 14,
|
|
NotLink = 15,
|
|
NotProvider = 16,
|
|
NotFile = 17,
|
|
IsOpen = 18,
|
|
Unknown = 99,
|
|
}
|
|
|
|
// enumeration of the existing node types found in the namespace
|
|
// implementation and the filesystem
|
|
public enum NodeType
|
|
{
|
|
Directory = 1,
|
|
File = 2,
|
|
IoMemory = 4,
|
|
ServiceProvider = 8,
|
|
SymLink = 16,
|
|
BadNode = 32,
|
|
}
|
|
|
|
// a REP struct used to return responses to find or notify.
|
|
public rep struct EnumerationRecords : ITracked
|
|
{
|
|
public char[]! in ExHeap Path; // short name within a directory
|
|
public NodeType Type; // its type
|
|
}
|
|
// a REP struct used to return responses to Get Attributes.
|
|
public rep struct FileAttributesRecord
|
|
{
|
|
public long CreationTime;
|
|
public long LastAccessTime;
|
|
public long LastWriteTime;
|
|
public long FileSize;
|
|
public NodeType Type; // its type
|
|
}
|
|
|
|
public contract DirectoryServiceContract : ServiceContract
|
|
{
|
|
|
|
// REPARSE MESSAGES
|
|
// used for 2 different scenarios: DirectoryProvider and SymLink traversal
|
|
// DirectoryProvider:
|
|
// path=new directoryProvider to bind to to continue traversal
|
|
// rest=suffix(P): the remainder of the initial path not yet parsed.
|
|
// SymLink
|
|
// path=contents of the symbolic link
|
|
// rest=suffix(P): the remainder of the initial path not yet parsed.
|
|
|
|
|
|
// attempt to bind to an service exp endpoint
|
|
in message Bind(char[]! in ExHeap path,
|
|
ServiceContract.Exp:Start! exp);
|
|
out message AckBind();
|
|
// attempt to return unused endpoint if possible
|
|
out message NakBind(ServiceContract.Exp:Start exp,
|
|
ErrorCode code);
|
|
out message NakBindReparse(char[]! in ExHeap path,
|
|
char[] in ExHeap rest,
|
|
bool linkFound,
|
|
ServiceContract.Exp:Start! exp);
|
|
|
|
// Find path and notify caller of any changes matching pattern over
|
|
// the imp endpoint supplied.
|
|
in message Notify(char[]! in ExHeap path,
|
|
char[]! in ExHeap pattern,
|
|
bool sendExisting,
|
|
NotifyContract.Imp:Start! imp);
|
|
out message AckNotify();
|
|
out message NakNotify(NotifyContract.Imp:Start! imp,
|
|
ErrorCode error);
|
|
out message NakNotifyReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound,
|
|
NotifyContract.Imp:Start imp);
|
|
|
|
// Enumerate the contents of the current directory
|
|
in message BeginEnumeration();
|
|
in message ReadEnumeration();
|
|
in message EndEnumeration();
|
|
|
|
out message EnumerationEntries (EnumerationRecords[]! in ExHeap results, bool moreEntries);
|
|
out message EnumerationTerminated(ErrorCode error);
|
|
|
|
// given a path return its nodetype and if meaningful its length
|
|
in message GetAttributes(char []! in ExHeap path);
|
|
out message AckGetAttributes(FileAttributesRecord fileAttributes);
|
|
out message NakGetAttributes(ErrorCode code);
|
|
out message NakGetAttributesReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
|
|
// given a path return the associated ACL if present
|
|
in message QueryACL(char []! in ExHeap path, bool effective);
|
|
out message AckQueryACL(char[] in ExHeap nodePattern, char[] in ExHeap descendantPattern);
|
|
out message NakQueryACL(ErrorCode code);
|
|
out message NakQueryACLReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
|
|
// Greater permissions needed for ops below
|
|
|
|
// register a service's name serviceProvider endpoint with the SDS
|
|
in message Register(char[]! in ExHeap path,
|
|
ServiceProviderContract.Imp:Start! imp);
|
|
out message AckRegister();
|
|
out message NakRegister(ServiceProviderContract.Imp:Start imp,
|
|
ErrorCode error);
|
|
out message NakRegisterReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound,
|
|
ServiceProviderContract.Imp:Start! imp);
|
|
|
|
// Deregister a service's name from the SDS
|
|
in message Deregister(char[]! in ExHeap path);
|
|
out message AckDeregister(ServiceProviderContract.Imp:Start! imp); // return deregistered endpoint
|
|
out message NakDeregister(ErrorCode error);
|
|
out message NakDeregisterReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
|
|
// create dirName within the current directory
|
|
// the current directory is the one bound on this channel
|
|
in message CreateDirectory(char []! in ExHeap dirName);
|
|
out message AckCreateDirectory();
|
|
out message NakCreateDirectory(ErrorCode code);
|
|
out message NakCreateDirectoryReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
// delete dirName within the current directory
|
|
// the current directory is the one bound on this channel
|
|
in message DeleteDirectory(char []! in ExHeap dirName);
|
|
out message AckDeleteDirectory();
|
|
out message NakDeleteDirectory(ErrorCode code);
|
|
out message NakDeleteDirectoryReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
// create file within the current directory
|
|
// the current directory is the one bound on this channel
|
|
// file creation only applies to the FS
|
|
in message CreateFile(char []! in ExHeap fileName);
|
|
out message AckCreateFile();
|
|
out message NakCreateFile(ErrorCode code);
|
|
out message NakCreateFileReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
// create and "open" or bind to fileName within the current directory
|
|
// the current directory is the one bound on this channel
|
|
// this is common enough pattern to supply an optimization
|
|
in message CreateAndBindFile(char []! in ExHeap fileName,
|
|
FileContract.Exp:Start! exp);
|
|
out message AckCreateAndBindFile();
|
|
out message NakCreateAndBindFile(FileContract.Exp:Start! exp,
|
|
ErrorCode code);
|
|
|
|
// delete fileName within the current directory
|
|
// the current directory is the one bound on this channel
|
|
in message DeleteFile(char []! in ExHeap fileName);
|
|
out message AckDeleteFile();
|
|
out message NakDeleteFile(ErrorCode code);
|
|
out message NakDeleteFileReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
// for the given path and permission, return the associated ACL if present
|
|
|
|
in message StoreACL(char []! in ExHeap fileName,
|
|
char[] in ExHeap nodePattern, char[] in ExHeap descendantPattern);
|
|
out message AckStoreACL();
|
|
out message NakStoreACL(ErrorCode code);
|
|
out message NakStoreACLReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
// create a symlink node at linkPath with value linkValue
|
|
// Upon traversal linkPath will be returned to client
|
|
// it is up to the client to interpret and re-submit bind
|
|
// see reparse messages below.
|
|
|
|
in message CreateLink(char []! in ExHeap linkPath,
|
|
char []! in ExHeap linkValue );
|
|
out message AckCreateLink();
|
|
out message NakCreateLink(ErrorCode code);
|
|
out message NakCreateLinkReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
// delete symlink node at linkPath
|
|
in message DeleteLink(char []! in ExHeap linkPath);
|
|
out message AckDeleteLink();
|
|
out message NakDeleteLink(ErrorCode code);
|
|
out message NakDeleteLinkReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
// Get symlink value
|
|
in message GetLinkValue(char []! in ExHeap linkPath);
|
|
out message AckGetLinkValue(char []! in ExHeap linkPath);
|
|
out message NakGetLinkValue(ErrorCode code);
|
|
out message NakGetLinkValueReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
|
|
out message Success();
|
|
|
|
////////////////////////////////////////////////////////
|
|
// State Machine
|
|
////////////////////////////////////////////////////////
|
|
|
|
override state Start: one {
|
|
Success! -> Ready;
|
|
}
|
|
|
|
state Enumerate : one {
|
|
EnumerationTerminated! -> Ready;
|
|
EnumerationEntries! -> EnumerateAck;
|
|
}
|
|
|
|
state EnumerateAck : one {
|
|
ReadEnumeration? -> Enumerate;
|
|
EndEnumeration? -> Ready;
|
|
}
|
|
|
|
|
|
state Ready: one
|
|
{
|
|
Bind? -> (AckBind!
|
|
or NakBind!
|
|
or NakBindReparse!
|
|
) -> Ready;
|
|
|
|
BeginEnumeration? -> Enumerate;
|
|
|
|
CreateAndBindFile? -> (AckCreateAndBindFile!
|
|
or NakCreateAndBindFile!
|
|
) -> Ready;
|
|
|
|
CreateDirectory? -> (AckCreateDirectory!
|
|
or NakCreateDirectory!
|
|
or NakCreateDirectoryReparse!
|
|
) -> Ready;
|
|
|
|
CreateFile? -> (AckCreateFile!
|
|
or NakCreateFile!
|
|
or NakCreateFileReparse!
|
|
) -> Ready;
|
|
|
|
CreateLink? -> (AckCreateLink!
|
|
or NakCreateLink!
|
|
or NakCreateLinkReparse!
|
|
) -> Ready;
|
|
|
|
|
|
DeleteDirectory? -> (AckDeleteDirectory!
|
|
or NakDeleteDirectory!
|
|
or NakDeleteDirectoryReparse!
|
|
) -> Ready;
|
|
|
|
DeleteFile? -> (AckDeleteFile!
|
|
or NakDeleteFile!
|
|
or NakDeleteFileReparse!
|
|
) -> Ready;
|
|
|
|
DeleteLink? -> (AckDeleteLink!
|
|
or NakDeleteLink!
|
|
or NakDeleteLinkReparse!
|
|
) -> Ready;
|
|
|
|
Deregister? -> (AckDeregister!
|
|
or NakDeregister!
|
|
or NakDeregisterReparse!
|
|
) -> Ready;
|
|
|
|
|
|
GetAttributes? -> (AckGetAttributes!
|
|
or NakGetAttributes!
|
|
or NakGetAttributesReparse!
|
|
) -> Ready;
|
|
|
|
GetLinkValue? -> (AckGetLinkValue!
|
|
or NakGetLinkValue!
|
|
or NakGetLinkValueReparse!
|
|
) -> Ready;
|
|
Notify? -> (AckNotify!
|
|
or NakNotify!
|
|
or NakNotifyReparse!
|
|
) -> Ready;
|
|
|
|
QueryACL? -> (AckQueryACL!
|
|
or NakQueryACL!
|
|
or NakQueryACLReparse!
|
|
) -> Ready;
|
|
|
|
Register? -> (AckRegister!
|
|
or NakRegister!
|
|
or NakRegisterReparse!
|
|
) -> Ready;
|
|
|
|
StoreACL? -> (AckStoreACL!
|
|
or NakStoreACL!
|
|
or NakStoreACLReparse!
|
|
) -> Ready;
|
|
}
|
|
}
|
|
}
|