Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Cannot extract bitmap from resources section of app!

Posted on 2010-01-04
16
Medium Priority
?
564 Views
Last Modified: 2013-12-03
Ah hello.

Firstly, I would like to wish everyone a happy, safe and prosperous 2010 :-)

Now, I am trying to extract a bitmap from executable using the following code:

      if ( HRSRC hRes = FindResource ( NULL, MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP ) )
      {
            if ( HGLOBAL hResLoad = LoadResource ( NULL, hRes ) )
            {
                  LPVOID pVoid = LockResource ( hResLoad );
                  DWORD dwSize = SizeofResource ( NULL, hRes );
                  CFile file ( _T("C:\\test.bmp"), CFile::modeCreate | CFile::modeWrite );
                  file.Write ( pVoid, dwSize );
            }
      }

The file is created, but when I double click it to open it, I get told it is an invalid bitmap.  This code is based on that found at http://www.codeproject.com/KB/winsdk/binaryresources.aspx, which, incidentally, does not work for bitmap resources either, but does work for custom resources (the article demonstrates extracting an EXE).

So, two questions:

1) Why does this code not work for a bitmap resource?

2) Assuming I can exract the bitmap correctly, I would like to be able to change it (say, using Paint), then re-embed it in my executable, in a similar way we can edit the resources of an executable/DLL in visual studio.  How can I do this?

(I assume that 2) is going to be the hardest question :))

TIA
0
Comment
Question by:mrwad99
  • 7
  • 5
  • 2
  • +2
16 Comments
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 200 total points
ID: 26172127
1) I would guess you are missing the bitmap header with information about the type of bitmap being stored.

2) Do you want to automate paint or was that just an example?
0
 
LVL 9

Assisted Solution

by:JohnGaby
JohnGaby earned 200 total points
ID: 26172134
I am not sure about #1.  Perhaps when the bitmap is stored as a resource, it does not contain the file header.?

As for the second, you should be able to load the .exe or .dll using VisualStudio and edit the resources directly.
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26172196
If everything happens in your application (I think so because I see the code you posted), you can simply use LoadBitmap function to load the bitmap from the resources:

hBitmap = (HBITMAP)LoadImage(hInstance,  MAKEINTRESOURCE(IDB_BITMAP1),
      IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
 
This is the correct way. You will get the correct object that you can save in a file (we are in the MFC zone, so you have a million of ways to implement it).
 
The code you posted looks OK. I hope you are sure (or at least you can debug and be sure) that you retrieve a correct object from the resources. Also the file is created, so the code works.

Only one thing - the bitmap in the resources is not the same as the bitmap that can be saved in the file. I do not remember exactly right now, but, at least, you need to add BITMAPFILEHEADER. When you add a bitmap to an application projects all these headers are removed (or replaced by one? - I do not remember exactly).

For sure the bm-file has an own structure.
How to save an image in the bmp-file:
http://www.experts-exchange.com/articles/Programming/System/Windows__Programming/Win32-Capture-an-image.html

http://msdn.microsoft.com/en-us/library/dd145119(VS.85).aspx

If you will load the image in the way I showed above and use the a function from the article from this link, it will work.

I read the article very fast, but, I'm afraid, you got it a bit wrong - it is about the binary resources, about a way to extract a binary resources.
0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 19

Author Comment

by:mrwad99
ID: 26172199
Andy/John:

1) That makes sense.  I have compared the two files in notepad and they are slightly different in the header area.

2) No, I don't want to automate paint.  Forget extracting the resource for now, what I need to be able to do is update my executable with a new resource.  I have my executable (a simple dialog app for the purposes of this discussion), which has a RESOURCES section containing a single bitmap (IDB_BITMAP1).  I want to be able to update the bitmap without a) having to rebuild the project in VS b) use VS at all in the manner JohnGaby/I have mentioned.  Something like this:

MyExe /update C:\NewBitmap.bmp

When called in this manner, the exe's IDB_BITMAP1 is C:\NewBitmap.bmp, instead of what was there previously.
0
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 1200 total points
ID: 26172213
My answer is the longest. :) It took too much time to type it. We all said the same.
Here is a blog post explaining the mistake if you are interested:
http://blogs.msdn.com/oldnewthing/archive/2009/12/11/9935462.aspx

0
 
LVL 19

Author Comment

by:mrwad99
ID: 26172225
pgnatyuk

Thanks for that.  

All:

I was using bitmap resources as an example; the codeproject article describes exactly what I need, and indeed I am using the code to extract a binary resource.  I was curious as to why it did not work for bitmaps.  This has been resolved as the fact that the header is missing.

So the main issue now is how I can update the resource in the executable.
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26172295
I think, you can do it in Visual Studio. Just open the executable and choose Resource Editor.
Without it, it is not a very easy task. You need a PE Editor. OllyDbg or something like that.

You can write your own application that will show the bitmap resources from an executable. I think, it will be possible to load an exe with LoadLibrary and retrieve the resource.

0
 
LVL 19

Author Comment

by:mrwad99
ID: 26172316
>> I think, you can do it in Visual Studio.

I know I definitely can do it in VS, I have done it many times before.  But I don't want to have to rely on VS to do it, I want to be able to code it myself.  VS obviously does it via code, so it must use functionality available to me.

Where should I start looking?
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26172374
http://msdn.microsoft.com/en-us/library/ms648049(VS.85).aspx

Check here. It will give you an idea. I have to say that I've not tried that way.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 26172388
Thank you :-)

I will look into that, but leave this question open for a short time in case anyone else has any input.
0
 
LVL 33

Accepted Solution

by:
pgnatyuk earned 1200 total points
ID: 26172418
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 26172443
I don't know if the exe can update itself - the file on disc might be locked to prevent changes.

You should be able to test that rapidly yourself by attempting to write something (few random numbers) into the resource area.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 26172466
Excellent, plenty to keep me occupied there.

Andy: Heh, good point :)  I might well ask how that could be worked around at a later date :)  Of course, if anyone can suggest anything now, well, awesome :)
0
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 400 total points
ID: 26189105
Use
   BeginUpdateResource
      UpdateResource Function
      http://msdn.microsoft.com/en-us/library/ms648049(VS.85).aspx
   EndUpdateResource

as suggested by pgnatyuk.  There are certain new restrictions upon when you can use this, but it's easy to throw together a test.  It will work for simple updates of programs with a simple  resource section in the executable file.
   
0
 
LVL 19

Author Comment

by:mrwad99
ID: 26189112
Thanks Dan.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 26189119
Again, thanks very much all:)
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question