System.ArgumentException HResult = 0x80070057 Message = Parameter is not valid. Source = System.Drawing. Why?

0

Using c#, I have extracted a cursor resource from a PE file and removed the x-y hotspots and prepended the BITMAPFILEHEADER but when I try to convert to a BITMAP for display in a Picture Box as pbResImage.Image = Image.FromStream(bitmapStream.BaseStream); I receive an argument exception.

My code works for dozens of cursors and the cursor in question is extractable using other programs.

I believe the simplest approach is to examine the actual inputs to both by code (bitmapBytes) and to the stream passed to Image.FromStream (bitmapStream). I have tried and tried with no success.

I am asking your help in examining the inputs and identifying what is ACTUALLY INVALID about bitmapStream. Once I know what .NET is finding faulty, a solution will probably be at hand.

Here is the bitmapBytes array that I extracted:

0000- 28 00 00 00 20 00 00 00 40 00 00 00 01 00 04 00
0010- 00 00 00 00 80 02 00 00 00 00 00 00 00 00 00 00
0020- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00
0030- 00 80 00 00 00 80 80 00 80 00 00 00 80 00 80 00
0040- 80 80 00 00 80 80 80 00 C0 c0 c0 00 00 00 FF 00
0050- 00 FF 00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00
0060- FF FF 00 00 FF FF FF 00 00 00 00 00 00 00 00 00
0070- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0080- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0090- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00a0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00b0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00c0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00d0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 88
00e0- 88 80 00 00 00 00 00 00 00 00 00 00 00 00 7F FF
00f0- FF F8 00 00 00 00 00 00 00 00 00 00 00 00 7F FF
0100- FF F8 00 00 00 00 00 00 00 00 00 00 00 07 FF FF
0110- FF FF 80 00 00 00 00 00 00 00 00 00 00 7F FF FF
0120- FF FF 80 00 00 00 00 00 00 00 00 00 07 FF FF FF
0130- FF FF F8 00 00 00 00 00 00 00 00 00 07 FF FF FF
0140- FF FF F8 00 00 00 00 00 00 00 00 00 7F FF FF FF
0150- FF FF F8 00 00 00 00 00 00 00 00 00 7F FF FF FF
0160- FF FF FF 80 00 00 00 00 00 00 00 07 FF FF FF FF
0170- FF FF FF 80 00 00 00 00 00 00 00 07 FF 88 FF FF
0180- FF FF FF 80 00 00 00 00 00 00 00 7F F8 00 FF FF
0190- FF FF FF 80 00 00 00 00 00 00 00 7F 80 07 FF FF
01a0- FF FF 7F 80 00 00 00 00 00 00 07 F8 00 07 FF 7F
01b0- F7 F8 0F 80 00 00 00 00 00 00 07 70 00 07 F8 0F
01c0- 80 F8 0F 80 00 00 00 00 00 00 00 00 00 07 F8 0F
01d0- 80 F8 07 70 00 00 00 00 00 00 00 00 00 07 F8 0F
01e0- 80 F8 00 00 00 00 00 00 00 00 00 00 00 07 F8 0F
01f0- 80 77 00 00 00 00 00 00 00 00 00 00 00 07 F8 07
0200- 70 00 00 00 00 00 00 00 00 00 00 00 00 07 F8 00
0210- 00 00 00 00 00 00 00 00 00 00 00 00 00 07 F8 00
0220- 00 00 00 00 00 00 00 00 00 00 00 00 00 07 F8 00
0230- 00 00 00 00 00 00 00 00 00 00 00 00 00 07 F8 00
0340- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 00
0250- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0260- 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF
0270- FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0280- FF FF FF FF FF F8 1F FF FF F0 0F FF FF F0 0F FF
0290- FF E0 03 FF FF c0 03 FF FF 80 01 FF FF 80 01 FF
02a0- FF 00 01 FF FF 00 00 FF FE 00 00 FF FE 00 00 FF
02b0- Fc 00 00 FF Fc 20 00 FF F8 60 00 FF F8 E0 00 FF
02c0- FF E0 01 FF FF E0 07 FF FF E0 0F FF FF E0 7F FF
02d0- FF E1 FF FF FF E1 FF FF FF E1 FF FF FF E1 FF FF
02e0- FF F3 FF FF FF FF FF FF

Here is the bitmapStream that is the "invalid" argument:

0000- 42 4D F6 02 00 00 00 00 00 00 76 00 00 00 28 00
0010- 00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00
0020- 00 00 80 02 00 00 00 00 00 00 00 00 00 00 00 00
0030- 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80
0040- 00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80
0050- 00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF
0060- 00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF
0070- 00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00
0080- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0090- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00a0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00b0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00c0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00d0- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00e0- 00 00 00 00 00 00 00 00 00 00 00 00 08 88 88 80
00f0- 00 00 00 00 00 00 00 00 00 00 00 00 7F FF FF F8
0100- 00 00 00 00 00 00 00 00 00 00 00 00 7F FF FF F8
0110- 00 00 00 00 00 00 00 00 00 00 00 07 FF FF FF FF
0120- 80 00 00 00 00 00 00 00 00 00 00 7F FF FF FF FF
0130- 80 00 00 00 00 00 00 00 00 00 07 FF FF FF FF FF
0140- F8 00 00 00 00 00 00 00 00 00 07 FF FF FF FF FF
0150- F8 00 00 00 00 00 00 00 00 00 7F FF FF FF FF FF
0160- F8 00 00 00 00 00 00 00 00 00 7F FF FF FF FF FF
0170- FF 80 00 00 00 00 00 00 00 07 FF FF FF FF FF FF
0180- FF 80 00 00 00 00 00 00 00 07 FF 88 FF FF FF FF
0190- FF 80 00 00 00 00 00 00 00 7F F8 00 FF FF FF FF
01a0- FF 80 00 00 00 00 00 00 00 7F 80 07 FF FF FF FF
01b0- 7F 80 00 00 00 00 00 00 07 F8 00 07 FF 7F F7 F8
01c0- 0F 80 00 00 00 00 00 00 07 70 00 07 F8 0F 80 F8
01d0- 0F 80 00 00 00 00 00 00 00 00 00 07 F8 0F 80 F8
01e0- 07 70 00 00 00 00 00 00 00 00 00 07 F8 0F 80 F8
01f0- 00 00 00 00 00 00 00 00 00 00 00 07 F8 0F 80 77
0200- 00 00 00 00 00 00 00 00 00 00 00 07 F8 07 70 00
0210- 00 00 00 00 00 00 00 00 00 00 00 07 F8 00 00 00
0220- 00 00 00 00 00 00 00 00 00 00 00 07 F8 00 00 00
0230- 00 00 00 00 00 00 00 00 00 00 00 07 F8 00 00 00
0340- 00 00 00 00 00 00 00 00 00 00 00 07 F8 00 00 00
0250- 00 00 00 00 00 00 00 00 00 00 00 00 77 00 00 00
0260- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0270- 00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF
0280- FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0290- FF FF FF F8 1F FF FF F0 0F FF FF F0 0F FF FF E0
02a0- 03 FF FF C0 03 FF FF 80 01 FF FF 80 01 FF FF 00
02b0- 01 FF FF 00 00 FF FE 00 00 FF FE 00 00 FF FC 00
02c0- 00 FF FC 20 00 FF F8 60 00 FF F8 E0 00 FF FF E0
02d0- 01 FF FF E0 07 FF FF E0 0F FF FF E0 7F FF FF E1
02e0- FF FF FF E1 FF FF FF E1 FF FF FF E1 FF FF FF F3
02f0- FF FF FF FF FF FF

Here is the relevant code:

    public void DisplayPECursor(TreeNode node)
    {
        Byte[] nodeBytes = (byte[])node.Tag;
        Byte[] bitmapBytes = new byte[nodeBytes.Length - 4];
        // Remove hotspot-x and hotspot-y values from the cursor resource data
        Buffer.BlockCopy(nodeBytes, 4, bitmapBytes, 0, nodeBytes.Count() - 4);

                   /////////////////////////////////// temp for debug
                   using (Stream file = File.OpenWrite(@"G:\___ProblemFiles\bitmapBytes.dat"))
                   {
                       file.Write(bitmapBytes, 0, bitmapBytes.Length);
                   }
                   ///////////////////////////////////

        (int sizeBITMAPINFOHEADER, int sizeColorTable) = GetBmHeaderInfo(bitmapBytes);


        int bitmapFileLen = bitmapBytes.Length + sizeBITMAPFILEHEADER;
        using (BinaryWriter bitmapStream = new BinaryWriter(new MemoryStream(bitmapFileLen)))
        {
            // Write the missing BITMAPFILEHEADER.
            const Int16 zero = 0;
            bitmapStream.Write(bmSignature);
            bitmapStream.Write(bitmapFileLen);
            bitmapStream.Write(zero);
            bitmapStream.Write(zero);
            bitmapStream.Write(sizeBITMAPFILEHEADER + sizeBITMAPINFOHEADER + sizeColorTable);
            bitmapStream.Seek(sizeBITMAPFILEHEADER, SeekOrigin.Begin);
            bitmapStream.Write(bitmapBytes, 0, bitmapBytes.Length);

                      /////////////////////////////////// temp for debug
                      //Save file for examination with hex editor
                      SaveStreamToFile(bitmapStream, @"G:\___ProblemFiles\My125.bmp");
                      ///////////////////////////////////

            pbResImage.Image = Image.FromStream(bitmapStream.BaseStream);
        }


            /////////////////////////////////////////////////////////////////// temp for debug
            //Internal method to save file for examination with hex editor
        void SaveStreamToFile(BinaryWriter streamName, string destFilename)
            {
                //The bmp file has been built in memory now save it to file
                  StreamReader reader = new StreamReader(streamName.BaseStream);
                int bufferLen = 4096;
                byte[] buffer = new byte[bufferLen];
                FileStream saveStream = new FileStream(destFilename, FileMode.Create, FileAccess.ReadWrite);
                streamName.Seek(0, SeekOrigin.Begin); // stream has been previously written so reposition to the beginning
                while (true)
                {
                    int read = streamName.BaseStream.Read(buffer, 0, bufferLen);

                    if (read > 0)
                    {
                        saveStream.Write(buffer, 0, read);
                    }
                    else
                        break;
                }
                saveStream.Close();
            }
            //////////////////////////////////////////////////////////////////////////
        return;
    }           
 _____________________________________________________________________________________________

    public (int sizeBITMAPINFOHEADER, int sizeColorTable) GetBmHeaderInfo(byte[] bitmapBytes)
    {
        //IntPtr offsetSizeInfoHeader = 
        //     Marshal.OffsetOf(typeof(NativeMethods.BITMAPINFOHEADER), "biSize");
        //IntPtr offsetBitCount = 
        //     Marshal.OffsetOf(typeof(NativeMethods.BITMAPINFOHEADER), "biBitCount");
        //IntPtr offsetClrUsed = 
        //     Marshal.OffsetOf(typeof(NativeMethods.BITMAPINFOHEADER), "biClrUsed");
        //IntPtr offsetCompression = 
        //     Marshal.OffsetOf(typeof(NativeMethods.BITMAPINFOHEADER), "biCompression");
        //int sizeBITMAPFILEHEADER = 
        //     System.Runtime.InteropServices.Marshal.SizeOf(typeof(NativeMethods.BITMAPFILEHEADER));
        //int sizeRGBQUAD = 
        //     System.Runtime.InteropServices.Marshal.SizeOf(typeof(NativeMethods.RGBQUAD));
        //UInt16 bmSignature;
        // the above variables were refactored to be class level; left here for now for clarity
        // for the Stackoverflow community.

        var headerSize = new byte[2];
        var bitCount = new byte[2];
        var compression = new byte[4];
        var clrUsed = new byte[4];
        Array.Copy(bitmapBytes, (int)offsetSizeInfoHeader, headerSize, 0, 2);
        Array.Copy(bitmapBytes, (int)offsetBitCount, bitCount, 0, 2);
        Array.Copy(bitmapBytes, (int)offsetCompression, compression, 0, 4);
        Array.Copy(bitmapBytes, (int)offsetClrUsed, clrUsed, 0, 4);
        int sizeBITMAPINFOHEADER = BitConverter.ToInt16(headerSize, 0);
        int count = BitConverter.ToInt16(bitCount, 0);
        int compress = BitConverter.ToInt32(compression, 0);
        int used = BitConverter.ToInt32(clrUsed, 0);
        if (used == 0) used = (int)Math.Pow(2, count);  // Assume the maximum if used = 0
        // Determine the size of the color table
        int sizeColorTable = 0;
        if (compress == (int)NativeMethods.biCompression.BI_BITFIELDS)
        {
            sizeColorTable = 12;
        }
        else if (compress == (int)NativeMethods.biCompression.BI_ALPHABITFIELDS)
        {
            sizeColorTable = 16;
        }
        else if (count < 16 && used > 0)
        {
            sizeColorTable = sizeRGBQUAD * used;
        }
        return (sizeBITMAPINFOHEADER, sizeColorTable);
    }              
c#
bitmap
system.drawing
asked on Stack Overflow Apr 17, 2021 by softwareguy

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0