private MemoryMappedFile( IBinaryDocument binaryDocument, byte* buffer, uint length ) { this.binaryDocument = binaryDocument; this.buffer = buffer; this.length = length; }
/// <summary> /// Open the binary document as a memory block in host dependent fashion. /// </summary> /// <param name="sourceDocument">The binary document that is to be opened.</param> /// <returns>The unmanaged memory block corresponding to the source document.</returns> public override IBinaryDocumentMemoryBlock/*?*/ OpenBinaryDocument(IBinaryDocument sourceDocument) { try { IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); this.disposableObjectAllocatedByThisHost.Add((IDisposable)binDocMemoryBlock); return binDocMemoryBlock; } catch (IOException) { return null; } }
public override IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument sourceDocument) { VSServiceProvider.Current.Logger.WriteToLog("Opening document: " + sourceDocument.Name + " from: " + sourceDocument.Location); try { IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); return binDocMemoryBlock; } catch (IOException) { VSServiceProvider.Current.Logger.WriteToLog("Failed to open document."); return null; } }
/// <summary> /// Factory method for opening the memory mapped file. The content of the map is assumed to come from localFileName. /// This can throw FileLoadException in case of error. /// </summary> /// <param name="localFileName">Name of the file from where the binary document needs to be opened. /// This is useful in case we want to copy the file to temporary location and then open or when we want to open document on the network.</param> /// <param name="binaryDocument">The binary document for which the memory mapping is requested.</param> public static MemoryMappedFile CreateMemoryMappedFile( string localFileName, IBinaryDocument binaryDocument ) { uint length; Byte* buffer; MemoryMappedFile.OpenFileMemoryMap(localFileName, out buffer, out length); if (length != binaryDocument.Length) throw new IOException("File size difference: " + localFileName); return new MemoryMappedFile( binaryDocument, buffer, length ); }
/// <summary> /// If the given binary document contains a CLR assembly, return the identity of the assembly. Otherwise, return null. /// </summary> public AssemblyIdentity /*?*/ GetAssemblyIdentifier(IBinaryDocument binaryDocument) { IBinaryDocumentMemoryBlock /*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { return(null); } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { return(null); } if (!peFileReader.IsAssembly) { return(null); } return(this.GetAssemblyIdentifier(peFileReader)); }
// Overriding this method allows us to read the binaries without blocking the files. The default // implementation will use a memory mapped file (MMF) which causes the files to be locked. That // means you can delete them, but you can't overwrite them in-palce, which is especially painful // when reading binaries directly from a build ouput folder. // // Measuring indicated that performance implications are negligible. That's why we decided to // make this the default and not exposing any (more) options to our ctor. public override IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument sourceDocument) { // First let's see whether the document is a stream-based document. In that case, we'll // call the overload that processes the stream. var streamDocument = sourceDocument as StreamDocument; if (streamDocument != null) { return(UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(streamDocument.Stream, sourceDocument)); } // Otherwise we assume that we can load the data from the location of sourceDocument. try { var memoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); disposableObjectAllocatedByThisHost.Add(memoryBlock); return(memoryBlock); } catch (IOException) { return(null); } }
/// <summary> /// Method to open the module in the MetadataReader. This method loads the module and returns the object corresponding to the opened module. /// Also returns the ModuleIDentifier corresponding to the module as the out parameter. Modules are opened as if they are not contained in any assembly. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <param name="moduleIdentity">Contains the module identity of the binary document in case it is an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenModule( IBinaryDocument binaryDocument, out ModuleIdentity/*?*/ moduleIdentity ) { moduleIdentity = null; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Module; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } //^ assert peFileReader.ReaderState >= ReaderState.Metadata; if (peFileReader.IsAssembly) { AssemblyIdentity assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); moduleIdentity = assemblyIdentity; Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } } else { moduleIdentity = this.GetModuleIdentifier(peFileReader); Module/*?*/ lookupModule = this.LookupModule(null, moduleIdentity); if (lookupModule != null) { return lookupModule; } } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, null, this.metadataReaderHost.PointerSize); this.LoadedModule(peFileToObjectModel.Module); Assembly/*?*/ assembly = peFileToObjectModel.Module as Assembly; if (assembly != null) { this.OpenMemberModules(binaryDocument, assembly); } return peFileToObjectModel.Module; } catch (MetadataReaderException) { // Error... } } return Dummy.Module; }
/// <summary> /// Method to open the assembly in MetadataReader. This method loads the assembly and returns the object corresponding to the /// opened assembly. Also returns the AssemblyIdentifier corresponding to the assembly as the out parameter. /// Only assemblies that unify to themselves can be opened i.e. if the unification policy of the compilation host says that mscorlib 1.0 unifies to mscorlib 2.0 /// then only mscorlib 2.0 can be loaded. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an assembly.</param> /// <param name="assemblyIdentity">Contains the assembly identifier of the binary document in case it is an assembly.</param> /// <returns>Assembly that is loaded or Dummy.Assembly in case assembly could not be loaded.</returns> public IAssembly OpenAssembly( IBinaryDocument binaryDocument, out AssemblyIdentity/*?*/ assemblyIdentity ) { assemblyIdentity = null; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Assembly; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Assembly; } //^ assert peFileReader.ReaderState >= ReaderState.Metadata; if (!peFileReader.IsAssembly) { // Error... return Dummy.Assembly; } assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, assemblyIdentity, null, this.metadataReaderHost.PointerSize); Assembly/*?*/ assembly = peFileToObjectModel.Module as Assembly; //^ assert assembly != null; this.LoadedModule(assembly); this.OpenMemberModules(binaryDocument, assembly); return assembly; } catch (MetadataReaderException) { return Dummy.Assembly; } } }
/// <summary> /// This method is called when an assembly is loaded. This makes sure that all the member modules of the assembly are loaded. /// </summary> /// <param name="binaryDocument"></param> /// <param name="assembly"></param> void OpenMemberModules(IBinaryDocument binaryDocument, Assembly assembly) { List<Module> memberModuleList = new List<Module>(); AssemblyIdentity assemblyIdentity = assembly.AssemblyIdentity; foreach (IFileReference fileRef in assembly.PEFileToObjectModel.GetFiles()) { if (!fileRef.HasMetadata) continue; IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument, fileRef.FileName.Value); if (binaryDocumentMemoryBlock == null) { // Error... continue; } try { PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... continue; } if (peFileReader.IsAssembly) { // Error... continue; } ModuleIdentity moduleIdentity = this.GetModuleIdentifier(peFileReader, assemblyIdentity); PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, assembly, this.metadataReaderHost.PointerSize); memberModuleList.Add(peFileToObjectModel.Module); } catch (MetadataReaderException) { continue; } } if (memberModuleList.Count == 0) return; assembly.SetMemberModules(new EnumerableArrayWrapper<Module, IModule>(memberModuleList.ToArray(), Dummy.Module)); }
/// <summary> /// Opens a binary document. /// </summary> public override IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument sourceDocument) { try { IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); return binDocMemoryBlock; } catch (IOException) { return null; } }
/// <summary> /// Open the binary document as a memory block in host dependent fashion. /// </summary> /// <param name="sourceDocument">The binary document that is to be opened.</param> /// <returns> /// The unmanaged memory block corresponding to the source document. /// </returns> public IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument sourceDocument) { Contract.Requires(sourceDocument != null); Contract.Ensures(Contract.Result<IBinaryDocumentMemoryBlock>() != null); throw new NotImplementedException(); }
/// <summary> /// Method to open the module in the MetadataReader. This method loads the module and returns the object corresponding to the opened module. /// Also returns the ModuleIDentifier corresponding to the module as the out parameter. Modules are opened as if they are not contained in any assembly. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenModule(IBinaryDocument binaryDocument) { Contract.Requires(binaryDocument != null); Contract.Ensures(Contract.Result<IModule>() != null); ModuleIdentity/*?*/ retModuleIdentity; return this.OpenModule(binaryDocument, out retModuleIdentity); }
/// <summary> /// If the given binary document contains a CLR assembly, return the identity of the assembly. Otherwise, return null. /// </summary> public AssemblyIdentity/*?*/ GetAssemblyIdentifier(IBinaryDocument binaryDocument) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) return null; PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) return null; if (!peFileReader.IsAssembly) return null; return this.GetAssemblyIdentifier(peFileReader); }
/// <summary> /// Open the binary document as a memory block in host dependent fashion. /// </summary> /// <param name="sourceDocument">The binary document that is to be opened.</param> /// <returns>The unmanaged memory block corresponding to the source document.</returns> public virtual IBinaryDocumentMemoryBlock/*?*/ OpenBinaryDocument(IBinaryDocument sourceDocument) { try { #if !COMPACTFX IBinaryDocumentMemoryBlock binDocMemoryBlock = MemoryMappedFile.CreateMemoryMappedFile(sourceDocument.Location, sourceDocument); #else IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); #endif return binDocMemoryBlock; } catch (IOException) { return null; } }
/// <summary> /// Constructor for IL location /// </summary> /// <param name="binaryDocument"></param> /// <param name="methodDefinition"></param> /// <param name="offset"></param> public ILLocation( IBinaryDocument binaryDocument, IMethodDefinition methodDefinition, uint offset ) { this.binaryDocument = binaryDocument; this.methodDefinition = methodDefinition; this.offset = offset; }
private UnmanagedBinaryMemoryBlock(IBinaryDocument binaryDocument) { this.binaryDocument = binaryDocument; this.Pointer = Marshal.AllocHGlobal((int)binaryDocument.Length); if (this.Pointer == IntPtr.Zero) { throw new OutOfMemoryException(); } }
//^ invariant offset >= 0 && offset <= binaryDocument.Length; /// <summary> /// Constructor for the Binary location /// </summary> /// <param name="binaryDocument"></param> /// <param name="offset"></param> public BinaryLocation( IBinaryDocument binaryDocument, uint offset ) { this.binaryDocument = binaryDocument; this.offset = offset; }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the given byte enumeration into the block. /// </summary> /// <param name="stream">A stream of bytes that are to be copied into the resulting memory block.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.IO.IOException">The length of the stream is not the same as the length of the binary document, or the stream length is greater than Int32.MaxValue.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(IEnumerable<byte> stream, IBinaryDocument binaryDocument) { UnmanagedBinaryMemoryBlock unmanagedBinaryMemoryBlock = new UnmanagedBinaryMemoryBlock(binaryDocument); byte* pMainBuffer = (byte*)unmanagedBinaryMemoryBlock.Pointer; byte* endOfBuffer = pMainBuffer + binaryDocument.Length; foreach (var b in stream) { if (pMainBuffer == endOfBuffer) throw new IOException("stream length != binaryDocument.Length: " + binaryDocument.Location); *pMainBuffer++ = b; } if (pMainBuffer != endOfBuffer) throw new IOException("stream length != binaryDocument.Length: " + binaryDocument.Location); return unmanagedBinaryMemoryBlock; }
/// <summary> /// This method loads a module from a file containing only the metadata section of a PE file. (No headers and no IL.) /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenSnapshot(IBinaryDocument binaryDocument) { ModuleIdentity moduleIdentity; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Module; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock, snapshot: true); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } if (peFileReader.IsAssembly) { AssemblyIdentity assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); moduleIdentity = assemblyIdentity; Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } } else { moduleIdentity = this.GetModuleIdentifier(peFileReader); Module/*?*/ lookupModule = this.LookupModule(null, moduleIdentity); if (lookupModule != null) { return lookupModule; } } if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, null, this.metadataReaderHost.PointerSize); this.LoadedModule(peFileToObjectModel.Module); CciEventSource.Log.ModuleOpened(peFileToObjectModel.Module, moduleIdentity, binaryDocument.Length); return peFileToObjectModel.Module; } catch (MetadataReaderException) { // Error... } } return Dummy.Module; }
/// <summary> /// Method to open the assembly in MetadataReader. This method loads the assembly and returns the object corresponding to the /// opened assembly. Also returns the AssemblyIdentifier corresponding to the assembly as the out parameter. /// Only assemblies that unify to themselves can be opened i.e. if the unification policy of the compilation host says that mscorlib 1.0 unifies to mscorlib 2.0 /// then only mscorlib 2.0 can be loaded. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an assembly.</param> /// <returns>Assembly that is loaded or Dummy.Assembly in case assembly could not be loaded.</returns> public IAssembly OpenAssembly( IBinaryDocument binaryDocument ) { AssemblyIdentity/*?*/ retAssemblyIdentity; return this.OpenAssembly(binaryDocument, out retAssemblyIdentity); }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the given stream into the block. /// </summary> /// <param name="stream">A stream of bytes that are to be copied into the resulting memory block.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.IO.IOException">The length of the stream is not the same as the length of the binary document, or the stream length is greater than Int32.MaxValue.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(Stream stream, IBinaryDocument binaryDocument) { if (stream.Length != binaryDocument.Length) { throw new IOException("stream.Length != binaryDocument.Length: " + binaryDocument.Location); } if (stream.Length > Int32.MaxValue) { throw new IOException("stream.Length > Int32.MaxValue: " + binaryDocument.Location); } UnmanagedBinaryMemoryBlock unmanagedBinaryMemoryBlock = new UnmanagedBinaryMemoryBlock(binaryDocument); byte *pMainBuffer = (byte *)unmanagedBinaryMemoryBlock.Pointer; //Read a fixed length block at a time, so that the GC does not come under pressure from lots of large byte arrays. int remainingLength = (int)binaryDocument.Length; int copyBufferLength = 8096; byte[] tempBuffer = new byte[copyBufferLength]; fixed(byte *tempBufferPtr = tempBuffer) { while (remainingLength > 0) { if (remainingLength < copyBufferLength) { copyBufferLength = remainingLength; } stream.Read(tempBuffer, 0, copyBufferLength); byte *iterBuffer = tempBufferPtr; byte *endBuffer = tempBufferPtr + copyBufferLength; while (iterBuffer < endBuffer) { *pMainBuffer++ = *iterBuffer++; } remainingLength -= copyBufferLength; } } return(unmanagedBinaryMemoryBlock); }
/// <summary> /// Method to open the module in the MetadataReader. This method loads the module and returns the object corresponding to the opened module. /// Also returns the ModuleIDentifier corresponding to the module as the out parameter. Modules are opened as if they are not contained in any assembly. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenModule( IBinaryDocument binaryDocument ) { ModuleIdentity/*?*/ retModuleIdentity; return this.OpenModule(binaryDocument, out retModuleIdentity); }
/// <summary> /// Open the binary document as a memory block in host dependent fashion. /// IMPORTANT: The lifetime of the memory block is the same as the lifetime of this host object. /// Be sure to call Dispose on the host object when it is no longer needed, otherwise files may stay locked, /// or resources such as large blocks of memory may remain allocated until the host's finalizer method runs. /// </summary> /// <param name="sourceDocument">The binary document that is to be opened.</param> /// <returns>The unmanaged memory block corresponding to the source document.</returns> /// <remarks>When overridding this method, be sure to add any disposable objects to this.disposableObjectAllocatedByThisHost.</remarks> public virtual IBinaryDocumentMemoryBlock/*?*/ OpenBinaryDocument(IBinaryDocument sourceDocument) { try { #if !COMPACTFX && !__MonoCS__ IBinaryDocumentMemoryBlock binDocMemoryBlock = MemoryMappedFile.CreateMemoryMappedFile(sourceDocument.Location, sourceDocument); #else IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(sourceDocument.Location, sourceDocument); #endif this.disposableObjectAllocatedByThisHost.Add((IDisposable)binDocMemoryBlock); return binDocMemoryBlock; } catch (IOException) { return null; } }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the file at the given location into the block. /// </summary> /// <param name="localFileName">The path to the file to read.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.ArgumentException">localFileName is an empty string (""), contains only white space, or contains one /// or more invalid characters. -or- localFileName refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment.</exception> /// <exception cref="System.NotSupportedException">localFileName refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment.</exception> /// <exception cref="System.IO.FileNotFoundException">The file specified by localFileName does not exist.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <exception cref="System.IO.DirectoryNotFoundException">The specified path is invalid, such as being on an unmapped drive.</exception> /// <exception cref="System.UnauthorizedAccessException">The file cannot be be read, for example because it is already being accessed exclusively by another process.</exception> /// <exception cref="System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, /// paths must be less than 248 characters, and file names must be less than 260 characters.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(string localFileName, IBinaryDocument binaryDocument) { using (FileStream stream = new FileStream(localFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { return CreateUnmanagedBinaryMemoryBlock(stream, binaryDocument); } }
/// <summary> /// Method to open the assembly in MetadataReader. This method loads the assembly and returns the object corresponding to the /// opened assembly. Also returns the AssemblyIdentifier corresponding to the assembly as the out parameter. /// Only assemblies that unify to themselves can be opened i.e. if the unification policy of the compilation host says that mscorlib 1.0 unifies to mscorlib 2.0 /// then only mscorlib 2.0 can be loaded. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an assembly.</param> /// <returns>Assembly that is loaded or Dummy.Assembly in case assembly could not be loaded.</returns> public IAssembly OpenAssembly(IBinaryDocument binaryDocument) { Contract.Requires(binaryDocument != null); Contract.Ensures(Contract.Result<IAssembly>() != null); AssemblyIdentity/*?*/ retAssemblyIdentity; return this.OpenAssembly(binaryDocument, out retAssemblyIdentity); }
/// <summary> /// Open the child binary document within the context of parent source document.as a memory block in host dependent fashion /// For example: in multimodule assemblies the main module will be parentSourceDocument, where as other modules will be child /// docuements. /// </summary> /// <param name="parentSourceDocument">The source document indicating the child document location.</param> /// <param name="childDocumentName">The name of the child document.</param> /// <returns>The unmanaged memory block corresponding to the child document.</returns> public virtual IBinaryDocumentMemoryBlock/*?*/ OpenBinaryDocument(IBinaryDocument parentSourceDocument, string childDocumentName) { try { string directory = Path.GetDirectoryName(parentSourceDocument.Location); string fullPath = Path.Combine(directory, childDocumentName); IBinaryDocument newBinaryDocument = BinaryDocument.GetBinaryDocumentForFile(fullPath, this); #if !COMPACTFX IBinaryDocumentMemoryBlock binDocMemoryBlock = MemoryMappedFile.CreateMemoryMappedFile(newBinaryDocument.Location, newBinaryDocument); #else IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(newBinaryDocument.Location, newBinaryDocument); #endif return binDocMemoryBlock; } catch (IOException) { return null; } }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the given stream into the block. /// </summary> /// <param name="stream">A stream of bytes that are to be copied into the resulting memory block.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.IO.IOException">The length of the stream is not the same as the length of the binary document, or the stream length is greater than Int32.MaxValue.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(Stream stream, IBinaryDocument binaryDocument) { if (stream.Length != binaryDocument.Length) throw new IOException("stream.Length != binaryDocument.Length: " + binaryDocument.Location); if (stream.Length > Int32.MaxValue) throw new IOException("stream.Length > Int32.MaxValue: " + binaryDocument.Location); UnmanagedBinaryMemoryBlock unmanagedBinaryMemoryBlock = new UnmanagedBinaryMemoryBlock(binaryDocument); byte* pMainBuffer = (byte*)unmanagedBinaryMemoryBlock.Pointer; //Read a fixed length block at a time, so that the GC does not come under pressure from lots of large byte arrays. int remainingLength = (int)binaryDocument.Length; int copyBufferLength = 8096; byte[] tempBuffer = new byte[copyBufferLength]; fixed (byte* tempBufferPtr = tempBuffer) { while (remainingLength > 0) { if (remainingLength < copyBufferLength) { copyBufferLength = remainingLength; } stream.Read(tempBuffer, 0, copyBufferLength); byte* iterBuffer = tempBufferPtr; byte* endBuffer = tempBufferPtr + copyBufferLength; while (iterBuffer < endBuffer) { *pMainBuffer++ = *iterBuffer++; } remainingLength -= copyBufferLength; } } return unmanagedBinaryMemoryBlock; }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the file at the given location into the block. /// </summary> /// <param name="localFileName">The path to the file to read.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.ArgumentException">localFileName is an empty string (""), contains only white space, or contains one /// or more invalid characters. -or- localFileName refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in an NTFS environment.</exception> /// <exception cref="System.NotSupportedException">localFileName refers to a non-file device, such as "con:", "com1:", "lpt1:", etc. in a non-NTFS environment.</exception> /// <exception cref="System.IO.FileNotFoundException">The file specified by localFileName does not exist.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <exception cref="System.IO.DirectoryNotFoundException">The specified path is invalid, such as being on an unmapped drive.</exception> /// <exception cref="System.UnauthorizedAccessException">The file cannot be be read, for example because it is already being accessed exclusively by another process.</exception> /// <exception cref="System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, /// paths must be less than 248 characters, and file names must be less than 260 characters.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(string localFileName, IBinaryDocument binaryDocument) { using (FileStream stream = new FileStream(localFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { return(CreateUnmanagedBinaryMemoryBlock(stream, binaryDocument)); } }
internal DirectoryLocation( IBinaryDocument binaryDocument, Directories directory, uint offset ) { this.binaryDocument = binaryDocument; this.directory = directory; this.offset = offset; }
/// <summary> /// Creates an unmanaged binary memory block and copies the contents of the given byte enumeration into the block. /// </summary> /// <param name="stream">A stream of bytes that are to be copied into the resulting memory block.</param> /// <param name="binaryDocument">The binary document whose contents are stored in the given file.</param> /// <exception cref="System.IO.IOException">The length of the stream is not the same as the length of the binary document, or the stream length is greater than Int32.MaxValue.</exception> public static UnmanagedBinaryMemoryBlock CreateUnmanagedBinaryMemoryBlock(IEnumerable <byte> stream, IBinaryDocument binaryDocument) { UnmanagedBinaryMemoryBlock unmanagedBinaryMemoryBlock = new UnmanagedBinaryMemoryBlock(binaryDocument); byte *pMainBuffer = (byte *)unmanagedBinaryMemoryBlock.Pointer; byte *endOfBuffer = pMainBuffer + binaryDocument.Length; foreach (var b in stream) { if (pMainBuffer == endOfBuffer) { throw new IOException("stream length != binaryDocument.Length: " + binaryDocument.Location); } *pMainBuffer++ = b; } if (pMainBuffer != endOfBuffer) { throw new IOException("stream length != binaryDocument.Length: " + binaryDocument.Location); } return(unmanagedBinaryMemoryBlock); }
internal MetadataErrorContainer( PeReader metadataReader, IBinaryDocument binaryDocument ) { this.MetadataReader = metadataReader; this.BinaryDocument = binaryDocument; this.ErrorList = new MultiHashtable<MetadataReaderErrorMessage>(); }
/// <summary> /// Open the child binary document within the context of parent source document.as a memory block in host dependent fashion /// For example: in multimodule assemblies the main module will be parentSourceDocument, where as other modules will be child /// documents. /// IMPORTANT: The lifetime of the memory block is the same as the lifetime of this host object. /// Be sure to call Dispose on the host object when it is no longer needed, otherwise files may stay locked, /// or resources such as large blocks of memory may remain allocated until the host's finalizer method runs. /// </summary> /// <param name="parentSourceDocument">The source document indicating the child document location.</param> /// <param name="childDocumentName">The name of the child document.</param> /// <returns>The unmanaged memory block corresponding to the child document.</returns> /// <remarks>When overridding this method, be sure to add any disposable objects to this.disposableObjectAllocatedByThisHost.</remarks> public virtual IBinaryDocumentMemoryBlock/*?*/ OpenBinaryDocument(IBinaryDocument parentSourceDocument, string childDocumentName) { try { var directory = Path.GetDirectoryName(parentSourceDocument.Location)??""; var fullPath = Path.Combine(directory, childDocumentName); IBinaryDocument newBinaryDocument = BinaryDocument.GetBinaryDocumentForFile(fullPath, this); #if !COMPACTFX && !__MonoCS__ IBinaryDocumentMemoryBlock binDocMemoryBlock = MemoryMappedFile.CreateMemoryMappedFile(newBinaryDocument.Location, newBinaryDocument); #else IBinaryDocumentMemoryBlock binDocMemoryBlock = UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(newBinaryDocument.Location, newBinaryDocument); #endif this.disposableObjectAllocatedByThisHost.Add((IDisposable)binDocMemoryBlock); return binDocMemoryBlock; } catch (IOException) { return null; } }
internal MetadataLocation( IBinaryDocument binaryDocument, TableIndices tableIndex, uint rowId ) { this.binaryDocument = binaryDocument; this.tableIndex = tableIndex; this.rowId = rowId; }
/// <summary> /// Open the child binary document within the context of parent source document.as a memory block in host dependent fashion /// For example: in multimodule assemblies the main module will be parentSourceDocument, where as other modules will be child /// docuements. /// </summary> /// <param name="parentSourceDocument">The source document indicating the child document location.</param> /// <param name="childDocumentName">The name of the child document.</param> /// <returns> /// The unmanaged memory block corresponding to the child document. /// </returns> public IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument parentSourceDocument, string childDocumentName) { Contract.Requires(parentSourceDocument != null); Contract.Requires(childDocumentName != null); Contract.Ensures(Contract.Result<IBinaryDocumentMemoryBlock>() != null); throw new NotImplementedException(); }
internal MetadataStreamLocation( IBinaryDocument binaryDocument, string streamName, uint offset ) { this.binaryDocument = binaryDocument; this.streamName = streamName; this.offset = offset; }