Hello,
i'm currently working with Sytem.Runtime.InteropServices and i've a
problem with the marshalling between managed and unmanaged code.

I created a file called APIWin32.cs and declared the various structs
needed to use MapAndLoad method (the code is at the end of this mail).

When i try to use MapAndLoad from another type, it works fine, but
when i use PtrToStructure method it throws a System.TypeLoadException
and reports that it can't marshal OptionalHeader field in
IMAGE_NT_HEADERS type because the type definition of the field has no
layout information :

if(APIWin32.MapAndLoad(fileName,pathTo, ref loadedImage,false,true)){
IntPtr ptr =loadedImage.FileHeader;
IMAGE_NT_HEADERS imageNTHeaders = 
(IMAGE_NT_HEADERS)Marshal.PtrToStructure(ptr,typeof(IMAGE_NT_HEADERS));
...
}

I found out that this only happens when the last member of
the IMAGE_OPTIONAL_HEADER type is declared, it represents an array of structs (
public IMAGE_DATA_DIRECTORY [] DataDirectory;).

I know that this code is not complete for working with 64 bits PE
files... but i'm only trying to get this to work first.

Could anyone please explain me the correct way of marshalling an array
of structs? thanks

Here is the code i'm using:


        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_DATA_DIRECTORY
        {
                public UInt32   VirtualAddress;
                public UInt32   Size;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_OPTIONAL_HEADER
        {
                public UInt16    Magic;
                public Byte    MajorLinkerVersion;
                public Byte    MinorLinkerVersion;
                public UInt32   SizeOfCode;
                public UInt32   SizeOfInitializedData;
                public UInt32   SizeOfUninitializedData;
                public UInt32   AddressOfEntryPoint;
                public UInt32   BaseOfCode;
                public UInt32   BaseOfData;
                public UInt32   ImageBase;//UInt32
                public UInt32   SectionAlignment;
                public UInt32   FileAlignment;
                public UInt16    MajorOperatingSystemVersion;
                public UInt16    MinorOperatingSystemVersion;
                public UInt16    MajorImageVersion;
                public UInt16    MinorImageVersion;
                public UInt16    MajorSubsystemVersion;
                public UInt16    MinorSubsystemVersion;
                public UInt32   Win32VersionValue;
                public UInt32   SizeOfImage;
                public UInt32   SizeOfHeaders;
                public UInt32   CheckSum;
                public UInt16    Subsystem;
                public UInt16    DllCharacteristics;
                public UInt32   SizeOfStackReserve;//UInt32
                public UInt32   SizeOfStackCommit;//UInt32
                public UInt32   SizeOfHeapReserve;//UInt32
                public UInt32   SizeOfHeapCommit;//UInt32
                public UInt32   LoaderFlags;
                public UInt32   NumberOfRvaAndSizes;
                
[MarshalAs(UnmanagedType.ByValArray,SizeConst=16,ArraySubType=UnmanagedType.Struct)]
                public IMAGE_DATA_DIRECTORY [] DataDirectory;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_FILE_HEADER {
                public UInt16 Machine;
                public UInt16 NumberOfSections;
                public UInt32 TimeDateStamp;
                public UInt32 PointerToSymbolTable;
                public UInt32 NumberOfSymbols;
                public UInt16 SizeOfOptionalHeader;
                public UInt16 Characteristics;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_NT_HEADERS
        {
                public UInt32 Signature;
                public IMAGE_FILE_HEADER FileHeader; //IMAGE_FILE_HEADER
                public IMAGE_OPTIONAL_HEADER OptionalHeader;//IMAGE_OPTIONAL_HEADER
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LOADED_IMAGE
        {
                public String ModuleName; //PSTR
                public IntPtr hFile;  //handle
                public byte MappedAddress; //puchar
#if IMAGEHLP64
                public IntPtr FileHeader; //PIMAGE_NT_HEADERS64
#else
                PIMAGE_NT_HEADERS32 FileHeader;
#endif
                public IntPtr LastRvaSection; //PIMAGE_SECTION_HEADER
                public UInt32 NumberOfSections;//ULONG
                public IntPtr Sections;//PIMAGE_SECTION_HEADER
                public UInt32 Characteristics;//ULONG
                public bool fSystemImage;
                public bool fDOSImage;
                public IntPtr Links;//LIST_ENTRY
                public UInt32 SizeOfImage;//ULONG
        }

        public class Win32
        {

                [DllImport("imagehlp.dll")]
                public static extern bool MapAndLoad(
                        string ImageName,
                        string DllPath,
                        ref LOADED_IMAGE LoadedImage,  //PLOADED_IMAGE
                        bool DotDll,
                        bool ReadOnly
                        );
        ...
        }



--
Best regards,
 Bruno                          mailto:[EMAIL PROTECTED]

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to