1204 lines
52 KiB
Plaintext
1204 lines
52 KiB
Plaintext
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: WorkerFunctions.sg
|
||
|
//
|
||
|
// Note:
|
||
|
//
|
||
|
|
||
|
using System;
|
||
|
using System.Text;
|
||
|
using System.Collections;
|
||
|
using System.Runtime.Remoting;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Threading;
|
||
|
using Microsoft.SingSharp;
|
||
|
using Microsoft.Singularity.Channels;
|
||
|
using Microsoft.Singularity.Directory;
|
||
|
using Microsoft.Singularity.Security;
|
||
|
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
namespace Microsoft.Singularity.Directory
|
||
|
#else
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.V1.Services;
|
||
|
namespace Microsoft.Application.DSP
|
||
|
#endif
|
||
|
{
|
||
|
using SharedHeap = Microsoft.Singularity.Memory.SharedHeap;
|
||
|
|
||
|
class WorkerFunctions
|
||
|
{
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
// Worker functions for DirectoryServiceWorker loop
|
||
|
//------------------------------------------------------------------------------------
|
||
|
|
||
|
public static void DoDeregister(Node! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap i_path)
|
||
|
{
|
||
|
ErrorCode error;
|
||
|
bool reparse;
|
||
|
bool linkFound;
|
||
|
string link;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
string pathCopy = Bitter.ToString2(i_path);
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
try {
|
||
|
ServiceProviderContract.Imp:Start service =
|
||
|
dir.Deregister(new StringBuilder (Bitter.ToString2(i_path)),
|
||
|
pr,
|
||
|
ep,
|
||
|
out linkFound, out error, out reparse, out link);
|
||
|
|
||
|
if (service != null) {
|
||
|
ep.SendAckDeregister(service);
|
||
|
Tracing.Log(Tracing.Debug,"Register success");
|
||
|
delete i_path;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakDeregister(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakDeregisterReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakDeregister(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakDeregisterReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
//DebugStub.Break();
|
||
|
ep.SendNakDeregister(error);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
DebugStub.Print(" Exception {0}\n", __arglist(e.ToString()));
|
||
|
}
|
||
|
delete i_path;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
// Directory Enumeration
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoEnumerate(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep
|
||
|
)
|
||
|
{
|
||
|
ErrorCode error;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
EnumerationRecords[] in ExHeap results =
|
||
|
dir.Enumerate(pr, out error);
|
||
|
if (results == null) ep.SendEnumerationTerminated(ErrorCode.InsufficientResources);
|
||
|
else ep.SendEnumerationEntries(results, false);
|
||
|
}
|
||
|
|
||
|
public static void DoMore(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep
|
||
|
)
|
||
|
{
|
||
|
|
||
|
ep.SendEnumerationTerminated(ErrorCode.NotImplemented);
|
||
|
}
|
||
|
|
||
|
public static void DoStop(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep
|
||
|
)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoRegister(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap i_path,
|
||
|
[Claims] ServiceProviderContract.Imp:Start! i_provider
|
||
|
)
|
||
|
{
|
||
|
ErrorCode error;
|
||
|
bool reparse;
|
||
|
bool linkFound;
|
||
|
string link;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
string pathCopy = Bitter.ToString2(i_path);
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
ServiceProviderContract.Imp reject = null;
|
||
|
try {
|
||
|
Tracing.Log(Tracing.Debug," Register started");
|
||
|
reject = dir.Register(new StringBuilder(Bitter.ToString2(i_path)),
|
||
|
pr,
|
||
|
i_provider,
|
||
|
out linkFound, out error, out reparse, out link);
|
||
|
|
||
|
Tracing.Log(Tracing.Debug,"Register: linkFound={0}, reparse={1}",
|
||
|
linkFound ? (UIntPtr) 1 : (UIntPtr) 0,
|
||
|
reparse ? (UIntPtr) 1 : (UIntPtr) 0
|
||
|
);
|
||
|
if (reject == null) {
|
||
|
ep.SendAckRegister();
|
||
|
Tracing.Log(Tracing.Debug,"Register success");
|
||
|
}
|
||
|
else {
|
||
|
if (reparse) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing "+link);
|
||
|
if (link == null ) {
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakRegister(reject,ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakRegisterReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound,
|
||
|
reject);
|
||
|
}
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug,"Register(reparse)"+link);
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakRegister(reject, ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakRegisterReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound,
|
||
|
reject);
|
||
|
}
|
||
|
}
|
||
|
//DebugStub.Break();
|
||
|
}
|
||
|
} // reparse
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug," Bind failure!");
|
||
|
ep.SendNakRegister(reject, error);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
DebugStub.Print(" Exception {0}\n", __arglist(e.ToString()));
|
||
|
}
|
||
|
delete i_path;
|
||
|
Tracing.Log(Tracing.Debug," register {0}", (reject == null) ? "failed" : "success");
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoNotify(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap i_path,
|
||
|
[Claims] char[]! in ExHeap i_pattern,
|
||
|
bool sendExisting,
|
||
|
[Claims] NotifyContract.Imp:Start! i_notifyImp
|
||
|
)
|
||
|
{
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
|
||
|
string path1 = Bitter.ToString2(i_path);
|
||
|
string pattern = Bitter.ToString2(i_pattern);
|
||
|
string pathCopy = Bitter.ToString2(i_path);
|
||
|
|
||
|
delete i_path;
|
||
|
delete i_pattern;
|
||
|
|
||
|
Tracing.Log(Tracing.Debug,"Notify {0} {1} "+path1,pattern);
|
||
|
NotifyContract.Imp reject =
|
||
|
dir.Notify(new StringBuilder(path1),
|
||
|
pr,
|
||
|
pattern,
|
||
|
sendExisting,
|
||
|
out linkFound,
|
||
|
out error, out reparse, out link, i_notifyImp);
|
||
|
if (reject == null) { // success
|
||
|
delete reject;
|
||
|
ep.SendAckNotify();
|
||
|
Tracing.Log(Tracing.Debug,"Notify success");
|
||
|
}
|
||
|
else {
|
||
|
if (reparse) {
|
||
|
if (null == link ) {
|
||
|
ep.SendNakNotify(reject,error);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakNotifyReparse(exPrefix, exSuffix, linkFound, reject);
|
||
|
}
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug,"Notify(reparse)"+link);
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakNotify(reject, ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakNotifyReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound,
|
||
|
reject);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug," Bind failure!");
|
||
|
ep.SendNakNotify(reject, error);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
|
||
|
public static void DoBind(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap i_path,
|
||
|
[Claims] ServiceContract.Exp:Start! i_server
|
||
|
)
|
||
|
{
|
||
|
try {
|
||
|
bool success;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(i_path);
|
||
|
Tracing.Log(Tracing.Debug," lookup started: {0}",pathCopy);
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoBind,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
ServiceContract.Exp reject =
|
||
|
dir.Bind(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out success, out linkFound, out error, out reparse, out link, i_server);
|
||
|
Tracing.Log(Tracing.Debug," success={0}, linkFound={1}, reparse={2}",
|
||
|
success ? (UIntPtr) 1 : (UIntPtr) 0,
|
||
|
linkFound ? (UIntPtr) 1 : (UIntPtr) 0,
|
||
|
reparse ? (UIntPtr) 1 : (UIntPtr) 0
|
||
|
);
|
||
|
if (reject == null && success) { // success
|
||
|
ep.SendAckBind();
|
||
|
Tracing.Log(Tracing.Debug," Bind success");
|
||
|
}
|
||
|
else {
|
||
|
if (reparse) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing "+link);
|
||
|
if (link == null || reject == null) {
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakBind(reject,ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
ep.SendNakBindReparse(exPrefix,
|
||
|
null,
|
||
|
linkFound,
|
||
|
reject);
|
||
|
}
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug,"Bind(reparse)"+link);
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakBind(reject, ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakBindReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound,
|
||
|
reject);
|
||
|
}
|
||
|
}
|
||
|
//DebugStub.Break();
|
||
|
}
|
||
|
} // reparse
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug," Bind failure!");
|
||
|
ep.SendNakBind(reject, error);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
DebugStub.Print(" Exception {0}\n", __arglist(e.ToString()));
|
||
|
}
|
||
|
delete i_path;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoGetAttributes(DirNode! dir, DirectoryServiceContract.Exp! ep ,[Claims] char[]! in ExHeap i_path)
|
||
|
{
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
long length;
|
||
|
NodeType nodeType;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(i_path);
|
||
|
string! path1 = Bitter.ToString2(i_path);
|
||
|
delete i_path;
|
||
|
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoGetAttributes,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
bool aSuccess = dir.GetAttributes(new StringBuilder(path1),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link,
|
||
|
out length,
|
||
|
out nodeType
|
||
|
);
|
||
|
|
||
|
Tracing.Log(Tracing.Debug,"linkFound={1}, reparse={2}",
|
||
|
linkFound ? (UIntPtr) 1 : (UIntPtr) 0,
|
||
|
reparse ? (UIntPtr) 1 : (UIntPtr) 0
|
||
|
);
|
||
|
if (aSuccess) {
|
||
|
//if (error != ErrorCode.NoError) DebugStub.Break();
|
||
|
ep.SendAckGetAttributes(nodeType,length);
|
||
|
}
|
||
|
else {
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakGetAttributes(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakGetAttributesReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
Tracing.Log(Tracing.Debug,"GetAttr(reparse)"+link);
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakGetAttributes(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) {
|
||
|
prefix = pathCopy;
|
||
|
}
|
||
|
else {
|
||
|
prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
}
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakGetAttributesReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
ep.SendNakGetAttributes(error);
|
||
|
}
|
||
|
}
|
||
|
Kernel.Waypoint(3401);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoCreateDirectory(DirNode! dir, DirectoryServiceContract.Exp! ep ,[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
|
||
|
#if SINGULARITY_PROCESS
|
||
|
//DebugStub.Break();
|
||
|
#else
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoCreateDirectory,
|
||
|
pathCopy);
|
||
|
|
||
|
#endif
|
||
|
ok = dir.CreateDirectory(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckCreateDirectory();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakCreateDirectory(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakCreateDirectoryReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakCreateDirectory(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakCreateDirectoryReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
//DebugStub.Break();
|
||
|
ep.SendNakCreateDirectory(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoCreateFile(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep,
|
||
|
[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoCreateFile,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
|
||
|
ok = dir.CreateFile(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckCreateFile();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakCreateFile(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakCreateFileReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakCreateFile(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakCreateFileReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakCreateFile(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoDeleteDirectory( DirNode! dir, DirectoryServiceContract.Exp! ep ,[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoDeleteDirectory,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
ok = dir.DeleteDirectory(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckDeleteDirectory();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakDeleteDirectory(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakDeleteDirectoryReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakDeleteDirectory(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakDeleteDirectoryReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakDeleteDirectory(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoDeleteFile( DirNode! dir, DirectoryServiceContract.Exp! ep,
|
||
|
[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoCreateFile,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
|
||
|
ok = dir.DeleteFile(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckDeleteFile();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakDeleteFile(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakDeleteFileReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakDeleteFile(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakDeleteFileReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakDeleteFile(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void DoQueryACL( DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath
|
||
|
)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Acl acl;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
string! pathCopy = Bitter.ToString2(exPath);
|
||
|
|
||
|
delete exPath;
|
||
|
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
ok = dir.QueryACL(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link,
|
||
|
out acl);
|
||
|
if (ok) {
|
||
|
ep.SendAckQueryACL(Bitter.FromString(acl.val));
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakQueryACL(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link", link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakQueryACLReparse(exPrefix, exSuffix, linkFound);
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakQueryACL(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakQueryACLReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakQueryACL(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void DoStoreACL( DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath,
|
||
|
[Claims] char[] in ExHeap acl
|
||
|
)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
string! pathCopy = Bitter.ToString2(exPath);
|
||
|
Acl myacl = new Acl(Bitter.ToString(acl));
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
delete exPath;
|
||
|
|
||
|
ok = dir.StoreACL(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
myacl,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if (ok) {
|
||
|
ep.SendAckStoreACL();
|
||
|
}
|
||
|
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakStoreACL(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link", link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakStoreACLReparse(exPrefix, exSuffix, linkFound, acl);
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakStoreACL(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakStoreACLReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound,
|
||
|
acl);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakStoreACL(error);
|
||
|
}
|
||
|
delete acl;
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void DoCreateAndBindFile(DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath,
|
||
|
[Claims] FileContract.Imp:Ready! imp
|
||
|
)
|
||
|
{
|
||
|
ep.SendNakCreateAndBindFile(imp, ErrorCode.NotImplemented);
|
||
|
delete exPath;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
// DeleteLink
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoDeleteLink( DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoDeleteLink,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
ok = dir.DeleteLink(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckDeleteLink();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakDeleteLink(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakDeleteLinkReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakDeleteLink(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakDeleteLinkReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakDeleteLink(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
// GetLinkValue
|
||
|
//------------------------------------------------------------------------------------
|
||
|
public static void DoGetLinkValue( DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoGetLinkValue,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
ok = dir.GetLinkValue(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
if ( link == null ) {
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakGetLinkValue(ErrorCode.Unknown);
|
||
|
return;
|
||
|
}
|
||
|
ep.SendAckGetLinkValue(Bitter.FromString2(link));
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakGetLinkValue(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakGetLinkValueReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakGetLinkValue(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakGetLinkValueReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
ep.SendNakGetLinkValue(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void DoCreateLink( DirNode! dir,
|
||
|
DirectoryServiceContract.Exp! ep ,
|
||
|
[Claims] char[]! in ExHeap exPath,
|
||
|
[Claims] char[]! in ExHeap exValue
|
||
|
)
|
||
|
{
|
||
|
try {
|
||
|
bool ok;
|
||
|
bool reparse;
|
||
|
string link;
|
||
|
ErrorCode error;
|
||
|
bool linkFound;
|
||
|
string prefix;
|
||
|
Char[] in ExHeap exPrefix;
|
||
|
Char[] in ExHeap exSuffix;
|
||
|
Principal pr = AclCore.EndpointPeer(ep);
|
||
|
|
||
|
string pathCopy = Bitter.ToString2(exPath);
|
||
|
delete exPath;
|
||
|
string value = Bitter.ToString2(exValue);
|
||
|
delete exValue;
|
||
|
|
||
|
#if !SINGULARITY_PROCESS
|
||
|
Monitoring.Log(Monitoring.Provider.Directory,
|
||
|
(ushort)DirectoryEvent.DoCreateLink,
|
||
|
pathCopy);
|
||
|
#endif
|
||
|
|
||
|
ok = dir.CreateLink(new StringBuilder (pathCopy),
|
||
|
pr,
|
||
|
value,
|
||
|
out linkFound,
|
||
|
out error,
|
||
|
out reparse,
|
||
|
out link);
|
||
|
if(ok) {
|
||
|
ep.SendAckCreateLink();
|
||
|
return;
|
||
|
}
|
||
|
if (reparse) {
|
||
|
if (null == link) {
|
||
|
ep.SendNakCreateLink(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
if (linkFound) {
|
||
|
Tracing.Log(Tracing.Debug,"reparsing {0} as link",link);
|
||
|
exPrefix = Bitter.FromString2(link);
|
||
|
exSuffix = Bitter.FromString2("");
|
||
|
ep.SendNakCreateLinkReparse(exPrefix, exSuffix, linkFound);
|
||
|
}
|
||
|
else {
|
||
|
// need to construct prefix from original path
|
||
|
int prefixIndex = pathCopy.IndexOf(link);
|
||
|
if (-1 == prefixIndex) {
|
||
|
exSuffix = null;
|
||
|
exPrefix = null;
|
||
|
DebugStub.Break();
|
||
|
ep.SendNakCreateLink(ErrorCode.Unknown);
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
if (prefixIndex == 0) prefix = pathCopy;
|
||
|
else prefix = pathCopy.Substring(0,prefixIndex);
|
||
|
|
||
|
exPrefix = Bitter.FromString2(prefix);
|
||
|
exSuffix = Bitter.FromString2(link);
|
||
|
ep.SendNakCreateLinkReparse(exPrefix,
|
||
|
exSuffix,
|
||
|
linkFound
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} //reparse
|
||
|
else {
|
||
|
//DebugStub.Break();
|
||
|
ep.SendNakCreateLink(error);
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} //WorkerFunctions class
|
||
|
} //namespace
|