internal ObjRef DeserializeInTheCurrentDomain (int domainId, byte[] tInfo) { string local_uri = string.Copy (this.uri); ChannelInfo cinfo = new ChannelInfo (new CrossAppDomainData (domainId)); ObjRef res = new ObjRef (local_uri, cinfo); IRemotingTypeInfo typeInfo = (IRemotingTypeInfo)CADSerializer.DeserializeObjectSafe (tInfo); res.typeInfo = typeInfo; return res; }
} // GetObjectDataHelper // This method retrieves the channel info object to be serialized. // It does special checking to see if a channel url needs to be bashed // (currently used for switching "http://..." url to "https://...". private IChannelInfo GetChannelInfoHelper() { ChannelInfo oldChannelInfo = channelInfo as ChannelInfo; if (oldChannelInfo == null) return channelInfo; Object[] oldChannelData = oldChannelInfo.ChannelData; if (oldChannelData == null) return oldChannelInfo; String[] bashInfo = (String[])CallContext.GetData("__bashChannelUrl"); if (bashInfo == null) return oldChannelInfo; String urlToBash = bashInfo[0]; String replacementUrl = bashInfo[1]; // Copy channel info and go bash urls. ChannelInfo newChInfo = new ChannelInfo(); newChInfo.ChannelData = new Object[oldChannelData.Length]; for (int co = 0; co < oldChannelData.Length; co++) { newChInfo.ChannelData[co] = oldChannelData[co]; // see if this is one of the ones that we need to bash ChannelDataStore channelDataStore = newChInfo.ChannelData[co] as ChannelDataStore; if (channelDataStore != null) { String[] urls = channelDataStore.ChannelUris; if ((urls != null) && (urls.Length == 1) && urls[0].Equals(urlToBash)) { // We want to bash just the url, so we do a shallow copy // and replace the url array with the replacementUrl. ChannelDataStore newChannelDataStore = channelDataStore.InternalShallowCopy(); newChannelDataStore.ChannelUris = new String[1]; newChannelDataStore.ChannelUris[0] = replacementUrl; newChInfo.ChannelData[co] = newChannelDataStore; } } } return newChInfo; } // GetChannelInfoHelper
[System.Security.SecurityCritical] // auto-generated private IChannelInfo GetChannelInfoHelper() { ChannelInfo oldChannelInfo = channelInfo as ChannelInfo; if (oldChannelInfo == null) return channelInfo; Object[] oldChannelData = oldChannelInfo.ChannelData; if (oldChannelData == null) return oldChannelInfo; // <STRIP>This will work for the IIS scenario since the machine name + application name // will differentiate the url. If we generalize this mechanism in the future, // we should only [....] the url if the ObjRef is from the current appdomain.</STRIP> String[] bashInfo = (String[])CallContext.GetData("__bashChannelUrl"); if (bashInfo == null) return oldChannelInfo; String urlToBash = bashInfo[0]; String replacementUrl = bashInfo[1]; // Copy channel info and go [....] urls. ChannelInfo newChInfo = new ChannelInfo(); newChInfo.ChannelData = new Object[oldChannelData.Length]; for (int co = 0; co < oldChannelData.Length; co++) { newChInfo.ChannelData[co] = oldChannelData[co]; // see if this is one of the ones that we need to [....] ChannelDataStore channelDataStore = newChInfo.ChannelData[co] as ChannelDataStore; if (channelDataStore != null) { String[] urls = channelDataStore.ChannelUris; if ((urls != null) && (urls.Length == 1) && urls[0].Equals(urlToBash)) { // We want to [....] just the url, so we do a shallow copy // and replace the url array with the replacementUrl. ChannelDataStore newChannelDataStore = channelDataStore.InternalShallowCopy(); newChannelDataStore.ChannelUris = new String[1]; newChannelDataStore.ChannelUris[0] = replacementUrl; newChInfo.ChannelData[co] = newChannelDataStore; } } } return newChInfo; } // GetChannelInfoHelper
protected object UnmarshalArgument (object arg, ArrayList args) { if (arg == null) return null; // Check if argument is an holder (then we know that it's a serialized argument) CADArgHolder holder = arg as CADArgHolder; if (null != holder) { return args [holder.index]; } CADObjRef objref = arg as CADObjRef; if (null != objref) { string typeName = string.Copy (objref.TypeName); string uri = string.Copy (objref.URI); int domid = objref.SourceDomain; ChannelInfo cinfo = new ChannelInfo (new CrossAppDomainData (domid)); ObjRef localRef = new ObjRef (typeName, uri, cinfo); return RemotingServices.Unmarshal (localRef); } if (arg is Array) { Array argb = (Array)arg; Array argn; // We can't use Array.CreateInstance (arg.GetType().GetElementType()) because // GetElementType() returns a type from the source domain. switch (Type.GetTypeCode (arg.GetType().GetElementType())) { case TypeCode.Boolean: argn = new bool [argb.Length]; break; case TypeCode.Byte: argn = new Byte [argb.Length]; break; case TypeCode.Char: argn = new Char [argb.Length]; break; case TypeCode.Decimal: argn = new Decimal [argb.Length]; break; case TypeCode.Double: argn = new Double [argb.Length]; break; case TypeCode.Int16: argn = new Int16 [argb.Length]; break; case TypeCode.Int32: argn = new Int32 [argb.Length]; break; case TypeCode.Int64: argn = new Int64 [argb.Length]; break; case TypeCode.SByte: argn = new SByte [argb.Length]; break; case TypeCode.Single: argn = new Single [argb.Length]; break; case TypeCode.UInt16: argn = new UInt16 [argb.Length]; break; case TypeCode.UInt32: argn = new UInt32 [argb.Length]; break; case TypeCode.UInt64: argn = new UInt64 [argb.Length]; break; default: throw new NotSupportedException (); } argb.CopyTo (argn, 0); return argn; } switch (Type.GetTypeCode (arg.GetType())) { case TypeCode.Boolean: return (bool)arg; case TypeCode.Byte: return (byte)arg; case TypeCode.Char: return (char)arg; case TypeCode.Decimal: return (decimal)arg; case TypeCode.Double: return (double)arg; case TypeCode.Int16: return (Int16)arg; case TypeCode.Int32: return (Int32)arg; case TypeCode.Int64: return (Int64)arg; case TypeCode.SByte: return (SByte)arg; case TypeCode.Single: return (Single)arg; case TypeCode.UInt16: return (UInt16)arg; case TypeCode.UInt32: return (UInt32)arg; case TypeCode.UInt64: return (UInt64)arg; case TypeCode.String: return string.Copy ((string) arg); case TypeCode.DateTime: return new DateTime (((DateTime)arg).Ticks); default: if (arg is TimeSpan) return new TimeSpan (((TimeSpan)arg).Ticks); if (arg is IntPtr) return (IntPtr) arg; break; } throw new NotSupportedException ("Parameter of type " + arg.GetType () + " cannot be unmarshalled"); }
/* * Flushes any buffered writes to the channel */ Int32 FlushChannel(ChannelInfo ChannelToFlush) { Int32 ReturnValue = Constants.INVALID; if ((ChannelToFlush.ChannelFlags & EChannelFlags.ACCESS_WRITE) != 0 && (ChannelToFlush.ChannelOffset > 0) && (ChannelToFlush.ChannelData != null) && (ChannelToFlush.ChannelFileStream != null)) { try { ChannelToFlush.ChannelFileStream.Write(ChannelToFlush.ChannelData, 0, ChannelToFlush.ChannelOffset); ReturnValue = ChannelToFlush.ChannelOffset; } catch (Exception Ex) { Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:FlushChannel] Error: " + Ex.Message); ReturnValue = Constants.ERROR_CHANNEL_IO_FAILED; } ChannelToFlush.ChannelOffset = 0; } return ReturnValue; }
/** * Opens a data channel for streaming data into the cache associated with an Agent * * @param ChannelName The name of the channel being opened * @param ChannelFlags The mode, access, and other attributes of the channel being opened * * @return A handle to the opened channel (< 0 is error) */ public virtual Int32 OpenChannel(String ChannelName, EChannelFlags ChannelFlags) { StartTiming("OpenChannel-Managed", true); Int32 ChannelHandle = Constants.INVALID; bool NewChannelSuccessfullyCreated = false; if (Connection != null) { try { // Ask the Agent if the file is safe to open, if required if (!ConnectionConfiguration.IsPureLocalConnection) { StartTiming("OpenChannel-Remote", false); ChannelHandle = Connection.OpenChannel(ConnectionHandle, ChannelName, (EChannelFlags)ChannelFlags); StopTiming(); } else { // If this is a pure local connection, then all we need to assure // if that the handle we generate here is unique to the connection ChannelHandle = Interlocked.Increment(ref BaseChannelHandle); } // If the channel is safe to open, open it up if (ChannelHandle >= 0) { // Track the newly created temp file ChannelInfo NewChannelInfo = new ChannelInfo(); NewChannelInfo.ChannelName = ChannelName; NewChannelInfo.ChannelFlags = ChannelFlags; NewChannelInfo.ChannelHandle = ChannelHandle; NewChannelInfo.ChannelFileStream = null; NewChannelInfo.ChannelData = null; NewChannelInfo.ChannelOffset = 0; // Determine the proper path name for the file String FullManagedName = GenerateFullChannelName(ChannelName, ChannelFlags); // Try to open the file if ((ChannelFlags & EChannelFlags.ACCESS_WRITE) != 0) { // Open the file stream NewChannelInfo.ChannelFileStream = new FileStream(FullManagedName, FileMode.Create, FileAccess.Write, FileShare.None); // Slightly different path for compressed files if ((ChannelFlags & EChannelFlags.MISC_ENABLE_COMPRESSION) != 0) { Stream NewChannelStream = NewChannelInfo.ChannelFileStream; NewChannelInfo.ChannelFileStream = new GZipStream(NewChannelStream, CompressionMode.Compress, false); } // If we were able to open the file, add it to the active channel list Monitor.Enter(FreeChannelWriteBuffers); try { // If available, take the next free write buffer from the list if (FreeChannelWriteBuffers.Count > 0) { NewChannelInfo.ChannelData = FreeChannelWriteBuffers.Pop(); } else { // Otherwise, allocate a new write buffer for this channel (default to 1MB) NewChannelInfo.ChannelData = new byte[1024 * 1024]; } } finally { Monitor.Exit( FreeChannelWriteBuffers ); } // Track the newly created file OpenChannels.Add(ChannelHandle, NewChannelInfo); NewChannelSuccessfullyCreated = true; } else if ((ChannelFlags & EChannelFlags.ACCESS_READ) != 0) { if (File.Exists(FullManagedName)) { // Slightly different paths for compressed and non-compressed files if ((ChannelFlags & EChannelFlags.MISC_ENABLE_COMPRESSION) != 0) { // Open the input stream, loading it entirely into memory byte[] RawCompressedData = File.ReadAllBytes(FullManagedName); // Allocate the destination buffer // The size of the uncompressed data is contained in the last four bytes of the file // http://www.ietf.org/rfc/rfc1952.txt?number=1952 Int32 UncompressedSize = BitConverter.ToInt32(RawCompressedData, RawCompressedData.Length - 4); NewChannelInfo.ChannelData = new byte[UncompressedSize]; // Open the decompression stream and decompress directly into the destination Stream DecompressionChannelStream = new GZipStream(new MemoryStream(RawCompressedData), CompressionMode.Decompress, false); DecompressionChannelStream.Read(NewChannelInfo.ChannelData, 0, UncompressedSize); DecompressionChannelStream.Close(); } else { // Simply read in the entire file in one go NewChannelInfo.ChannelData = File.ReadAllBytes(FullManagedName); } // Track the newly created channel OpenChannels.Add(ChannelHandle, NewChannelInfo); NewChannelSuccessfullyCreated = true; } else { // Failed to find the channel to read, return an error ChannelHandle = Constants.ERROR_CHANNEL_NOT_FOUND; } } } } catch (Exception Ex) { Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:OpenChannel] Error: " + Ex.ToString()); ChannelHandle = Constants.ERROR_CONNECTION_DISCONNECTED; CleanupClosedConnection(); } // If we opened the channel on the agent, but failed to create // the file, close it on the agent if ((ChannelHandle >= 0) && (NewChannelSuccessfullyCreated == false)) { if (!ConnectionConfiguration.IsPureLocalConnection) { StartTiming("CloseChannel-Remote", false); try { Connection.CloseChannel(ConnectionHandle, ChannelHandle); } catch (Exception Ex) { Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:OpenChannel] Cleanup error: " + Ex.Message); CleanupClosedConnection(); } StopTiming(); } ChannelHandle = Constants.ERROR_CHANNEL_IO_FAILED; } } else { ChannelHandle = Constants.ERROR_CONNECTION_NOT_FOUND; } StopTiming(); return ChannelHandle; }
} // GetObjectDataHelper // This method retrieves the channel info object to be serialized. // It does special checking to see if a channel url needs to be bashed // (currently used for switching "http://..." url to "https://...". private IChannelInfo GetChannelInfoHelper() { ChannelInfo oldChannelInfo = channelInfo as ChannelInfo; if (oldChannelInfo == null) return channelInfo; Object[] oldChannelData = oldChannelInfo.ChannelData; if (oldChannelData == null) return oldChannelInfo; String[] bashInfo = (String[])CallContext.GetData("__bashChannelUrl"); if (bashInfo == null) return oldChannelInfo; String urlToBash = bashInfo[0]; String replacementUrl = bashInfo[1]; ChannelInfo newChInfo = new ChannelInfo(); newChInfo.ChannelData = new Object[oldChannelData.Length]; for (int co = 0; co < oldChannelData.Length; co++) { newChInfo.ChannelData[co] = oldChannelData[co]; ChannelDataStore channelDataStore = newChInfo.ChannelData[co] as ChannelDataStore; if (channelDataStore != null) { String[] urls = channelDataStore.ChannelUris; if ((urls != null) && (urls.Length == 1) && urls[0].Equals(urlToBash)) { ChannelDataStore newChannelDataStore = channelDataStore.InternalShallowCopy(); newChannelDataStore.ChannelUris = new String[1]; newChannelDataStore.ChannelUris[0] = replacementUrl; newChInfo.ChannelData[co] = newChannelDataStore; } } } return newChInfo; } // GetChannelInfoHelper