EDITED: Reading Icon From EXE and Write it To Disk

EDIT: So after retrieving the RT_GROUP_ICON data and RT_ICON`s write them to the ICON structs for the .ICO on disk/ file. But I stile don't get a displayable icon.
If anyone have the time to point me in the right direction.
I would be wary grateful.

Here is a link to the code I have come up with this far.
http://pastebin.com/zHbA2TFA ( thought to use pastebin as longer codes get so messy. )
Last edited on
A Callback function is a function in your program that you write and give the address of to the system. The WindowProc is probably the most famous example of this: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx

The function usually has to to designate itself as such by including the "CALLBACK" function specifier in between the functions data type and name.
Last edited on
Hey thanks for your reply, so what you are saying is that a CALLBACK function is like a virtual function? (That analogy may be wery of.)
That I can / need to write my self?

Am stile not sure what you are saying.
It is a function that you have to write yourself but it is not related to an object in the way that a virtual function is. It's an application defined function that is accessible from an external library at run-time.
@Computergeek01: I guess this is something I need to research since I feel I know the Win32 API to a good extent, but I guess I was wrong.

Anyways I did a second attempt at on retrieving a resource from a "remote" executable.
And it finds the resources but when copying the buffer and and writes it to disk it is not a valid .ico/.png/.bmp image. Do anyone have any insight on way this is?

Re-Re-Edit: The code works, BUT by all the difrent icon sizes only 1 works / is displayable of the 7 entry's in RT_ICON with the difrent sizes on the icon. This has me wondering way, and are there any way to tell the difference of the entry's except for the name?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Resources.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <Windows.h>

using namespace std;

typedef BOOL (CALLBACK *EnumResNameProc)( HMODULE hModule,
                       LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam);

int main(int argc, char* argv[])
{
	HRSRC hRes = NULL;
	HGLOBAL hGlob = NULL;
	HMODULE hExe = NULL;
	char *cBuffer = NULL;
	DWORD dwSize = 0;

	hExe = LoadLibrary("TestRes.exe");
	if ( hExe == NULL )
	{
		cout << "FAILED! To get module. - Error Code: " << GetLastError() << endl;
	}

	hRes = FindResourceEx( hExe, RT_ICON, MAKEINTRESOURCE(1),
                             MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
	if ( hRes == NULL )
	{
		cout << "FAILED! To FindResourceEx. - Error Code: " << GetLastError() << endl;
	}

	hGlob = LoadResource( hExe, hRes );
	if ( hGlob == NULL )
	{
		cout << "FAILED! To LoadResource. - Error Code: " << GetLastError() << endl;
	}

	dwSize = SizeofResource( hExe, hRes );
	cBuffer = new char[dwSize];

	cBuffer = (char*)LockResource( hGlob );
	if ( cBuffer == NULL )
	{
		cout << "FAILED! To LockResource. - Error Code: " << GetLastError() << endl;
	}

	HANDLE hFile = CreateFile("test.ico", GENERIC_WRITE, 0,
                               NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if ( hFile == NULL )
	{
		cout << "FAILED! To CreateFile. - Error Code: " << GetLastError() << endl;
	}
	DWORD read = 0;
	
	if (!WriteFile(hFile, cBuffer, dwSize, &read, NULL))
	{
		cout << "Error Code: " << GetLastError() << " > An error acured when "
                             "writing file to disk abort." << endl;
		CloseHandle(hFile);
	} else {
		cout << ".";
		}

	cout << endl;
	CloseHandle(hFile);

	system("PAUSE");
	return 0;
}

EDIT: Also tryd with RT_GROUP_ICON with the same results.

Cheers
WetCode
Last edited on

And it finds the resources but when copying the buffer and and writes it to disk it is not a valid .ico/.png/.bmp image. Do anyone have any insight on way this is?

An icon file is more than just the icon resource(s). It also contains an icon directory, which is stored as a separate resource entry (of type RT_GROUP_ICON).

Andy

The format of icon resources
http://blogs.msdn.com/b/oldnewthing/archive/2012/07/20/10331787.aspx

Icons
http://msdn.microsoft.com/en-us/library/ms997538.aspx
Which includes code showing how to read an icon from an .ico file, and from a modules resource segment.
Last edited on
@andywestken: Wow thanks for great documentation I think this is exactly what I needed haven't manage to read it all yet.
But it looks like its the information I was missing to achieve this.

Cheers
WetCode.
EDIT: Removed code, it was all wrong.
Here is where am at with the problem now, for anyone intrested.

So now i should take the data i have and write them to the structurs for the .ICO file (not memory / resource )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
        BYTE   bWidth;               // Width, in pixels, of the image
        BYTE   bHeight;              // Height, in pixels, of the image
        BYTE   bColorCount;          // Number of colors in image (0 if >=8bpp)
        BYTE   bReserved;            // Reserved
        WORD   wPlanes;              // Color Planes
        WORD   wBitCount;            // Bits per pixel
        DWORD   dwBytesInRes;        // how many bytes in this resource?
        WORD   nID;                  // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
#pragma pack( pop )
 
// #pragmas are used here to insure that the structure's
// packing in memory matches the packing of the EXE or DLL.
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
        WORD            idReserved;             // Reserved (must be 0)
        WORD            idType;                 // Resource type (1 for icons)
        WORD            idCount;                        // How many images?
        GRPICONDIRENTRY   idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )
 
typedef struct
{
        BITMAPINFOHEADER   icHeader;   // DIB header
        RGBQUAD         icColors[1];   // Color table
        BYTE            icXOR[1];      // DIB bits for XOR mask
        BYTE            icAND[1];      // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE;
 
int main(int argc, char* argv[])
{
        HMODULE hExe = LoadLibrary("TestRes.exe");
        EnumResourceTypes(hExe, (ENUMRESTYPEPROC)ResTypes, 0);
 
        // Find the group resource which lists its images
                                       /* Need to set "IconGrpName" this from ResTypee */
        HRSRC hRsrc = FindResource( hExe, MAKEINTRESOURCE(1), RT_GROUP_ICON );
        // Load and Lock to get a pointer to a GRPICONDIR
        HGLOBAL hGlobal = LoadResource( hExe, hRsrc );
        GRPICONDIR *lpIconGroup = new GRPICONDIR[ SizeofResource( hExe, hRsrc ) ];
        RtlZeroMemory( lpIconGroup, SizeofResource( hExe, hRsrc ) );
        lpIconGroup = (GRPICONDIR*)LockResource( hGlobal );
        // We now have the header of the icon file now we need all the icons.
       
        cout << "Icon Count: " << lpIconGroup->idCount << endl;
        cout << "Type: " << lpIconGroup->idType  << endl;
        cout << "idReserved: " << lpIconGroup->idReserved << endl;
        for ( unsigned i = 0; i < lpIconGroup->idCount; i++ )
        {
                cout << "\tEntry ID: " << lpIconGroup->idEntries[i].nID << endl;
                cout << "\tEntry Height: " << (int)lpIconGroup->idEntries[i].bHeight << endl;
                cout << "\tEntry Height: " << (int)lpIconGroup->idEntries[i].bWidth << endl;
                cout << "\tEntry Size: " << lpIconGroup->idEntries[i].dwBytesInRes << endl << endl;
        }
 
        vector<ICONIMAGE*> vec_ICONIMAGE;
        for ( int i = 0; i < lpIconGroup->idCount; i++ )
        {
                HRSRC hrSrc = FindResource( hExe, MAKEINTRESOURCE( lpIconGroup->idEntries[0].nID ), RT_ICON );
                HGLOBAL hGlobEntry = LoadResource( hExe, hrSrc );
                ICONIMAGE *lpIconImage = new ICONIMAGE[ SizeofResource( hExe, hrSrc ) ];
                RtlZeroMemory( lpIconImage, SizeofResource( hExe, hrSrc ) );
                lpIconImage = (ICONIMAGE*)LockResource( hGlobEntry );
 
                vec_ICONIMAGE.push_back( lpIconImage );
        }
 
        system("PAUSE");
        return 0;
}
Last edited on
Ok so i did an atempt and it dont work, if this isent the way what is?
http://pastebin.com/zHbA2TFA ( tought to use pastebin as longer codes get so messy. )

I whould realy aprichiate som help if anyone have the time.

Thanks
WetCode
Topic archived. No new replies allowed.