private unsafe Stream GetBitmapStream(byte[] rawData)
        {
            try
            {
                try
                {
                    fixed(byte *numRef = rawData)
                    {
                        IntPtr ptr = (IntPtr)numRef;

                        if (ptr == IntPtr.Zero)
                        {
                            return(null);
                        }
                        if ((rawData.Length <= sizeof(SafeNativeMethods.OBJECTHEADER)) || (Marshal.ReadInt16(ptr) != 0x1c15))
                        {
                            return(null);
                        }
                        SafeNativeMethods.OBJECTHEADER objectheader = (SafeNativeMethods.OBJECTHEADER)Marshal.PtrToStructure(ptr, typeof(SafeNativeMethods.OBJECTHEADER));
                        if (rawData.Length <= (objectheader.headersize + 0x12))
                        {
                            return(null);
                        }
                        if (Encoding.ASCII.GetString(rawData, objectheader.headersize + 12, 6) != "PBrush")
                        {
                            return(null);
                        }
                        byte[] bytes = Encoding.ASCII.GetBytes("BM");
                        for (int i = objectheader.headersize + 0x12; (i < (objectheader.headersize + 510)) && ((i + 1) < rawData.Length); i++)
                        {
                            if ((bytes[0] == numRef[i]) && (bytes[1] == numRef[i + 1]))
                            {
                                return(new MemoryStream(rawData, i, rawData.Length - i));
                            }
                        }
                    }
                }
                finally
                {
                    numRef = null;
                }
            }
            catch (OutOfMemoryException)
            {
            }
            catch (ArgumentException)
            {
            }
            return(null);
        }
Example #2
0
        private unsafe Stream GetBitmapStream(byte[] rawData)
        {
            Debug.Assert(rawData != null, "rawData is null.");
            try
            {
                fixed(byte *pByte = rawData)
                {
                    IntPtr addr = (IntPtr)pByte;

                    if (addr == IntPtr.Zero)
                    {
                        return(null);
                    }

                    // this will be pHeader.signature, but we try to
                    // do this first so we avoid building the structure when we shouldn't
                    //
                    if (rawData.Length <= sizeof(SafeNativeMethods.OBJECTHEADER) || Marshal.ReadInt16(addr) != 0x1c15)
                    {
                        return(null);
                    }

                    // the data is one of these OBJECTHEADER dudes.  It's an encoded format that Access uses to push images
                    // into the DB.  It's not particularly documented, but I found a KB:
                    //
                    // http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175261
                    //
                    SafeNativeMethods.OBJECTHEADER pHeader = (SafeNativeMethods.OBJECTHEADER)Marshal.PtrToStructure(addr, typeof(SafeNativeMethods.OBJECTHEADER));

                    // "PBrush" should be the 6 chars after position 12 as well.
                    //
                    if (rawData.Length <= pHeader.headersize + 18)
                    {
                        return(null);
                    }
                    string strPBrush = System.Text.Encoding.ASCII.GetString(rawData, pHeader.headersize + 12, 6);

                    if (strPBrush != "PBrush")
                    {
                        return(null);
                    }

                    // okay, now we can safely trust that we've got a bitmap.
                    byte[] searchArray = System.Text.Encoding.ASCII.GetBytes("BM");

                    // search for "BM" in the data which is the start of our bitmap data...
                    //
                    // 18 is from (12+6) above.
                    //
                    for (int i = pHeader.headersize + 18; i < pHeader.headersize + 510 && i + 1 < rawData.Length; i++)
                    {
                        if (searchArray[0] == pByte[i] &&
                            searchArray[1] == pByte[i + 1])
                        {
                            // found the bitmap data.
                            //
                            return(new MemoryStream(rawData, i, rawData.Length - i));
                        }
                    }
                }
            }
            catch (OutOfMemoryException)            // this exception may be caused by creating a new MemoryStream
            {
            }
            catch (ArgumentException)               // may be caused by Marshal.PtrToStructure
            {
            }
            // nevermind...
            return(null);
        }