} // ValidateReturnArg // This is shared code path that executes when an EndInvoke is called // either on a delegate on a proxy // OR a regular delegate (called asynchronously). internal static IMessage EndInvokeHelper(Message reqMsg, bool bProxyCase) { AsyncResult ar = reqMsg.GetAsyncResult() as AsyncResult; IMessage retMsg = null; // used for proxy case only! if (ar == null) { throw new RemotingException( Environment.GetResourceString( "Remoting_Message_BadAsyncResult")); } if (ar.AsyncDelegate != reqMsg.GetThisPtr()) { throw new InvalidOperationException(Environment.GetResourceString( "InvalidOperation_MismatchedAsyncResult")); } if (!ar.IsCompleted) { // Note: using ThreadPoolAware to detect if this is a // ThreadAffinity or Synchronization context. ar.AsyncWaitHandle.WaitOne( Int32.MaxValue, Thread.CurrentContext.IsThreadPoolAware); } lock (ar) { if (ar.EndInvokeCalled) { throw new InvalidOperationException( Environment.GetResourceString( "InvalidOperation_EndInvokeCalledMultiple")); } ar.EndInvokeCalled = true; IMethodReturnMessage mrm = (IMethodReturnMessage)ar.GetReplyMessage(); BCLDebug.Assert( mrm != null, "Reply sink should ensure we have a reply message before signalling"); // For the proxy case this is handled by RealProxy if (!bProxyCase) { Exception e = mrm.Exception; if (e != null) { // throw e; throw e.PrepForRemoting(); } else { reqMsg.PropagateOutParameters( mrm.Args, mrm.ReturnValue); } } else { retMsg = mrm; } // Merge the call context back into the thread that // called EndInvoke CallContext.GetLogicalCallContext().Merge( mrm.LogicalCallContext); } // Will be non-null only for proxy case! return(retMsg); } // EndInvokeHelper
unsafe public static void UnregisterChannel(IChannel chnl) { // we allow null to be passed in, so we can use this api to trigger the // refresh of the channel data lock (s_channelLock) { if (chnl != null) { RegisteredChannelList regChnlList = s_registeredChannels; // Check to make sure that the channel has been registered int matchingIdx = regChnlList.FindChannelIndex(chnl); if (-1 == matchingIdx) { throw new RemotingException(String.Format(Environment.GetResourceString("Remoting_ChannelNotRegistered"), chnl.ChannelName)); } RegisteredChannel[] oldList = regChnlList.RegisteredChannels; RegisteredChannel[] newList = null; BCLDebug.Assert((oldList != null) && (oldList.Length != 0), "channel list should not be empty"); newList = new RegisteredChannel[oldList.Length - 1]; // Call stop listening on the channel if it is a receiver. IChannelReceiver srvChannel = chnl as IChannelReceiver; if (srvChannel != null) { srvChannel.StopListening(null); } int current = 0; int oldPos = 0; while (oldPos < oldList.Length) { if (oldPos == matchingIdx) { oldPos++; } else { newList[current] = oldList[oldPos]; current++; oldPos++; } } if (perf_Contexts != null) { perf_Contexts->cChannels--; } if (perf_globalContexts != null) { perf_globalContexts->cChannels--; } s_registeredChannels = new RegisteredChannelList(newList); } RefreshChannelData(); } // lock (s_channelLock) } // UnregisterChannel
public static ServerProcessing DispatchMessage( IServerChannelSinkStack sinkStack, IMessage msg, out IMessage replyMsg) { ServerProcessing processing = ServerProcessing.Complete; replyMsg = null; try { if (null == msg) { throw new ArgumentNullException("msg"); } BCLDebug.Trace("REMOTE", "Dispatching for URI " + InternalSink.GetURI(msg)); // we must switch to the target context of the object and call the context chains etc... // Currenly XContextChannel does exactly so. So this method is just a wrapper.. // Make sure that incoming calls are counted as a remote call. This way it // makes more sense on a server. IncrementRemoteCalls(); // Check if the object has been disconnected or if it is // a well known object then we have to create it lazily. ServerIdentity srvId = CheckDisconnectedOrCreateWellKnownObject(msg); // Make sure that this isn't an AppDomain object since we don't allow // calls to the AppDomain from out of process (and x-process calls // are always dispatched through this method) if (srvId.ServerType == typeof(System.AppDomain)) { throw new RemotingException( Environment.GetResourceString( "Remoting_AppDomainsCantBeCalledRemotely")); } IMethodCallMessage mcm = msg as IMethodCallMessage; if (mcm == null) { // It's a plain IMessage, so just check to make sure that the // target object implements IMessageSink and dispatch synchronously. if (!typeof(IMessageSink).IsAssignableFrom(srvId.ServerType)) { throw new RemotingException( Environment.GetResourceString( "Remoting_AppDomainsCantBeCalledRemotely")); } processing = ServerProcessing.Complete; replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg); } else { // It's an IMethodCallMessage. // Check if the method is one way. Dispatch one way calls in // an asynchronous manner MethodInfo method = (MethodInfo)mcm.MethodBase; // X-process / X-machine calls should be to non-static // public methods only! Non-public or static methods can't // be called remotely. if ((!method.IsPublic || method.IsStatic) && !RemotingServices.IsMethodAllowedRemotely(method)) { throw new RemotingException( Environment.GetResourceString( "Remoting_NonPublicOrStaticCantBeCalledRemotely")); } RemotingMethodCachedData cache = (RemotingMethodCachedData) InternalRemotingServices.GetReflectionCachedData(method); if (RemotingServices.IsOneWay(method)) { processing = ServerProcessing.OneWay; ChannelServices.GetCrossContextChannelSink().AsyncProcessMessage(msg, null); } else { // regular processing processing = ServerProcessing.Complete; replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg); } } // end of case for IMethodCallMessage } catch (Exception e) { if (processing != ServerProcessing.OneWay) { try { IMethodCallMessage mcm = (IMethodCallMessage)((msg != null)?msg:new ErrorMessage()); replyMsg = (IMessage) new ReturnMessage(e, mcm); if (msg != null) { ((ReturnMessage)replyMsg).SetLogicalCallContext( (LogicalCallContext) msg.Properties[Message.CallContextKey]); } } catch (Exception) { // Fatal exception .. ignore } } } return(processing); } // DispatchMessage
private static Object _GetAccountingInfo( Evidence evidence, Type evidenceType, bool fDomain, out Object oNormalized) { Object o = null; IEnumerator e; BCLDebug.Assert(evidence != null, "evidence != null"); e = evidence.GetHostEnumerator(); if (evidenceType == null) { // Caller does not have any preference // Order of preference is Publisher, Strong Name, Url, Site Publisher pub = null; StrongName sn = null; Url url = null; Site site = null; Zone zone = null; while (e.MoveNext()) { o = e.Current; if (o is Publisher) { pub = (Publisher)o; break; } else if (o is StrongName) { sn = (StrongName)o; } else if (o is Url) { url = (Url)o; } else if (o is Site) { site = (Site)o; } else if (o is Zone) { zone = (Zone)o; } } if (pub != null) { o = pub; } else if (sn != null) { o = sn; } else if (url != null) { o = url; } else if (site != null) { o = site; } else if (zone != null) { o = zone; } else { // The evidence object can have tons of other objects // creatd by the policy system. Ignore those. if (fDomain) { throw new IsolatedStorageException( Environment.GetResourceString( "IsolatedStorage_DomainNoEvidence")); } else { throw new IsolatedStorageException( Environment.GetResourceString( "IsolatedStorage_AssemblyNoEvidence")); } } } else { Object obj; while (e.MoveNext()) { obj = e.Current; if (evidenceType.Equals(obj.GetType())) { o = obj; break; } } if (o == null) { if (fDomain) { throw new IsolatedStorageException( Environment.GetResourceString( "IsolatedStorage_DomainEvidenceMissing")); } else { throw new IsolatedStorageException( Environment.GetResourceString( "IsolatedStorage_AssemblyEvidenceMissing")); } } } // For startup Perf, Url, Site, StrongName types don't implement // INormalizeForIsolatedStorage interface, instead they have // Normalize() method. if (o is INormalizeForIsolatedStorage) { oNormalized = ((INormalizeForIsolatedStorage)o).Normalize(); } else if (o is Publisher) { oNormalized = ((Publisher)o).Normalize(); } else if (o is StrongName) { oNormalized = ((StrongName)o).Normalize(); } else if (o is Url) { oNormalized = ((Url)o).Normalize(); } else if (o is Site) { oNormalized = ((Site)o).Normalize(); } else if (o is Zone) { oNormalized = ((Zone)o).Normalize(); } else { oNormalized = null; } return(o); }
internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity) { if (checkSecurity) { // Name can be null! It's the most common use of RegQueryValueEx EnsureNotDisposed(); } Object data = defaultValue; int type = 0; int datasize = 0; int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); if (ret != 0) { if (IsPerfDataKey()) { int size = 65000; int sizeInput = size; int r; byte[] blob = new byte[size]; while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) { if (size == Int32.MaxValue) { // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond Int32.MaxValue Win32Error(r, name); } else if (size > (Int32.MaxValue / 2)) { // at this point in the loop "size * 2" would cause an overflow size = Int32.MaxValue; } else { size *= 2; } sizeInput = size; blob = new byte[size]; } if (r != 0) { Win32Error(r, name); } return(blob); } else { // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data). // Some OS's returned ERROR_MORE_DATA even in success cases, so we // want to continue on through the function. if (ret != Win32Native.ERROR_MORE_DATA) { return(data); } } } if (datasize < 0) { // unexpected code path BCLDebug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize"); datasize = 0; } switch (type) { case Win32Native.REG_NONE: case Win32Native.REG_DWORD_BIG_ENDIAN: case Win32Native.REG_BINARY: { byte[] blob = new byte[datasize]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); data = blob; } break; case Win32Native.REG_QWORD: { // also REG_QWORD_LITTLE_ENDIAN if (datasize > 8) { // prevent an AV in the edge case that datasize is larger than sizeof(long) goto case Win32Native.REG_BINARY; } long blob = 0; BCLDebug.Assert(datasize == 8, "datasize==8"); // Here, datasize must be 8 when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); data = blob; } break; case Win32Native.REG_DWORD: { // also REG_DWORD_LITTLE_ENDIAN if (datasize > 4) { // prevent an AV in the edge case that datasize is larger than sizeof(int) goto case Win32Native.REG_QWORD; } int blob = 0; BCLDebug.Assert(datasize == 4, "datasize==4"); // Here, datasize must be four when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); data = blob; } break; case Win32Native.REG_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked (datasize + 1); } catch (OverflowException e) { throw new IOException(SR.Arg_RegGetOverflowBug, e); } } char[] blob = new char[datasize / 2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { data = new String(blob, 0, blob.Length - 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character data = new String(blob); } } break; case Win32Native.REG_EXPAND_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked (datasize + 1); } catch (OverflowException e) { throw new IOException(SR.Arg_RegGetOverflowBug, e); } } char[] blob = new char[datasize / 2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { data = new String(blob, 0, blob.Length - 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character data = new String(blob); } if (!doNotExpand) { data = Environment.ExpandEnvironmentVariables((String)data); } } break; case Win32Native.REG_MULTI_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked (datasize + 1); } catch (OverflowException e) { throw new IOException(SR.Arg_RegGetOverflowBug, e); } } char[] blob = new char[datasize / 2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); // make sure the string is null terminated before processing the data if (blob.Length > 0 && blob[blob.Length - 1] != (char)0) { try { char[] newBlob = new char[checked (blob.Length + 1)]; for (int i = 0; i < blob.Length; i++) { newBlob[i] = blob[i]; } newBlob[newBlob.Length - 1] = (char)0; blob = newBlob; } catch (OverflowException e) { throw new IOException(SR.Arg_RegGetOverflowBug, e); } blob[blob.Length - 1] = (char)0; } IList <String> strings = new List <String>(); int cur = 0; int len = blob.Length; while (ret == 0 && cur < len) { int nextNull = cur; while (nextNull < len && blob[nextNull] != (char)0) { nextNull++; } if (nextNull < len) { BCLDebug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0"); if (nextNull - cur > 0) { strings.Add(new String(blob, cur, nextNull - cur)); } else { // we found an empty string. But if we're at the end of the data, // it's just the extra null terminator. if (nextNull != len - 1) { strings.Add(String.Empty); } } } else { strings.Add(new String(blob, cur, len - cur)); } cur = nextNull + 1; } data = new String[strings.Count]; strings.CopyTo((String[])data, 0); } break; case Win32Native.REG_LINK: default: break; } return(data); }
// From a name, finds the associated virtual offset for the data. // This does a binary search through the names. internal int FindPosForResource(String name) { BCLDebug.Assert(_store != null, "ResourceReader is closed!"); int hash = FastResourceComparer.GetHashCode(name); BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " hash: " + hash.ToString("x")); // Binary search over the hashes. Use the _namePositions array to // determine where they exist in the underlying stream. int lo = 0; int hi = _numResources - 1; int index = -1; bool success = false; while (lo <= hi) { index = (lo + hi) >> 1; // Do NOT use subtraction here, since it will wrap for large // negative numbers. //int c = _nameHashes[index].CompareTo(hash); int currentHash = GetNameHash(index); int c; if (currentHash == hash) { c = 0; } else if (currentHash < hash) { c = -1; } else { c = 1; } //BCLDebug.Log("RESMGRFILEFORMAT", " Probing index "+index+" lo: "+lo+" hi: "+hi+" c: "+c); if (c == 0) { success = true; break; } if (c < 0) { lo = index + 1; } else { hi = index - 1; } } if (!success) { #if RESOURCE_FILE_FORMAT_DEBUG lock (this) { _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(index), SeekOrigin.Begin); String lastReadString = _store.ReadString(); } BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " failed. i: " + index + " lo: " + lo + " hi: " + hi + " last read string: \"" + lastReadString + "\""); #endif return(-1); } // index is the location in our hash array that corresponds with a // value in the namePositions array. // There could be collisions in our hash function. Check on both sides // of index to find the range of hash values that are equal to the // target hash value. if (lo != index) { lo = index; while (lo > 0 && GetNameHash(lo - 1) == hash) { lo--; } } if (hi != index) { hi = index; while (hi < _numResources && GetNameHash(hi + 1) == hash) { hi++; } } lock (this) { for (int i = lo; i <= hi; i++) { _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin); if (CompareStringEqualsName(name)) { int dataPos = _store.ReadInt32(); BCLDebug.Assert(dataPos >= 0 || dataPos < _store.BaseStream.Length - _dataSectionOffset, "Data section relative offset is out of the bounds of the data section! dataPos: " + dataPos); return(dataPos); } } } BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + ": Found a hash collision, HOWEVER, neither of these collided values equaled the given string."); return(-1); }
// Reads in the header information for a .resources file. Verifies some // of the assumptions about this resource set, and builds the class table // for the default resource file format. private void ReadResources() { BCLDebug.Assert(_store != null, "ResourceReader is closed!"); BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence)); // Do partial binds so we can be tolerant of version number changes. bf.AssemblyFormat = FormatterAssemblyStyle.Simple; _objFormatter = bf; try { // Read ResourceManager header // Check for magic number int magicNum = _store.ReadInt32(); if (magicNum != ResourceManager.MagicNumber) { throw new ArgumentException(Environment.GetResourceString("Resources_StreamNotValid")); } // Assuming this is ResourceManager header V1 or greater, hopefully // after the version number there is a number of bytes to skip // to bypass the rest of the ResMgr header. int resMgrHeaderVersion = _store.ReadInt32(); if (resMgrHeaderVersion > 1) { int numBytesToSkip = _store.ReadInt32(); BCLDebug.Log("RESMGRFILEFORMAT", LogLevel.Status, "ReadResources: Unexpected ResMgr header version: {0} Skipping ahead {1} bytes.", resMgrHeaderVersion, numBytesToSkip); BCLDebug.Assert(numBytesToSkip >= 0, "numBytesToSkip in ResMgr header should be positive!"); _store.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current); } else { BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Parsing ResMgr header v1."); _store.ReadInt32(); // We don't care about numBytesToSkip. // Read in type name for a suitable ResourceReader // Note ResourceWriter & InternalResGen use different Strings. String readerType = _store.ReadString(); if (!readerType.Equals(ResourceManager.ResReaderTypeName) && !readerType.Equals(typeof(ResourceReader).FullName) && !readerType.Equals(ResourceManager.ResReaderTypeNameInternal)) { throw new NotSupportedException("This .resources file shouldn't be used with this reader. Your resource reader type: " + readerType); } // Skip over type name for a suitable ResourceSet _store.ReadString(); } // Read RuntimeResourceSet header // Do file version check int version = _store.ReadInt32(); if (version != RuntimeResourceSet.Version) { throw new ArgumentException(String.Format("Version conflict with ResourceManager .resources files! Expected version: {0} but got: {1}", RuntimeResourceSet.Version, version)); } _numResources = _store.ReadInt32(); BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Expecting " + _numResources + " resources."); #if _DEBUG if (ResourceManager.DEBUG >= 4) { Console.WriteLine("ResourceReader::ReadResources - Reading in " + _numResources + " resources"); } #endif // Read type names into type array. int numTypes = _store.ReadInt32(); _typeTable = new Type[numTypes]; for (int i = 0; i < numTypes; i++) { String typeName = _store.ReadString(); // Do partial binds to be tolerant of version number changes. _typeTable[i] = Assembly.LoadTypeWithPartialName(typeName, false); if (_typeTable[i] == null) { throw new TypeLoadException(Environment.GetResourceString("TypeLoad_PartialBindFailed", typeName)); } } // Initialize deserialization permission array InitSafeToDeserializeArray(); #if _DEBUG if (ResourceManager.DEBUG >= 5) { Console.WriteLine("ResourceReader::ReadResources - Reading in " + numTypes + " type table entries"); } #endif // Prepare to read in the array of name hashes // Note that the name hashes array is aligned to 8 bytes so // we can use pointers into it on 64 bit machines. (4 bytes // may be sufficient, but let's plan for the future) // Skip over alignment stuff, if it's present. long pos = _store.BaseStream.Position; int alignBytes = ((int)pos) & 7; bool fileIsAligned = true; if (alignBytes != 0) { // For backwards compatibility, don't require the "PAD" stuff // in here, but we should definitely skip it if present. for (int i = 0; i < 8 - alignBytes; i++) { byte b = _store.ReadByte(); if (b != "PAD"[i % 3]) { fileIsAligned = false; break; } } // If we weren't aligned, we shouldn't have skipped this data! if (!fileIsAligned) { _store.BaseStream.Position = pos; } else { BCLDebug.Assert((_store.BaseStream.Position & 7) == 0, "ResourceReader: Stream should be aligned on an 8 byte boundary now!"); } } #if RESOURCE_FILE_FORMAT_DEBUG Console.WriteLine("ResourceReader: File alignment: " + fileIsAligned); #endif #if !WIN32 // If the file wasn't aligned, we can't use the _ums code on IA64. // However, this should only be a problem for .resources files // that weren't rebuilt after ~August 11, 2001 when I introduced // the alignment code. We can rip this check in the next // version. -- Brian Grunkemeyer, 8/8/2001 if (!fileIsAligned) { _ums = null; } #endif // Read in the array of name hashes #if RESOURCE_FILE_FORMAT_DEBUG // Skip over "HASHES->" _store.BaseStream.Position += 8; #endif if (_ums == null) { _nameHashes = new int[_numResources]; for (int i = 0; i < _numResources; i++) { _nameHashes[i] = _store.ReadInt32(); } } else { _nameHashesPtr = (int *)_ums.GetBytePtr(); // Skip over the array of nameHashes. _ums.Seek(4 * _numResources, SeekOrigin.Current); } // Read in the array of relative positions for all the names. #if RESOURCE_FILE_FORMAT_DEBUG // Skip over "POS---->" _store.BaseStream.Position += 8; #endif if (_ums == null) { _namePositions = new int[_numResources]; for (int i = 0; i < _numResources; i++) { _namePositions[i] = _store.ReadInt32(); } } else { _namePositionsPtr = (int *)_ums.GetBytePtr(); // Skip over the array of namePositions. _ums.Seek(4 * _numResources, SeekOrigin.Current); } // Read location of data section. _dataSectionOffset = _store.ReadInt32(); // Store current location as start of name section _nameSectionOffset = _store.BaseStream.Position; BCLDebug.Log("RESMGRFILEFORMAT", String.Format("ReadResources: _nameOffset = 0x{0:x} _dataOffset = 0x{1:x}", _nameSectionOffset, _dataSectionOffset)); } catch (EndOfStreamException eof) { throw new ArgumentException("Stream is not a valid .resources file! It was possibly truncated.", eof); } }
// This is internal and called by something else, internal override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS decoder) { // Just assert, we're called internally so these should be safe, checked already BCLDebug.Assert(bytes != null, "[SBCSCodePageEncoding.GetCharCount]bytes is null"); BCLDebug.Assert(count >= 0, "[SBCSCodePageEncoding.GetCharCount]byteCount is negative"); CheckMemorySection(); // See if we have best fit bool bUseBestFit = false; // Only need decoder fallback buffer if not using default replacement fallback or best fit fallback. DecoderReplacementFallback fallback = null; if (decoder == null) { fallback = this.DecoderFallback as DecoderReplacementFallback; bUseBestFit = this.DecoderFallback.IsMicrosoftBestFitFallback; } else { fallback = decoder.Fallback as DecoderReplacementFallback; bUseBestFit = decoder.Fallback.IsMicrosoftBestFitFallback; BCLDebug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start"); } if (bUseBestFit || (fallback != null && fallback.MaxCharCount == 1)) { // Just return length, SBCS stay the same length because they don't map to surrogate // pairs and we don't have a decoder fallback. return(count); } // Might need one of these later DecoderFallbackBuffer fallbackBuffer = null; // Have to do it the hard way. // Assume charCount will be == count int charCount = count; byte[] byteBuffer = new byte[1]; // Do it our fast way byte *byteEnd = bytes + count; // Quick loop while (bytes < byteEnd) { // Faster if don't use *bytes++; char c; c = mapBytesToUnicode[*bytes]; bytes++; // If unknown we have to do fallback count if (c == UNKNOWN_CHAR) { // Must have a fallback buffer if (fallbackBuffer == null) { // Need to adjust count so we get real start if (decoder == null) { fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = decoder.FallbackBuffer; } fallbackBuffer.InternalInitialize(byteEnd - count, null); } // Use fallback buffer byteBuffer[0] = *(bytes - 1); charCount--; // We'd already reserved one for *(bytes-1) charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes); } } // Fallback buffer must be empty BCLDebug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetCharCount]Expected Empty fallback buffer at end"); // Converted sequence is same length as input return(charCount); }
// We have a managed code page entry, so load our tables // SBCS data section looks like: // // char[256] - what each byte maps to in unicode. No support for surrogates. 0 is undefined code point // (except 0 for byte 0 is expected to be a real 0) // // byte/char* - Data for best fit (unicode->bytes), again no best fit for Unicode // 1st WORD is Unicode // of 1st character position // Next bytes are best fit byte for that position. Position is incremented after each byte // byte < 0x20 means skip the next n positions. (Where n is the byte #) // byte == 1 means that next word is another unicode code point # // byte == 0 is unknown. (doesn't override initial WCHAR[256] table! protected override unsafe void LoadManagedCodePage() { // Should be loading OUR code page BCLDebug.Assert(pCodePage->CodePage == this.dataTableCodePage, "[SBCSCodePageEncoding.LoadManagedCodePage]Expected to load data table code page"); // Make sure we're really a 1 byte code page if (pCodePage->ByteCount != 1) { throw new NotSupportedException( Environment.GetResourceString("NotSupported_NoCodepageData", CodePage)); } // Remember our unknown bytes & chars byteUnknown = (byte)pCodePage->ByteReplace; charUnknown = pCodePage->UnicodeReplace; // Get our mapped section 65536 bytes for unicode->bytes, 256 * 2 bytes for bytes->unicode // Plus 4 byte to remember CP # when done loading it. (Don't want to get IA64 or anything out of alignment) byte *pMemorySection = GetSharedMemory(65536 * 1 + 256 * 2 + 4 + iExtraBytes); mapBytesToUnicode = (char *)pMemorySection; mapUnicodeToBytes = (byte *)(pMemorySection + 256 * 2); mapCodePageCached = (int *)(pMemorySection + 256 * 2 + 65536 * 1 + iExtraBytes); // If its cached (& filled in) we don't have to do anything else if (*mapCodePageCached != 0) { BCLDebug.Assert(*mapCodePageCached == this.dataTableCodePage, "[DBCSCodePageEncoding.LoadManagedCodePage]Expected mapped section cached page to be same as data table code page. Cached : " + *mapCodePageCached + " Expected:" + this.dataTableCodePage); if (*mapCodePageCached != this.dataTableCodePage) { throw new OutOfMemoryException( Environment.GetResourceString("Arg_OutOfMemoryException")); } // If its cached (& filled in) we don't have to do anything else return; } // Need to read our data file and fill in our section. // WARNING: Multiple code pieces could do this at once (so we don't have to lock machine-wide) // so be careful here. Only stick legal values in here, don't stick temporary values. // Read our data file and set mapBytesToUnicode and mapUnicodeToBytes appropriately // First table is just all 256 mappings char *pTemp = (char *)&(pCodePage->FirstDataWord); for (int b = 0; b < 256; b++) { if (pTemp[b] != 0 || b == 0) { mapBytesToUnicode[b] = pTemp[b]; if (pTemp[b] != UNKNOWN_CHAR) { mapUnicodeToBytes[pTemp[b]] = (byte)b; } } else { mapBytesToUnicode[b] = UNKNOWN_CHAR; } } // We're done with our mapped section, set our flag so others don't have to rebuild table. *mapCodePageCached = this.dataTableCodePage; }
internal override unsafe int GetBytes(char *chars, int charCount, byte *bytes, int byteCount, EncoderNLS encoder) { // Just need to ASSERT, this is called by something else internal that checked parameters already BCLDebug.Assert(bytes != null, "[SBCSCodePageEncoding.GetBytes]bytes is null"); BCLDebug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetBytes]byteCount is negative"); BCLDebug.Assert(chars != null, "[SBCSCodePageEncoding.GetBytes]chars is null"); BCLDebug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetBytes]charCount is negative"); // Assert because we shouldn't be able to have a null encoder. BCLDebug.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback"); CheckMemorySection(); // Need to test fallback EncoderReplacementFallback fallback = null; // Get any left over characters char charLeftOver = (char)0; if (encoder != null) { charLeftOver = encoder.charLeftOver; BCLDebug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver), "[SBCSCodePageEncoding.GetBytes]leftover character should be high surrogate"); fallback = encoder.Fallback as EncoderReplacementFallback; // Verify that we have no fallbackbuffer, for SBCS its always empty, so just assert BCLDebug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer || encoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetBytes]Expected empty fallback buffer at start"); // if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer && // encoder.FallbackBuffer.Remaining > 0) // throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty", // this.EncodingName, encoder.Fallback.GetType())); } else { // If we aren't using default fallback then we may have a complicated count. fallback = this.EncoderFallback as EncoderReplacementFallback; } // prepare our end char *charEnd = chars + charCount; byte *byteStart = bytes; char *charStart = chars; // See if we do the fast default or slightly slower fallback if (fallback != null && fallback.MaxCharCount == 1) { // Make sure our fallback character is valid first byte bReplacement = mapUnicodeToBytes[fallback.DefaultString[0]]; // Check for replacements in range, otherwise fall back to slow version. if (bReplacement != 0) { // We should have exactly as many output bytes as input bytes, unless there's a left // over character, in which case we may need one more. // If we had a left over character will have to add a ? (This happens if they had a funky // fallback last time, but not this time.) (We can't spit any out though // because with fallback encoder each surrogate is treated as a seperate code point) if (charLeftOver > 0) { // Have to have room // Throw even if doing no throw version because this is just 1 char, // so buffer will never be big enough if (byteCount == 0) { ThrowBytesOverflow(encoder, true); } // This'll make sure we still have more room and also make sure our return value is correct. *(bytes++) = bReplacement; byteCount--; // We used one of the ones we were counting. } // This keeps us from overrunning our output buffer if (byteCount < charCount) { // Throw or make buffer smaller? ThrowBytesOverflow(encoder, byteCount < 1); // Just use what we can charEnd = chars + byteCount; } // Simple way while (chars < charEnd) { char ch2 = *chars; chars++; byte bTemp = mapUnicodeToBytes[ch2]; // Check for fallback if (bTemp == 0 && ch2 != (char)0) { *bytes = bReplacement; } else { *bytes = bTemp; } bytes++; } // Clear encoder if (encoder != null) { encoder.charLeftOver = (char)0; encoder.m_charsUsed = (int)(chars - charStart); } return((int)(bytes - byteStart)); } } // Slower version, have to do real fallback. // For fallback we may need a fallback buffer, we know we aren't default fallback EncoderFallbackBuffer fallbackBuffer = null; // prepare our end byte *byteEnd = bytes + byteCount; // We may have a left over character from last time, try and process it. if (charLeftOver > 0) { // Since left over char was a surrogate, it'll have to be fallen back. // Get Fallback BCLDebug.Assert(encoder != null, "[SBCSCodePageEncoding.GetBytes]Expect to have encoder if we have a charLeftOver"); fallbackBuffer = encoder.FallbackBuffer; fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true); // This will fallback a pair if *chars is a low surrogate fallbackBuffer.InternalFallback(charLeftOver, ref chars); if (fallbackBuffer.Remaining > byteEnd - bytes) { // Throw it, if we don't have enough for this we never will ThrowBytesOverflow(encoder, true); } } // Now we may have fallback char[] already from the encoder fallback above // Go ahead and do it, including the fallback. char ch; while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 || chars < charEnd) { // First unwind any fallback if (ch == 0) { // No fallback, just get next char ch = *chars; chars++; } // get byte for this char byte bTemp = mapUnicodeToBytes[ch]; // Check for fallback, this'll catch surrogate pairs too. if (bTemp == 0 && ch != (char)0) { // Get Fallback if (fallbackBuffer == null) { // Create & init fallback buffer if (encoder == null) { fallbackBuffer = this.encoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = encoder.FallbackBuffer; } // chars has moved so we need to remember figure it out so Exception fallback // index will be correct fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, true); } // Make sure we have enough room. Each fallback char will be 1 output char // (or recursion exception will be thrown) fallbackBuffer.InternalFallback(ch, ref chars); if (fallbackBuffer.Remaining > byteEnd - bytes) { // Didn't use this char, reset it BCLDebug.Assert(chars > charStart, "[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (fallback)"); chars--; fallbackBuffer.InternalReset(); // Throw it & drop this data ThrowBytesOverflow(encoder, chars == charStart); break; } continue; } // We'll use this one // Bounds check if (bytes >= byteEnd) { // didn't use this char, we'll throw or use buffer BCLDebug.Assert(fallbackBuffer == null || fallbackBuffer.bFallingBack == false, "[SBCSCodePageEncoding.GetBytes]Expected to NOT be falling back"); if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false) { BCLDebug.Assert(chars > charStart, "[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (normal)"); chars--; // don't use last char } ThrowBytesOverflow(encoder, chars == charStart); // throw ? break; // don't throw, stop } // Go ahead and add it *bytes = bTemp; bytes++; } // encoder stuff if we have one if (encoder != null) { // Fallback stuck it in encoder if necessary, but we have to clear MustFlush cases if (fallbackBuffer != null && !fallbackBuffer.bUsedEncoder) { // Clear it in case of MustFlush encoder.charLeftOver = (char)0; } // Set our chars used count encoder.m_charsUsed = (int)(chars - charStart); } // Expect Empty fallback buffer for SBCS BCLDebug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetBytes]Expected Empty fallback buffer at end"); return((int)(bytes - byteStart)); }
// Constructor called by serialization. // Note: We use the base GetObjectData however internal SBCSCodePageEncoding(SerializationInfo info, StreamingContext context) : base(0) { // Actually this can't ever get called, CodePageEncoding is our proxy BCLDebug.Assert(false, "Didn't expect to make it to SBCSCodePageEncoding serialization constructor"); throw new ArgumentNullException("this"); }
// GetByteCount // Note: We start by assuming that the output will be the same as count. Having // an encoder or fallback may change that assumption internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS encoder) { // Just need to ASSERT, this is called by something else internal that checked parameters already BCLDebug.Assert(count >= 0, "[SBCSCodePageEncoding.GetByteCount]count is negative"); BCLDebug.Assert(chars != null, "[SBCSCodePageEncoding.GetByteCount]chars is null"); // Assert because we shouldn't be able to have a null encoder. BCLDebug.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetByteCount]Attempting to use null fallback"); CheckMemorySection(); // Need to test fallback EncoderReplacementFallback fallback = null; // Get any left over characters char charLeftOver = (char)0; if (encoder != null) { charLeftOver = encoder.charLeftOver; BCLDebug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver), "[SBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate"); fallback = encoder.Fallback as EncoderReplacementFallback; // Verify that we have no fallbackbuffer, actually for SBCS this is always empty, so just assert BCLDebug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer || encoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetByteCount]Expected empty fallback buffer at start"); } else { // If we aren't using default fallback then we may have a complicated count. fallback = this.EncoderFallback as EncoderReplacementFallback; } if ((fallback != null && fallback.MaxCharCount == 1) /* || bIsBestFit*/) { // Replacement fallback encodes surrogate pairs as two ?? (or two whatever), so return size is always // same as input size. // Note that no existing SBCS code pages map code points to supplimentary characters, so this is easy. // We could however have 1 extra byte if the last call had an encoder and a funky fallback and // if we don't use the funky fallback this time. // Do we have an extra char left over from last time? if (charLeftOver > 0) { count++; } return(count); } // It had a funky fallback, so its more complicated // Need buffer maybe later EncoderFallbackBuffer fallbackBuffer = null; // prepare our end int byteCount = 0; char *charEnd = chars + count; // We may have a left over character from last time, try and process it. if (charLeftOver > 0) { // Since left over char was a surrogate, it'll have to be fallen back. // Get Fallback BCLDebug.Assert(encoder != null, "[SBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver"); fallbackBuffer = encoder.FallbackBuffer; fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false); // This will fallback a pair if *chars is a low surrogate fallbackBuffer.InternalFallback(charLeftOver, ref chars); } // Now we may have fallback char[] already from the encoder // Go ahead and do it, including the fallback. char ch; while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 || chars < charEnd) { // First unwind any fallback if (ch == 0) { // No fallback, just get next char ch = *chars; chars++; } // get byte for this char byte bTemp = mapUnicodeToBytes[ch]; // Check for fallback, this'll catch surrogate pairs too. if (bTemp == 0 && ch != (char)0) { if (fallbackBuffer == null) { // Create & init fallback buffer if (encoder == null) { fallbackBuffer = this.encoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = encoder.FallbackBuffer; } // chars has moved so we need to remember figure it out so Exception fallback // index will be correct fallbackBuffer.InternalInitialize(charEnd - count, charEnd, encoder, false); } // Get Fallback fallbackBuffer.InternalFallback(ch, ref chars); continue; } // We'll use this one byteCount++; } BCLDebug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetByteCount]Expected Empty fallback buffer at end"); return((int)byteCount); }
// Read in our best fit table protected unsafe override void ReadBestFitTable() { // Lock so we don't confuse ourselves. lock (InternalSyncObject) { // If we got a best fit array already, then don't do this if (arrayUnicodeBestFit == null) { // // Read in Best Fit table. // // First check the SBCS->Unicode best fit table, which starts right after the // 256 word data table. This table looks like word, word where 1st word is byte and 2nd // word is replacement for that word. It ends when byte == 0. byte *pData = (byte *)&(pCodePage->FirstDataWord); pData += 512; // Need new best fit array char[] arrayTemp = new char[256]; for (int i = 0; i < 256; i++) { arrayTemp[i] = mapBytesToUnicode[i]; } // See if our words are zero ushort byteTemp; while ((byteTemp = *((ushort *)pData)) != 0) { BCLDebug.Assert(arrayTemp[byteTemp] == UNKNOWN_CHAR, String.Format(CultureInfo.InvariantCulture, "[SBCSCodePageEncoding::ReadBestFitTable] Expected unallocated byte (not 0x{2:X2}) for best fit byte at 0x{0:X2} for code page {1}", byteTemp, CodePage, (int)arrayTemp[byteTemp])); pData += 2; arrayTemp[byteTemp] = *((char *)pData); pData += 2; } // Remember our new array arrayByteBestFit = arrayTemp; // It was on 0, it needs to be on next byte pData += 2; byte *pUnicodeToSBCS = pData; // Now count our characters from our Unicode->SBCS best fit table, // which is right after our 256 byte data table int iBestFitCount = 0; // Now do the UnicodeToBytes Best Fit mapping (this is the one we normally think of when we say "best fit") // pData should be pointing at the first data point for Bytes->Unicode table int unicodePosition = *((ushort *)pData); pData += 2; while (unicodePosition < 0x10000) { // Get the next byte byte input = *pData; pData++; // build our table: if (input == 1) { // Use next 2 bytes as our byte position unicodePosition = *((ushort *)pData); pData += 2; } else if (input < 0x20 && input > 0 && input != 0x1e) { // Advance input characters unicodePosition += input; } else { // Use this character if it isn't zero if (input > 0) { iBestFitCount++; } // skip this unicode position in any case unicodePosition++; } } // Make an array for our best fit data arrayTemp = new char[iBestFitCount * 2]; // Now actually read in the data // reset pData should be pointing at the first data point for Bytes->Unicode table pData = pUnicodeToSBCS; unicodePosition = *((ushort *)pData); pData += 2; iBestFitCount = 0; while (unicodePosition < 0x10000) { // Get the next byte byte input = *pData; pData++; // build our table: if (input == 1) { // Use next 2 bytes as our byte position unicodePosition = *((ushort *)pData); pData += 2; } else if (input < 0x20 && input > 0 && input != 0x1e) { // Advance input characters unicodePosition += input; } else { // Check for escape for glyph range if (input == 0x1e) { // Its an escape, so just read next byte directly input = *pData; pData++; } // 0 means just skip me if (input > 0) { // Use this character arrayTemp[iBestFitCount++] = (char)unicodePosition; // Have to map it to Unicode because best fit will need unicode value of best fit char. arrayTemp[iBestFitCount++] = mapBytesToUnicode[input]; BCLDebug.Assert(arrayTemp[iBestFitCount - 1] != (char)0, String.Format(CultureInfo.InvariantCulture, "[SBCSCodePageEncoding.ReadBestFitTable] No valid Unicode value {0:X4} for round trip bytes {1:X4}, encoding {2}", (int)mapBytesToUnicode[input], (int)input, CodePage)); } unicodePosition++; } } // Remember it arrayUnicodeBestFit = arrayTemp; } } }
// Private method invoked by the transparent proxy private void PrivateInvoke(ref MessageData msgData, int type) { IMessage reqMsg = null; CallType callType = (CallType)type; IMessage retMsg = null; int msgFlags = -1; // Used only for Construction case RemotingProxy rp = null; // Create a message object based on the type of call if (CallType.MethodCall == callType) { Message msg = new Message(); msg.InitFields(msgData); reqMsg = msg; msgFlags = msg.GetCallType(); } else if (CallType.ConstructorCall == (CallType)callType) { // We use msgFlags to handle CallContext around // the virtual call to Invoke() msgFlags = Message.Sync; rp = this as RemotingProxy; ConstructorCallMessage ctorMsg = null; bool bIsWellKnown = false; if (!IsRemotingProxy()) { // Create a new constructor call message // FUTURE: We should have a means to pass call-site // attributes to extensible proxies during activation ctorMsg = new ConstructorCallMessage(null, null, null, GetProxiedType()); } else { // Extract the constructor message set in the first step of activation. ctorMsg = rp.ConstructorMessage; // If the proxy is a wellknown client proxy, we don't // need to run the c'tor. Identity id = rp.IdentityObject; if (id != null) { bIsWellKnown = id.IsWellKnown(); } } if ((null == ctorMsg) || bIsWellKnown) { // This is also used to short-circuit the activation path // when we have a well known proxy that has already been // initialized (there's a race condition if we don't do this). // // This is a special case, where we have a remoting proxy // but the constructormessage hasn't been setup. // so let us just bail out.. // this is currently used by ServicedComponent's for cross // appdomain pooling: rajak // ctorMsg = new ConstructorCallMessage(null, null, null, GetProxiedType()); // Set the constructor frame info in the CCM ctorMsg.SetFrame(msgData); reqMsg = ctorMsg; // If this was the default ctor, check that default .ctor was called. if (bIsWellKnown) { BCLDebug.Assert(rp != null, "RemotingProxy expected here!"); // Clear any cached ctorMsg on the RemotingProxy rp.ConstructorMessage = null; // We did execute a Connect. Throw if the client // code is also trying to use a non-default constructor // at the same time. if (ctorMsg.ArgCount != 0) { throw new RemotingException( Environment.GetResourceString( "Remoting_Activation_WellKnownCTOR")); } } // Create a constructor return message retMsg = new ConstructorReturnMessage((MarshalByRefObject)GetTransparentProxy(), null, 0, null, ctorMsg); } else { // Set the constructor frame info in the CCM ctorMsg.SetFrame(msgData); reqMsg = ctorMsg; } } else { BCLDebug.Assert(false, "Unknown call type"); } // Make sure that outgoing remote calls are counted. ChannelServices.IncrementRemoteCalls(); // For non-remoting proxies, EndAsync should not call Invoke() // because the proxy cannot support Async and the call has already // finished executing in BeginAsync if (!IsRemotingProxy() && ((msgFlags & Message.EndAsync) == Message.EndAsync)) { Message msg = reqMsg as Message; retMsg = EndInvokeHelper(msg, true); BCLDebug.Assert(null != retMsg, "null != retMsg"); } // Invoke BCLDebug.Assert(null != reqMsg, "null != reqMsg"); if (null == retMsg) { // NOTE: there are cases where we setup a return message // and we don't want the activation call to go through // refer to the note above for ServicedComponents and Cross Appdomain // pooling LogicalCallContext cctx = null; Thread currentThread = Thread.CurrentThread; // Pick up or clone the call context from the thread // and install it in the reqMsg as appropriate cctx = currentThread.GetLogicalCallContext(); SetCallContextInMessage(reqMsg, msgFlags, cctx); // Add the outgoing "Header"'s to the message. cctx.PropagateOutgoingHeadersToMessage(reqMsg); retMsg = Invoke(reqMsg); // Get the call context returned and set it on the thread ReturnCallContextToThread(currentThread, retMsg, msgFlags, cctx); // Pull response "Header"'s out of the message CallContext.GetLogicalCallContext().PropagateIncomingHeadersToCallContext(retMsg); } if (!IsRemotingProxy() && ((msgFlags & Message.BeginAsync) == Message.BeginAsync)) { // This was a begin-async on a non-Remoting Proxy. For V-1 they // cannot support Async and end up doing a Sync call. We need // to fill up here to make the call look like async to // the caller. // Create the async result to return Message msg = reqMsg as Message; AsyncResult ar = new AsyncResult(msg); // Tell the async result that the call has actually completed // so it can hold on to the return message. ar.SyncProcessMessage(retMsg); // create a returnMessage to propagate just the asyncResult back // to the caller's stack. retMsg = new ReturnMessage(ar, null, 0, null /*cctx*/, msg); } // Propagate out parameters HandleReturnMessage(reqMsg, retMsg); // For constructor calls do some extra bookkeeping if (CallType.ConstructorCall == callType) { // NOTE: It is the responsiblity of the callee to propagate // the out parameters // Everything went well, we are ready to return // a proxy to the caller // Extract the return value MarshalByRefObject retObj = null; IConstructionReturnMessage ctorRetMsg = retMsg as IConstructionReturnMessage; if (null == ctorRetMsg) { throw new RemotingException( Environment.GetResourceString("Remoting_Proxy_BadReturnTypeForActivation")); } ConstructorReturnMessage crm = ctorRetMsg as ConstructorReturnMessage; if (null != crm) { // If return message is of type ConstructorReturnMessage // this is an in-appDomain activation. So no unmarshaling // needed. retObj = (MarshalByRefObject)crm.GetObject(); if (retObj == null) { throw new RemotingException( Environment.GetResourceString("Remoting_Activation_NullReturnValue")); } } else { // Fetch the objRef out of the returned message and unmarshal it retObj = (MarshalByRefObject)RemotingServices.InternalUnmarshal( (ObjRef)ctorRetMsg.ReturnValue, GetTransparentProxy(), true /*fRefine*/); if (retObj == null) { throw new RemotingException( Environment.GetResourceString("Remoting_Activation_NullFromInternalUnmarshal")); } } if (retObj != (MarshalByRefObject)GetTransparentProxy()) { throw new RemotingException( Environment.GetResourceString( "Remoting_Activation_InconsistentState")); } if (IsRemotingProxy()) { // Clear any cached ctorMsg on the RemotingProxy rp.ConstructorMessage = null; } } }
// We can remove this link demand in a future version - we will // have scenarios for this in partial trust in the future, but // we're doing this just to restrict this in case the code below // is somehow incorrect. public MemoryFailPoint(int sizeInMegabytes) { if (sizeInMegabytes <= 0) { throw new ArgumentOutOfRangeException(nameof(sizeInMegabytes), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } Contract.EndContractBlock(); #if !FEATURE_PAL // Remove this when CheckForAvailableMemory is able to provide legitimate estimates ulong size = ((ulong)sizeInMegabytes) << 20; _reservedMemory = size; // Check to see that we both have enough memory on the system // and that we have enough room within the user section of the // process's address space. Also, we need to use the GC segment // size, not the amount of memory the user wants to allocate. // Consider correcting this to reflect free memory within the GC // heap, and to check both the normal & large object heaps. ulong segmentSize = (ulong)(Math.Ceiling((double)size / GCSegmentSize) * GCSegmentSize); if (segmentSize >= TopOfMemory) { throw new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_TooBig")); } ulong requestedSizeRounded = (ulong)(Math.Ceiling((double)sizeInMegabytes / MemoryCheckGranularity) * MemoryCheckGranularity); //re-convert into bytes requestedSizeRounded <<= 20; ulong availPageFile = 0; // available VM (physical + page file) ulong totalAddressSpaceFree = 0; // non-contiguous free address space // Check for available memory, with 2 attempts at getting more // memory. // Stage 0: If we don't have enough, trigger a GC. // Stage 1: If we don't have enough, try growing the swap file. // Stage 2: Update memory state, then fail or leave loop. // // (In the future, we could consider adding another stage after // Stage 0 to run finalizers. However, before doing that make sure // that we could abort this constructor when we call // GC.WaitForPendingFinalizers, noting that this method uses a CER // so it can't be aborted, and we have a critical finalizer. It // would probably work, but do some thinking first.) for (int stage = 0; stage < 3; stage++) { CheckForAvailableMemory(out availPageFile, out totalAddressSpaceFree); // If we have enough room, then skip some stages. // Note that multiple threads can still lead to a race condition for our free chunk // of address space, which can't be easily solved. ulong reserved = SharedStatics.MemoryFailPointReservedMemory; ulong segPlusReserved = segmentSize + reserved; bool overflow = segPlusReserved < segmentSize || segPlusReserved < reserved; bool needPageFile = availPageFile < (requestedSizeRounded + reserved + LowMemoryFudgeFactor) || overflow; bool needAddressSpace = totalAddressSpaceFree < segPlusReserved || overflow; // Ensure our cached amount of free address space is not stale. long now = Environment.TickCount; // Handle wraparound. if ((now > LastTimeCheckingAddressSpace + CheckThreshold || now < LastTimeCheckingAddressSpace) || LastKnownFreeAddressSpace < (long)segmentSize) { CheckForFreeAddressSpace(segmentSize, false); } bool needContiguousVASpace = (ulong)LastKnownFreeAddressSpace < segmentSize; BCLDebug.Trace("MEMORYFAILPOINT", "MemoryFailPoint: Checking for {0} MB, for allocation size of {1} MB, stage {9}. Need page file? {2} Need Address Space? {3} Need Contiguous address space? {4} Avail page file: {5} MB Total free VA space: {6} MB Contiguous free address space (found): {7} MB Space reserved via process's MemoryFailPoints: {8} MB", segmentSize >> 20, sizeInMegabytes, needPageFile, needAddressSpace, needContiguousVASpace, availPageFile >> 20, totalAddressSpaceFree >> 20, LastKnownFreeAddressSpace >> 20, reserved, stage); if (!needPageFile && !needAddressSpace && !needContiguousVASpace) { break; } switch (stage) { case 0: // The GC will release empty segments to the OS. This will // relieve us from having to guess whether there's // enough memory in either GC heap, and whether // internal fragmentation will prevent those // allocations from succeeding. GC.Collect(); continue; case 1: // Do this step if and only if the page file is too small. if (!needPageFile) { continue; } // Attempt to grow the OS's page file. Note that we ignore // any allocation routines from the host intentionally. RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { // This shouldn't overflow due to the if clauses above. UIntPtr numBytes = new UIntPtr(segmentSize); unsafe { void *pMemory = Win32Native.VirtualAlloc(null, numBytes, Win32Native.MEM_COMMIT, Win32Native.PAGE_READWRITE); if (pMemory != null) { bool r = Win32Native.VirtualFree(pMemory, UIntPtr.Zero, Win32Native.MEM_RELEASE); if (!r) { __Error.WinIOError(); } } } } continue; case 2: // The call to CheckForAvailableMemory above updated our // state. if (needPageFile || needAddressSpace) { InsufficientMemoryException e = new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint")); #if _DEBUG e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize, needPageFile, needAddressSpace, needContiguousVASpace, availPageFile >> 20, totalAddressSpaceFree >> 20, LastKnownFreeAddressSpace >> 20, reserved); #endif throw e; } if (needContiguousVASpace) { InsufficientMemoryException e = new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_VAFrag")); #if _DEBUG e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize, needPageFile, needAddressSpace, needContiguousVASpace, availPageFile >> 20, totalAddressSpaceFree >> 20, LastKnownFreeAddressSpace >> 20, reserved); #endif throw e; } break; default: Debug.Assert(false, "Fell through switch statement!"); break; } } // Success - we have enough room the last time we checked. // Now update our shared state in a somewhat atomic fashion // and handle a simple race condition with other MemoryFailPoint instances. AddToLastKnownFreeAddressSpace(-((long)size)); if (LastKnownFreeAddressSpace < 0) { CheckForFreeAddressSpace(segmentSize, true); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { SharedStatics.AddMemoryFailPointReservation((long)size); _mustSubtractReservation = true; } #endif }
internal override unsafe int GetChars(byte *bytes, int byteCount, char *chars, int charCount, DecoderNLS decoder) { // Just need to ASSERT, this is called by something else internal that checked parameters already BCLDebug.Assert(bytes != null, "[SBCSCodePageEncoding.GetChars]bytes is null"); BCLDebug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetChars]byteCount is negative"); BCLDebug.Assert(chars != null, "[SBCSCodePageEncoding.GetChars]chars is null"); BCLDebug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetChars]charCount is negative"); CheckMemorySection(); // See if we have best fit bool bUseBestFit = false; // Do it fast way if using ? replacement or best fit fallbacks byte *byteEnd = bytes + byteCount; byte *byteStart = bytes; char *charStart = chars; // Only need decoder fallback buffer if not using default replacement fallback or best fit fallback. DecoderReplacementFallback fallback = null; if (decoder == null) { fallback = this.DecoderFallback as DecoderReplacementFallback; bUseBestFit = this.DecoderFallback.IsMicrosoftBestFitFallback; } else { fallback = decoder.Fallback as DecoderReplacementFallback; bUseBestFit = decoder.Fallback.IsMicrosoftBestFitFallback; BCLDebug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start"); } if (bUseBestFit || (fallback != null && fallback.MaxCharCount == 1)) { // Try it the fast way char replacementChar; if (fallback == null) { replacementChar = '?'; // Best fit alwasy has ? for fallback for SBCS } else { replacementChar = fallback.DefaultString[0]; } // Need byteCount chars, otherwise too small buffer if (charCount < byteCount) { // Need at least 1 output byte, throw if must throw ThrowCharsOverflow(decoder, charCount < 1); // Not throwing, use what we can byteEnd = bytes + charCount; } // Quick loop, just do '?' replacement because we don't have fallbacks for decodings. while (bytes < byteEnd) { char c; if (bUseBestFit) { if (arrayByteBestFit == null) { ReadBestFitTable(); } c = arrayByteBestFit[*bytes]; } else { c = mapBytesToUnicode[*bytes]; } bytes++; if (c == UNKNOWN_CHAR) { // This is an invalid byte in the ASCII encoding. *chars = replacementChar; } else { *chars = c; } chars++; } // bytes & chars used are the same if (decoder != null) { decoder.m_bytesUsed = (int)(bytes - byteStart); } return((int)(chars - charStart)); } // Slower way's going to need a fallback buffer DecoderFallbackBuffer fallbackBuffer = null; byte[] byteBuffer = new byte[1]; char * charEnd = chars + charCount; // Not quite so fast loop while (bytes < byteEnd) { // Faster if don't use *bytes++; char c = mapBytesToUnicode[*bytes]; bytes++; // See if it was unknown if (c == UNKNOWN_CHAR) { // Make sure we have a fallback buffer if (fallbackBuffer == null) { if (decoder == null) { fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = decoder.FallbackBuffer; } fallbackBuffer.InternalInitialize(byteEnd - byteCount, charEnd); } // Use fallback buffer BCLDebug.Assert(bytes > byteStart, "[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (unknown byte)"); byteBuffer[0] = *(bytes - 1); // Fallback adds fallback to chars, but doesn't increment chars unless the whole thing fits. if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars)) { // May or may not throw, but we didn't get this byte bytes--; // unused byte fallbackBuffer.InternalReset(); // Didn't fall this back ThrowCharsOverflow(decoder, bytes == byteStart); // throw? break; // don't throw, but stop loop } } else { // Make sure we have buffer space if (chars >= charEnd) { BCLDebug.Assert(bytes > byteStart, "[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (known byte)"); bytes--; // unused byte ThrowCharsOverflow(decoder, bytes == byteStart); // throw? break; // don't throw, but stop loop } *(chars) = c; chars++; } } // Might have had decoder fallback stuff. if (decoder != null) { decoder.m_bytesUsed = (int)(bytes - byteStart); } // Expect Empty fallback buffer for GetChars BCLDebug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetChars]Expected Empty fallback buffer at end"); return((int)(chars - charStart)); }
// Migrating InheritanceDemands requires this default ctor, so we can mark it critical protected SafeHandle() { BCLDebug.Assert(false, "SafeHandle's protected default ctor should never be used!"); throw new NotImplementedException(); }
public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ CliCtxTerminator: SyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return(errMsg); } Context ctx = Thread.CurrentContext; bool bHasDynamicSinks = ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide true, // bStart false, // bAsync true); // bNotifyGlobals IMessage replyMsg; if (reqMsg is IConstructionCallMessage) { errMsg = ctx.NotifyActivatorProperties( reqMsg, false /*bServerSide*/); if (errMsg != null) { return(errMsg); } replyMsg = ((IConstructionCallMessage)reqMsg).Activator.Activate( (IConstructionCallMessage)reqMsg); BCLDebug.Assert(replyMsg is IConstructionReturnMessage, "bad ctorRetMsg"); errMsg = ctx.NotifyActivatorProperties( replyMsg, false /*bServerSide*/); if (errMsg != null) { return(errMsg); } } else { replyMsg = null; ChannelServices.NotifyProfiler(reqMsg, RemotingProfilerEvent.ClientSend); Object[] args = new Object[] { null, null }; IMessageSink channelSink = GetChannelSink(reqMsg); // Forward call to the channel. args[0] = reqMsg; args[1] = channelSink; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback); // Move to default context unless we are going through // the cross-context channel if (channelSink != CrossContextChannel.MessageSink) { replyMsg = (IMessage)Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, xctxDel, args); } else { replyMsg = (IMessage)xctxDel(args); } ChannelServices.NotifyProfiler(replyMsg, RemotingProfilerEvent.ClientReceive); } if (bHasDynamicSinks) { ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide false, // bStart false, // bAsync true); // bNotifyGlobals } return(replyMsg); }
// This takes a virtual offset into the data section and reads an Object // from that location. // Anyone who calls LoadObject should make sure they take a lock so // no one can cause us to do a seek in here. internal Object LoadObject(int pos) { BCLDebug.Assert(_store != null, "ResourceReader is closed!"); _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); int typeIndex = Read7BitEncodedInt(_store); if (typeIndex == -1) { return(null); } Type type = _typeTable[typeIndex]; BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: " + type.Name + " pos: 0x" + _store.BaseStream.Position.ToString("x")); // @TODO: Consider putting in logic to see if this type is a // primitive or a value type first, so we can reach the // deserialization code faster for arbitrary objects. if (type == typeof(String)) { return(_store.ReadString()); } else if (type == typeof(Int32)) { return(_store.ReadInt32()); } else if (type == typeof(Byte)) { return(_store.ReadByte()); } else if (type == typeof(SByte)) { return(_store.ReadSByte()); } else if (type == typeof(Int16)) { return(_store.ReadInt16()); } else if (type == typeof(Int64)) { return(_store.ReadInt64()); } else if (type == typeof(UInt16)) { return(_store.ReadUInt16()); } else if (type == typeof(UInt32)) { return(_store.ReadUInt32()); } else if (type == typeof(UInt64)) { return(_store.ReadUInt64()); } else if (type == typeof(Single)) { return(_store.ReadSingle()); } else if (type == typeof(Double)) { return(_store.ReadDouble()); } else if (type == typeof(DateTime)) { return(new DateTime(_store.ReadInt64())); } else if (type == typeof(TimeSpan)) { return(new TimeSpan(_store.ReadInt64())); } else if (type == typeof(Decimal)) { int[] bits = new int[4]; for (int i = 0; i < bits.Length; i++) { bits[i] = _store.ReadInt32(); } return(new Decimal(bits)); } else { // For a few Windows Forms types, we must be able to deserialize // these apps in semi-trusted scenarios so localization will // work. We've verified these types are safe. if (_safeToDeserialize[typeIndex]) { new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert(); } Object graph = _objFormatter.Deserialize(_store.BaseStream); // Ensure that the object we deserialized is exactly the same // type of object we thought we should be deserializing. This // will help prevent hacked .resources files from using our // serialization permission assert to deserialize anything // via a hacked type ID. -- Brian Grunkemeyer, 12/12/2001 if (graph.GetType() != _typeTable[typeIndex]) { throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResType&SerBlobMismatch", _typeTable[typeIndex].FullName, graph.GetType().FullName)); } return(graph); } }
[System.Security.SecurityCritical] // auto-generated internal IMessageSink GetServerObjectChain(out MarshalByRefObject obj) { obj = null; // NOTE: Lifetime relies on the Identity flags for // SingleCall and Singleton being set by the time this getter // is called. if (!this.IsSingleCall()) { // This is the common case if (_serverObjectChain == null) { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(this, ref fLocked); if (_serverObjectChain == null) { MarshalByRefObject srvObj = (MarshalByRefObject) this.TPOrObject; _serverObjectChain = _srvCtx.CreateServerObjectChain( srvObj); } } finally { if (fLocked) { Monitor.Exit(this); } } } BCLDebug.Assert(null != _serverObjectChain, "null != _serverObjectChain"); return(_serverObjectChain); } else { // ---------- SINGLE CALL WKO -------------- // In this case, we are expected to provide // a fresh server object for each dispatch. // Since the server object chain is object // specific, we must create a fresh chain too. // We must be in the correct context for this // to succeed. // < BCLDebug.Assert(Thread.CurrentContext == _srvCtx, "Bad context mismatch"); MarshalByRefObject srvObj = null; IMessageSink objChain = null; if (_tpOrObject != null && _firstCallDispatched == 0 && Interlocked.CompareExchange(ref _firstCallDispatched, 1, 0) == 0) { // use the instance of server object created to // set up the pipeline. srvObj = (MarshalByRefObject)_tpOrObject; objChain = _serverObjectChain; if (objChain == null) { objChain = _srvCtx.CreateServerObjectChain(srvObj); } } else { // For singleCall we create a fresh object & its chain // on each dispatch! srvObj = (MarshalByRefObject) Activator.CreateInstance((Type)_srvType, true); // make sure that object didn't Marshal itself. // (well known objects should live up to their promise // of exporting themselves through exactly one url) String tempUri = RemotingServices.GetObjectUri(srvObj); if (tempUri != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_WellKnown_CtorCantMarshal"), this.URI)); } // Set the identity depending on whether we have the server // or proxy if (!RemotingServices.IsTransparentProxy(srvObj)) { #if _DEBUG Identity idObj = srvObj.__RaceSetServerIdentity(this); #else srvObj.__RaceSetServerIdentity(this); #endif #if _DEBUG BCLDebug.Assert(idObj == this, "Bad ID state!"); BCLDebug.Assert(idObj == MarshalByRefObject.GetIdentity(srvObj), "Bad ID state!"); #endif } else { RealProxy rp = null; rp = RemotingServices.GetRealProxy(srvObj); BCLDebug.Assert(null != rp, "null != rp"); // #if _DEBUG // Identity idObj = (ServerIdentity) rp.SetIdentity(this); // #else rp.IdentityObject = this; // #endif #if false #if _DEBUG // #endif #endif } // Create the object chain and return it objChain = _srvCtx.CreateServerObjectChain(srvObj); } // This is passed out to the caller so that for single-call // case we can call Dispose when the incoming call is done obj = srvObj; return(objChain); } }
internal static String ToBase32StringSuitableForDirName(byte[] buff) { // This routine is optimised to be used with buffs of length 20 BCLDebug.Assert(((buff.Length % 5) == 0), "Unexpected hash length"); #if _DEBUG if (s_fDebug) { if (s_iDebug >= 10) { Console.Write("Stream : "); for (int j = 0; j < buff.Length; ++j) { Console.Write("{0} ", buff[j]); } Console.WriteLine(""); } } #endif StringBuilder sb = new StringBuilder(); byte b0, b1, b2, b3, b4; int l, i; l = buff.Length; i = 0; // Create l chars using the last 5 bits of each byte. // Consume 3 MSB bits 5 bytes at a time. do { b0 = (i < l) ? buff[i++] : (byte)0; b1 = (i < l) ? buff[i++] : (byte)0; b2 = (i < l) ? buff[i++] : (byte)0; b3 = (i < l) ? buff[i++] : (byte)0; b4 = (i < l) ? buff[i++] : (byte)0; // Consume the 5 Least significant bits of each byte sb.Append(s_Base32Char[b0 & 0x1F]); sb.Append(s_Base32Char[b1 & 0x1F]); sb.Append(s_Base32Char[b2 & 0x1F]); sb.Append(s_Base32Char[b3 & 0x1F]); sb.Append(s_Base32Char[b4 & 0x1F]); // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4 sb.Append(s_Base32Char[( ((b0 & 0xE0) >> 5) | ((b3 & 0x60) >> 2))]); sb.Append(s_Base32Char[( ((b1 & 0xE0) >> 5) | ((b4 & 0x60) >> 2))]); // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4 b2 >>= 5; BCLDebug.Assert(((b2 & 0xF8) == 0), "Unexpected set bits"); if ((b3 & 0x80) != 0) { b2 |= 0x08; } if ((b4 & 0x80) != 0) { b2 |= 0x10; } sb.Append(s_Base32Char[b2]); } while (i < l); #if _DEBUG if (s_fDebug) { if (s_iDebug >= 10) { Console.WriteLine("Hash : " + sb.ToString()); } } #endif return(sb.ToString()); }
private ModuleBuilder DefineDynamicModuleInternalNoLock( String name, bool emitSymbolInfo, // specify if emit symbol info or not ref StackCrawlMark stackMark) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (name.Length == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name)); } if (name[0] == '\0') { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), nameof(name)); } Contract.Ensures(Contract.Result <ModuleBuilder>() != null); Contract.EndContractBlock(); BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )"); Debug.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal"); ModuleBuilder dynModule; ISymbolWriter writer = null; IntPtr pInternalSymWriter = new IntPtr(); // create the dynamic module- only one ModuleBuilder per AssemblyBuilder can be created if (m_fManifestModuleUsedAsDefinedModule == true) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly")); } // Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule() dynModule = m_manifestModuleBuilder; // Create the symbol writer if (emitSymbolInfo) { writer = SymWrapperCore.SymWriter.CreateSymWriter(); String fileName = "Unused"; // this symfile is never written to disk so filename does not matter. // Pass the "real" module to the VM pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, fileName); // In Telesto, we took the SetUnderlyingWriter method private as it's a very rickety method. // This might someday be a good move for the desktop CLR too. ((SymWrapperCore.SymWriter)writer).InternalSetUnderlyingWriter(pInternalSymWriter); } // Creating the symbol writer dynModule.SetSymWriter(writer); m_assemblyData.AddModule(dynModule); if (dynModule == m_manifestModuleBuilder) { // We are reusing manifest module as user-defined dynamic module m_fManifestModuleUsedAsDefinedModule = true; } return(dynModule); } // DefineDynamicModuleInternalNoLock
private static void DemandPermission(IsolatedStorageScope scope) { IsolatedStorageFilePermission ip = null; // Ok to create more than one instnace of s_PermXXX, the last one // will be shared. No need to synchronize. // First check for permissions switch (scope) { case c_App: if (s_PermApp == null) { s_PermApp = new IsolatedStorageFilePermission( IsolatedStorageContainment.DomainIsolationByUser, 0, false); } ip = s_PermApp; break; case c_Assembly: if (s_PermAssem == null) { s_PermAssem = new IsolatedStorageFilePermission( IsolatedStorageContainment.AssemblyIsolationByUser, 0, false); } ip = s_PermAssem; break; case c_AppRoaming: if (s_PermAppRoaming == null) { s_PermAppRoaming = new IsolatedStorageFilePermission( IsolatedStorageContainment.DomainIsolationByRoamingUser, 0, false); } ip = s_PermAppRoaming; break; case c_AssemblyRoaming: if (s_PermAssemRoaming == null) { s_PermAssemRoaming = new IsolatedStorageFilePermission( IsolatedStorageContainment.AssemblyIsolationByRoamingUser, 0, false); } ip = s_PermAssemRoaming; break; #if _DEBUG default: BCLDebug.Assert(false, "Invalid scope"); break; #endif } ip.Demand(); }
private int InternalReadOneChar() { // I know having a separate InternalReadOneChar method seems a little // redundant, but this makes a scenario like the security parser code // 20% faster, in addition to the optimizations for UnicodeEncoding I // put in InternalReadChars. int charsRead = 0; int numBytes = 0; long posSav = posSav = 0; if (m_stream.CanSeek) { posSav = m_stream.Position; } if (m_charBytes == null) { m_charBytes = new byte[MaxCharBytesSize]; } if (m_singleChar == null) { m_singleChar = new char[1]; } while (charsRead == 0) { // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. // Assume 1 byte can be 1 char unless m_2BytesPerChar is true. numBytes = m_2BytesPerChar ? 2 : 1; int r = m_stream.ReadByte(); m_charBytes[0] = (byte)r; if (r == -1) { numBytes = 0; } if (numBytes == 2) { r = m_stream.ReadByte(); m_charBytes[1] = (byte)r; if (r == -1) { numBytes = 1; } } if (numBytes == 0) { // Console.WriteLine("Found no bytes. We're outta here."); return(-1); } BCLDebug.Assert(numBytes == 1 || numBytes == 2, "BinaryReader::InternalReadOneChar assumes it's reading one or 2 bytes only."); try { charsRead = m_decoder.GetChars(m_charBytes, 0, numBytes, m_singleChar, 0); } catch { // Handle surrogate char if (m_stream.CanSeek) { m_stream.Seek((posSav - m_stream.Position), SeekOrigin.Current); } // else - we can't do much here throw; } BCLDebug.Assert(charsRead < 2, "InternalReadOneChar - assuming we only got 0 or 1 char, not 2!"); // Console.WriteLine("That became: " + charsRead + " characters."); } if (charsRead == 0) { return(-1); } return(m_singleChar[0]); }
internal ServerAsyncReplyTerminatorSink(IMessageSink nextSink) { BCLDebug.Assert(nextSink != null, "null IMessageSink passed to ServerAsyncReplyTerminatorSink ctor."); _nextSink = nextSink; }
[SecuritySafeCritical] // Asserts permission to create & delete a temp file. public void Generate() { if (_resourceList == null) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceWriterSaved")); } BinaryWriter bw = new BinaryWriter(_output, Encoding.UTF8); List <String> typeNames = new List <String>(); // Write out the ResourceManager header // Write out magic number bw.Write(ResourceManager.MagicNumber); // Write out ResourceManager header version number bw.Write(ResourceManager.HeaderVersionNumber); MemoryStream resMgrHeaderBlob = new MemoryStream(240); BinaryWriter resMgrHeaderPart = new BinaryWriter(resMgrHeaderBlob); // Write out class name of IResourceReader capable of handling // this file. resMgrHeaderPart.Write(MultitargetingHelpers.GetAssemblyQualifiedName(typeof(ResourceReader), typeConverter)); // Write out class name of the ResourceSet class best suited to // handling this file. // This needs to be the same even with multi-targeting. It's the // full name -- not the ----sembly qualified name. resMgrHeaderPart.Write(ResourceManager.ResSetTypeName); resMgrHeaderPart.Flush(); // Write number of bytes to skip over to get past ResMgr header bw.Write((int)resMgrHeaderBlob.Length); // Write the rest of the ResMgr header bw.Write(resMgrHeaderBlob.GetBuffer(), 0, (int)resMgrHeaderBlob.Length); // End ResourceManager header // Write out the RuntimeResourceSet header // Version number bw.Write(RuntimeResourceSet.Version); #if RESOURCE_FILE_FORMAT_DEBUG // Write out a tag so we know whether to enable or disable // debugging support when reading the file. bw.Write("***DEBUG***"); #endif // number of resources int numResources = _resourceList.Count; if (_preserializedData != null) { numResources += _preserializedData.Count; } bw.Write(numResources); // Store values in temporary streams to write at end of file. int[] nameHashes = new int[numResources]; int[] namePositions = new int[numResources]; int curNameNumber = 0; MemoryStream nameSection = new MemoryStream(numResources * AverageNameSize); BinaryWriter names = new BinaryWriter(nameSection, Encoding.Unicode); // The data section can be very large, and worse yet, we can grow the byte[] used // for the data section repeatedly. When using large resources like ~100 images, // this can lead to both a fragmented large object heap as well as allocating about // 2-3x of our storage needs in extra overhead. Using a temp file can avoid this. // Assert permission to get a temp file name, which requires two permissions. // Additionally, we may be running under an account that doesn't have permission to // write to the temp directory (enforced via a Windows ACL). Fall back to a MemoryStream. Stream dataSection = null; // Either a FileStream or a MemoryStream String tempFile = null; #if !DISABLE_CAS_USE PermissionSet permSet = new PermissionSet(PermissionState.None); permSet.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted)); permSet.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); #endif try { #if !DISABLE_CAS_USE permSet.Assert(); #endif tempFile = Path.GetTempFileName(); File.SetAttributes(tempFile, FileAttributes.Temporary | FileAttributes.NotContentIndexed); // Explicitly opening with FileOptions.DeleteOnClose to avoid complicated File.Delete // (safe from ----s w/ antivirus software, etc) dataSection = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose | FileOptions.SequentialScan); } catch (UnauthorizedAccessException) { // In case we're running under an account that can't access a temp directory. dataSection = new MemoryStream(); } catch (IOException) { // In case Path.GetTempFileName fails because no unique file names are available dataSection = new MemoryStream(); } finally { #if !DISABLE_CAS_USE PermissionSet.RevertAssert(); #endif } using (dataSection) { BinaryWriter data = new BinaryWriter(dataSection, Encoding.UTF8); #if FEATURE_SERIALIZATION IFormatter objFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence)); #endif // FEATURE_SERIALIZATION #if RESOURCE_FILE_FORMAT_DEBUG // Write NAMES right before the names section. names.Write(new byte[] { (byte)'N', (byte)'A', (byte)'M', (byte)'E', (byte)'S', (byte)'-', (byte)'-', (byte)'>' }); // Write DATA at the end of the name table section. data.Write(new byte[] { (byte)'D', (byte)'A', (byte)'T', (byte)'A', (byte)'-', (byte)'-', (byte)'-', (byte)'>' }); #endif // We've stored our resources internally in a Hashtable, which // makes no guarantees about the ordering while enumerating. // While we do our own sorting of the resource names based on their // hash values, that's only sorting the nameHashes and namePositions // arrays. That's all that is strictly required for correctness, // but for ease of generating a patch in the future that // modifies just .resources files, we should re-sort them. SortedList sortedResources = new SortedList(_resourceList, FastResourceComparer.Default); if (_preserializedData != null) { foreach (KeyValuePair <String, PrecannedResource> entry in _preserializedData) { sortedResources.Add(entry.Key, entry.Value); } } IDictionaryEnumerator items = sortedResources.GetEnumerator(); // Write resource name and position to the file, and the value // to our temporary buffer. Save Type as well. while (items.MoveNext()) { nameHashes[curNameNumber] = FastResourceComparer.HashFunction((String)items.Key); namePositions[curNameNumber++] = (int)names.Seek(0, SeekOrigin.Current); names.Write((String)items.Key); // key names.Write((int)data.Seek(0, SeekOrigin.Current)); // virtual offset of value. #if RESOURCE_FILE_FORMAT_DEBUG names.Write((byte)'*'); #endif Object value = items.Value; ResourceTypeCode typeCode = FindTypeCode(value, typeNames); // Write out type code Write7BitEncodedInt(data, (int)typeCode); // Write out value PrecannedResource userProvidedResource = value as PrecannedResource; if (userProvidedResource != null) { data.Write(userProvidedResource.Data); } else { #if FEATURE_SERIALIZATION WriteValue(typeCode, value, data, objFormatter); #else WriteValue(typeCode, value, data); #endif } #if RESOURCE_FILE_FORMAT_DEBUG data.Write(new byte[] { (byte)'S', (byte)'T', (byte)'O', (byte)'P' }); #endif } // At this point, the ResourceManager header has been written. // Finish RuntimeResourceSet header // Write size & contents of class table bw.Write(typeNames.Count); for (int i = 0; i < typeNames.Count; i++) { bw.Write(typeNames[i]); } // Write out the name-related items for lookup. // Note that the hash array and the namePositions array must // be sorted in parallel. Array.Sort(nameHashes, namePositions); // Prepare to write sorted name hashes (alignment fixup) // Note: For 64-bit machines, these MUST be aligned on 8 byte // boundaries! Pointers on IA64 must be aligned! And we'll // run faster on X86 machines too. bw.Flush(); int alignBytes = ((int)bw.BaseStream.Position) & 7; if (alignBytes > 0) { for (int i = 0; i < 8 - alignBytes; i++) { bw.Write("PAD"[i % 3]); } } // Write out sorted name hashes. // Align to 8 bytes. Contract.Assert((bw.BaseStream.Position & 7) == 0, "ResourceWriter: Name hashes array won't be 8 byte aligned! Ack!"); #if RESOURCE_FILE_FORMAT_DEBUG bw.Write(new byte[] { (byte)'H', (byte)'A', (byte)'S', (byte)'H', (byte)'E', (byte)'S', (byte)'-', (byte)'>' }); #endif foreach (int hash in nameHashes) { bw.Write(hash); } #if RESOURCE_FILE_FORMAT_DEBUG Console.Write("Name hashes: "); foreach (int hash in nameHashes) { Console.Write(hash.ToString("x") + " "); } Console.WriteLine(); #endif // Write relative positions of all the names in the file. // Note: this data is 4 byte aligned, occuring immediately // after the 8 byte aligned name hashes (whose length may // potentially be odd). Contract.Assert((bw.BaseStream.Position & 3) == 0, "ResourceWriter: Name positions array won't be 4 byte aligned! Ack!"); #if RESOURCE_FILE_FORMAT_DEBUG bw.Write(new byte[] { (byte)'P', (byte)'O', (byte)'S', (byte)'-', (byte)'-', (byte)'-', (byte)'-', (byte)'>' }); #endif foreach (int pos in namePositions) { bw.Write(pos); } #if RESOURCE_FILE_FORMAT_DEBUG Console.Write("Name positions: "); foreach (int pos in namePositions) { Console.Write(pos.ToString("x") + " "); } Console.WriteLine(); #endif // Flush all BinaryWriters to their underlying streams. bw.Flush(); names.Flush(); data.Flush(); // Write offset to data section int startOfDataSection = (int)(bw.Seek(0, SeekOrigin.Current) + nameSection.Length); startOfDataSection += 4; // We're writing an int to store this data, adding more bytes to the header BCLDebug.Log("RESMGRFILEFORMAT", "Generate: start of DataSection: 0x" + startOfDataSection.ToString("x", CultureInfo.InvariantCulture) + " nameSection length: " + nameSection.Length); bw.Write(startOfDataSection); // Write name section. bw.Write(nameSection.GetBuffer(), 0, (int)nameSection.Length); names.Close(); // Write data section. Contract.Assert(startOfDataSection == bw.Seek(0, SeekOrigin.Current), "ResourceWriter::Generate - start of data section is wrong!"); dataSection.Position = 0; dataSection.CopyTo(bw.BaseStream); data.Close(); } // using(dataSection) <--- Closes dataSection, which was opened w/ FileOptions.DeleteOnClose bw.Flush(); // Indicate we've called Generate _resourceList = null; }
} // RefreshChannelData private static Object[] CollectChannelDataFromChannels() { // Ensure that our native cross-context & cross-domain channels // are registered RemotingServices.RegisterWellKnownChannels(); RegisteredChannelList regChnlList = s_registeredChannels; int count = regChnlList.Count; // Compute the number of channels that implement IChannelReceiver int numChnls = regChnlList.ReceiverCount; // Allocate array for channel data Object[] data = new Object[numChnls]; // we need to remove null entries int nonNullDataCount = 0; // Set the channel data, names and mime types for (int i = 0, j = 0; i < count; i++) { IChannel chnl = regChnlList.GetChannel(i); if (null == chnl) { throw new RemotingException(String.Format(Environment.GetResourceString("Remoting_ChannelNotRegistered"), "")); } if (regChnlList.IsReceiver(i)) { BCLDebug.Trace("REMOTE", "Setting info for receiver " + j + "\n"); // Extract the data Object channelData = ((IChannelReceiver)chnl).ChannelData; data[j] = channelData; if (channelData != null) { nonNullDataCount++; } // Increment the counter j++; } } if (nonNullDataCount != numChnls) { // there were null entries, so remove them. Object[] nonNullData = new Object[nonNullDataCount]; int nonNullCounter = 0; for (int co = 0; co < numChnls; co++) { Object channelData = data[co]; if (channelData != null) { nonNullData[nonNullCounter++] = channelData; } } data = nonNullData; } return(data); } // CollectChannelDataFromChannels
// Use this to translate error codes like the above into HRESULTs like // 0x80070006 for ERROR_INVALID_HANDLE internal static int MakeHRFromErrorCode(int errorCode) { BCLDebug.Assert((0xFFFF0000 & errorCode) == 0, "This is an HRESULT, not an error code!"); return(unchecked (((int)0x80070000) | errorCode)); }
internal void SetSingleCallObjectMode() { BCLDebug.Assert(!IsSingleCall() && !IsSingleton(), "Bad serverID"); _flags |= IDFLG_SERVER_SINGLECALL; }
public CLRIReferenceImpl(PropertyType type, T obj) : base(type, obj) { BCLDebug.Assert(obj != null, "Must not be null"); _value = obj; }